mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Large refactor and addedGetAllChanges to each change
tons of updates, so many things.
This commit is contained in:
@@ -86,7 +86,7 @@ type Schema struct {
|
||||
MinProperties *int64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
|
||||
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
Enum []any `json:"enum,omitempty" yaml:"enum,omitempty"`
|
||||
AdditionalProperties any `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
|
||||
AdditionalProperties any `json:"additionalProperties,omitempty" yaml:"additionalProperties,renderZero,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Default any `json:"default,omitempty" yaml:"default,omitempty"`
|
||||
Nullable *bool `json:"nullable,omitempty" yaml:"nullable,omitempty"`
|
||||
@@ -300,6 +300,7 @@ func NewSchema(schema *base.Schema) *Schema {
|
||||
p := &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||
ValueNode: sch.ValueNode,
|
||||
Value: sch.Value,
|
||||
Reference: sch.GetReference(),
|
||||
}}
|
||||
|
||||
bChan <- buildResult{idx: idx, s: p}
|
||||
|
||||
@@ -1019,3 +1019,74 @@ func TestNewSchemaProxy_RenderSchemaCheckAdditionalPropertiesSliceMap(t *testing
|
||||
assert.Len(t, schemaBytes, 75)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
func TestNewSchemaProxy_RenderAdditionalPropertiesFalse(t *testing.T) {
|
||||
testSpec := `additionalProperties: false`
|
||||
|
||||
var compNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(testSpec), &compNode)
|
||||
|
||||
sp := new(lowbase.SchemaProxy)
|
||||
err := sp.Build(compNode.Content[0], nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
lowproxy := low.NodeReference[*lowbase.SchemaProxy]{
|
||||
Value: sp,
|
||||
ValueNode: compNode.Content[0],
|
||||
}
|
||||
|
||||
schemaProxy := NewSchemaProxy(&lowproxy)
|
||||
compiled := schemaProxy.Schema()
|
||||
|
||||
// now render it out, it should be identical.
|
||||
schemaBytes, _ := compiled.Render()
|
||||
assert.Equal(t, testSpec, strings.TrimSpace(string(schemaBytes)))
|
||||
}
|
||||
|
||||
func TestNewSchemaProxy_RenderMultiplePoly(t *testing.T) {
|
||||
idxYaml := `openapi: 3.1.0
|
||||
components:
|
||||
schemas:
|
||||
balance_transaction:
|
||||
description: A balance transaction`
|
||||
|
||||
testSpec := `properties:
|
||||
bigBank:
|
||||
type: object
|
||||
properties:
|
||||
failure_balance_transaction:
|
||||
anyOf:
|
||||
- maxLength: 5000
|
||||
type: string
|
||||
- $ref: '#/components/schemas/balance_transaction'
|
||||
x-expansionResources:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/balance_transaction'`
|
||||
|
||||
var compNode, idxNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(testSpec), &compNode)
|
||||
_ = yaml.Unmarshal([]byte(idxYaml), &idxNode)
|
||||
|
||||
idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig())
|
||||
|
||||
sp := new(lowbase.SchemaProxy)
|
||||
|
||||
err := sp.Build(compNode.Content[0], idx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
lowproxy := low.NodeReference[*lowbase.SchemaProxy]{
|
||||
Value: sp,
|
||||
ValueNode: idxNode.Content[0],
|
||||
}
|
||||
|
||||
sch1 := SchemaProxy{schema: &lowproxy}
|
||||
compiled := sch1.Schema()
|
||||
|
||||
// now render it out, it should be identical.
|
||||
schemaBytes, _ := compiled.Render()
|
||||
assert.Equal(t, testSpec, strings.TrimSpace(string(schemaBytes)))
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/high"
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// SecurityRequirement is a high-level representation of a Swagger / OpenAPI 2 SecurityRequirement object.
|
||||
// SecurityRequirement is a high-level representation of a Swagger / OpenAPI 3 SecurityRequirement object.
|
||||
//
|
||||
// SecurityRequirement lists the required security schemes to execute this operation. The object can have multiple
|
||||
// security schemes declared in it which are all required (that is, there is a logical AND between the schemes).
|
||||
@@ -17,7 +19,7 @@ import (
|
||||
// The name used for each property MUST correspond to a security scheme declared in the Security Definitions
|
||||
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
||||
type SecurityRequirement struct {
|
||||
Requirements map[string][]string
|
||||
Requirements map[string][]string `json:"-" yaml:"-"`
|
||||
low *base.SecurityRequirement
|
||||
}
|
||||
|
||||
@@ -55,6 +57,69 @@ func (s *SecurityRequirement) Render() ([]byte, error) {
|
||||
|
||||
// MarshalYAML will create a ready to render YAML representation of the SecurityRequirement object.
|
||||
func (s *SecurityRequirement) MarshalYAML() (interface{}, error) {
|
||||
nb := high.NewNodeBuilder(s, s.low)
|
||||
return nb.Render(), nil
|
||||
|
||||
type req struct {
|
||||
line int
|
||||
key string
|
||||
val []string
|
||||
lowKey *low.KeyReference[string]
|
||||
lowVal *low.ValueReference[[]low.ValueReference[string]]
|
||||
}
|
||||
|
||||
m := utils.CreateEmptyMapNode()
|
||||
keys := make([]*req, len(s.Requirements))
|
||||
|
||||
i := 0
|
||||
|
||||
for k := range s.Requirements {
|
||||
keys[i] = &req{key: k, val: s.Requirements[k]}
|
||||
i++
|
||||
}
|
||||
i = 0
|
||||
for k := range s.low.Requirements.Value {
|
||||
if k.Value == keys[i].key {
|
||||
gh := s.low.Requirements.Value[k]
|
||||
keys[i].line = k.KeyNode.Line
|
||||
keys[i].lowKey = &k
|
||||
keys[i].lowVal = &gh
|
||||
}
|
||||
i++
|
||||
}
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
return keys[i].line < keys[j].line
|
||||
})
|
||||
|
||||
for k := range keys {
|
||||
l := utils.CreateStringNode(keys[k].key)
|
||||
l.Line = keys[k].line
|
||||
|
||||
// for each key, extract all the values and order them.
|
||||
type req struct {
|
||||
line int
|
||||
val string
|
||||
}
|
||||
|
||||
reqs := make([]*req, len(keys[k].val))
|
||||
for t := range keys[k].val {
|
||||
reqs[t] = &req{val: keys[k].val[t], line: 9999 + t}
|
||||
for _ = range keys[k].lowVal.Value[t].Value {
|
||||
fh := keys[k].val[t]
|
||||
df := keys[k].lowVal.Value[t].Value
|
||||
if fh == df {
|
||||
reqs[t].line = keys[k].lowVal.Value[t].ValueNode.Line
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(reqs, func(i, j int) bool {
|
||||
return reqs[i].line < reqs[j].line
|
||||
})
|
||||
sn := utils.CreateEmptySequenceNode()
|
||||
for z := range reqs {
|
||||
sn.Content = append(sn.Content, utils.CreateStringNode(reqs[z].val))
|
||||
}
|
||||
|
||||
m.Content = append(m.Content, l, sn)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -16,10 +16,11 @@ import (
|
||||
|
||||
// NodeEntry represents a single node used by NodeBuilder.
|
||||
type NodeEntry struct {
|
||||
Tag string
|
||||
Key string
|
||||
Value any
|
||||
Line int
|
||||
Tag string
|
||||
Key string
|
||||
Value any
|
||||
Line int
|
||||
RenderZero bool
|
||||
}
|
||||
|
||||
// NodeBuilder is a structure used by libopenapi high-level objects, to render themselves back to YAML.
|
||||
@@ -30,13 +31,16 @@ type NodeBuilder struct {
|
||||
Low any
|
||||
}
|
||||
|
||||
const renderZero = "renderZero"
|
||||
|
||||
// NewNodeBuilder will create a new NodeBuilder instance, this is the only way to create a NodeBuilder.
|
||||
// The function accepts a high level object and a low level object (need to be siblings/same type).
|
||||
//
|
||||
// Using reflection, a map of every field in the high level object is created, ready to be rendered.
|
||||
func NewNodeBuilder(high any, low any) *NodeBuilder {
|
||||
// create a new node builder
|
||||
nb := &NodeBuilder{High: high}
|
||||
nb := new(NodeBuilder)
|
||||
nb.High = high
|
||||
if low != nil {
|
||||
nb.Low = low
|
||||
}
|
||||
@@ -103,21 +107,27 @@ func (n *NodeBuilder) add(key string, i int) {
|
||||
field, _ := reflect.TypeOf(n.High).Elem().FieldByName(key)
|
||||
tag := string(field.Tag.Get("yaml"))
|
||||
tagName := strings.Split(tag, ",")[0]
|
||||
|
||||
if tag == "-" {
|
||||
return
|
||||
}
|
||||
|
||||
renderZeroVal := strings.Split(tag, ",")[1]
|
||||
|
||||
// extract the value of the field
|
||||
fieldValue := reflect.ValueOf(n.High).Elem().FieldByName(key)
|
||||
f := fieldValue.Interface()
|
||||
value := reflect.ValueOf(f)
|
||||
|
||||
if f == nil || value.IsZero() {
|
||||
if renderZeroVal != renderZero && (f == nil || value.IsZero()) {
|
||||
return
|
||||
}
|
||||
|
||||
// create a new node entry
|
||||
nodeEntry := &NodeEntry{Tag: tagName, Key: key}
|
||||
if renderZeroVal == renderZero {
|
||||
nodeEntry.RenderZero = true
|
||||
}
|
||||
|
||||
switch value.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
@@ -134,7 +144,7 @@ func (n *NodeBuilder) add(key string, i int) {
|
||||
nodeEntry.Value = f
|
||||
}
|
||||
} else {
|
||||
if !value.IsNil() && !value.IsZero() {
|
||||
if (renderZeroVal == renderZero) || (!value.IsNil() && !value.IsZero()) {
|
||||
nodeEntry.Value = f
|
||||
}
|
||||
}
|
||||
@@ -158,13 +168,30 @@ func (n *NodeBuilder) add(key string, i int) {
|
||||
fLow := lowFieldValue.Interface()
|
||||
value = reflect.ValueOf(fLow)
|
||||
switch value.Kind() {
|
||||
case reflect.Map:
|
||||
for _, ky := range value.MapKeys() {
|
||||
if we, wok := ky.Interface().(low.HasKeyNode); wok {
|
||||
nodeEntry.Line = we.GetKeyNode().Line
|
||||
break
|
||||
|
||||
case reflect.Slice:
|
||||
l := value.Len()
|
||||
lines := make([]int, l)
|
||||
for g := 0; g < l; g++ {
|
||||
qw := value.Index(g).Interface()
|
||||
if we, wok := qw.(low.HasKeyNode); wok {
|
||||
lines[g] = we.GetKeyNode().Line
|
||||
}
|
||||
}
|
||||
sort.Ints(lines)
|
||||
nodeEntry.Line = lines[0] // pick the lowest line number so this key is sorted in order.
|
||||
break
|
||||
case reflect.Map:
|
||||
|
||||
l := value.Len()
|
||||
lines := make([]int, l)
|
||||
for q, ky := range value.MapKeys() {
|
||||
if we, wok := ky.Interface().(low.HasKeyNode); wok {
|
||||
lines[q] = we.GetKeyNode().Line
|
||||
}
|
||||
}
|
||||
sort.Ints(lines)
|
||||
nodeEntry.Line = lines[0] // pick the lowest line number, sort in order
|
||||
|
||||
case reflect.Struct:
|
||||
y := value.Interface()
|
||||
@@ -202,6 +229,10 @@ func (n *NodeBuilder) renderReference() []*yaml.Node {
|
||||
|
||||
// Render will render the NodeBuilder back to a YAML node, iterating over every NodeEntry defined
|
||||
func (n *NodeBuilder) Render() *yaml.Node {
|
||||
if len(n.Nodes) == 0 {
|
||||
return utils.CreateEmptyMapNode()
|
||||
}
|
||||
|
||||
// order nodes by line number, retain original order
|
||||
m := utils.CreateEmptyMapNode()
|
||||
if fg, ok := n.Low.(low.IsReferenced); ok {
|
||||
@@ -223,7 +254,7 @@ func (n *NodeBuilder) Render() *yaml.Node {
|
||||
|
||||
for i := range n.Nodes {
|
||||
node := n.Nodes[i]
|
||||
n.AddYAMLNode(m, node.Tag, node.Key, node.Value, node.Line)
|
||||
n.AddYAMLNode(m, node)
|
||||
}
|
||||
if len(m.Content) > 0 {
|
||||
return m
|
||||
@@ -234,35 +265,45 @@ func (n *NodeBuilder) Render() *yaml.Node {
|
||||
// AddYAMLNode will add a new *yaml.Node to the parent node, using the tag, key and value provided.
|
||||
// If the value is nil, then the node will not be added. This method is recursive, so it will dig down
|
||||
// into any non-scalar types.
|
||||
func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, tag, key string, value any, line int) *yaml.Node {
|
||||
if value == nil {
|
||||
func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, entry *NodeEntry) *yaml.Node {
|
||||
if entry.Value == nil {
|
||||
return parent
|
||||
}
|
||||
|
||||
// check the type
|
||||
t := reflect.TypeOf(value)
|
||||
t := reflect.TypeOf(entry.Value)
|
||||
var l *yaml.Node
|
||||
if tag != "" {
|
||||
l = utils.CreateStringNode(tag)
|
||||
if entry.Tag != "" {
|
||||
l = utils.CreateStringNode(entry.Tag)
|
||||
}
|
||||
|
||||
value := entry.Value
|
||||
line := entry.Line
|
||||
key := entry.Key
|
||||
|
||||
var valueNode *yaml.Node
|
||||
switch t.Kind() {
|
||||
|
||||
case reflect.String:
|
||||
val := value.(string)
|
||||
if val == "" {
|
||||
if val == "" && !entry.RenderZero {
|
||||
return parent
|
||||
}
|
||||
|
||||
valueNode = utils.CreateStringNode(val)
|
||||
valueNode.Line = line
|
||||
break
|
||||
|
||||
case reflect.Bool:
|
||||
val := value.(bool)
|
||||
if !val {
|
||||
if !val && !entry.RenderZero {
|
||||
return parent
|
||||
}
|
||||
valueNode = utils.CreateBoolNode("true")
|
||||
if !val {
|
||||
valueNode = utils.CreateBoolNode("false")
|
||||
} else {
|
||||
valueNode = utils.CreateBoolNode("true")
|
||||
}
|
||||
valueNode.Line = line
|
||||
break
|
||||
|
||||
@@ -371,7 +412,7 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, tag, key string, value any,
|
||||
|
||||
// build out each map node in original order.
|
||||
for _, cv := range orderedCollection {
|
||||
n.AddYAMLNode(p, cv.Tag, cv.Key, cv.Value, cv.Line)
|
||||
n.AddYAMLNode(p, cv)
|
||||
}
|
||||
if len(p.Content) > 0 {
|
||||
valueNode = p
|
||||
@@ -387,6 +428,7 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, tag, key string, value any,
|
||||
var rawNode yaml.Node
|
||||
m := reflect.ValueOf(value)
|
||||
sl := utils.CreateEmptySequenceNode()
|
||||
skip := false
|
||||
for i := 0; i < m.Len(); i++ {
|
||||
|
||||
sqi := m.Index(i).Interface()
|
||||
@@ -407,10 +449,29 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, tag, key string, value any,
|
||||
nodes[1] = utils.CreateStringNode(glu.GoLowUntyped().(low.IsReferenced).GetReference())
|
||||
rt.Content = append(rt.Content, nodes...)
|
||||
sl.Content = append(sl.Content, rt)
|
||||
skip = true
|
||||
|
||||
} else {
|
||||
|
||||
// TODO: pick up here in the AM looks like we need to correctly handle
|
||||
|
||||
if er, ko := sqi.(Renderable); ko {
|
||||
rend, _ := er.(Renderable).MarshalYAML()
|
||||
sl.Content = append(sl.Content, rend.(*yaml.Node))
|
||||
skip = true
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if er, ko := sqi.(Renderable); ko {
|
||||
rend, _ := er.(Renderable).MarshalYAML()
|
||||
sl.Content = append(sl.Content, rend.(*yaml.Node))
|
||||
skip = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -419,6 +480,9 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, tag, key string, value any,
|
||||
valueNode = sl
|
||||
break
|
||||
}
|
||||
if skip {
|
||||
break
|
||||
}
|
||||
|
||||
err := rawNode.Encode(value)
|
||||
if err != nil {
|
||||
@@ -468,6 +532,11 @@ func (n *NodeBuilder) AddYAMLNode(parent *yaml.Node, tag, key string, value any,
|
||||
if *b {
|
||||
valueNode = utils.CreateBoolNode("true")
|
||||
valueNode.Line = line
|
||||
} else {
|
||||
if entry.RenderZero {
|
||||
valueNode = utils.CreateBoolNode("false")
|
||||
valueNode.Line = line
|
||||
}
|
||||
}
|
||||
}
|
||||
if b, bok := value.(*int64); bok {
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type key struct {
|
||||
Name string `yaml:"name"`
|
||||
Name string `yaml:"name,omitempty"`
|
||||
ref bool
|
||||
refStr string
|
||||
ln int
|
||||
@@ -71,27 +71,27 @@ func (k key) MarshalYAML() (interface{}, error) {
|
||||
}
|
||||
|
||||
type test1 struct {
|
||||
Thing string `yaml:"thing"`
|
||||
Thong int `yaml:"thong"`
|
||||
Thrum int64 `yaml:"thrum"`
|
||||
Thang float32 `yaml:"thang"`
|
||||
Thung float64 `yaml:"thung"`
|
||||
Thyme bool `yaml:"thyme"`
|
||||
Thurm any `yaml:"thurm"`
|
||||
Thugg *bool `yaml:"thugg"`
|
||||
Thurr *int64 `yaml:"thurr"`
|
||||
Thral *float64 `yaml:"thral"`
|
||||
Tharg []string `yaml:"tharg"`
|
||||
Type []string `yaml:"type"`
|
||||
Throg []*key `yaml:"throg"`
|
||||
Thrug map[string]string `yaml:"thrug"`
|
||||
Thoom []map[string]string `yaml:"thoom"`
|
||||
Thomp map[key]string `yaml:"thomp"`
|
||||
Thump key `yaml:"thump"`
|
||||
Thane key `yaml:"thane"`
|
||||
Thunk key `yaml:"thunk"`
|
||||
Thrim *key `yaml:"thrim"`
|
||||
Thril map[string]*key `yaml:"thril"`
|
||||
Thing string `yaml:"thing,omitempty"`
|
||||
Thong int `yaml:"thong,omitempty"`
|
||||
Thrum int64 `yaml:"thrum,omitempty"`
|
||||
Thang float32 `yaml:"thang,omitempty"`
|
||||
Thung float64 `yaml:"thung,omitempty"`
|
||||
Thyme bool `yaml:"thyme,omitempty"`
|
||||
Thurm any `yaml:"thurm,omitempty"`
|
||||
Thugg *bool `yaml:"thugg,omitempty"`
|
||||
Thurr *int64 `yaml:"thurr,omitempty"`
|
||||
Thral *float64 `yaml:"thral,omitempty"`
|
||||
Tharg []string `yaml:"tharg,omitempty"`
|
||||
Type []string `yaml:"type,omitempty"`
|
||||
Throg []*key `yaml:"throg,omitempty"`
|
||||
Thrug map[string]string `yaml:"thrug,omitempty"`
|
||||
Thoom []map[string]string `yaml:"thoom,omitempty"`
|
||||
Thomp map[key]string `yaml:"thomp,omitempty"`
|
||||
Thump key `yaml:"thump,omitempty"`
|
||||
Thane key `yaml:"thane,omitempty"`
|
||||
Thunk key `yaml:"thunk,omitempty"`
|
||||
Thrim *key `yaml:"thrim,omitempty"`
|
||||
Thril map[string]*key `yaml:"thril,omitempty"`
|
||||
Extensions map[string]any `yaml:"-"`
|
||||
ignoreMe string `yaml:"-"`
|
||||
IgnoreMe string `yaml:"-"`
|
||||
@@ -159,7 +159,7 @@ func TestNewNodeBuilder(t *testing.T) {
|
||||
ignoreMe: "I should never be seen!",
|
||||
Thing: "ding",
|
||||
Thong: 1,
|
||||
Thurm: &test1{},
|
||||
Thurm: nil,
|
||||
Thrum: 1234567,
|
||||
Thang: 2.2,
|
||||
Thung: 3.33333,
|
||||
@@ -195,16 +195,12 @@ func TestNewNodeBuilder(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
nb := NewNodeBuilder(&t1, &t1)
|
||||
nb := NewNodeBuilder(&t1, nil)
|
||||
node := nb.Render()
|
||||
|
||||
data, _ := yaml.Marshal(node)
|
||||
|
||||
desired := `thrug:
|
||||
chicken: nuggets
|
||||
thomp:
|
||||
meddy: princess
|
||||
thing: ding
|
||||
desired := `thing: ding
|
||||
thong: "1"
|
||||
thrum: "1234567"
|
||||
thang: 2.20
|
||||
@@ -217,9 +213,13 @@ tharg:
|
||||
- chicken
|
||||
- nuggets
|
||||
type: chicken
|
||||
thrug:
|
||||
chicken: nuggets
|
||||
thoom:
|
||||
- maddy: champion
|
||||
- ember: naughty
|
||||
thomp:
|
||||
meddy: princess
|
||||
x-pizza: time`
|
||||
|
||||
assert.Equal(t, desired, strings.TrimSpace(string(data)))
|
||||
@@ -306,22 +306,25 @@ func TestNewNodeBuilder_NoValue(t *testing.T) {
|
||||
Thing: "",
|
||||
}
|
||||
|
||||
nodeEnty := NodeEntry{}
|
||||
nb := NewNodeBuilder(&t1, &t1)
|
||||
node := nb.AddYAMLNode(nil, "", "", nil, 0)
|
||||
node := nb.AddYAMLNode(nil, &nodeEnty)
|
||||
assert.Nil(t, node)
|
||||
}
|
||||
|
||||
func TestNewNodeBuilder_EmptyString(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nodeEnty := NodeEntry{}
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
node := nb.AddYAMLNode(nil, "", "", "", 0)
|
||||
node := nb.AddYAMLNode(nil, &nodeEnty)
|
||||
assert.Nil(t, node)
|
||||
}
|
||||
|
||||
func TestNewNodeBuilder_Bool(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
node := nb.AddYAMLNode(nil, "", "", false, 0)
|
||||
nodeEnty := NodeEntry{}
|
||||
node := nb.AddYAMLNode(nil, &nodeEnty)
|
||||
assert.Nil(t, node)
|
||||
}
|
||||
|
||||
@@ -329,7 +332,8 @@ func TestNewNodeBuilder_Int(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
p := utils.CreateEmptyMapNode()
|
||||
node := nb.AddYAMLNode(p, "p", "p", 12, 0)
|
||||
nodeEnty := NodeEntry{Tag: "p", Value: 12, Key: "p"}
|
||||
node := nb.AddYAMLNode(p, &nodeEnty)
|
||||
assert.NotNil(t, node)
|
||||
assert.Len(t, node.Content, 2)
|
||||
assert.Equal(t, "12", node.Content[1].Value)
|
||||
@@ -339,7 +343,8 @@ func TestNewNodeBuilder_Int64(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
p := utils.CreateEmptyMapNode()
|
||||
node := nb.AddYAMLNode(p, "p", "p", int64(234556), 0)
|
||||
nodeEnty := NodeEntry{Tag: "p", Value: int64(234556), Key: "p"}
|
||||
node := nb.AddYAMLNode(p, &nodeEnty)
|
||||
assert.NotNil(t, node)
|
||||
assert.Len(t, node.Content, 2)
|
||||
assert.Equal(t, "234556", node.Content[1].Value)
|
||||
@@ -349,7 +354,8 @@ func TestNewNodeBuilder_Float32(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
p := utils.CreateEmptyMapNode()
|
||||
node := nb.AddYAMLNode(p, "p", "p", float32(1234.23), 0)
|
||||
nodeEnty := NodeEntry{Tag: "p", Value: float32(1234.23), Key: "p"}
|
||||
node := nb.AddYAMLNode(p, &nodeEnty)
|
||||
assert.NotNil(t, node)
|
||||
assert.Len(t, node.Content, 2)
|
||||
assert.Equal(t, "1234.23", node.Content[1].Value)
|
||||
@@ -359,7 +365,8 @@ func TestNewNodeBuilder_Float64(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
p := utils.CreateEmptyMapNode()
|
||||
node := nb.AddYAMLNode(p, "p", "p", 1234.232323, 0)
|
||||
nodeEnty := NodeEntry{Tag: "p", Value: 1234.232323, Key: "p"}
|
||||
node := nb.AddYAMLNode(p, &nodeEnty)
|
||||
assert.NotNil(t, node)
|
||||
assert.Len(t, node.Content, 2)
|
||||
assert.Equal(t, "1234.232323", node.Content[1].Value)
|
||||
@@ -478,7 +485,8 @@ func TestNewNodeBuilder_MissingLabel(t *testing.T) {
|
||||
t1 := new(test1)
|
||||
nb := NewNodeBuilder(t1, t1)
|
||||
p := utils.CreateEmptyMapNode()
|
||||
node := nb.AddYAMLNode(p, "", "p", 1234.232323, 0)
|
||||
nodeEnty := NodeEntry{Value: 1234.232323, Key: "p"}
|
||||
node := nb.AddYAMLNode(p, &nodeEnty)
|
||||
assert.NotNil(t, node)
|
||||
assert.Len(t, node.Content, 0)
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ type Document struct {
|
||||
// an empty security requirement ({}) can be included in the array.
|
||||
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
||||
Security []*base.SecurityRequirement `json:"security,omitempty" yaml:"security,omitempty"`
|
||||
//Security []*base.SecurityRequirement `json:"-" yaml:"-"`
|
||||
|
||||
// Tags is a slice of base.Tag instances defined by the specification
|
||||
// A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on
|
||||
@@ -70,7 +71,7 @@ type Document struct {
|
||||
// The default value for the $schema keyword within Schema Objects contained within this OAS document.
|
||||
// This MUST be in the form of a URI.
|
||||
// - https://spec.openapis.org/oas/v3.1.0#schema-object
|
||||
JsonSchemaDialect string `json:"$schema,omitempty" yaml:"$schema,omitempty"`
|
||||
JsonSchemaDialect string `json:"jsonSchemaDialect,omitempty" yaml:"jsonSchemaDialect,omitempty"`
|
||||
|
||||
// Webhooks is a 3.1+ property that is similar to callbacks, except, this defines incoming webhooks.
|
||||
// The incoming webhooks that MAY be received as part of this API and that the API consumer MAY choose to implement.
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
type RequestBody struct {
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Content map[string]*MediaType `json:"content,omitempty" yaml:"content,omitempty"`
|
||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
Required *bool `json:"required,omitempty" yaml:"required,renderZero,omitempty"`
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
low *low.RequestBody
|
||||
}
|
||||
@@ -24,7 +24,9 @@ func NewRequestBody(rb *low.RequestBody) *RequestBody {
|
||||
r := new(RequestBody)
|
||||
r.low = rb
|
||||
r.Description = rb.Description.Value
|
||||
r.Required = rb.Required.Value
|
||||
if rb.Required.ValueNode != nil {
|
||||
r.Required = &rb.Required.Value
|
||||
}
|
||||
r.Extensions = high.ExtractExtensions(rb.Extensions)
|
||||
r.Content = ExtractContent(rb.Content.Value)
|
||||
return r
|
||||
|
||||
@@ -11,9 +11,10 @@ import (
|
||||
|
||||
func TestRequestBody_MarshalYAML(t *testing.T) {
|
||||
|
||||
rb := true
|
||||
req := &RequestBody{
|
||||
Description: "beer",
|
||||
Required: true,
|
||||
Required: &rb,
|
||||
Extensions: map[string]interface{}{"x-high-gravity": "why not?"},
|
||||
}
|
||||
|
||||
@@ -26,3 +27,38 @@ x-high-gravity: why not?`
|
||||
assert.Equal(t, desired, strings.TrimSpace(string(rend)))
|
||||
|
||||
}
|
||||
|
||||
func TestRequestBody_MarshalNoRequired(t *testing.T) {
|
||||
rb := false
|
||||
req := &RequestBody{
|
||||
Description: "beer",
|
||||
Required: &rb,
|
||||
Extensions: map[string]interface{}{"x-high-gravity": "why not?"},
|
||||
}
|
||||
|
||||
rend, _ := req.Render()
|
||||
|
||||
desired := `description: beer
|
||||
required: false
|
||||
x-high-gravity: why not?`
|
||||
|
||||
assert.Equal(t, desired, strings.TrimSpace(string(rend)))
|
||||
|
||||
}
|
||||
|
||||
func TestRequestBody_MarshalRequiredNil(t *testing.T) {
|
||||
|
||||
req := &RequestBody{
|
||||
Description: "beer",
|
||||
Extensions: map[string]interface{}{"x-high-gravity": "why not?"},
|
||||
}
|
||||
|
||||
rend, _ := req.Render()
|
||||
|
||||
desired := `description: beer
|
||||
x-high-gravity: why not?`
|
||||
|
||||
assert.Equal(t, desired, strings.TrimSpace(string(rend)))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1468,6 +1468,31 @@ func TestSchema_Hash_AdditionalPropsSlice(t *testing.T) {
|
||||
assert.Equal(t, lHash, rHash)
|
||||
}
|
||||
|
||||
func TestSchema_Hash_AdditionalPropsSliceNoMap(t *testing.T) {
|
||||
left := `schema:
|
||||
additionalProperties:
|
||||
- hello`
|
||||
|
||||
right := `schema:
|
||||
additionalProperties:
|
||||
- hello`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
lDoc, _ := ExtractSchema(lNode.Content[0], nil)
|
||||
rDoc, _ := ExtractSchema(rNode.Content[0], nil)
|
||||
|
||||
assert.NotNil(t, lDoc)
|
||||
assert.NotNil(t, rDoc)
|
||||
|
||||
lHash := lDoc.Value.Schema().Hash()
|
||||
rHash := rDoc.Value.Schema().Hash()
|
||||
|
||||
assert.Equal(t, lHash, rHash)
|
||||
}
|
||||
|
||||
func TestSchema_Hash_NotEqual(t *testing.T) {
|
||||
left := `schema:
|
||||
title: an OK message - but different
|
||||
|
||||
@@ -1536,3 +1536,27 @@ func TestGenerateHashString(t *testing.T) {
|
||||
GenerateHashString("hello"))
|
||||
|
||||
}
|
||||
|
||||
func TestSetReference(t *testing.T) {
|
||||
|
||||
type testObj struct {
|
||||
*Reference
|
||||
}
|
||||
|
||||
n := testObj{Reference: &Reference{}}
|
||||
SetReference(&n, "#/pigeon/street")
|
||||
|
||||
assert.Equal(t, "#/pigeon/street", n.GetReference())
|
||||
|
||||
}
|
||||
|
||||
func TestSetReference_nil(t *testing.T) {
|
||||
|
||||
type testObj struct {
|
||||
*Reference
|
||||
}
|
||||
|
||||
n := testObj{Reference: &Reference{}}
|
||||
SetReference(nil, "#/pigeon/street")
|
||||
assert.NotEqual(t, "#/pigeon/street", n.GetReference())
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ type hotdog struct {
|
||||
LotsOfUnknowns []NodeReference[any]
|
||||
Where map[string]NodeReference[any]
|
||||
There map[string]NodeReference[string]
|
||||
AllTheThings NodeReference[map[KeyReference[string]]ValueReference[string]]
|
||||
}
|
||||
|
||||
func TestBuildModel_Mismatch(t *testing.T) {
|
||||
@@ -99,7 +100,10 @@ where:
|
||||
bears: 200
|
||||
there:
|
||||
oh: yeah
|
||||
care: bear`
|
||||
care: bear
|
||||
allTheThings:
|
||||
beer: isGood
|
||||
cake: isNice`
|
||||
|
||||
var rootNode yaml.Node
|
||||
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
@@ -129,6 +133,16 @@ there:
|
||||
assert.Len(t, hd.There, 2)
|
||||
assert.Equal(t, "bear", hd.There["care"].Value)
|
||||
assert.Equal(t, 324938249028.98234892374892374923874823974, hd.Mustard.Value)
|
||||
|
||||
allTheThings := hd.AllTheThings.Value
|
||||
for i := range allTheThings {
|
||||
if i.Value == "beer" {
|
||||
assert.Equal(t, "isGood", allTheThings[i].Value)
|
||||
}
|
||||
if i.Value == "cake" {
|
||||
assert.Equal(t, "isNice", allTheThings[i].Value)
|
||||
}
|
||||
}
|
||||
assert.NoError(t, cErr)
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,9 @@ func (n ValueReference[T]) MarshalYAML() (interface{}, error) {
|
||||
nodes := make([]*yaml.Node, 2)
|
||||
nodes[0] = utils.CreateStringNode("$ref")
|
||||
nodes[1] = utils.CreateStringNode(n.Reference)
|
||||
return nodes, nil
|
||||
m := utils.CreateEmptyMapNode()
|
||||
m.Content = nodes
|
||||
return m, nil
|
||||
}
|
||||
var h yaml.Node
|
||||
e := n.ValueNode.Decode(&h)
|
||||
|
||||
@@ -5,6 +5,9 @@ package low
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
@@ -558,3 +561,196 @@ func TestHashToString(t *testing.T) {
|
||||
HashToString(sha256.Sum256([]byte("12345"))))
|
||||
|
||||
}
|
||||
|
||||
func TestReference_IsReference(t *testing.T) {
|
||||
ref := Reference{
|
||||
Reference: "#/components/schemas/SomeSchema",
|
||||
}
|
||||
assert.True(t, ref.IsReference())
|
||||
|
||||
}
|
||||
|
||||
func TestNodeReference_NodeLineNumber(t *testing.T) {
|
||||
|
||||
n := utils.CreateStringNode("pizza")
|
||||
nr := NodeReference[string]{
|
||||
Value: "pizza",
|
||||
ValueNode: n,
|
||||
}
|
||||
|
||||
n.Line = 3
|
||||
assert.Equal(t, 3, nr.NodeLineNumber())
|
||||
}
|
||||
|
||||
func TestNodeReference_NodeLineNumberEmpty(t *testing.T) {
|
||||
|
||||
nr := NodeReference[string]{
|
||||
Value: "pizza",
|
||||
}
|
||||
assert.Equal(t, 0, nr.NodeLineNumber())
|
||||
}
|
||||
|
||||
func TestNodeReference_GetReference(t *testing.T) {
|
||||
|
||||
nr := NodeReference[string]{
|
||||
Reference: "#/happy/sunday",
|
||||
}
|
||||
assert.Equal(t, "#/happy/sunday", nr.GetReference())
|
||||
}
|
||||
|
||||
func TestNodeReference_SetReference(t *testing.T) {
|
||||
|
||||
nr := NodeReference[string]{}
|
||||
nr.SetReference("#/happy/sunday")
|
||||
}
|
||||
|
||||
func TestNodeReference_IsReference(t *testing.T) {
|
||||
|
||||
nr := NodeReference[string]{
|
||||
ReferenceNode: true,
|
||||
}
|
||||
assert.True(t, nr.IsReference())
|
||||
}
|
||||
|
||||
func TestNodeReference_GetKeyNode(t *testing.T) {
|
||||
|
||||
nr := NodeReference[string]{
|
||||
KeyNode: utils.CreateStringNode("pizza"),
|
||||
}
|
||||
assert.Equal(t, "pizza", nr.GetKeyNode().Value)
|
||||
|
||||
}
|
||||
|
||||
func TestNodeReference_GetValueUntyped(t *testing.T) {
|
||||
|
||||
type anything struct {
|
||||
thing string
|
||||
}
|
||||
|
||||
nr := NodeReference[any]{
|
||||
Value: anything{thing: "ding"},
|
||||
}
|
||||
|
||||
assert.Equal(t, "{ding}", fmt.Sprint(nr.GetValueUntyped()))
|
||||
}
|
||||
|
||||
func TestValueReference_NodeLineNumber(t *testing.T) {
|
||||
|
||||
n := utils.CreateStringNode("pizza")
|
||||
nr := ValueReference[string]{
|
||||
Value: "pizza",
|
||||
ValueNode: n,
|
||||
}
|
||||
|
||||
n.Line = 3
|
||||
assert.Equal(t, 3, nr.NodeLineNumber())
|
||||
}
|
||||
|
||||
func TestValueReference_NodeLineNumber_Nil(t *testing.T) {
|
||||
|
||||
nr := ValueReference[string]{
|
||||
Value: "pizza",
|
||||
}
|
||||
|
||||
assert.Equal(t, 0, nr.NodeLineNumber())
|
||||
}
|
||||
|
||||
func TestValueReference_GetReference(t *testing.T) {
|
||||
|
||||
nr := ValueReference[string]{
|
||||
Reference: "#/happy/sunday",
|
||||
}
|
||||
assert.Equal(t, "#/happy/sunday", nr.GetReference())
|
||||
}
|
||||
|
||||
func TestValueReference_SetReference(t *testing.T) {
|
||||
|
||||
nr := ValueReference[string]{}
|
||||
nr.SetReference("#/happy/sunday")
|
||||
}
|
||||
|
||||
func TestValueReference_GetValueUntyped(t *testing.T) {
|
||||
|
||||
type anything struct {
|
||||
thing string
|
||||
}
|
||||
|
||||
nr := ValueReference[any]{
|
||||
Value: anything{thing: "ding"},
|
||||
}
|
||||
|
||||
assert.Equal(t, "{ding}", fmt.Sprint(nr.GetValueUntyped()))
|
||||
}
|
||||
|
||||
func TestValueReference_IsReference(t *testing.T) {
|
||||
|
||||
nr := NodeReference[string]{
|
||||
ReferenceNode: true,
|
||||
}
|
||||
assert.True(t, nr.IsReference())
|
||||
}
|
||||
|
||||
func TestValueReference_MarshalYAML_Ref(t *testing.T) {
|
||||
|
||||
nr := ValueReference[string]{
|
||||
ReferenceNode: true,
|
||||
Reference: "#/burgers/beer",
|
||||
}
|
||||
|
||||
data, _ := yaml.Marshal(nr)
|
||||
assert.Equal(t, `$ref: '#/burgers/beer'`, strings.TrimSpace(string(data)))
|
||||
|
||||
}
|
||||
|
||||
func TestValueReference_MarshalYAML(t *testing.T) {
|
||||
|
||||
v := map[string]interface{}{
|
||||
"beer": "burger",
|
||||
"wine": "cheese",
|
||||
}
|
||||
|
||||
var enc yaml.Node
|
||||
enc.Encode(&v)
|
||||
|
||||
nr := ValueReference[any]{
|
||||
Value: v,
|
||||
ValueNode: &enc,
|
||||
}
|
||||
|
||||
data, _ := yaml.Marshal(nr)
|
||||
|
||||
expected := `beer: burger
|
||||
wine: cheese`
|
||||
|
||||
assert.Equal(t, expected, strings.TrimSpace(string(data)))
|
||||
}
|
||||
|
||||
func TestKeyReference_GetValueUntyped(t *testing.T) {
|
||||
|
||||
type anything struct {
|
||||
thing string
|
||||
}
|
||||
|
||||
nr := KeyReference[any]{
|
||||
Value: anything{thing: "ding"},
|
||||
}
|
||||
|
||||
assert.Equal(t, "{ding}", fmt.Sprint(nr.GetValueUntyped()))
|
||||
}
|
||||
|
||||
func TestKeyReference_GetKeyNode(t *testing.T) {
|
||||
kn := utils.CreateStringNode("pizza")
|
||||
kn.Line = 3
|
||||
|
||||
nr := KeyReference[any]{
|
||||
KeyNode: kn,
|
||||
}
|
||||
|
||||
assert.Equal(t, 3, nr.GetKeyNode().Line)
|
||||
assert.Equal(t, "pizza", nr.GetKeyNode().Value)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@ func initTest() {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
var err []error
|
||||
doc, err = CreateDocument(info)
|
||||
doc, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
wait := true
|
||||
for wait {
|
||||
select {
|
||||
@@ -38,7 +41,10 @@ func BenchmarkCreateDocument(b *testing.B) {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
for i := 0; i < b.N; i++ {
|
||||
doc, _ = CreateDocument(info)
|
||||
doc, _ = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,28 +11,29 @@ const (
|
||||
HeadersLabel = "headers"
|
||||
ExpressionLabel = "expression"
|
||||
InfoLabel = "info"
|
||||
SwaggerLabel = "swagger"
|
||||
ParametersLabel = "parameters"
|
||||
RequestBodyLabel = "requestBody"
|
||||
RequestBodiesLabel = "requestBodies"
|
||||
ResponsesLabel = "responses"
|
||||
CallbacksLabel = "callbacks"
|
||||
ContentLabel = "content"
|
||||
PathsLabel = "paths"
|
||||
PathLabel = "path"
|
||||
WebhooksLabel = "webhooks"
|
||||
JSONSchemaDialectLabel = "jsonSchemaDialect"
|
||||
GetLabel = "get"
|
||||
PostLabel = "post"
|
||||
PatchLabel = "patch"
|
||||
PutLabel = "put"
|
||||
DeleteLabel = "delete"
|
||||
OptionsLabel = "options"
|
||||
HeadLabel = "head"
|
||||
TraceLabel = "trace"
|
||||
LinksLabel = "links"
|
||||
DefaultLabel = "default"
|
||||
SecurityLabel = "security"
|
||||
SwaggerLabel = "swagger"
|
||||
ParametersLabel = "parameters"
|
||||
RequestBodyLabel = "requestBody"
|
||||
RequestBodiesLabel = "requestBodies"
|
||||
ResponsesLabel = "responses"
|
||||
CallbacksLabel = "callbacks"
|
||||
ContentLabel = "content"
|
||||
PathsLabel = "paths"
|
||||
PathLabel = "path"
|
||||
WebhooksLabel = "webhooks"
|
||||
JSONSchemaDialectLabel = "jsonSchemaDialect"
|
||||
JSONSchemaLabel = "$schema"
|
||||
GetLabel = "get"
|
||||
PostLabel = "post"
|
||||
PatchLabel = "patch"
|
||||
PutLabel = "put"
|
||||
DeleteLabel = "delete"
|
||||
OptionsLabel = "options"
|
||||
HeadLabel = "head"
|
||||
TraceLabel = "trace"
|
||||
LinksLabel = "links"
|
||||
DefaultLabel = "default"
|
||||
SecurityLabel = "security"
|
||||
SecuritySchemesLabel = "securitySchemes"
|
||||
OAuthFlowsLabel = "flows"
|
||||
VariablesLabel = "variables"
|
||||
|
||||
@@ -19,6 +19,7 @@ func initTest() {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/burgershop.openapi.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
var err []error
|
||||
// deprecated function test.
|
||||
doc, err = CreateDocument(info)
|
||||
if err != nil {
|
||||
panic("broken something")
|
||||
@@ -29,7 +30,10 @@ func BenchmarkCreateDocument(b *testing.B) {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/burgershop.openapi.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
for i := 0; i < b.N; i++ {
|
||||
doc, _ = CreateDocument(info)
|
||||
doc, _ = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +41,10 @@ func BenchmarkCreateDocument_Circular(b *testing.B) {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/circular-tests.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := CreateDocument(info)
|
||||
_, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
if err != nil {
|
||||
panic("this should not error")
|
||||
}
|
||||
@@ -51,7 +58,10 @@ func BenchmarkCreateDocument_k8s(b *testing.B) {
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
||||
_, err := CreateDocument(info)
|
||||
_, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
if err != nil {
|
||||
panic("this should not error")
|
||||
}
|
||||
@@ -62,7 +72,10 @@ func TestCircularReferenceError(t *testing.T) {
|
||||
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/circular-tests.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
circDoc, err := CreateDocument(info)
|
||||
circDoc, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.NotNil(t, circDoc)
|
||||
assert.Len(t, err, 3)
|
||||
}
|
||||
@@ -72,7 +85,10 @@ func BenchmarkCreateDocument_Stripe(b *testing.B) {
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := CreateDocument(info)
|
||||
_, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
if err != nil {
|
||||
panic("this should not error")
|
||||
}
|
||||
@@ -83,7 +99,10 @@ func BenchmarkCreateDocument_Petstore(b *testing.B) {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/petstorev3.json")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := CreateDocument(info)
|
||||
_, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
if err != nil {
|
||||
panic("this should not error")
|
||||
}
|
||||
@@ -94,7 +113,11 @@ func TestCreateDocumentStripe(t *testing.T) {
|
||||
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/stripe.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
d, err := CreateDocument(info)
|
||||
d, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
BasePath: "/here",
|
||||
})
|
||||
assert.Len(t, err, 3)
|
||||
|
||||
assert.Equal(t, "3.0.0", d.Version.Value)
|
||||
@@ -137,7 +160,10 @@ func TestCreateDocument_WebHooks_Error(t *testing.T) {
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
_, err = CreateDocument(info)
|
||||
_, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
}
|
||||
|
||||
@@ -523,7 +549,10 @@ components:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
doc, err = CreateDocument(info)
|
||||
doc, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 0)
|
||||
|
||||
ob := doc.Components.Value.FindSchema("bork").Value
|
||||
@@ -539,7 +568,10 @@ webhooks:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
doc, err = CreateDocument(info)
|
||||
doc, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
}
|
||||
|
||||
@@ -552,7 +584,10 @@ components:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
_, err = CreateDocument(info)
|
||||
_, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
|
||||
}
|
||||
@@ -565,7 +600,10 @@ paths:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
_, err = CreateDocument(info)
|
||||
_, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
}
|
||||
|
||||
@@ -576,7 +614,10 @@ tags:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
_, err = CreateDocument(info)
|
||||
_, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
}
|
||||
|
||||
@@ -587,7 +628,10 @@ security:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
_, err = CreateDocument(info)
|
||||
_, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
}
|
||||
|
||||
@@ -598,7 +642,10 @@ externalDocs:
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
_, err = CreateDocument(info)
|
||||
_, err = CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
assert.Len(t, err, 1)
|
||||
}
|
||||
|
||||
@@ -612,7 +659,10 @@ func ExampleCreateDocument() {
|
||||
info, _ := datamodel.ExtractSpecInfo(petstoreBytes)
|
||||
|
||||
// build low-level document model
|
||||
document, errors := CreateDocument(info)
|
||||
document, errors := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
})
|
||||
|
||||
// if something went wrong, a slice of errors is returned
|
||||
if len(errors) > 0 {
|
||||
|
||||
21
document.go
21
document.go
@@ -70,7 +70,7 @@ type Document interface {
|
||||
// **IMPORTANT** This method only supports OpenAPI Documents. The Swagger model will not support mutations correctly
|
||||
// and will not update when called. This choice has been made because we don't want to continue supporting Swagger,
|
||||
// it's too old, so it should be motivation to upgrade to OpenAPI 3.
|
||||
RenderAndReload() ([]byte, *Document, *DocumentModel[v3high.Document], []error)
|
||||
RenderAndReload() ([]byte, Document, *DocumentModel[v3high.Document], []error)
|
||||
|
||||
// Serialize will re-render a Document back into a []byte slice. If any modifications have been made to the
|
||||
// underlying data model using low level APIs, then those changes will be reflected in the serialized output.
|
||||
@@ -156,7 +156,7 @@ func (d *document) Serialize() ([]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *document) RenderAndReload() ([]byte, *Document, *DocumentModel[v3high.Document], []error) {
|
||||
func (d *document) RenderAndReload() ([]byte, Document, *DocumentModel[v3high.Document], []error) {
|
||||
if d.highSwaggerModel != nil && d.highOpenAPI3Model == nil {
|
||||
return nil, nil, nil, []error{errors.New("this method only supports OpenAPI 3 documents, not Swagger")}
|
||||
}
|
||||
@@ -166,15 +166,15 @@ func (d *document) RenderAndReload() ([]byte, *Document, *DocumentModel[v3high.D
|
||||
}
|
||||
newDoc, err := NewDocument(newBytes)
|
||||
if err != nil {
|
||||
return newBytes, &newDoc, nil, []error{err}
|
||||
return newBytes, newDoc, nil, []error{err}
|
||||
}
|
||||
// build the model.
|
||||
model, errs := newDoc.BuildV3Model()
|
||||
if errs != nil {
|
||||
return newBytes, &newDoc, model, errs
|
||||
return newBytes, newDoc, model, errs
|
||||
}
|
||||
// this document is now dead, long live the new document!
|
||||
return newBytes, &newDoc, model, nil
|
||||
return newBytes, newDoc, model, nil
|
||||
}
|
||||
|
||||
func (d *document) BuildV2Model() (*DocumentModel[v2high.Swagger], []error) {
|
||||
@@ -278,14 +278,13 @@ func CompareDocuments(original, updated Document) (*model.DocumentChanges, []err
|
||||
}
|
||||
v3ModelRight, errs := updated.BuildV3Model()
|
||||
if len(errs) > 0 {
|
||||
errors = errs
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if v3ModelLeft != nil && v3ModelRight != nil {
|
||||
return what_changed.CompareOpenAPIDocuments(v3ModelLeft.Model.GoLow(), v3ModelRight.Model.GoLow()), errors
|
||||
} else {
|
||||
return nil, errs
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
}
|
||||
if original.GetSpecInfo().SpecType == utils.OpenApi2 && updated.GetSpecInfo().SpecType == utils.OpenApi2 {
|
||||
v2ModelLeft, errs := original.BuildV2Model()
|
||||
@@ -294,13 +293,13 @@ func CompareDocuments(original, updated Document) (*model.DocumentChanges, []err
|
||||
}
|
||||
v2ModelRight, errs := updated.BuildV2Model()
|
||||
if len(errs) > 0 {
|
||||
errors = errs
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if v2ModelLeft != nil && v2ModelRight != nil {
|
||||
return what_changed.CompareSwaggerDocuments(v2ModelLeft.Model.GoLow(), v2ModelRight.Model.GoLow()), errors
|
||||
} else {
|
||||
return nil, errs
|
||||
return nil, errors
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
return nil, []error{fmt.Errorf("unable to compare documents, one or both documents are not of the same version")}
|
||||
}
|
||||
|
||||
601
document_examples_test.go
Normal file
601
document_examples_test.go
Normal file
@@ -0,0 +1,601 @@
|
||||
// Copyright 2023 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package libopenapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/datamodel"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pb33f/libopenapi/datamodel/high"
|
||||
low "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"github.com/pb33f/libopenapi/resolver"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func ExampleNewDocument_fromOpenAPI3Document() {
|
||||
|
||||
// How to read in an OpenAPI 3 Specification, into a Document.
|
||||
|
||||
// load an OpenAPI 3 specification from bytes
|
||||
petstore, _ := ioutil.ReadFile("test_specs/petstorev3.json")
|
||||
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument(petstore)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// because we know this is a v3 spec, we can build a ready to go model from it.
|
||||
v3Model, errors := document.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// get a count of the number of paths and schemas.
|
||||
paths := len(v3Model.Model.Paths.PathItems)
|
||||
schemas := len(v3Model.Model.Components.Schemas)
|
||||
|
||||
// print the number of paths and schemas in the document
|
||||
fmt.Printf("There are %d paths and %d schemas in the document", paths, schemas)
|
||||
// Output: There are 13 paths and 8 schemas in the document
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromWithDocumentConfigurationFailure() {
|
||||
|
||||
// This example shows how to create a document that prevents the loading of external references/
|
||||
// from files or the network
|
||||
|
||||
// load in the Digital Ocean OpenAPI specification
|
||||
digitalOcean, _ := ioutil.ReadFile("test_specs/digitalocean.yaml")
|
||||
|
||||
// create a DocumentConfiguration that prevents loading file and remote references
|
||||
config := datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
}
|
||||
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocumentWithConfiguration(digitalOcean, &config)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// only errors will be thrown, so just capture them and print the number of errors.
|
||||
_, errors := doc.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
fmt.Println("Error building Digital Ocean spec errors reported")
|
||||
}
|
||||
// Output: Error building Digital Ocean spec errors reported
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromWithDocumentConfigurationSuccess() {
|
||||
|
||||
// This example shows how to create a document that prevents the loading of external references/
|
||||
// from files or the network
|
||||
|
||||
// load in the Digital Ocean OpenAPI specification
|
||||
digitalOcean, _ := ioutil.ReadFile("test_specs/digitalocean.yaml")
|
||||
|
||||
// Digital Ocean needs a baseURL to be set, so we can resolve relative references.
|
||||
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
|
||||
|
||||
// create a DocumentConfiguration that allows loading file and remote references, and sets the baseURL
|
||||
// to somewhere that can resolve the relative references.
|
||||
config := datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: true,
|
||||
AllowRemoteReferences: true,
|
||||
BaseURL: baseURL,
|
||||
}
|
||||
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocumentWithConfiguration(digitalOcean, &config)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// only errors will be thrown, so just capture them and print the number of errors.
|
||||
_, errors := doc.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
fmt.Println("Error building Digital Ocean spec errors reported")
|
||||
} else {
|
||||
fmt.Println("Digital Ocean spec built successfully")
|
||||
}
|
||||
// Output: Digital Ocean spec built successfully
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromSwaggerDocument() {
|
||||
|
||||
// How to read in a Swagger / OpenAPI 2 Specification, into a Document.
|
||||
|
||||
// load a Swagger specification from bytes
|
||||
petstore, _ := ioutil.ReadFile("test_specs/petstorev2.json")
|
||||
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument(petstore)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// because we know this is a v2 spec, we can build a ready to go model from it.
|
||||
v2Model, errors := document.BuildV2Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// get a count of the number of paths and schemas.
|
||||
paths := len(v2Model.Model.Paths.PathItems)
|
||||
schemas := len(v2Model.Model.Definitions.Definitions)
|
||||
|
||||
// print the number of paths and schemas in the document
|
||||
fmt.Printf("There are %d paths and %d schemas in the document", paths, schemas)
|
||||
// Output: There are 14 paths and 6 schemas in the document
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromUnknownVersion() {
|
||||
|
||||
// load an unknown version of an OpenAPI spec
|
||||
petstore, _ := ioutil.ReadFile("test_specs/burgershop.openapi.yaml")
|
||||
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument(petstore)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
var paths, schemas int
|
||||
var errors []error
|
||||
|
||||
// We don't know which type of document this is, so we can use the spec info to inform us
|
||||
if document.GetSpecInfo().SpecType == utils.OpenApi3 {
|
||||
v3Model, errs := document.BuildV3Model()
|
||||
if len(errs) > 0 {
|
||||
errors = errs
|
||||
}
|
||||
if len(errors) <= 0 {
|
||||
paths = len(v3Model.Model.Paths.PathItems)
|
||||
schemas = len(v3Model.Model.Components.Schemas)
|
||||
}
|
||||
}
|
||||
if document.GetSpecInfo().SpecType == utils.OpenApi2 {
|
||||
v2Model, errs := document.BuildV2Model()
|
||||
if len(errs) > 0 {
|
||||
errors = errs
|
||||
}
|
||||
if len(errors) <= 0 {
|
||||
paths = len(v2Model.Model.Paths.PathItems)
|
||||
schemas = len(v2Model.Model.Definitions.Definitions)
|
||||
}
|
||||
}
|
||||
|
||||
// if anything went wrong when building the model, report errors.
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// print the number of paths and schemas in the document
|
||||
fmt.Printf("There are %d paths and %d schemas in the document", paths, schemas)
|
||||
// Output: There are 5 paths and 6 schemas in the document
|
||||
}
|
||||
|
||||
func ExampleNewDocument_mutateValuesAndSerialize() {
|
||||
|
||||
// How to mutate values in an OpenAPI Specification, without re-ordering original content.
|
||||
|
||||
// create very small, and useless spec that does nothing useful, except showcase this feature.
|
||||
spec := `
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: This is a title
|
||||
contact:
|
||||
name: Some Person
|
||||
email: some@emailaddress.com
|
||||
license:
|
||||
url: http://some-place-on-the-internet.com/license
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// because we know this is a v3 spec, we can build a ready to go model from it.
|
||||
v3Model, errors := document.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// mutate the title, to do this we currently need to drop down to the low-level API.
|
||||
v3Model.Model.GoLow().Info.Value.Title.Mutate("A new title for a useless spec")
|
||||
|
||||
// mutate the email address in the contact object.
|
||||
v3Model.Model.GoLow().Info.Value.Contact.Value.Email.Mutate("buckaroo@pb33f.io")
|
||||
|
||||
// mutate the name in the contact object.
|
||||
v3Model.Model.GoLow().Info.Value.Contact.Value.Name.Mutate("Buckaroo")
|
||||
|
||||
// mutate the URL for the license object.
|
||||
v3Model.Model.GoLow().Info.Value.License.Value.URL.Mutate("https://pb33f.io/license")
|
||||
|
||||
// serialize the document back into the original YAML or JSON
|
||||
mutatedSpec, serialError := document.Serialize()
|
||||
|
||||
// if something went wrong serializing
|
||||
if serialError != nil {
|
||||
panic(fmt.Sprintf("cannot serialize document: %e", serialError))
|
||||
}
|
||||
|
||||
// print our modified spec!
|
||||
fmt.Println(string(mutatedSpec))
|
||||
// Output: openapi: 3.1.0
|
||||
//info:
|
||||
// title: A new title for a useless spec
|
||||
// contact:
|
||||
// name: Buckaroo
|
||||
// email: buckaroo@pb33f.io
|
||||
// license:
|
||||
// url: https://pb33f.io/license
|
||||
}
|
||||
|
||||
func ExampleCompareDocuments_openAPI() {
|
||||
|
||||
// How to compare two different OpenAPI specifications.
|
||||
|
||||
// load an original OpenAPI 3 specification from bytes
|
||||
burgerShopOriginal, _ := ioutil.ReadFile("test_specs/burgershop.openapi.yaml")
|
||||
|
||||
// load an **updated** OpenAPI 3 specification from bytes
|
||||
burgerShopUpdated, _ := ioutil.ReadFile("test_specs/burgershop.openapi-modified.yaml")
|
||||
|
||||
// create a new document from original specification bytes
|
||||
originalDoc, err := NewDocument(burgerShopOriginal)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// create a new document from updated specification bytes
|
||||
updatedDoc, err := NewDocument(burgerShopUpdated)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// Compare documents for all changes made
|
||||
documentChanges, errs := CompareDocuments(originalDoc, updatedDoc)
|
||||
|
||||
// If anything went wrong when building models for documents.
|
||||
if len(errs) > 0 {
|
||||
for i := range errs {
|
||||
fmt.Printf("error: %e\n", errs[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot compare documents: %d errors reported", len(errs)))
|
||||
}
|
||||
|
||||
// Extract SchemaChanges from components changes.
|
||||
schemaChanges := documentChanges.ComponentsChanges.SchemaChanges
|
||||
|
||||
// Print out some interesting stats about the OpenAPI document changes.
|
||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||
documentChanges.TotalChanges(), documentChanges.TotalBreakingChanges(), len(schemaChanges))
|
||||
//Output: There are 72 changes, of which 17 are breaking. 5 schemas have changes.
|
||||
|
||||
}
|
||||
|
||||
func ExampleCompareDocuments_swagger() {
|
||||
|
||||
// How to compare two different Swagger specifications.
|
||||
|
||||
// load an original OpenAPI 3 specification from bytes
|
||||
petstoreOriginal, _ := ioutil.ReadFile("test_specs/petstorev2-complete.yaml")
|
||||
|
||||
// load an **updated** OpenAPI 3 specification from bytes
|
||||
petstoreUpdated, _ := ioutil.ReadFile("test_specs/petstorev2-complete-modified.yaml")
|
||||
|
||||
// create a new document from original specification bytes
|
||||
originalDoc, err := NewDocument(petstoreOriginal)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// create a new document from updated specification bytes
|
||||
updatedDoc, err := NewDocument(petstoreUpdated)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// Compare documents for all changes made
|
||||
documentChanges, errs := CompareDocuments(originalDoc, updatedDoc)
|
||||
|
||||
// If anything went wrong when building models for documents.
|
||||
if len(errs) > 0 {
|
||||
for i := range errs {
|
||||
fmt.Printf("error: %e\n", errs[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot compare documents: %d errors reported", len(errs)))
|
||||
}
|
||||
|
||||
// Extract SchemaChanges from components changes.
|
||||
schemaChanges := documentChanges.ComponentsChanges.SchemaChanges
|
||||
|
||||
// Print out some interesting stats about the Swagger document changes.
|
||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||
documentChanges.TotalChanges(), documentChanges.TotalBreakingChanges(), len(schemaChanges))
|
||||
//Output: There are 52 changes, of which 27 are breaking. 5 schemas have changes.
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_Paths_As_Array(t *testing.T) {
|
||||
|
||||
// paths can now be wrapped in an array.
|
||||
spec := `{
|
||||
"openapi": "3.1.0",
|
||||
"paths": [
|
||||
"/": {
|
||||
"get": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
v3Model, _ := doc.BuildV3Model()
|
||||
assert.NotNil(t, v3Model)
|
||||
}
|
||||
|
||||
// If you want to know more about circular references that have been found
|
||||
// during the parsing/indexing/building of a document, you can capture the
|
||||
// []errors thrown which are pointers to *resolver.ResolvingError
|
||||
func ExampleNewDocument_infinite_circular_references() {
|
||||
|
||||
// create a specification with an obvious and deliberate circular reference
|
||||
spec := `openapi: "3.1"
|
||||
components:
|
||||
schemas:
|
||||
One:
|
||||
description: "test one"
|
||||
properties:
|
||||
things:
|
||||
"$ref": "#/components/schemas/Two"
|
||||
required:
|
||||
- things
|
||||
Two:
|
||||
description: "test two"
|
||||
properties:
|
||||
testThing:
|
||||
"$ref": "#/components/schemas/One"
|
||||
required:
|
||||
- testThing
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
_, errs := doc.BuildV3Model()
|
||||
|
||||
// extract resolving error
|
||||
resolvingError := errs[0]
|
||||
|
||||
// resolving error is a pointer to *resolver.ResolvingError
|
||||
// which provides access to rich details about the error.
|
||||
circularReference := resolvingError.(*resolver.ResolvingError).CircularReference
|
||||
|
||||
// capture the journey with all details
|
||||
var buf strings.Builder
|
||||
for n := range circularReference.Journey {
|
||||
|
||||
// add the full definition name to the journey.
|
||||
buf.WriteString(circularReference.Journey[n].Definition)
|
||||
if n < len(circularReference.Journey)-1 {
|
||||
buf.WriteString(" -> ")
|
||||
}
|
||||
}
|
||||
|
||||
// print out the journey and the loop point.
|
||||
fmt.Printf("Journey: %s\n", buf.String())
|
||||
fmt.Printf("Loop Point: %s", circularReference.LoopPoint.Definition)
|
||||
// Output: Journey: #/components/schemas/Two -> #/components/schemas/One -> #/components/schemas/Two
|
||||
// Loop Point: #/components/schemas/Two
|
||||
}
|
||||
|
||||
// This tests checks that circular references which are _not_ marked as required pass correctly
|
||||
func TestNewDocument_terminable_circular_references(t *testing.T) {
|
||||
|
||||
// create a specification with an obvious and deliberate circular reference
|
||||
spec := `openapi: "3.1"
|
||||
components:
|
||||
schemas:
|
||||
One:
|
||||
description: "test one"
|
||||
properties:
|
||||
things:
|
||||
"$ref": "#/components/schemas/Two"
|
||||
Two:
|
||||
description: "test two"
|
||||
properties:
|
||||
testThing:
|
||||
"$ref": "#/components/schemas/One"
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
_, errs := doc.BuildV3Model()
|
||||
|
||||
assert.Len(t, errs, 0)
|
||||
}
|
||||
|
||||
// If you're using complex types with OpenAPI Extensions, it's simple to unpack extensions into complex
|
||||
// types using `high.UnpackExtensions()`. libopenapi retains the original raw data in the low model (not the high)
|
||||
// which means unpacking them can be a little complex.
|
||||
//
|
||||
// This example demonstrates how to use the `UnpackExtensions` with custom OpenAPI extensions.
|
||||
func ExampleNewDocument_unpacking_extensions() {
|
||||
|
||||
// define an example struct representing a cake
|
||||
type cake struct {
|
||||
Candles int `yaml:"candles"`
|
||||
Frosting string `yaml:"frosting"`
|
||||
Some_Strange_Var_Name string `yaml:"someStrangeVarName"`
|
||||
}
|
||||
|
||||
// define a struct that holds a map of cake pointers.
|
||||
type cakes struct {
|
||||
Description string
|
||||
Cakes map[string]*cake
|
||||
}
|
||||
|
||||
// define a struct representing a burger
|
||||
type burger struct {
|
||||
Sauce string
|
||||
Patty string
|
||||
}
|
||||
|
||||
// define a struct that holds a map of cake pointers
|
||||
type burgers struct {
|
||||
Description string
|
||||
Burgers map[string]*burger
|
||||
}
|
||||
|
||||
// create a specification with a schema and parameter that use complex custom cakes and burgers extensions.
|
||||
spec := `openapi: "3.1"
|
||||
components:
|
||||
schemas:
|
||||
SchemaOne:
|
||||
description: "Some schema with custom complex extensions"
|
||||
x-custom-cakes:
|
||||
description: some cakes
|
||||
cakes:
|
||||
someCake:
|
||||
candles: 10
|
||||
frosting: blue
|
||||
someStrangeVarName: something
|
||||
anotherCake:
|
||||
candles: 1
|
||||
frosting: green
|
||||
parameters:
|
||||
ParameterOne:
|
||||
description: "Some parameter also using complex extensions"
|
||||
x-custom-burgers:
|
||||
description: some burgers
|
||||
burgers:
|
||||
someBurger:
|
||||
sauce: ketchup
|
||||
patty: meat
|
||||
anotherBurger:
|
||||
sauce: mayo
|
||||
patty: lamb`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// build a v3 model.
|
||||
docModel, errs := doc.BuildV3Model()
|
||||
|
||||
// if anything went wrong building, indexing and resolving the model, an error is thrown
|
||||
if errs != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// get a reference to SchemaOne and ParameterOne
|
||||
schemaOne := docModel.Model.Components.Schemas["SchemaOne"].Schema()
|
||||
parameterOne := docModel.Model.Components.Parameters["ParameterOne"]
|
||||
|
||||
// unpack schemaOne extensions into complex `cakes` type
|
||||
schemaOneExtensions, schemaUnpackErrors := high.UnpackExtensions[cakes, *low.Schema](schemaOne)
|
||||
if schemaUnpackErrors != nil {
|
||||
panic(fmt.Sprintf("cannot unpack schema extensions: %e", err))
|
||||
}
|
||||
|
||||
// unpack parameterOne into complex `burgers` type
|
||||
parameterOneExtensions, paramUnpackErrors := high.UnpackExtensions[burgers, *v3.Parameter](parameterOne)
|
||||
if paramUnpackErrors != nil {
|
||||
panic(fmt.Sprintf("cannot unpack parameter extensions: %e", err))
|
||||
}
|
||||
|
||||
// extract extension by name for schemaOne
|
||||
customCakes := schemaOneExtensions["x-custom-cakes"]
|
||||
|
||||
// extract extension by name for schemaOne
|
||||
customBurgers := parameterOneExtensions["x-custom-burgers"]
|
||||
|
||||
// print out schemaOne complex extension details.
|
||||
fmt.Printf("schemaOne 'x-custom-cakes' (%s) has %d cakes, 'someCake' has %d candles and %s frosting\n",
|
||||
customCakes.Description,
|
||||
len(customCakes.Cakes),
|
||||
customCakes.Cakes["someCake"].Candles,
|
||||
customCakes.Cakes["someCake"].Frosting,
|
||||
)
|
||||
|
||||
// print out parameterOne complex extension details.
|
||||
fmt.Printf("parameterOne 'x-custom-burgers' (%s) has %d burgers, 'anotherBurger' has %s sauce and a %s patty\n",
|
||||
customBurgers.Description,
|
||||
len(customBurgers.Burgers),
|
||||
customBurgers.Burgers["anotherBurger"].Sauce,
|
||||
customBurgers.Burgers["anotherBurger"].Patty,
|
||||
)
|
||||
|
||||
// Output: schemaOne 'x-custom-cakes' (some cakes) has 2 cakes, 'someCake' has 10 candles and blue frosting
|
||||
//parameterOne 'x-custom-burgers' (some burgers) has 2 burgers, 'anotherBurger' has mayo sauce and a lamb patty
|
||||
}
|
||||
705
document_test.go
705
document_test.go
@@ -1,23 +1,15 @@
|
||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package libopenapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/datamodel"
|
||||
"github.com/pb33f/libopenapi/datamodel/high/base"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pb33f/libopenapi/datamodel/high"
|
||||
low "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"github.com/pb33f/libopenapi/resolver"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/pb33f/libopenapi/what-changed/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadDocument_Simple_V2(t *testing.T) {
|
||||
@@ -158,6 +150,60 @@ info:
|
||||
assert.Equal(t, ymlModified, string(serial))
|
||||
}
|
||||
|
||||
func TestDocument_RenderAndReload_ChangeCheck_Burgershop(t *testing.T) {
|
||||
|
||||
bs, _ := ioutil.ReadFile("test_specs/burgershop.openapi.yaml")
|
||||
doc, _ := NewDocument(bs)
|
||||
doc.BuildV3Model()
|
||||
|
||||
rend, newDoc, _, _ := doc.RenderAndReload()
|
||||
os.WriteFile("rendered-bs.yaml", rend, 0644)
|
||||
|
||||
// compare documents
|
||||
compReport, errs := CompareDocuments(doc, newDoc)
|
||||
|
||||
// should noth be nil.
|
||||
assert.Nil(t, errs)
|
||||
assert.NotNil(t, rend)
|
||||
assert.Nil(t, compReport)
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_RenderAndReload_ChangeCheck_Stripe(t *testing.T) {
|
||||
|
||||
bs, _ := ioutil.ReadFile("test_specs/stripe.yaml")
|
||||
doc, _ := NewDocument(bs)
|
||||
doc.BuildV3Model()
|
||||
|
||||
b, newDoc, _, _ := doc.RenderAndReload()
|
||||
|
||||
os.WriteFile("rendered-data.yaml", b, 0644)
|
||||
|
||||
// compare documents
|
||||
compReport, errs := CompareDocuments(doc, newDoc)
|
||||
|
||||
// get flat list of changes.
|
||||
flatChanges := compReport.GetAllChanges()
|
||||
|
||||
// remove everything that is a description change (stripe has a lot of those from having 519 empty descriptions)
|
||||
var filtered []*model.Change
|
||||
for i := range flatChanges {
|
||||
if flatChanges[i].Property != "description" {
|
||||
filtered = append(filtered, flatChanges[i])
|
||||
}
|
||||
}
|
||||
|
||||
assert.Nil(t, errs)
|
||||
tc := compReport.TotalChanges()
|
||||
bc := compReport.TotalBreakingChanges()
|
||||
assert.Equal(t, 0, bc)
|
||||
assert.Equal(t, 519, tc)
|
||||
|
||||
// there should be no other changes than the 519 descriptions.
|
||||
assert.Equal(t, 0, len(filtered))
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_RenderAndReload(t *testing.T) {
|
||||
|
||||
// load an OpenAPI 3 specification from bytes
|
||||
@@ -209,6 +255,41 @@ func TestDocument_RenderAndReload(t *testing.T) {
|
||||
h.Components.SecuritySchemes["petstore_auth"].Flows.Implicit.AuthorizationUrl)
|
||||
|
||||
}
|
||||
func TestDocument_RenderAndReload_Swagger(t *testing.T) {
|
||||
petstore, _ := ioutil.ReadFile("test_specs/petstorev2.json")
|
||||
doc, _ := NewDocument(petstore)
|
||||
doc.BuildV2Model()
|
||||
doc.BuildV2Model()
|
||||
_, _, _, e := doc.RenderAndReload()
|
||||
assert.Len(t, e, 1)
|
||||
assert.Equal(t, "this method only supports OpenAPI 3 documents, not Swagger", e[0].Error())
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_BuildModelPreBuild(t *testing.T) {
|
||||
petstore, _ := ioutil.ReadFile("test_specs/petstorev3.json")
|
||||
doc, _ := NewDocument(petstore)
|
||||
doc.BuildV3Model()
|
||||
doc.BuildV3Model()
|
||||
_, _, _, e := doc.RenderAndReload()
|
||||
assert.Len(t, e, 0)
|
||||
}
|
||||
|
||||
func TestDocument_BuildModelCircular(t *testing.T) {
|
||||
petstore, _ := ioutil.ReadFile("test_specs/circular-tests.yaml")
|
||||
doc, _ := NewDocument(petstore)
|
||||
m, e := doc.BuildV3Model()
|
||||
assert.NotNil(t, m)
|
||||
assert.Len(t, e, 3)
|
||||
}
|
||||
|
||||
func TestDocument_BuildModelBad(t *testing.T) {
|
||||
petstore, _ := ioutil.ReadFile("test_specs/badref-burgershop.openapi.yaml")
|
||||
doc, _ := NewDocument(petstore)
|
||||
m, e := doc.BuildV3Model()
|
||||
assert.Nil(t, m)
|
||||
assert.Len(t, e, 9)
|
||||
}
|
||||
|
||||
func TestDocument_Serialize_JSON_Modified(t *testing.T) {
|
||||
|
||||
@@ -267,585 +348,49 @@ paths:
|
||||
operation.GoLow().Parameters.Value[0].Reference)
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromOpenAPI3Document() {
|
||||
|
||||
// How to read in an OpenAPI 3 Specification, into a Document.
|
||||
|
||||
// load an OpenAPI 3 specification from bytes
|
||||
petstore, _ := ioutil.ReadFile("test_specs/petstorev3.json")
|
||||
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument(petstore)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// because we know this is a v3 spec, we can build a ready to go model from it.
|
||||
v3Model, errors := document.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// get a count of the number of paths and schemas.
|
||||
paths := len(v3Model.Model.Paths.PathItems)
|
||||
schemas := len(v3Model.Model.Components.Schemas)
|
||||
|
||||
// print the number of paths and schemas in the document
|
||||
fmt.Printf("There are %d paths and %d schemas in the document", paths, schemas)
|
||||
// Output: There are 13 paths and 8 schemas in the document
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromWithDocumentConfigurationFailure() {
|
||||
|
||||
// This example shows how to create a document that prevents the loading of external references/
|
||||
// from files or the network
|
||||
|
||||
// load in the Digital Ocean OpenAPI specification
|
||||
digitalOcean, _ := ioutil.ReadFile("test_specs/digitalocean.yaml")
|
||||
|
||||
// create a DocumentConfiguration that prevents loading file and remote references
|
||||
config := datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: false,
|
||||
AllowRemoteReferences: false,
|
||||
}
|
||||
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocumentWithConfiguration(digitalOcean, &config)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// only errors will be thrown, so just capture them and print the number of errors.
|
||||
_, errors := doc.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
fmt.Println("Error building Digital Ocean spec errors reported")
|
||||
}
|
||||
// Output: Error building Digital Ocean spec errors reported
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromWithDocumentConfigurationSuccess() {
|
||||
|
||||
// This example shows how to create a document that prevents the loading of external references/
|
||||
// from files or the network
|
||||
|
||||
// load in the Digital Ocean OpenAPI specification
|
||||
digitalOcean, _ := ioutil.ReadFile("test_specs/digitalocean.yaml")
|
||||
|
||||
// Digital Ocean needs a baseURL to be set, so we can resolve relative references.
|
||||
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
|
||||
|
||||
// create a DocumentConfiguration that allows loading file and remote references, and sets the baseURL
|
||||
// to somewhere that can resolve the relative references.
|
||||
config := datamodel.DocumentConfiguration{
|
||||
AllowFileReferences: true,
|
||||
AllowRemoteReferences: true,
|
||||
BaseURL: baseURL,
|
||||
}
|
||||
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocumentWithConfiguration(digitalOcean, &config)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// only errors will be thrown, so just capture them and print the number of errors.
|
||||
_, errors := doc.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
fmt.Println("Error building Digital Ocean spec errors reported")
|
||||
} else {
|
||||
fmt.Println("Digital Ocean spec built successfully")
|
||||
}
|
||||
// Output: Digital Ocean spec built successfully
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromSwaggerDocument() {
|
||||
|
||||
// How to read in a Swagger / OpenAPI 2 Specification, into a Document.
|
||||
|
||||
// load a Swagger specification from bytes
|
||||
petstore, _ := ioutil.ReadFile("test_specs/petstorev2.json")
|
||||
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument(petstore)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// because we know this is a v2 spec, we can build a ready to go model from it.
|
||||
v2Model, errors := document.BuildV2Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// get a count of the number of paths and schemas.
|
||||
paths := len(v2Model.Model.Paths.PathItems)
|
||||
schemas := len(v2Model.Model.Definitions.Definitions)
|
||||
|
||||
// print the number of paths and schemas in the document
|
||||
fmt.Printf("There are %d paths and %d schemas in the document", paths, schemas)
|
||||
// Output: There are 14 paths and 6 schemas in the document
|
||||
}
|
||||
|
||||
func ExampleNewDocument_fromUnknownVersion() {
|
||||
|
||||
// load an unknown version of an OpenAPI spec
|
||||
petstore, _ := ioutil.ReadFile("test_specs/burgershop.openapi.yaml")
|
||||
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument(petstore)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
var paths, schemas int
|
||||
var errors []error
|
||||
|
||||
// We don't know which type of document this is, so we can use the spec info to inform us
|
||||
if document.GetSpecInfo().SpecType == utils.OpenApi3 {
|
||||
v3Model, errs := document.BuildV3Model()
|
||||
if len(errs) > 0 {
|
||||
errors = errs
|
||||
}
|
||||
if len(errors) <= 0 {
|
||||
paths = len(v3Model.Model.Paths.PathItems)
|
||||
schemas = len(v3Model.Model.Components.Schemas)
|
||||
}
|
||||
}
|
||||
if document.GetSpecInfo().SpecType == utils.OpenApi2 {
|
||||
v2Model, errs := document.BuildV2Model()
|
||||
if len(errs) > 0 {
|
||||
errors = errs
|
||||
}
|
||||
if len(errors) <= 0 {
|
||||
paths = len(v2Model.Model.Paths.PathItems)
|
||||
schemas = len(v2Model.Model.Definitions.Definitions)
|
||||
}
|
||||
}
|
||||
|
||||
// if anything went wrong when building the model, report errors.
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// print the number of paths and schemas in the document
|
||||
fmt.Printf("There are %d paths and %d schemas in the document", paths, schemas)
|
||||
// Output: There are 5 paths and 6 schemas in the document
|
||||
}
|
||||
|
||||
func ExampleNewDocument_mutateValuesAndSerialize() {
|
||||
|
||||
// How to mutate values in an OpenAPI Specification, without re-ordering original content.
|
||||
|
||||
// create very small, and useless spec that does nothing useful, except showcase this feature.
|
||||
spec := `
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: This is a title
|
||||
contact:
|
||||
name: Some Person
|
||||
email: some@emailaddress.com
|
||||
license:
|
||||
url: http://some-place-on-the-internet.com/license
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
document, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// because we know this is a v3 spec, we can build a ready to go model from it.
|
||||
v3Model, errors := document.BuildV3Model()
|
||||
|
||||
// if anything went wrong when building the v3 model, a slice of errors will be returned
|
||||
if len(errors) > 0 {
|
||||
for i := range errors {
|
||||
fmt.Printf("error: %e\n", errors[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
|
||||
}
|
||||
|
||||
// mutate the title, to do this we currently need to drop down to the low-level API.
|
||||
v3Model.Model.GoLow().Info.Value.Title.Mutate("A new title for a useless spec")
|
||||
|
||||
// mutate the email address in the contact object.
|
||||
v3Model.Model.GoLow().Info.Value.Contact.Value.Email.Mutate("buckaroo@pb33f.io")
|
||||
|
||||
// mutate the name in the contact object.
|
||||
v3Model.Model.GoLow().Info.Value.Contact.Value.Name.Mutate("Buckaroo")
|
||||
|
||||
// mutate the URL for the license object.
|
||||
v3Model.Model.GoLow().Info.Value.License.Value.URL.Mutate("https://pb33f.io/license")
|
||||
|
||||
// serialize the document back into the original YAML or JSON
|
||||
mutatedSpec, serialError := document.Serialize()
|
||||
|
||||
// if something went wrong serializing
|
||||
if serialError != nil {
|
||||
panic(fmt.Sprintf("cannot serialize document: %e", serialError))
|
||||
}
|
||||
|
||||
// print our modified spec!
|
||||
fmt.Println(string(mutatedSpec))
|
||||
// Output: openapi: 3.1.0
|
||||
//info:
|
||||
// title: A new title for a useless spec
|
||||
// contact:
|
||||
// name: Buckaroo
|
||||
// email: buckaroo@pb33f.io
|
||||
// license:
|
||||
// url: https://pb33f.io/license
|
||||
}
|
||||
|
||||
func ExampleCompareDocuments_openAPI() {
|
||||
|
||||
// How to compare two different OpenAPI specifications.
|
||||
|
||||
// load an original OpenAPI 3 specification from bytes
|
||||
burgerShopOriginal, _ := ioutil.ReadFile("test_specs/burgershop.openapi.yaml")
|
||||
|
||||
// load an **updated** OpenAPI 3 specification from bytes
|
||||
func TestDocument_BuildModel_CompareDocsV3_LeftError(t *testing.T) {
|
||||
burgerShopOriginal, _ := ioutil.ReadFile("test_specs/badref-burgershop.openapi.yaml")
|
||||
burgerShopUpdated, _ := ioutil.ReadFile("test_specs/burgershop.openapi-modified.yaml")
|
||||
originalDoc, _ := NewDocument(burgerShopOriginal)
|
||||
updatedDoc, _ := NewDocument(burgerShopUpdated)
|
||||
changes, errors := CompareDocuments(originalDoc, updatedDoc)
|
||||
assert.Len(t, errors, 9)
|
||||
assert.Nil(t, changes)
|
||||
}
|
||||
|
||||
// create a new document from original specification bytes
|
||||
originalDoc, err := NewDocument(burgerShopOriginal)
|
||||
func TestDocument_BuildModel_CompareDocsV3_RightError(t *testing.T) {
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// create a new document from updated specification bytes
|
||||
updatedDoc, err := NewDocument(burgerShopUpdated)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// Compare documents for all changes made
|
||||
documentChanges, errs := CompareDocuments(originalDoc, updatedDoc)
|
||||
|
||||
// If anything went wrong when building models for documents.
|
||||
if len(errs) > 0 {
|
||||
for i := range errs {
|
||||
fmt.Printf("error: %e\n", errs[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot compare documents: %d errors reported", len(errs)))
|
||||
}
|
||||
|
||||
// Extract SchemaChanges from components changes.
|
||||
schemaChanges := documentChanges.ComponentsChanges.SchemaChanges
|
||||
|
||||
// Print out some interesting stats about the OpenAPI document changes.
|
||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||
documentChanges.TotalChanges(), documentChanges.TotalBreakingChanges(), len(schemaChanges))
|
||||
//Output: There are 72 changes, of which 17 are breaking. 5 schemas have changes.
|
||||
burgerShopOriginal, _ := ioutil.ReadFile("test_specs/badref-burgershop.openapi.yaml")
|
||||
burgerShopUpdated, _ := ioutil.ReadFile("test_specs/burgershop.openapi-modified.yaml")
|
||||
originalDoc, _ := NewDocument(burgerShopOriginal)
|
||||
updatedDoc, _ := NewDocument(burgerShopUpdated)
|
||||
changes, errors := CompareDocuments(updatedDoc, originalDoc)
|
||||
assert.Len(t, errors, 9)
|
||||
assert.Nil(t, changes)
|
||||
|
||||
}
|
||||
|
||||
func ExampleCompareDocuments_swagger() {
|
||||
func TestDocument_BuildModel_CompareDocsV2_Error(t *testing.T) {
|
||||
|
||||
// How to compare two different Swagger specifications.
|
||||
|
||||
// load an original OpenAPI 3 specification from bytes
|
||||
petstoreOriginal, _ := ioutil.ReadFile("test_specs/petstorev2-complete.yaml")
|
||||
|
||||
// load an **updated** OpenAPI 3 specification from bytes
|
||||
petstoreUpdated, _ := ioutil.ReadFile("test_specs/petstorev2-complete-modified.yaml")
|
||||
|
||||
// create a new document from original specification bytes
|
||||
originalDoc, err := NewDocument(petstoreOriginal)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// create a new document from updated specification bytes
|
||||
updatedDoc, err := NewDocument(petstoreUpdated)
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// Compare documents for all changes made
|
||||
documentChanges, errs := CompareDocuments(originalDoc, updatedDoc)
|
||||
|
||||
// If anything went wrong when building models for documents.
|
||||
if len(errs) > 0 {
|
||||
for i := range errs {
|
||||
fmt.Printf("error: %e\n", errs[i])
|
||||
}
|
||||
panic(fmt.Sprintf("cannot compare documents: %d errors reported", len(errs)))
|
||||
}
|
||||
|
||||
// Extract SchemaChanges from components changes.
|
||||
schemaChanges := documentChanges.ComponentsChanges.SchemaChanges
|
||||
|
||||
// Print out some interesting stats about the Swagger document changes.
|
||||
fmt.Printf("There are %d changes, of which %d are breaking. %v schemas have changes.",
|
||||
documentChanges.TotalChanges(), documentChanges.TotalBreakingChanges(), len(schemaChanges))
|
||||
//Output: There are 52 changes, of which 27 are breaking. 5 schemas have changes.
|
||||
burgerShopOriginal, _ := ioutil.ReadFile("test_specs/petstorev2-badref.json")
|
||||
burgerShopUpdated, _ := ioutil.ReadFile("test_specs/petstorev2-badref.json")
|
||||
originalDoc, _ := NewDocument(burgerShopOriginal)
|
||||
updatedDoc, _ := NewDocument(burgerShopUpdated)
|
||||
changes, errors := CompareDocuments(updatedDoc, originalDoc)
|
||||
assert.Len(t, errors, 2)
|
||||
assert.Nil(t, changes)
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_Paths_As_Array(t *testing.T) {
|
||||
func TestDocument_BuildModel_CompareDocsV2V3Mix_Error(t *testing.T) {
|
||||
|
||||
// paths can now be wrapped in an array.
|
||||
spec := `{
|
||||
"openapi": "3.1.0",
|
||||
"paths": [
|
||||
"/": {
|
||||
"get": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
v3Model, _ := doc.BuildV3Model()
|
||||
assert.NotNil(t, v3Model)
|
||||
}
|
||||
|
||||
// If you want to know more about circular references that have been found
|
||||
// during the parsing/indexing/building of a document, you can capture the
|
||||
// []errors thrown which are pointers to *resolver.ResolvingError
|
||||
func ExampleNewDocument_infinite_circular_references() {
|
||||
|
||||
// create a specification with an obvious and deliberate circular reference
|
||||
spec := `openapi: "3.1"
|
||||
components:
|
||||
schemas:
|
||||
One:
|
||||
description: "test one"
|
||||
properties:
|
||||
things:
|
||||
"$ref": "#/components/schemas/Two"
|
||||
required:
|
||||
- things
|
||||
Two:
|
||||
description: "test two"
|
||||
properties:
|
||||
testThing:
|
||||
"$ref": "#/components/schemas/One"
|
||||
required:
|
||||
- testThing
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
_, errs := doc.BuildV3Model()
|
||||
|
||||
// extract resolving error
|
||||
resolvingError := errs[0]
|
||||
|
||||
// resolving error is a pointer to *resolver.ResolvingError
|
||||
// which provides access to rich details about the error.
|
||||
circularReference := resolvingError.(*resolver.ResolvingError).CircularReference
|
||||
|
||||
// capture the journey with all details
|
||||
var buf strings.Builder
|
||||
for n := range circularReference.Journey {
|
||||
|
||||
// add the full definition name to the journey.
|
||||
buf.WriteString(circularReference.Journey[n].Definition)
|
||||
if n < len(circularReference.Journey)-1 {
|
||||
buf.WriteString(" -> ")
|
||||
}
|
||||
}
|
||||
|
||||
// print out the journey and the loop point.
|
||||
fmt.Printf("Journey: %s\n", buf.String())
|
||||
fmt.Printf("Loop Point: %s", circularReference.LoopPoint.Definition)
|
||||
// Output: Journey: #/components/schemas/Two -> #/components/schemas/One -> #/components/schemas/Two
|
||||
// Loop Point: #/components/schemas/Two
|
||||
}
|
||||
|
||||
// This tests checks that circular references which are _not_ marked as required pass correctly
|
||||
func TestNewDocument_terminable_circular_references(t *testing.T) {
|
||||
|
||||
// create a specification with an obvious and deliberate circular reference
|
||||
spec := `openapi: "3.1"
|
||||
components:
|
||||
schemas:
|
||||
One:
|
||||
description: "test one"
|
||||
properties:
|
||||
things:
|
||||
"$ref": "#/components/schemas/Two"
|
||||
Two:
|
||||
description: "test two"
|
||||
properties:
|
||||
testThing:
|
||||
"$ref": "#/components/schemas/One"
|
||||
`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
_, errs := doc.BuildV3Model()
|
||||
|
||||
assert.Len(t, errs, 0)
|
||||
}
|
||||
|
||||
// If you're using complex types with OpenAPI Extensions, it's simple to unpack extensions into complex
|
||||
// types using `high.UnpackExtensions()`. libopenapi retains the original raw data in the low model (not the high)
|
||||
// which means unpacking them can be a little complex.
|
||||
//
|
||||
// This example demonstrates how to use the `UnpackExtensions` with custom OpenAPI extensions.
|
||||
func ExampleNewDocument_unpacking_extensions() {
|
||||
|
||||
// define an example struct representing a cake
|
||||
type cake struct {
|
||||
Candles int `yaml:"candles"`
|
||||
Frosting string `yaml:"frosting"`
|
||||
Some_Strange_Var_Name string `yaml:"someStrangeVarName"`
|
||||
}
|
||||
|
||||
// define a struct that holds a map of cake pointers.
|
||||
type cakes struct {
|
||||
Description string
|
||||
Cakes map[string]*cake
|
||||
}
|
||||
|
||||
// define a struct representing a burger
|
||||
type burger struct {
|
||||
Sauce string
|
||||
Patty string
|
||||
}
|
||||
|
||||
// define a struct that holds a map of cake pointers
|
||||
type burgers struct {
|
||||
Description string
|
||||
Burgers map[string]*burger
|
||||
}
|
||||
|
||||
// create a specification with a schema and parameter that use complex custom cakes and burgers extensions.
|
||||
spec := `openapi: "3.1"
|
||||
components:
|
||||
schemas:
|
||||
SchemaOne:
|
||||
description: "Some schema with custom complex extensions"
|
||||
x-custom-cakes:
|
||||
description: some cakes
|
||||
cakes:
|
||||
someCake:
|
||||
candles: 10
|
||||
frosting: blue
|
||||
someStrangeVarName: something
|
||||
anotherCake:
|
||||
candles: 1
|
||||
frosting: green
|
||||
parameters:
|
||||
ParameterOne:
|
||||
description: "Some parameter also using complex extensions"
|
||||
x-custom-burgers:
|
||||
description: some burgers
|
||||
burgers:
|
||||
someBurger:
|
||||
sauce: ketchup
|
||||
patty: meat
|
||||
anotherBurger:
|
||||
sauce: mayo
|
||||
patty: lamb`
|
||||
// create a new document from specification bytes
|
||||
doc, err := NewDocument([]byte(spec))
|
||||
|
||||
// if anything went wrong, an error is thrown
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// build a v3 model.
|
||||
docModel, errs := doc.BuildV3Model()
|
||||
|
||||
// if anything went wrong building, indexing and resolving the model, an error is thrown
|
||||
if errs != nil {
|
||||
panic(fmt.Sprintf("cannot create new document: %e", err))
|
||||
}
|
||||
|
||||
// get a reference to SchemaOne and ParameterOne
|
||||
schemaOne := docModel.Model.Components.Schemas["SchemaOne"].Schema()
|
||||
parameterOne := docModel.Model.Components.Parameters["ParameterOne"]
|
||||
|
||||
// unpack schemaOne extensions into complex `cakes` type
|
||||
schemaOneExtensions, schemaUnpackErrors := high.UnpackExtensions[cakes, *low.Schema](schemaOne)
|
||||
if schemaUnpackErrors != nil {
|
||||
panic(fmt.Sprintf("cannot unpack schema extensions: %e", err))
|
||||
}
|
||||
|
||||
// unpack parameterOne into complex `burgers` type
|
||||
parameterOneExtensions, paramUnpackErrors := high.UnpackExtensions[burgers, *v3.Parameter](parameterOne)
|
||||
if paramUnpackErrors != nil {
|
||||
panic(fmt.Sprintf("cannot unpack parameter extensions: %e", err))
|
||||
}
|
||||
|
||||
// extract extension by name for schemaOne
|
||||
customCakes := schemaOneExtensions["x-custom-cakes"]
|
||||
|
||||
// extract extension by name for schemaOne
|
||||
customBurgers := parameterOneExtensions["x-custom-burgers"]
|
||||
|
||||
// print out schemaOne complex extension details.
|
||||
fmt.Printf("schemaOne 'x-custom-cakes' (%s) has %d cakes, 'someCake' has %d candles and %s frosting\n",
|
||||
customCakes.Description,
|
||||
len(customCakes.Cakes),
|
||||
customCakes.Cakes["someCake"].Candles,
|
||||
customCakes.Cakes["someCake"].Frosting,
|
||||
)
|
||||
|
||||
// print out parameterOne complex extension details.
|
||||
fmt.Printf("parameterOne 'x-custom-burgers' (%s) has %d burgers, 'anotherBurger' has %s sauce and a %s patty\n",
|
||||
customBurgers.Description,
|
||||
len(customBurgers.Burgers),
|
||||
customBurgers.Burgers["anotherBurger"].Sauce,
|
||||
customBurgers.Burgers["anotherBurger"].Patty,
|
||||
)
|
||||
|
||||
// Output: schemaOne 'x-custom-cakes' (some cakes) has 2 cakes, 'someCake' has 10 candles and blue frosting
|
||||
//parameterOne 'x-custom-burgers' (some burgers) has 2 burgers, 'anotherBurger' has mayo sauce and a lamb patty
|
||||
burgerShopOriginal, _ := ioutil.ReadFile("test_specs/petstorev2.json")
|
||||
burgerShopUpdated, _ := ioutil.ReadFile("test_specs/petstorev3.json")
|
||||
originalDoc, _ := NewDocument(burgerShopOriginal)
|
||||
updatedDoc, _ := NewDocument(burgerShopUpdated)
|
||||
changes, errors := CompareDocuments(updatedDoc, originalDoc)
|
||||
assert.Len(t, errors, 1)
|
||||
assert.Nil(t, changes)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,10 @@ func (resolver *Resolver) GetPolymorphicCircularErrors() []*index.CircularRefere
|
||||
if !resolver.circularReferences[i].IsInfiniteLoop {
|
||||
continue
|
||||
}
|
||||
|
||||
if resolver.circularReferences[i].IsPolymorphicResult {
|
||||
res = append(res, resolver.circularReferences[i])
|
||||
if !resolver.circularReferences[i].IsPolymorphicResult {
|
||||
continue
|
||||
}
|
||||
res = append(res, resolver.circularReferences[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
@@ -62,6 +63,31 @@ func TestResolver_CheckForCircularReferences(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestResolver_CheckForCircularReferences_DigitalOcean(t *testing.T) {
|
||||
circular, _ := ioutil.ReadFile("../test_specs/digitalocean.yaml")
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal(circular, &rootNode)
|
||||
|
||||
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
|
||||
|
||||
index := index.NewSpecIndexWithConfig(&rootNode, &index.SpecIndexConfig{
|
||||
AllowRemoteLookup: true,
|
||||
AllowFileLookup: true,
|
||||
BaseURL: baseURL,
|
||||
})
|
||||
|
||||
resolver := NewResolver(index)
|
||||
assert.NotNil(t, resolver)
|
||||
|
||||
circ := resolver.CheckForCircularReferences()
|
||||
assert.Len(t, circ, 0)
|
||||
assert.Len(t, resolver.GetResolvingErrors(), 0)
|
||||
assert.Len(t, resolver.GetCircularErrors(), 0)
|
||||
|
||||
_, err := yaml.Marshal(resolver.resolvedRoot)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestResolver_CircularReferencesRequiredValid(t *testing.T) {
|
||||
circular, _ := ioutil.ReadFile("../test_specs/swagger-valid-recursive-model.yaml")
|
||||
var rootNode yaml.Node
|
||||
@@ -170,6 +196,37 @@ components:
|
||||
assert.Len(t, circ, 0)
|
||||
}
|
||||
|
||||
func TestResolver_ResolveComponents_PolyCircRef(t *testing.T) {
|
||||
yml := `openapi: 3.1.0
|
||||
components:
|
||||
schemas:
|
||||
cheese:
|
||||
description: cheese
|
||||
anyOf:
|
||||
- $ref: '#/components/schemas/crackers'
|
||||
crackers:
|
||||
description: crackers
|
||||
anyOf:
|
||||
- $ref: '#/components/schemas/cheese'
|
||||
tea:
|
||||
description: tea`
|
||||
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
|
||||
index := index.NewSpecIndex(&rootNode)
|
||||
|
||||
resolver := NewResolver(index)
|
||||
assert.NotNil(t, resolver)
|
||||
|
||||
_ = resolver.CheckForCircularReferences()
|
||||
resolver.circularReferences[0].IsInfiniteLoop = true // override
|
||||
assert.Len(t, index.GetCircularReferences(), 1)
|
||||
assert.Len(t, resolver.GetPolymorphicCircularErrors(), 1)
|
||||
assert.Equal(t, 2, index.GetCircularReferences()[0].LoopIndex)
|
||||
|
||||
}
|
||||
|
||||
func TestResolver_ResolveComponents_Missing(t *testing.T) {
|
||||
yml := `paths:
|
||||
/hey:
|
||||
|
||||
1061
test_specs/petstorev2-badref.json
Normal file
1061
test_specs/petstorev2-badref.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20721,6 +20721,7 @@ components:
|
||||
type: object
|
||||
x-expandableFields: []
|
||||
refund:
|
||||
description: |-
|
||||
description: |-
|
||||
`Refund` objects allow you to refund a charge that has previously been created
|
||||
but not yet refunded. Funds will be refunded to the credit or debit card that
|
||||
|
||||
@@ -5,6 +5,15 @@ package utils
|
||||
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
func CreateRefNode(ref string) *yaml.Node {
|
||||
m := CreateEmptyMapNode()
|
||||
nodes := make([]*yaml.Node, 2)
|
||||
nodes[0] = CreateStringNode("$ref")
|
||||
nodes[1] = CreateStringNode(ref)
|
||||
m.Content = nodes
|
||||
return m
|
||||
}
|
||||
|
||||
func CreateEmptyMapNode() *yaml.Node {
|
||||
n := &yaml.Node{
|
||||
Kind: yaml.MappingNode,
|
||||
|
||||
49
utils/nodes_test.go
Normal file
49
utils/nodes_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2023 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreateBoolNode(t *testing.T) {
|
||||
b := CreateBoolNode("true")
|
||||
assert.Equal(t, "!!bool", b.Tag)
|
||||
assert.Equal(t, "true", b.Value)
|
||||
}
|
||||
|
||||
func TestCreateEmptyMapNode(t *testing.T) {
|
||||
m := CreateEmptyMapNode()
|
||||
assert.Equal(t, "!!map", m.Tag)
|
||||
assert.Len(t, m.Content, 0)
|
||||
}
|
||||
|
||||
func TestCreateEmptySequenceNode(t *testing.T) {
|
||||
s := CreateEmptySequenceNode()
|
||||
assert.Equal(t, "!!seq", s.Tag)
|
||||
assert.Len(t, s.Content, 0)
|
||||
}
|
||||
|
||||
func TestCreateFloatNode(t *testing.T) {
|
||||
f := CreateFloatNode("3.14")
|
||||
assert.Equal(t, "!!float", f.Tag)
|
||||
assert.Equal(t, "3.14", f.Value)
|
||||
}
|
||||
|
||||
func TestCreateIntNode(t *testing.T) {
|
||||
i := CreateIntNode("42")
|
||||
assert.Equal(t, "!!int", i.Tag)
|
||||
assert.Equal(t, "42", i.Value)
|
||||
}
|
||||
|
||||
func TestCreateRefNode(t *testing.T) {
|
||||
r := CreateRefNode("#/components/schemas/MySchema")
|
||||
assert.Equal(t, "!!map", r.Tag)
|
||||
assert.Len(t, r.Content, 2)
|
||||
assert.Equal(t, "!!str", r.Content[0].Tag)
|
||||
assert.Equal(t, "$ref", r.Content[0].Value)
|
||||
assert.Equal(t, "!!str", r.Content[1].Tag)
|
||||
assert.Equal(t, "#/components/schemas/MySchema", r.Content[1].Value)
|
||||
}
|
||||
@@ -27,6 +27,19 @@ func (c *CallbackChanges) TotalChanges() int {
|
||||
return d
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Callback objects
|
||||
func (c *CallbackChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, c.Changes...)
|
||||
for k := range c.ExpressionChanges {
|
||||
changes = append(changes, c.ExpressionChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if c.ExtensionChanges != nil {
|
||||
changes = append(changes, c.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalBreakingChanges returns a total count of all changes made between Callback objects
|
||||
func (c *CallbackChanges) TotalBreakingChanges() int {
|
||||
d := c.PropertyChanges.TotalBreakingChanges()
|
||||
|
||||
@@ -87,6 +87,7 @@ func TestCompareCallback_Add(t *testing.T) {
|
||||
|
||||
// compare.
|
||||
extChanges := CompareCallback(&lDoc, &rDoc)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
@@ -138,6 +139,7 @@ func TestCompareCallback_Modify(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareCallback(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.ExpressionChanges["{$request.query.queryUrl}"].Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.GetLabel, extChanges.ExpressionChanges["{$request.query.queryUrl}"].Changes[0].Property)
|
||||
@@ -187,6 +189,7 @@ func TestCompareCallback_Remove(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareCallback(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "slippers", extChanges.Changes[0].Property)
|
||||
|
||||
@@ -50,15 +50,15 @@ func (c *ChangeContext) HasChanged() bool {
|
||||
if c.NewLine != nil && c.OriginalLine != nil && *c.NewLine != *c.OriginalLine {
|
||||
return true
|
||||
}
|
||||
if c.NewColumn != nil && c.OriginalColumn != nil && *c.NewColumn != *c.OriginalColumn {
|
||||
return true
|
||||
}
|
||||
//if c.NewColumn != nil && c.OriginalColumn != nil && *c.NewColumn != *c.OriginalColumn {
|
||||
// return true
|
||||
//}
|
||||
if (c.NewLine == nil && c.OriginalLine != nil) || (c.NewLine != nil && c.OriginalLine == nil) {
|
||||
return true
|
||||
}
|
||||
if (c.NewColumn == nil && c.OriginalColumn != nil) || (c.NewColumn != nil && c.OriginalColumn == nil) {
|
||||
return true
|
||||
}
|
||||
//if (c.NewColumn == nil && c.OriginalColumn != nil) || (c.NewColumn != nil && c.OriginalColumn == nil) {
|
||||
// return true
|
||||
//}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +235,22 @@ func runComparison[T any, R any](l, r map[low.KeyReference[string]]low.ValueRefe
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Callback objects
|
||||
func (c *ComponentsChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, c.Changes...)
|
||||
for k := range c.SchemaChanges {
|
||||
changes = append(changes, c.SchemaChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range c.SecuritySchemeChanges {
|
||||
changes = append(changes, c.SecuritySchemeChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if c.ExtensionChanges != nil {
|
||||
changes = append(changes, c.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns total changes for all Components and Definitions
|
||||
func (c *ComponentsChanges) TotalChanges() int {
|
||||
v := c.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -75,6 +75,7 @@ thing2:
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
@@ -113,6 +114,7 @@ thing3:
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
|
||||
@@ -152,6 +154,7 @@ thing3:
|
||||
// compare.
|
||||
extChanges := CompareComponents(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "thing3", extChanges.Changes[0].Original)
|
||||
@@ -190,6 +193,7 @@ param4:
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "param4", extChanges.Changes[0].New)
|
||||
@@ -228,6 +232,7 @@ param4:
|
||||
// compare.
|
||||
extChanges := CompareComponents(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "param4", extChanges.Changes[0].Original)
|
||||
@@ -263,6 +268,7 @@ resp3:
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, "resp3", extChanges.Changes[0].New)
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
@@ -299,6 +305,7 @@ resp3:
|
||||
extChanges := CompareComponents(&rDoc, &lDoc)
|
||||
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, "resp3", extChanges.Changes[0].Original)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
@@ -330,6 +337,7 @@ scheme2:
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.SecuritySchemeChanges["scheme1"].TotalChanges())
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.SecuritySchemeChanges["scheme1"].Changes[0].Property)
|
||||
@@ -1088,4 +1096,5 @@ func TestCompareComponents_OpenAPI_Extensions_Modified(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ type ContactChanges struct {
|
||||
*PropertyChanges
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Callback objects
|
||||
func (c *ContactChanges) GetAllChanges() []*Change {
|
||||
return c.Changes
|
||||
}
|
||||
|
||||
// TotalChanges represents the total number of changes that have occurred to a Contact object
|
||||
func (c *ContactChanges) TotalChanges() int {
|
||||
return c.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -33,6 +33,7 @@ url: https://pb33f.io`
|
||||
// compare.
|
||||
extChanges := CompareContact(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,16 @@ func (d *DiscriminatorChanges) TotalChanges() int {
|
||||
return l
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Callback objects
|
||||
func (c *DiscriminatorChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, c.Changes...)
|
||||
if c.MappingChanges != nil {
|
||||
changes = append(changes, c.MappingChanges...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalBreakingChanges returns the number of breaking changes made by the Discriminator
|
||||
func (d *DiscriminatorChanges) TotalBreakingChanges() int {
|
||||
return d.PropertyChanges.TotalBreakingChanges() + CountBreakingChanges(d.MappingChanges)
|
||||
|
||||
@@ -30,6 +30,7 @@ func TestCompareDiscriminator_PropertyNameChanged(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareDiscriminator(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -56,6 +57,7 @@ propertyName: chicken`
|
||||
// compare.
|
||||
extChanges := CompareDiscriminator(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@ propertyName: chicken`
|
||||
// compare.
|
||||
extChanges := CompareDiscriminator(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -106,6 +109,7 @@ mapping:
|
||||
// compare.
|
||||
extChanges := CompareDiscriminator(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
|
||||
for _, k := range extChanges.MappingChanges {
|
||||
assert.Equal(t, ObjectAdded, k.ChangeType)
|
||||
|
||||
@@ -66,6 +66,40 @@ func (d *DocumentChanges) TotalChanges() int {
|
||||
return c
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Document objects
|
||||
func (d *DocumentChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, d.Changes...)
|
||||
if d.InfoChanges != nil {
|
||||
changes = append(changes, d.InfoChanges.GetAllChanges()...)
|
||||
}
|
||||
if d.PathsChanges != nil {
|
||||
changes = append(changes, d.PathsChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range d.TagChanges {
|
||||
changes = append(changes, d.TagChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if d.ExternalDocChanges != nil {
|
||||
changes = append(changes, d.ExternalDocChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range d.WebhookChanges {
|
||||
changes = append(changes, d.WebhookChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range d.ServerChanges {
|
||||
changes = append(changes, d.ServerChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range d.SecurityRequirementChanges {
|
||||
changes = append(changes, d.SecurityRequirementChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if d.ComponentsChanges != nil {
|
||||
changes = append(changes, d.ComponentsChanges.GetAllChanges()...)
|
||||
}
|
||||
if d.ExtensionChanges != nil {
|
||||
changes = append(changes, d.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalBreakingChanges returns a total count of all breaking changes made in the Document
|
||||
func (d *DocumentChanges) TotalBreakingChanges() int {
|
||||
c := d.PropertyChanges.TotalBreakingChanges()
|
||||
|
||||
@@ -85,6 +85,7 @@ produces:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 10, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 10)
|
||||
assert.Equal(t, 6, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -113,6 +114,7 @@ produces:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -141,6 +143,7 @@ basePath: /api`
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 3, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -171,6 +174,7 @@ info:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 3, extChanges.InfoChanges.TotalChanges())
|
||||
}
|
||||
@@ -196,6 +200,7 @@ info:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.InfoLabel, extChanges.Changes[0].Property)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
@@ -222,6 +227,7 @@ info:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(rDoc, lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.InfoLabel, extChanges.Changes[0].Property)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
@@ -248,6 +254,7 @@ externalDocs:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 2, extChanges.ExternalDocChanges.TotalChanges())
|
||||
}
|
||||
@@ -270,6 +277,7 @@ externalDocs:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExternalDocsLabel, extChanges.Changes[0].Property)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
@@ -294,6 +302,7 @@ externalDocs:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(rDoc, lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExternalDocsLabel, extChanges.Changes[0].Property)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
@@ -367,6 +376,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -399,6 +409,7 @@ definitions:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -459,6 +470,7 @@ securityDefinitions:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -527,6 +539,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -594,6 +607,7 @@ responses:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -657,6 +671,7 @@ paths:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -689,6 +704,7 @@ paths:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -748,6 +764,7 @@ tags:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -801,6 +818,7 @@ jsonSchemaDialect: https://pb33f.io/schema/changed`
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -829,6 +847,7 @@ components:
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -858,6 +877,7 @@ components:
|
||||
extChanges := CompareDocuments(rDoc, lDoc)
|
||||
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -897,6 +917,7 @@ paths:
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -969,6 +990,7 @@ components:
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -1000,6 +1022,7 @@ servers:
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -1034,6 +1057,7 @@ components:
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -1072,6 +1096,7 @@ webhooks:
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -1114,6 +1139,7 @@ paths:
|
||||
// compare.
|
||||
extChanges := CompareDocuments(lDoc, rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,16 @@ type EncodingChanges struct {
|
||||
HeaderChanges map[string]*HeaderChanges `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Encoding objects
|
||||
func (e *EncodingChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, e.Changes...)
|
||||
for k := range e.HeaderChanges {
|
||||
changes = append(changes, e.HeaderChanges[k].GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes made between two Encoding objects
|
||||
func (e *EncodingChanges) TotalChanges() int {
|
||||
c := e.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -80,6 +80,7 @@ allowReserved: true`
|
||||
extChanges := CompareEncoding(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
@@ -114,6 +115,7 @@ allowReserved: true`
|
||||
extChanges := CompareEncoding(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.HeadersLabel, extChanges.Changes[0].Property)
|
||||
@@ -149,6 +151,7 @@ allowReserved: true`
|
||||
extChanges := CompareEncoding(&rDoc, &lDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,16 @@ type ExampleChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Example objects
|
||||
func (e *ExampleChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, e.Changes...)
|
||||
if e.ExtensionChanges != nil {
|
||||
changes = append(changes, e.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes made to Example
|
||||
func (e *ExampleChanges) TotalChanges() int {
|
||||
l := e.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -34,6 +34,7 @@ func TestCompareExamples_SummaryModified(t *testing.T) {
|
||||
extChanges := CompareExamples(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.SummaryLabel, extChanges.Changes[0].Property)
|
||||
@@ -66,6 +67,7 @@ func TestCompareExamples_Map(t *testing.T) {
|
||||
extChanges := CompareExamples(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, extChanges.TotalChanges(), 2)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -94,6 +96,7 @@ func TestCompareExamples_MapAdded(t *testing.T) {
|
||||
extChanges := CompareExamples(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -147,6 +150,7 @@ description: cure all`
|
||||
extChanges := CompareExamples(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.Changes[0].Property)
|
||||
assert.Equal(t, "cure all", extChanges.Changes[0].New)
|
||||
@@ -173,6 +177,7 @@ x-herbs: cure all`
|
||||
extChanges := CompareExamples(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, extChanges.ExtensionChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "x-herbs", extChanges.ExtensionChanges.Changes[0].Property)
|
||||
assert.Equal(t, "cure all", extChanges.ExtensionChanges.Changes[0].New)
|
||||
|
||||
@@ -13,6 +13,11 @@ type ExamplesChanges struct {
|
||||
*PropertyChanges
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Examples objects
|
||||
func (a *ExamplesChanges) GetAllChanges() []*Change {
|
||||
return a.Changes
|
||||
}
|
||||
|
||||
// TotalChanges represents the total number of changes made between Example instances.
|
||||
func (a *ExamplesChanges) TotalChanges() int {
|
||||
return a.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -31,6 +31,7 @@ func TestCompareExamplesV2(t *testing.T) {
|
||||
|
||||
extChanges := CompareExamplesV2(&lDoc, &rDoc)
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.SummaryLabel, extChanges.Changes[0].Property)
|
||||
@@ -58,6 +59,7 @@ yummy: coffee`
|
||||
|
||||
extChanges := CompareExamplesV2(&lDoc, &rDoc)
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -82,6 +84,7 @@ yummy: coffee`
|
||||
|
||||
extChanges := CompareExamplesV2(&rDoc, &lDoc)
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ type ExtensionChanges struct {
|
||||
*PropertyChanges
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Extension objects
|
||||
func (e *ExtensionChanges) GetAllChanges() []*Change {
|
||||
return e.Changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of object extensions that were made.
|
||||
func (e *ExtensionChanges) TotalChanges() int {
|
||||
return e.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -25,6 +25,7 @@ func TestCompareExtensions(t *testing.T) {
|
||||
extChanges := CompareExtensions(lExt, rExt)
|
||||
|
||||
assert.Equal(t, extChanges.TotalChanges(), 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "1", extChanges.Changes[0].Original)
|
||||
assert.Equal(t, "2", extChanges.Changes[0].New)
|
||||
@@ -49,6 +50,7 @@ x-test: 1`
|
||||
extChanges := CompareExtensions(lExt, rExt)
|
||||
|
||||
assert.Len(t, extChanges.Changes, 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, 2, *extChanges.Changes[0].Context.OriginalLine)
|
||||
assert.Nil(t, extChanges.Changes[0].Context.NewLine)
|
||||
@@ -73,6 +75,7 @@ x-test: 1`
|
||||
extChanges := CompareExtensions(lExt, rExt)
|
||||
|
||||
assert.Len(t, extChanges.Changes, 1)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Nil(t, extChanges.Changes[0].Context.OriginalLine)
|
||||
assert.Equal(t, 2, *extChanges.Changes[0].Context.NewLine)
|
||||
|
||||
@@ -14,6 +14,16 @@ type ExternalDocChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Example objects
|
||||
func (e *ExternalDocChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, e.Changes...)
|
||||
if e.ExtensionChanges != nil {
|
||||
changes = append(changes, e.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns a count of everything that changed
|
||||
func (e *ExternalDocChanges) TotalChanges() int {
|
||||
c := e.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -38,6 +38,7 @@ x-testing: hiya!`
|
||||
extChanges := CompareExternalDocs(&lDoc, &rDoc)
|
||||
assert.Len(t, extChanges.ExtensionChanges.Changes, 1)
|
||||
assert.Len(t, extChanges.Changes, 2)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
|
||||
// validate property changes
|
||||
@@ -94,6 +95,7 @@ url: https://quobix.com`
|
||||
extChanges := CompareExternalDocs(&lDoc, &rDoc)
|
||||
assert.Len(t, extChanges.ExtensionChanges.Changes, 1)
|
||||
assert.Len(t, extChanges.Changes, 2)
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
|
||||
// validate property changes
|
||||
urlChange := extChanges.Changes[0]
|
||||
@@ -169,6 +171,7 @@ x-testing: hello`
|
||||
// compare.
|
||||
extChanges := CompareExternalDocs(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -194,6 +197,7 @@ url: https://pb33f.io`
|
||||
// compare.
|
||||
extChanges := CompareExternalDocs(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -219,6 +223,7 @@ description: something`
|
||||
// compare.
|
||||
extChanges := CompareExternalDocs(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -244,5 +249,6 @@ url: https://pb33f.io`
|
||||
// compare
|
||||
extChanges := CompareExternalDocs(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,28 @@ type HeaderChanges struct {
|
||||
ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Header objects
|
||||
func (h *HeaderChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, h.Changes...)
|
||||
for k := range h.ExamplesChanges {
|
||||
changes = append(changes, h.ExamplesChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range h.ContentChanges {
|
||||
changes = append(changes, h.ContentChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if h.ExtensionChanges != nil {
|
||||
changes = append(changes, h.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
if h.SchemaChanges != nil {
|
||||
changes = append(changes, h.SchemaChanges.GetAllChanges()...)
|
||||
}
|
||||
if h.ItemsChanges != nil {
|
||||
changes = append(changes, h.ItemsChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes made between two Header objects.
|
||||
func (h *HeaderChanges) TotalChanges() int {
|
||||
c := h.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -123,6 +123,7 @@ x-beer: really yummy`
|
||||
extChanges := CompareHeadersV2(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -167,6 +168,7 @@ x-beer: yummy`
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -211,6 +213,7 @@ x-beer: yummy`
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -301,6 +304,7 @@ x-beer: yummy`
|
||||
extChanges := CompareHeadersV3(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 5, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 5)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,19 @@ type InfoChanges struct {
|
||||
LicenseChanges *LicenseChanges `json:"license,omitempty" yaml:"license,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Info objects
|
||||
func (i *InfoChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, i.Changes...)
|
||||
if i.ContactChanges != nil {
|
||||
changes = append(changes, i.ContactChanges.GetAllChanges()...)
|
||||
}
|
||||
if i.LicenseChanges != nil {
|
||||
changes = append(changes, i.LicenseChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges represents the total number of changes made to an Info object.
|
||||
func (i *InfoChanges) TotalChanges() int {
|
||||
t := i.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -48,6 +48,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -88,6 +89,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.TitleLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -127,6 +129,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.VersionLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -164,6 +167,7 @@ contact:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.LicenseLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -201,6 +205,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.LicenseLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -240,6 +245,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.LicenseChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.NameLabel, extChanges.LicenseChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -276,6 +282,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ContactLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -312,6 +319,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ContactLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -351,6 +359,7 @@ license:
|
||||
// compare.
|
||||
extChanges := CompareInfo(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.ContactChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.NameLabel, extChanges.ContactChanges.Changes[0].Property)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
|
||||
@@ -15,6 +15,16 @@ type ItemsChanges struct {
|
||||
ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Items objects
|
||||
func (i *ItemsChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, i.Changes...)
|
||||
if i.ItemsChanges != nil {
|
||||
changes = append(changes, i.ItemsChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes found between two Items objects
|
||||
// This is a recursive function because Items can contain Items. Be careful!
|
||||
func (i *ItemsChanges) TotalChanges() int {
|
||||
|
||||
@@ -34,6 +34,7 @@ func TestCompareItems(t *testing.T) {
|
||||
changes := CompareItems(&lDoc, &rDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -64,6 +65,7 @@ items:
|
||||
changes := CompareItems(&lDoc, &rDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 2, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.ItemsChanges.TotalChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.Changes[0].Property)
|
||||
@@ -93,6 +95,7 @@ items:
|
||||
changes := CompareItems(&lDoc, &rDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ItemsLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, PropertyAdded, changes.Changes[0].ChangeType)
|
||||
@@ -122,6 +125,7 @@ items:
|
||||
changes := CompareItems(&rDoc, &lDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ItemsLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, PropertyRemoved, changes.Changes[0].ChangeType)
|
||||
|
||||
@@ -13,6 +13,11 @@ type LicenseChanges struct {
|
||||
*PropertyChanges
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between License objects
|
||||
func (l *LicenseChanges) GetAllChanges() []*Change {
|
||||
return l.Changes
|
||||
}
|
||||
|
||||
// TotalChanges represents the total number of changes made to a License instance.
|
||||
func (l *LicenseChanges) TotalChanges() int {
|
||||
return l.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -33,6 +33,7 @@ url: https://pb33f.io`
|
||||
// compare.
|
||||
extChanges := CompareLicense(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
|
||||
@@ -60,6 +61,7 @@ url: https://pb33f.io`
|
||||
// compare.
|
||||
extChanges := CompareLicense(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -86,6 +88,7 @@ name: buckaroo`
|
||||
// compare.
|
||||
extChanges := CompareLicense(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -112,6 +115,7 @@ name: buckaroo`
|
||||
// compare.
|
||||
extChanges := CompareLicense(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -137,6 +141,7 @@ func TestCompareLicense_URLModified(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareLicense(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -163,6 +168,7 @@ url: https://pb33f.io`
|
||||
// compare.
|
||||
extChanges := CompareLicense(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[1].ChangeType)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,19 @@ type LinkChanges struct {
|
||||
ServerChanges *ServerChanges `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Link objects
|
||||
func (l *LinkChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, l.Changes...)
|
||||
if l.ServerChanges != nil {
|
||||
changes = append(changes, l.ServerChanges.GetAllChanges()...)
|
||||
}
|
||||
if l.ExtensionChanges != nil {
|
||||
changes = append(changes, l.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total changes made between OpenAPI Link objects
|
||||
func (l *LinkChanges) TotalChanges() int {
|
||||
c := l.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -76,6 +76,7 @@ x-cake: very tasty`
|
||||
// compare.
|
||||
extChanges := CompareLinks(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ExtensionChanges.Changes[0].ChangeType)
|
||||
|
||||
@@ -114,6 +115,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareLinks(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ServerChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -149,6 +151,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareLinks(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -184,6 +187,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareLinks(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -221,6 +225,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareLinks(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "nice", extChanges.Changes[0].NewObject)
|
||||
@@ -262,6 +267,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareLinks(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "hot", extChanges.Changes[0].NewObject)
|
||||
@@ -302,6 +308,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareLinks(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "hot", extChanges.Changes[0].OriginalObject)
|
||||
|
||||
@@ -19,6 +19,25 @@ type MediaTypeChanges struct {
|
||||
EncodingChanges map[string]*EncodingChanges `json:"encoding,omitempty" yaml:"encoding,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between MediaType objects
|
||||
func (m *MediaTypeChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, m.Changes...)
|
||||
if m.SchemaChanges != nil {
|
||||
changes = append(changes, m.SchemaChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range m.ExampleChanges {
|
||||
changes = append(changes, m.ExampleChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range m.EncodingChanges {
|
||||
changes = append(changes, m.EncodingChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if m.ExtensionChanges != nil {
|
||||
changes = append(changes, m.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes between two MediaType instances.
|
||||
func (m *MediaTypeChanges) TotalChanges() int {
|
||||
c := m.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -84,6 +84,7 @@ encoding:
|
||||
extChanges := CompareMediaTypes(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ExampleLabel, extChanges.Changes[0].Property)
|
||||
@@ -118,6 +119,7 @@ example:
|
||||
extChanges := CompareMediaTypes(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ExampleLabel, extChanges.Changes[0].Property)
|
||||
@@ -150,6 +152,7 @@ example:
|
||||
extChanges := CompareMediaTypes(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ExampleLabel, extChanges.Changes[0].Property)
|
||||
@@ -182,6 +185,7 @@ example:
|
||||
extChanges := CompareMediaTypes(&rDoc, &lDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ExampleLabel, extChanges.Changes[0].Property)
|
||||
@@ -221,6 +225,7 @@ encoding:
|
||||
extChanges := CompareMediaTypes(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.SchemaLabel, extChanges.Changes[0].Property)
|
||||
@@ -260,6 +265,7 @@ encoding:
|
||||
extChanges := CompareMediaTypes(&rDoc, &lDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.SchemaLabel, extChanges.Changes[0].Property)
|
||||
@@ -305,5 +311,6 @@ x-tea: cup`
|
||||
extChanges := CompareMediaTypes(&lDoc, &rDoc)
|
||||
assert.NotNil(t, extChanges)
|
||||
assert.Equal(t, 5, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 5)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -18,6 +18,28 @@ type OAuthFlowsChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between OAuthFlows objects
|
||||
func (o *OAuthFlowsChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, o.Changes...)
|
||||
if o.ImplicitChanges != nil {
|
||||
changes = append(changes, o.ImplicitChanges.GetAllChanges()...)
|
||||
}
|
||||
if o.PasswordChanges != nil {
|
||||
changes = append(changes, o.PasswordChanges.GetAllChanges()...)
|
||||
}
|
||||
if o.ClientCredentialsChanges != nil {
|
||||
changes = append(changes, o.ClientCredentialsChanges.GetAllChanges()...)
|
||||
}
|
||||
if o.AuthorizationCodeChanges != nil {
|
||||
changes = append(changes, o.AuthorizationCodeChanges.GetAllChanges()...)
|
||||
}
|
||||
if o.ExtensionChanges != nil {
|
||||
changes = append(changes, o.ImplicitChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the number of changes made between two OAuthFlows instances.
|
||||
func (o *OAuthFlowsChanges) TotalChanges() int {
|
||||
c := o.PropertyChanges.TotalChanges()
|
||||
@@ -137,6 +159,16 @@ type OAuthFlowChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between OAuthFlow objects
|
||||
func (o *OAuthFlowChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, o.Changes...)
|
||||
if o.ExtensionChanges != nil {
|
||||
changes = append(changes, o.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes made between two OAuthFlow objects
|
||||
func (o *OAuthFlowChanges) TotalChanges() int {
|
||||
c := o.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -74,6 +74,7 @@ x-burgers: crispy`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlow(&lDoc, &rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 3)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -109,6 +110,7 @@ x-burgers: nice`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlow(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, "taff", extChanges.Changes[0].New)
|
||||
assert.Equal(t, "tiff", extChanges.Changes[0].NewObject)
|
||||
@@ -146,6 +148,7 @@ x-burgers: nice`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlow(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, "taff", extChanges.Changes[0].Original)
|
||||
assert.Equal(t, "tiff", extChanges.Changes[0].OriginalObject)
|
||||
@@ -182,6 +185,7 @@ x-burgers: nice`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlow(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, "raff", extChanges.Changes[0].New)
|
||||
assert.Equal(t, "raff", extChanges.Changes[0].NewObject)
|
||||
@@ -255,6 +259,7 @@ x-coke: cola`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlows(&lDoc, &rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -286,6 +291,7 @@ x-coke: cola`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlows(&rDoc, &lDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 4, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -325,5 +331,6 @@ x-coke: cherry`
|
||||
// compare
|
||||
extChanges := CompareOAuthFlows(&lDoc, &rDoc)
|
||||
assert.Equal(t, 5, extChanges.TotalChanges())
|
||||
assert.Equal(t, 4, extChanges.TotalBreakingChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 5)
|
||||
assert.Equal(t, 4, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -30,6 +30,37 @@ type OperationChanges struct {
|
||||
CallbackChanges map[string]*CallbackChanges `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Operation objects
|
||||
func (o *OperationChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, o.Changes...)
|
||||
if o.ExternalDocChanges != nil {
|
||||
changes = append(changes, o.ExternalDocChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range o.ParameterChanges {
|
||||
changes = append(changes, o.ParameterChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if o.ResponsesChanges != nil {
|
||||
changes = append(changes, o.ResponsesChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range o.SecurityRequirementChanges {
|
||||
changes = append(changes, o.SecurityRequirementChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if o.RequestBodyChanges != nil {
|
||||
changes = append(changes, o.RequestBodyChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range o.ServerChanges {
|
||||
changes = append(changes, o.ServerChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range o.CallbackChanges {
|
||||
changes = append(changes, o.CallbackChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if o.ExtensionChanges != nil {
|
||||
changes = append(changes, o.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes made between two Swagger or OpenAPI Operation objects.
|
||||
func (o *OperationChanges) TotalChanges() int {
|
||||
c := o.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -102,6 +102,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -152,6 +153,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "parameters", extChanges.Changes[0].Property)
|
||||
@@ -205,6 +207,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "parameters", extChanges.Changes[0].Property)
|
||||
@@ -264,6 +267,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -321,6 +325,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "jummy", extChanges.Changes[0].Original)
|
||||
@@ -378,6 +383,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[1].ChangeType)
|
||||
@@ -435,6 +441,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.TagsLabel, extChanges.Changes[0].Property)
|
||||
@@ -471,6 +478,7 @@ schemes:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 6, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 6)
|
||||
assert.Equal(t, 3, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -504,6 +512,7 @@ responses:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ResponsesChanges.ResponseChanges["200"].Changes[0].ChangeType)
|
||||
assert.Equal(t, Modified, extChanges.ExternalDocChanges.Changes[0].ChangeType)
|
||||
@@ -545,6 +554,7 @@ responses:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -574,6 +584,7 @@ responses:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[1].ChangeType)
|
||||
@@ -605,6 +616,7 @@ responses:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[1].ChangeType)
|
||||
@@ -640,6 +652,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.SecurityRequirementChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "crap", extChanges.SecurityRequirementChanges[0].Changes[0].New)
|
||||
@@ -676,6 +689,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.SecurityRequirementChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "crap", extChanges.SecurityRequirementChanges[0].Changes[0].Original)
|
||||
@@ -714,6 +728,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "thongs", extChanges.Changes[0].New)
|
||||
@@ -752,6 +767,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "thongs", extChanges.Changes[0].Original)
|
||||
@@ -831,6 +847,7 @@ func TestCompareOperations_V3_ModifyParam(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ParameterChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -864,6 +881,7 @@ func TestCompareOperations_V3_AddParam(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -897,6 +915,7 @@ func TestCompareOperations_V3_RemoveParam(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -926,6 +945,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -955,6 +975,7 @@ parameters:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -985,6 +1006,7 @@ func TestCompareOperations_V3_ModifyServers(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1018,6 +1040,7 @@ func TestCompareOperations_V3_ModifyCallback(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.
|
||||
CallbackChanges["myCallback"].
|
||||
@@ -1058,6 +1081,7 @@ func TestCompareOperations_V3_AddCallback(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1092,6 +1116,7 @@ callbacks:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1126,6 +1151,7 @@ callbacks:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1163,6 +1189,7 @@ func TestCompareOperations_V3_RemoveCallback(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1191,6 +1218,7 @@ func TestCompareOperations_V3_AddServer(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1219,6 +1247,7 @@ func TestCompareOperations_V3_RemoveServer(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1247,6 +1276,7 @@ servers:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1275,6 +1305,7 @@ servers:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1307,6 +1338,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.SecurityRequirementChanges[0].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1335,6 +1367,7 @@ security:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Empty(t, extChanges.SecurityRequirementChanges)
|
||||
}
|
||||
@@ -1363,6 +1396,7 @@ security: []`
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Empty(t, extChanges.SecurityRequirementChanges)
|
||||
}
|
||||
@@ -1390,6 +1424,7 @@ func TestCompareOperations_V3_ModifyRequestBody(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.RequestBodyChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1417,6 +1452,7 @@ requestBody:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1442,6 +1478,7 @@ func TestCompareOperations_V3_ModifyExtension(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ExtensionChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -1469,6 +1506,7 @@ requestBody:
|
||||
// compare.
|
||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,28 @@ type ParameterChanges struct {
|
||||
ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Parameter objects
|
||||
func (p *ParameterChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, p.Changes...)
|
||||
if p.SchemaChanges != nil {
|
||||
changes = append(changes, p.SchemaChanges.GetAllChanges()...)
|
||||
}
|
||||
for i := range p.ExamplesChanges {
|
||||
changes = append(changes, p.ExamplesChanges[i].GetAllChanges()...)
|
||||
}
|
||||
if p.ItemsChanges != nil {
|
||||
changes = append(changes, p.ItemsChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.ExtensionChanges != nil {
|
||||
changes = append(changes, p.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
for i := range p.ContentChanges {
|
||||
changes = append(changes, p.ContentChanges[i].GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns a count of everything that changed
|
||||
func (p *ParameterChanges) TotalChanges() int {
|
||||
c := p.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -78,6 +78,7 @@ func TestCompareParameters_V3_Schema(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.SchemaChanges.TotalChanges())
|
||||
|
||||
@@ -105,6 +106,7 @@ schema:
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
|
||||
@@ -132,6 +134,7 @@ schema:
|
||||
// compare.
|
||||
extChanges := CompareParameters(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
|
||||
@@ -157,6 +160,7 @@ func TestCompareParameters_V3_Extensions(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.ExtensionChanges.TotalChanges())
|
||||
|
||||
@@ -183,6 +187,7 @@ func TestCompareParameters_V3_ExampleChange(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -229,6 +234,7 @@ example: a string`
|
||||
// compare
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -254,6 +260,7 @@ example: a string`
|
||||
// compare
|
||||
extChanges := CompareParameters(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -282,6 +289,7 @@ func TestCompareParameters_V3_ExamplesChanged(t *testing.T) {
|
||||
// compare
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ExamplesChanges["anExample"].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -313,6 +321,7 @@ func TestCompareParameters_V3_ExamplesAdded(t *testing.T) {
|
||||
// compare
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -344,6 +353,7 @@ func TestCompareParameters_V3_ExamplesRemoved(t *testing.T) {
|
||||
// compare
|
||||
extChanges := CompareParameters(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -375,6 +385,7 @@ func TestCompareParameters_V3_ContentChanged(t *testing.T) {
|
||||
// compare
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified,
|
||||
extChanges.ContentChanges["application/json"].SchemaChanges.Changes[0].ChangeType)
|
||||
@@ -410,6 +421,7 @@ func TestCompareParameters_V3_ContentAdded(t *testing.T) {
|
||||
// compare
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -434,6 +446,7 @@ func TestCompareParameters_V2_DefaultChange(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -458,6 +471,7 @@ default: wat?`
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -483,6 +497,7 @@ func TestCompareParameters_V2_EnumChange(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -533,6 +548,7 @@ example: a string`
|
||||
// compare
|
||||
extChanges := CompareParameters(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -603,6 +619,7 @@ func TestCompareParameters_V2_ItemsChange(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ItemsChanges.Changes[0].ChangeType)
|
||||
|
||||
@@ -630,6 +647,7 @@ items:
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -656,6 +674,7 @@ items:
|
||||
// compare.
|
||||
extChanges := CompareParameters(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -680,6 +699,7 @@ func TestCompareParameters_V2_Extensions(t *testing.T) {
|
||||
// compare.
|
||||
extChanges := CompareParameters(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.ExtensionChanges.TotalChanges())
|
||||
}
|
||||
|
||||
@@ -27,6 +27,46 @@ type PathItemChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between PathItem objects
|
||||
func (p *PathItemChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, p.Changes...)
|
||||
if p.GetChanges != nil {
|
||||
changes = append(changes, p.GetChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.PutChanges != nil {
|
||||
changes = append(changes, p.PutChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.PostChanges != nil {
|
||||
changes = append(changes, p.PostChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.DeleteChanges != nil {
|
||||
changes = append(changes, p.DeleteChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.OptionsChanges != nil {
|
||||
changes = append(changes, p.OptionsChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.HeadChanges != nil {
|
||||
changes = append(changes, p.HeadChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.PatchChanges != nil {
|
||||
changes = append(changes, p.PatchChanges.GetAllChanges()...)
|
||||
}
|
||||
if p.TraceChanges != nil {
|
||||
changes = append(changes, p.TraceChanges.GetAllChanges()...)
|
||||
}
|
||||
for i := range p.ServerChanges {
|
||||
changes = append(changes, p.ServerChanges[i].GetAllChanges()...)
|
||||
}
|
||||
for i := range p.ParameterChanges {
|
||||
changes = append(changes, p.ParameterChanges[i].GetAllChanges()...)
|
||||
}
|
||||
if p.ExtensionChanges != nil {
|
||||
changes = append(changes, p.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes found between two Swagger or OpenAPI PathItems
|
||||
func (p *PathItemChanges) TotalChanges() int {
|
||||
c := p.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -105,6 +105,7 @@ x-thing: ding-a-ling`
|
||||
// compare.
|
||||
extChanges := ComparePathItems(&lDoc, &rDoc)
|
||||
assert.Equal(t, 8, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 8)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,19 @@ type PathsChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Paths objects
|
||||
func (p *PathsChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, p.Changes...)
|
||||
for k := range p.PathItemsChanges {
|
||||
changes = append(changes, p.PathItemsChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if p.ExtensionChanges != nil {
|
||||
changes = append(changes, p.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes between two Swagger or OpenAPI Paths Objects
|
||||
func (p *PathsChanges) TotalChanges() int {
|
||||
c := p.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -84,6 +84,7 @@ x-windows: washed
|
||||
// compare.
|
||||
extChanges := ComparePaths(&lDoc, &rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -123,6 +124,7 @@ x-windows: dirty
|
||||
// compare.
|
||||
extChanges := ComparePaths(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "/crispy/chips", extChanges.Changes[0].New)
|
||||
@@ -164,6 +166,7 @@ x-windows: dirty
|
||||
// compare.
|
||||
extChanges := ComparePaths(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "/crispy/chips", extChanges.Changes[0].Original)
|
||||
@@ -240,6 +243,7 @@ x-windows: washed
|
||||
// compare.
|
||||
extChanges := ComparePaths(&lDoc, &rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -286,6 +290,7 @@ x-windows: dirty`
|
||||
// compare.
|
||||
extChanges := ComparePaths(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "/mushy/peas", extChanges.Changes[0].New)
|
||||
@@ -334,6 +339,7 @@ x-windows: dirty`
|
||||
// compare.
|
||||
extChanges := ComparePaths(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "/mushy/peas", extChanges.Changes[0].Original)
|
||||
|
||||
@@ -15,6 +15,19 @@ type RequestBodyChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between RequestBody objects
|
||||
func (rb *RequestBodyChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, rb.Changes...)
|
||||
for k := range rb.ContentChanges {
|
||||
changes = append(changes, rb.ContentChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if rb.ExtensionChanges != nil {
|
||||
changes = append(changes, rb.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes found between two OpenAPI RequestBody objects
|
||||
func (rb *RequestBodyChanges) TotalChanges() int {
|
||||
c := rb.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -78,5 +78,6 @@ content:
|
||||
extChanges := CompareRequestBodies(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -26,6 +26,34 @@ type ResponseChanges struct {
|
||||
ServerChanges *ServerChanges `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between RequestBody objects
|
||||
func (r *ResponseChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, r.Changes...)
|
||||
if r.ExtensionChanges != nil {
|
||||
changes = append(changes, r.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
if r.SchemaChanges != nil {
|
||||
changes = append(changes, r.SchemaChanges.GetAllChanges()...)
|
||||
}
|
||||
if r.ExamplesChanges != nil {
|
||||
changes = append(changes, r.ExamplesChanges.GetAllChanges()...)
|
||||
}
|
||||
if r.ServerChanges != nil {
|
||||
changes = append(changes, r.ServerChanges.GetAllChanges()...)
|
||||
}
|
||||
for k := range r.HeadersChanges {
|
||||
changes = append(changes, r.HeadersChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range r.ContentChanges {
|
||||
changes = append(changes, r.ContentChanges[k].GetAllChanges()...)
|
||||
}
|
||||
for k := range r.LinkChanges {
|
||||
changes = append(changes, r.LinkChanges[k].GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes found between two Swagger or OpenAPI Response Objects
|
||||
func (r *ResponseChanges) TotalChanges() int {
|
||||
c := r.PropertyChanges.TotalChanges()
|
||||
@@ -38,6 +66,9 @@ func (r *ResponseChanges) TotalChanges() int {
|
||||
if r.ExamplesChanges != nil {
|
||||
c += r.ExamplesChanges.TotalChanges()
|
||||
}
|
||||
if r.ServerChanges != nil {
|
||||
c += r.ServerChanges.TotalChanges()
|
||||
}
|
||||
for k := range r.HeadersChanges {
|
||||
c += r.HeadersChanges[k].TotalChanges()
|
||||
}
|
||||
@@ -57,6 +88,9 @@ func (r *ResponseChanges) TotalBreakingChanges() int {
|
||||
if r.SchemaChanges != nil {
|
||||
c += r.SchemaChanges.TotalBreakingChanges()
|
||||
}
|
||||
if r.ServerChanges != nil {
|
||||
c += r.ServerChanges.TotalBreakingChanges()
|
||||
}
|
||||
for k := range r.HeadersChanges {
|
||||
c += r.HeadersChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ x-toot: poot`
|
||||
|
||||
extChanges := CompareResponse(&lDoc, &rDoc)
|
||||
assert.Equal(t, 5, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 5)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -110,6 +111,7 @@ examples:
|
||||
|
||||
extChanges := CompareResponse(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -143,6 +145,7 @@ examples:
|
||||
|
||||
extChanges := CompareResponse(&rDoc, &lDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -223,5 +226,6 @@ x-toot: pooty`
|
||||
extChanges := CompareResponse(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, 5, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 5)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -18,6 +18,22 @@ type ResponsesChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Responses objects
|
||||
func (r *ResponsesChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, r.Changes...)
|
||||
for k := range r.ResponseChanges {
|
||||
changes = append(changes, r.ResponseChanges[k].GetAllChanges()...)
|
||||
}
|
||||
if r.DefaultChanges != nil {
|
||||
changes = append(changes, r.DefaultChanges.GetAllChanges()...)
|
||||
}
|
||||
if r.ExtensionChanges != nil {
|
||||
changes = append(changes, r.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes found between two Swagger or OpenAPI Responses objects
|
||||
func (r *ResponsesChanges) TotalChanges() int {
|
||||
c := r.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -81,6 +81,7 @@ x-ting: tang`
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
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)
|
||||
@@ -121,6 +122,7 @@ x-apple: pie`
|
||||
|
||||
extChanges := CompareResponses(&rDoc, &lDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.ResponseChanges["200"].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -156,6 +158,7 @@ func TestCompareResponses_V2_RemoveSchema(t *testing.T) {
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.ResponseChanges["200"].Changes[0].ChangeType)
|
||||
}
|
||||
@@ -189,6 +192,7 @@ default:
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -222,6 +226,7 @@ default:
|
||||
|
||||
extChanges := CompareResponses(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -259,6 +264,7 @@ default:
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -322,6 +328,7 @@ x-coffee: yum
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -355,6 +362,7 @@ default:
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DefaultLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -389,6 +397,7 @@ default:
|
||||
|
||||
extChanges := CompareResponses(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DefaultLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -425,6 +434,7 @@ default:
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.DefaultChanges.Changes[0].Property)
|
||||
}
|
||||
@@ -457,5 +467,6 @@ func TestCompareResponses_V3_AddRemoveMediaType(t *testing.T) {
|
||||
|
||||
extChanges := CompareResponses(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -45,6 +45,94 @@ type SchemaChanges struct {
|
||||
PatternPropertiesChanges map[string]*SchemaChanges `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Responses objects
|
||||
func (s *SchemaChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, s.Changes...)
|
||||
if s.DiscriminatorChanges != nil {
|
||||
changes = append(changes, s.DiscriminatorChanges.GetAllChanges()...)
|
||||
}
|
||||
if len(s.AllOfChanges) > 0 {
|
||||
for n := range s.AllOfChanges {
|
||||
if s.AllOfChanges[n] != nil {
|
||||
changes = append(changes, s.AllOfChanges[n].GetAllChanges()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(s.AnyOfChanges) > 0 {
|
||||
for n := range s.AnyOfChanges {
|
||||
if s.AnyOfChanges[n] != nil {
|
||||
changes = append(changes, s.AnyOfChanges[n].GetAllChanges()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(s.OneOfChanges) > 0 {
|
||||
for n := range s.OneOfChanges {
|
||||
if s.OneOfChanges[n] != nil {
|
||||
changes = append(changes, s.OneOfChanges[n].GetAllChanges()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.NotChanges != nil {
|
||||
changes = append(changes, s.NotChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.ItemsChanges != nil {
|
||||
changes = append(changes, s.ItemsChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.IfChanges != nil {
|
||||
changes = append(changes, s.IfChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.ElseChanges != nil {
|
||||
changes = append(changes, s.ElseChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.ThenChanges != nil {
|
||||
changes = append(changes, s.ThenChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.PropertyNamesChanges != nil {
|
||||
changes = append(changes, s.PropertyNamesChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.ContainsChanges != nil {
|
||||
changes = append(changes, s.ContainsChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.UnevaluatedItemsChanges != nil {
|
||||
changes = append(changes, s.UnevaluatedItemsChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.UnevaluatedPropertiesChanges != nil {
|
||||
changes = append(changes, s.UnevaluatedPropertiesChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.SchemaPropertyChanges != nil {
|
||||
for n := range s.SchemaPropertyChanges {
|
||||
if s.SchemaPropertyChanges[n] != nil {
|
||||
changes = append(changes, s.SchemaPropertyChanges[n].GetAllChanges()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.DependentSchemasChanges != nil {
|
||||
for n := range s.DependentSchemasChanges {
|
||||
if s.DependentSchemasChanges[n] != nil {
|
||||
changes = append(changes, s.DependentSchemasChanges[n].GetAllChanges()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.PatternPropertiesChanges != nil {
|
||||
for n := range s.PatternPropertiesChanges {
|
||||
if s.PatternPropertiesChanges[n] != nil {
|
||||
changes = append(changes, s.PatternPropertiesChanges[n].GetAllChanges()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.ExternalDocChanges != nil {
|
||||
changes = append(changes, s.ExternalDocChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.XMLChanges != nil {
|
||||
changes = append(changes, s.XMLChanges.GetAllChanges()...)
|
||||
}
|
||||
if s.ExtensionChanges != nil {
|
||||
changes = append(changes, s.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns a count of the total number of changes made to this schema and all sub-schemas
|
||||
func (s *SchemaChanges) TotalChanges() int {
|
||||
t := s.PropertyChanges.TotalChanges()
|
||||
@@ -58,7 +146,9 @@ func (s *SchemaChanges) TotalChanges() int {
|
||||
}
|
||||
if len(s.AnyOfChanges) > 0 {
|
||||
for n := range s.AnyOfChanges {
|
||||
t += s.AnyOfChanges[n].TotalChanges()
|
||||
if s.AnyOfChanges[n] != nil {
|
||||
t += s.AnyOfChanges[n].TotalChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(s.OneOfChanges) > 0 {
|
||||
@@ -95,7 +185,9 @@ func (s *SchemaChanges) TotalChanges() int {
|
||||
}
|
||||
if s.SchemaPropertyChanges != nil {
|
||||
for n := range s.SchemaPropertyChanges {
|
||||
t += s.SchemaPropertyChanges[n].TotalChanges()
|
||||
if s.SchemaPropertyChanges[n] != nil {
|
||||
t += s.SchemaPropertyChanges[n].TotalChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.DependentSchemasChanges != nil {
|
||||
@@ -302,7 +394,10 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
} else {
|
||||
sc.PropertyChanges = NewPropertyChanges(nil)
|
||||
}
|
||||
return sc
|
||||
if sc.TotalChanges() > 0 {
|
||||
return sc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkSchemaXML(lSchema *base.Schema, rSchema *base.Schema, changes *[]*Change, sc *SchemaChanges) {
|
||||
|
||||
@@ -43,6 +43,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "an OK message Changed", changes.Changes[0].New)
|
||||
@@ -71,6 +72,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "a thing", changes.Changes[0].New)
|
||||
assert.Equal(t, v3.DescriptionLabel, changes.Changes[0].Property)
|
||||
@@ -99,6 +101,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "a thing", changes.Changes[0].Original)
|
||||
assert.Equal(t, v3.DescriptionLabel, changes.Changes[0].Property)
|
||||
@@ -125,6 +128,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -149,6 +153,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -238,6 +243,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "#/components/schemas/Yo", changes.Changes[0].New)
|
||||
}
|
||||
@@ -268,6 +274,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.RefLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, "#/components/schemas/Yo", changes.Changes[0].Original)
|
||||
@@ -300,6 +307,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.RefLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, "#/components/schemas/Yo", changes.Changes[0].New)
|
||||
@@ -389,6 +397,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 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)
|
||||
@@ -419,6 +428,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 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)
|
||||
@@ -446,6 +456,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 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)
|
||||
@@ -473,6 +484,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 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)
|
||||
@@ -506,6 +518,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 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)
|
||||
@@ -539,6 +552,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Len(t, changes.GetAllChanges(), 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)
|
||||
@@ -568,6 +582,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.IfChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -596,6 +611,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.IfLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -624,6 +640,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.IfLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -652,6 +669,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.ElseChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -680,6 +698,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ElseLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -708,6 +727,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ElseLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -736,6 +756,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.ThenChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -764,6 +785,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ThenLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -792,6 +814,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ThenLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -822,6 +845,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.DependentSchemasChanges["schemaOne"].PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -852,6 +876,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.PatternPropertiesChanges["schemaOne"].PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -880,6 +905,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.PropertyNamesChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -908,6 +934,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.PropertyNamesLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -936,6 +963,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.PropertyNamesLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -964,6 +992,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.ContainsChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -992,6 +1021,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ContainsLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -1020,6 +1050,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ContainsLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -1048,6 +1079,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.UnevaluatedPropertiesChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -1076,6 +1108,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.UnevaluatedPropertiesLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -1104,6 +1137,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.UnevaluatedPropertiesLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -1132,6 +1166,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, changes.UnevaluatedItemsChanges.PropertyChanges.TotalChanges())
|
||||
}
|
||||
@@ -1160,6 +1195,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.UnevaluatedItemsLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -1188,6 +1224,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.UnevaluatedItemsLabel, changes.Changes[0].Property)
|
||||
}
|
||||
@@ -1213,6 +1250,7 @@ components:
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
}
|
||||
@@ -1239,6 +1277,7 @@ components:
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
}
|
||||
@@ -1265,6 +1304,7 @@ components:
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
}
|
||||
@@ -1292,6 +1332,7 @@ components:
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
}
|
||||
@@ -1320,6 +1361,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -1349,6 +1391,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
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)
|
||||
@@ -1381,6 +1424,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "propN", changes.Changes[0].New)
|
||||
@@ -1415,6 +1459,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.AnyOfLabel, changes.Changes[0].Property)
|
||||
@@ -1448,6 +1493,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 2, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.AnyOfLabel, changes.Changes[0].Property)
|
||||
@@ -1480,6 +1526,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
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)
|
||||
@@ -1512,6 +1559,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.OneOfLabel, changes.Changes[0].Property)
|
||||
@@ -1545,6 +1593,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 2, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.AllOfLabel, changes.Changes[0].Property)
|
||||
@@ -1579,6 +1628,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.ItemsChanges.Changes[0].ChangeType)
|
||||
@@ -1612,6 +1662,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.ItemsChanges.Changes[0].ChangeType)
|
||||
@@ -1645,6 +1696,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.NotChanges.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.NotChanges.Changes[0].ChangeType)
|
||||
@@ -1678,6 +1730,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
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)
|
||||
@@ -1709,6 +1762,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DiscriminatorLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
@@ -1741,6 +1795,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DiscriminatorLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
@@ -1775,6 +1830,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
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)
|
||||
@@ -1806,6 +1862,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExternalDocsLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
@@ -1838,6 +1895,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExternalDocsLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
@@ -1869,6 +1927,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
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)
|
||||
@@ -1927,6 +1986,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExampleLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, PropertyAdded, changes.Changes[0].ChangeType)
|
||||
@@ -1956,6 +2016,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExampleLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, PropertyRemoved, changes.Changes[0].ChangeType)
|
||||
@@ -1988,6 +2049,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExamplesLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
@@ -2019,6 +2081,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExamplesLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
@@ -2052,6 +2115,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExamplesLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
@@ -2085,6 +2149,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExamplesLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
@@ -2118,6 +2183,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExamplesLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.Changes[0].ChangeType)
|
||||
@@ -2151,6 +2217,7 @@ components:
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.NameLabel, changes.XMLChanges.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.XMLChanges.Changes[0].ChangeType)
|
||||
@@ -2210,6 +2277,7 @@ components:
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.XMLLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
@@ -2252,6 +2320,7 @@ components:
|
||||
changes := CompareDocuments(leftDoc, rightDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
@@ -2281,6 +2350,7 @@ components:
|
||||
changes := CompareDocuments(leftDoc, rightDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
@@ -2314,6 +2384,7 @@ components:
|
||||
changes := CompareDocuments(leftDoc, rightDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Len(t, changes.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,16 @@ type ScopesChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Scopes objects
|
||||
func (s *ScopesChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, s.Changes...)
|
||||
if s.ExtensionChanges != nil {
|
||||
changes = append(changes, s.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total changes found between two Swagger Scopes objects.
|
||||
func (s *ScopesChanges) TotalChanges() int {
|
||||
c := s.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -61,6 +61,7 @@ x-nugget: chicken`
|
||||
// compare.
|
||||
extChanges := CompareScopes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "pie", extChanges.Changes[0].New)
|
||||
@@ -89,6 +90,7 @@ x-nugget: chicken`
|
||||
// compare.
|
||||
extChanges := CompareScopes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "sky", extChanges.Changes[0].New)
|
||||
@@ -118,6 +120,7 @@ x-nugget: soup`
|
||||
// compare.
|
||||
extChanges := CompareScopes(&rDoc, &lDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "sky", extChanges.Changes[0].Original)
|
||||
|
||||
@@ -15,6 +15,11 @@ type SecurityRequirementChanges struct {
|
||||
*PropertyChanges
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between SecurityRequirement objects
|
||||
func (s *SecurityRequirementChanges) GetAllChanges() []*Change {
|
||||
return s.Changes
|
||||
}
|
||||
|
||||
// TotalChanges returns the total number of changes between two SecurityRequirement Objects.
|
||||
func (s *SecurityRequirementChanges) TotalChanges() int {
|
||||
return s.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -69,6 +69,7 @@ biscuit:
|
||||
// compare
|
||||
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "biscuit", extChanges.Changes[0].NewObject)
|
||||
@@ -101,6 +102,7 @@ biscuit:
|
||||
// compare
|
||||
extChanges := CompareSecurityRequirement(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -133,6 +135,7 @@ milk:
|
||||
// compare
|
||||
extChanges := CompareSecurityRequirement(&lDoc, &rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[1].ChangeType)
|
||||
|
||||
@@ -22,6 +22,22 @@ type SecuritySchemeChanges struct {
|
||||
ScopesChanges *ScopesChanges `json:"scopes,omitempty" yaml:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between SecurityRequirement objects
|
||||
func (ss *SecuritySchemeChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, ss.Changes...)
|
||||
if ss.OAuthFlowChanges != nil {
|
||||
changes = append(changes, ss.OAuthFlowChanges.GetAllChanges()...)
|
||||
}
|
||||
if ss.ScopesChanges != nil {
|
||||
changes = append(changes, ss.ScopesChanges.GetAllChanges()...)
|
||||
}
|
||||
if ss.ExtensionChanges != nil {
|
||||
changes = append(changes, ss.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges represents total changes found between two Swagger or OpenAPI SecurityScheme instances.
|
||||
func (ss *SecuritySchemeChanges) TotalChanges() int {
|
||||
c := ss.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -72,6 +72,7 @@ x-beer: very tasty`
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 4, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 4)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, Modified, extChanges.Changes[1].ChangeType)
|
||||
@@ -103,6 +104,7 @@ scopes:
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ScopesLabel, extChanges.Changes[0].Property)
|
||||
@@ -132,6 +134,7 @@ scopes:
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ScopesLabel, extChanges.Changes[0].Property)
|
||||
@@ -161,6 +164,7 @@ func TestCompareSecuritySchemes_v2_ModifyScope(t *testing.T) {
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.ScopesChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.ScopesLabel, extChanges.ScopesChanges.Changes[0].Property)
|
||||
@@ -226,6 +230,7 @@ x-beer: cool`
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 5, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 5)
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, Modified, extChanges.Changes[1].ChangeType)
|
||||
@@ -258,6 +263,7 @@ flows:
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -286,6 +292,7 @@ flows:
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -317,6 +324,7 @@ flows:
|
||||
// compare
|
||||
extChanges := CompareSecuritySchemes(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.OAuthFlowChanges.ImplicitChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,16 @@ type ServerChanges struct {
|
||||
ServerVariableChanges map[string]*ServerVariableChanges `json:"serverVariables,omitempty" yaml:"serverVariables,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between SecurityRequirement objects
|
||||
func (s *ServerChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, s.Changes...)
|
||||
for k := range s.ServerVariableChanges {
|
||||
changes = append(changes, s.ServerVariableChanges[k].GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns total changes found between two OpenAPI Server Objects
|
||||
func (s *ServerChanges) TotalChanges() int {
|
||||
c := s.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -83,6 +83,7 @@ variables:
|
||||
// compare.
|
||||
extChanges := CompareServers(&lDoc, &rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -120,6 +121,7 @@ variables:
|
||||
// compare.
|
||||
extChanges := CompareServers(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, ObjectAdded, extChanges.ServerVariableChanges["thing"].Changes[0].ChangeType)
|
||||
@@ -159,6 +161,7 @@ variables:
|
||||
// compare.
|
||||
extChanges := CompareServers(&rDoc, &lDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 2)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, ObjectRemoved, extChanges.ServerVariableChanges["thing"].Changes[0].ChangeType)
|
||||
|
||||
@@ -13,6 +13,11 @@ type ServerVariableChanges struct {
|
||||
*PropertyChanges
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between SecurityRequirement objects
|
||||
func (s *ServerVariableChanges) GetAllChanges() []*Change {
|
||||
return s.Changes
|
||||
}
|
||||
|
||||
// CompareServerVariables compares a left and right OpenAPI ServerVariable object for changes.
|
||||
// If anything is found, returns a pointer to a ServerVariableChanges instance, otherwise returns nil.
|
||||
func CompareServerVariables(l, r *v3.ServerVariable) *ServerVariableChanges {
|
||||
|
||||
@@ -67,6 +67,7 @@ enum:
|
||||
// compare.
|
||||
extChanges := CompareServerVariables(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
||||
|
||||
@@ -100,6 +101,7 @@ enum:
|
||||
// compare.
|
||||
extChanges := CompareServerVariables(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -129,6 +131,7 @@ enum:
|
||||
// compare.
|
||||
extChanges := CompareServerVariables(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
@@ -159,6 +162,7 @@ enum:
|
||||
// compare.
|
||||
extChanges := CompareServerVariables(&rDoc, &lDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,19 @@ type TagChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between Tag objects
|
||||
func (t *TagChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, t.Changes...)
|
||||
if t.ExternalDocs != nil {
|
||||
changes = append(changes, t.ExternalDocs.GetAllChanges()...)
|
||||
}
|
||||
if t.ExtensionChanges != nil {
|
||||
changes = append(changes, t.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns a count of everything that changed within tags.
|
||||
func (t *TagChanges) TotalChanges() int {
|
||||
c := t.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -44,6 +44,7 @@ tags:
|
||||
assert.Len(t, changes[0].ExternalDocs.Changes, 2)
|
||||
assert.Len(t, changes[0].ExtensionChanges.Changes, 1)
|
||||
assert.Equal(t, 4, changes[0].TotalChanges())
|
||||
assert.Len(t, changes[0].GetAllChanges(), 4)
|
||||
|
||||
descChange := changes[0].Changes[0]
|
||||
assert.Equal(t, "a lovelier tag description", descChange.New)
|
||||
@@ -86,6 +87,7 @@ tags:
|
||||
// evaluate.
|
||||
assert.Len(t, changes[0].Changes, 1)
|
||||
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||
assert.Len(t, changes[0].GetAllChanges(), 1)
|
||||
|
||||
descChange := changes[0].Changes[0]
|
||||
assert.Equal(t, ObjectAdded, descChange.ChangeType)
|
||||
@@ -119,6 +121,7 @@ tags:
|
||||
// evaluate.
|
||||
assert.Len(t, changes, 2)
|
||||
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||
assert.Len(t, changes[0].GetAllChanges(), 1)
|
||||
assert.Equal(t, 1, changes[1].TotalChanges())
|
||||
assert.Equal(t, 1, changes[0].TotalBreakingChanges())
|
||||
}
|
||||
@@ -222,6 +225,7 @@ tags:
|
||||
// evaluate.
|
||||
assert.Len(t, changes[0].Changes, 1)
|
||||
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||
assert.Len(t, changes[0].GetAllChanges(), 1)
|
||||
|
||||
descChange := changes[0].Changes[0]
|
||||
assert.Equal(t, Modified, descChange.ChangeType)
|
||||
@@ -288,6 +292,7 @@ tags:
|
||||
|
||||
// evaluate.
|
||||
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||
assert.Len(t, changes[0].GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, changes[0].Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -316,6 +321,7 @@ tags:
|
||||
|
||||
// evaluate.
|
||||
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||
assert.Len(t, changes[0].GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectRemoved, changes[0].Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,16 @@ type XMLChanges struct {
|
||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// GetAllChanges returns a slice of all changes made between XML objects
|
||||
func (x *XMLChanges) GetAllChanges() []*Change {
|
||||
var changes []*Change
|
||||
changes = append(changes, x.Changes...)
|
||||
if x.ExtensionChanges != nil {
|
||||
changes = append(changes, x.ExtensionChanges.GetAllChanges()...)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// TotalChanges returns a count of everything that was changed within an XML object.
|
||||
func (x *XMLChanges) TotalChanges() int {
|
||||
c := x.PropertyChanges.TotalChanges()
|
||||
|
||||
@@ -40,6 +40,7 @@ wrapped: true`
|
||||
// compare.
|
||||
extChanges := CompareXML(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
@@ -72,6 +73,7 @@ namespace: something`
|
||||
// compare.
|
||||
extChanges := CompareXML(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
|
||||
@@ -107,6 +109,7 @@ x-coffee: time`
|
||||
// compare.
|
||||
extChanges := CompareXML(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Len(t, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(t, ObjectAdded, extChanges.ExtensionChanges.Changes[0].ChangeType)
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low/v2"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"github.com/pb33f/libopenapi/what-changed/model"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// CompareOpenAPIDocuments will compare left (original) and right (updated) OpenAPI 3+ documents and extract every change
|
||||
@@ -34,3 +35,23 @@ func CompareOpenAPIDocuments(original, updated *v3.Document) *model.DocumentChan
|
||||
func CompareSwaggerDocuments(original, updated *v2.Swagger) *model.DocumentChanges {
|
||||
return model.CompareDocuments(original, updated)
|
||||
}
|
||||
|
||||
func ExtractFlatChanges(changes *model.DocumentChanges) []*model.Change {
|
||||
return extractChanges(changes)
|
||||
}
|
||||
|
||||
func extractChanges(anything any) []*model.Change {
|
||||
|
||||
vo := reflect.ValueOf(anything)
|
||||
switch vo.Kind() {
|
||||
case reflect.Ptr:
|
||||
extractChanges(vo.Elem().Interface())
|
||||
case reflect.Slice:
|
||||
|
||||
panic("slice not supported")
|
||||
|
||||
case reflect.Struct:
|
||||
extractChanges(vo.Elem().Interface())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user