mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 20:47:44 +00:00
Also adding in other properties to schema that are missing. Test coverage still needs improving and this is a breaking change to low and high models.
This commit is contained in:
@@ -11,6 +11,30 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DynamicValue is used to hold multiple possible values for a schema property. There are two values, a left
|
||||||
|
// value (A) and a right value (B). The left value (A) is a 3.0 schema property value, the right value (B) is a 3.1
|
||||||
|
// schema value.
|
||||||
|
//
|
||||||
|
// OpenAPI 3.1 treats a Schema as a real JSON schema, which means some properties become incompatible, or others
|
||||||
|
// now support more than one primitive type or structure.
|
||||||
|
// The N value is a bit to make it each to know which value (A or B) is used, this prevents having to
|
||||||
|
// if/else on the value to determine which one is set.
|
||||||
|
type DynamicValue[A any, B any] struct {
|
||||||
|
N int // 0 == A, 1 == B
|
||||||
|
A A
|
||||||
|
B B
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsA will return true if the 'A' or left value is set. (OpenAPI 3)
|
||||||
|
func (s DynamicValue[A, B]) IsA() bool {
|
||||||
|
return s.N == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsB will return true if the 'B' or right value is set (OpenAPI 3.1)
|
||||||
|
func (s DynamicValue[A, B]) IsB() bool {
|
||||||
|
return s.N == 1
|
||||||
|
}
|
||||||
|
|
||||||
// Schema represents a JSON Schema that support Swagger, OpenAPI 3 and OpenAPI 3.1
|
// Schema represents a JSON Schema that support Swagger, OpenAPI 3 and OpenAPI 3.1
|
||||||
//
|
//
|
||||||
// Until 3.1 OpenAPI had a strange relationship with JSON Schema. It's been a super-set/sub-set
|
// Until 3.1 OpenAPI had a strange relationship with JSON Schema. It's been a super-set/sub-set
|
||||||
@@ -26,16 +50,12 @@ type Schema struct {
|
|||||||
SchemaTypeRef string
|
SchemaTypeRef string
|
||||||
|
|
||||||
// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
|
// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
|
||||||
ExclusiveMaximumBool *bool
|
|
||||||
|
|
||||||
// In version 3.1, ExclusiveMaximum is an integer.
|
// In version 3.1, ExclusiveMaximum is an integer.
|
||||||
ExclusiveMaximum *int64
|
ExclusiveMaximum *DynamicValue[bool, int64]
|
||||||
|
|
||||||
// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
|
// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
|
||||||
ExclusiveMinimum *int64
|
|
||||||
|
|
||||||
// In version 3.1, ExclusiveMinimum is an integer.
|
// In version 3.1, ExclusiveMinimum is an integer.
|
||||||
ExclusiveMinimumBool *bool
|
ExclusiveMinimum *DynamicValue[bool, int64]
|
||||||
|
|
||||||
// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
|
// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
|
||||||
// in version 3.1, Type can be multiple values
|
// in version 3.1, Type can be multiple values
|
||||||
@@ -55,14 +75,24 @@ type Schema struct {
|
|||||||
// in 3.1 prefixItems provides tuple validation support.
|
// in 3.1 prefixItems provides tuple validation support.
|
||||||
PrefixItems []*SchemaProxy
|
PrefixItems []*SchemaProxy
|
||||||
|
|
||||||
// In 3.1 contains is used by arrays to define a single schema
|
// 3.1 Specific properties
|
||||||
Contains *SchemaProxy
|
Contains *SchemaProxy
|
||||||
MinContains *int64
|
MinContains *int64
|
||||||
MaxContains *int64
|
MaxContains *int64
|
||||||
|
If *SchemaProxy
|
||||||
|
Else *SchemaProxy
|
||||||
|
Then *SchemaProxy
|
||||||
|
DependentSchemas map[string]*SchemaProxy
|
||||||
|
PatternProperties map[string]*SchemaProxy
|
||||||
|
PropertyNames *SchemaProxy
|
||||||
|
UnevaluatedItems *SchemaProxy
|
||||||
|
UnevaluatedProperties *SchemaProxy
|
||||||
|
|
||||||
|
// in 3.1 Items can be a Schema or a boolean
|
||||||
|
Items *DynamicValue[*SchemaProxy, bool]
|
||||||
|
|
||||||
// Compatible with all versions
|
// Compatible with all versions
|
||||||
Not []*SchemaProxy
|
Not *SchemaProxy
|
||||||
Items *SchemaProxy
|
|
||||||
Properties map[string]*SchemaProxy
|
Properties map[string]*SchemaProxy
|
||||||
Title string
|
Title string
|
||||||
MultipleOf *int64
|
MultipleOf *int64
|
||||||
@@ -112,19 +142,27 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
}
|
}
|
||||||
// if we're dealing with a 3.0 spec using a bool
|
// if we're dealing with a 3.0 spec using a bool
|
||||||
if !schema.ExclusiveMaximum.IsEmpty() && schema.ExclusiveMaximum.Value.IsA() {
|
if !schema.ExclusiveMaximum.IsEmpty() && schema.ExclusiveMaximum.Value.IsA() {
|
||||||
s.ExclusiveMaximumBool = &schema.ExclusiveMaximum.Value.A
|
s.ExclusiveMaximum = &DynamicValue[bool, int64]{
|
||||||
|
A: schema.ExclusiveMaximum.Value.A,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if we're dealing with a 3.1 spec using an int
|
// if we're dealing with a 3.1 spec using an int
|
||||||
if !schema.ExclusiveMaximum.IsEmpty() && schema.ExclusiveMaximum.Value.IsB() {
|
if !schema.ExclusiveMaximum.IsEmpty() && schema.ExclusiveMaximum.Value.IsB() {
|
||||||
s.ExclusiveMaximum = &schema.ExclusiveMaximum.Value.B
|
s.ExclusiveMaximum = &DynamicValue[bool, int64]{
|
||||||
|
B: schema.ExclusiveMaximum.Value.B,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if we're dealing with a 3.0 spec using a bool
|
// if we're dealing with a 3.0 spec using a bool
|
||||||
if !schema.ExclusiveMinimum.IsEmpty() && schema.ExclusiveMinimum.Value.IsA() {
|
if !schema.ExclusiveMinimum.IsEmpty() && schema.ExclusiveMinimum.Value.IsA() {
|
||||||
s.ExclusiveMinimumBool = &schema.ExclusiveMinimum.Value.A
|
s.ExclusiveMinimum = &DynamicValue[bool, int64]{
|
||||||
|
A: schema.ExclusiveMinimum.Value.A,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if we're dealing with a 3.1 spec, using an int
|
// if we're dealing with a 3.1 spec, using an int
|
||||||
if !schema.ExclusiveMinimum.IsEmpty() && schema.ExclusiveMinimum.Value.IsB() {
|
if !schema.ExclusiveMinimum.IsEmpty() && schema.ExclusiveMinimum.Value.IsB() {
|
||||||
s.ExclusiveMinimum = &schema.ExclusiveMinimum.Value.B
|
s.ExclusiveMinimum = &DynamicValue[bool, int64]{
|
||||||
|
B: schema.ExclusiveMinimum.Value.B,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !schema.MaxLength.IsEmpty() {
|
if !schema.MaxLength.IsEmpty() {
|
||||||
s.MaxLength = &schema.MaxLength.Value
|
s.MaxLength = &schema.MaxLength.Value
|
||||||
@@ -144,6 +182,7 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
if !schema.MinProperties.IsEmpty() {
|
if !schema.MinProperties.IsEmpty() {
|
||||||
s.MinProperties = &schema.MinProperties.Value
|
s.MinProperties = &schema.MinProperties.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
if !schema.MaxContains.IsEmpty() {
|
if !schema.MaxContains.IsEmpty() {
|
||||||
s.MaxContains = &schema.MaxContains.Value
|
s.MaxContains = &schema.MaxContains.Value
|
||||||
}
|
}
|
||||||
@@ -157,6 +196,43 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !schema.If.IsEmpty() {
|
||||||
|
s.If = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.If.ValueNode,
|
||||||
|
Value: schema.If.Value,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
if !schema.Else.IsEmpty() {
|
||||||
|
s.Else = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.Else.ValueNode,
|
||||||
|
Value: schema.Else.Value,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
if !schema.Then.IsEmpty() {
|
||||||
|
s.Then = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.Then.ValueNode,
|
||||||
|
Value: schema.Then.Value,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
if !schema.PropertyNames.IsEmpty() {
|
||||||
|
s.PropertyNames = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.PropertyNames.ValueNode,
|
||||||
|
Value: schema.PropertyNames.Value,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
if !schema.UnevaluatedItems.IsEmpty() {
|
||||||
|
s.UnevaluatedItems = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.UnevaluatedItems.ValueNode,
|
||||||
|
Value: schema.UnevaluatedItems.Value,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
if !schema.UnevaluatedProperties.IsEmpty() {
|
||||||
|
s.UnevaluatedProperties = &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.UnevaluatedProperties.ValueNode,
|
||||||
|
Value: schema.UnevaluatedProperties.Value,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
s.Pattern = schema.Pattern.Value
|
s.Pattern = schema.Pattern.Value
|
||||||
s.Format = schema.Format.Value
|
s.Format = schema.Format.Value
|
||||||
|
|
||||||
@@ -215,33 +291,30 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
}
|
}
|
||||||
s.Enum = enum
|
s.Enum = enum
|
||||||
|
|
||||||
// build out
|
|
||||||
|
|
||||||
// async work.
|
// async work.
|
||||||
// any polymorphic properties need to be handled in their own threads
|
// any polymorphic properties need to be handled in their own threads
|
||||||
// any properties each need to be processed in their own thread.
|
// any properties each need to be processed in their own thread.
|
||||||
// we go as fast as we can.
|
// we go as fast as we can.
|
||||||
|
|
||||||
polyCompletedChan := make(chan bool)
|
polyCompletedChan := make(chan bool)
|
||||||
propsChan := make(chan bool)
|
propsChan := make(chan bool)
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
|
||||||
|
// for every item, build schema async
|
||||||
|
buildSchema := func(sch lowmodel.ValueReference[*base.SchemaProxy], bChan chan *SchemaProxy) {
|
||||||
|
p := &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: sch.ValueNode,
|
||||||
|
Value: sch.Value,
|
||||||
|
}}
|
||||||
|
bChan <- p
|
||||||
|
}
|
||||||
|
|
||||||
// schema async
|
// schema async
|
||||||
buildOutSchema := func(schemas []lowmodel.ValueReference[*base.SchemaProxy], items *[]*SchemaProxy,
|
buildOutSchemas := func(schemas []lowmodel.ValueReference[*base.SchemaProxy], items *[]*SchemaProxy,
|
||||||
doneChan chan bool, e chan error) {
|
doneChan chan bool, e chan error) {
|
||||||
bChan := make(chan *SchemaProxy)
|
bChan := make(chan *SchemaProxy)
|
||||||
|
|
||||||
// for every item, build schema async
|
|
||||||
buildSchemaChild := func(sch lowmodel.ValueReference[*base.SchemaProxy], bChan chan *SchemaProxy) {
|
|
||||||
p := &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
|
||||||
ValueNode: sch.ValueNode,
|
|
||||||
Value: sch.Value,
|
|
||||||
}}
|
|
||||||
bChan <- p
|
|
||||||
}
|
|
||||||
totalSchemas := len(schemas)
|
totalSchemas := len(schemas)
|
||||||
for v := range schemas {
|
for v := range schemas {
|
||||||
go buildSchemaChild(schemas[v], bChan)
|
go buildSchema(schemas[v], bChan)
|
||||||
}
|
}
|
||||||
j := 0
|
j := 0
|
||||||
for j < totalSchemas {
|
for j < totalSchemas {
|
||||||
@@ -257,7 +330,7 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
// props async
|
// props async
|
||||||
var plock sync.Mutex
|
var plock sync.Mutex
|
||||||
var buildProps = func(k lowmodel.KeyReference[string], v lowmodel.ValueReference[*base.SchemaProxy], c chan bool,
|
var buildProps = func(k lowmodel.KeyReference[string], v lowmodel.ValueReference[*base.SchemaProxy], c chan bool,
|
||||||
props map[string]*SchemaProxy) {
|
props map[string]*SchemaProxy, sw int) {
|
||||||
plock.Lock()
|
plock.Lock()
|
||||||
props[k.Value] = &SchemaProxy{
|
props[k.Value] = &SchemaProxy{
|
||||||
schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
@@ -267,51 +340,74 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
plock.Unlock()
|
plock.Unlock()
|
||||||
s.Properties = props
|
|
||||||
|
switch sw {
|
||||||
|
case 0:
|
||||||
|
s.Properties = props
|
||||||
|
case 1:
|
||||||
|
s.DependentSchemas = props
|
||||||
|
case 2:
|
||||||
|
s.PatternProperties = props
|
||||||
|
}
|
||||||
c <- true
|
c <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
props := make(map[string]*SchemaProxy)
|
props := make(map[string]*SchemaProxy)
|
||||||
for k, v := range schema.Properties.Value {
|
for k, v := range schema.Properties.Value {
|
||||||
go buildProps(k, v, propsChan, props)
|
go buildProps(k, v, propsChan, props, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
dependents := make(map[string]*SchemaProxy)
|
||||||
|
for k, v := range schema.DependentSchemas.Value {
|
||||||
|
go buildProps(k, v, propsChan, dependents, 1)
|
||||||
|
}
|
||||||
|
patternProps := make(map[string]*SchemaProxy)
|
||||||
|
for k, v := range schema.PatternProperties.Value {
|
||||||
|
go buildProps(k, v, propsChan, patternProps, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
var allOf []*SchemaProxy
|
var allOf []*SchemaProxy
|
||||||
var oneOf []*SchemaProxy
|
var oneOf []*SchemaProxy
|
||||||
var anyOf []*SchemaProxy
|
var anyOf []*SchemaProxy
|
||||||
var not []*SchemaProxy
|
var not *SchemaProxy
|
||||||
var items []*SchemaProxy
|
var items *DynamicValue[*SchemaProxy, bool]
|
||||||
var prefixItems []*SchemaProxy
|
var prefixItems []*SchemaProxy
|
||||||
|
|
||||||
children := 0
|
children := 0
|
||||||
if !schema.AllOf.IsEmpty() {
|
if !schema.AllOf.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
go buildOutSchema(schema.AllOf.Value, &allOf, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.AllOf.Value, &allOf, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
if !schema.AnyOf.IsEmpty() {
|
if !schema.AnyOf.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
go buildOutSchema(schema.AnyOf.Value, &anyOf, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.AnyOf.Value, &anyOf, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
if !schema.OneOf.IsEmpty() {
|
if !schema.OneOf.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
go buildOutSchema(schema.OneOf.Value, &oneOf, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.OneOf.Value, &oneOf, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
if !schema.Not.IsEmpty() {
|
if !schema.Not.IsEmpty() {
|
||||||
children++
|
not = NewSchemaProxy(&schema.Not)
|
||||||
go buildOutSchema(schema.Not.Value, ¬, polyCompletedChan, errChan)
|
|
||||||
}
|
}
|
||||||
if !schema.Items.IsEmpty() {
|
if !schema.Items.IsEmpty() {
|
||||||
children++
|
if schema.Items.Value.IsA() {
|
||||||
go buildOutSchema(schema.Items.Value, &items, polyCompletedChan, errChan)
|
items = &DynamicValue[*SchemaProxy, bool]{A: &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
|
ValueNode: schema.Items.ValueNode,
|
||||||
|
Value: schema.Items.Value.A,
|
||||||
|
KeyNode: schema.Items.KeyNode,
|
||||||
|
}}}
|
||||||
|
} else {
|
||||||
|
items = &DynamicValue[*SchemaProxy, bool]{B: schema.Items.Value.B}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !schema.PrefixItems.IsEmpty() {
|
if !schema.PrefixItems.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
go buildOutSchema(schema.PrefixItems.Value, &prefixItems, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.PrefixItems.Value, &prefixItems, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
completeChildren := 0
|
completeChildren := 0
|
||||||
completedProps := 0
|
completedProps := 0
|
||||||
totalProps := len(schema.Properties.Value)
|
totalProps := len(schema.Properties.Value) + len(schema.DependentSchemas.Value) + len(schema.PatternProperties.Value)
|
||||||
if totalProps+children > 0 {
|
if totalProps+children > 0 {
|
||||||
allDone:
|
allDone:
|
||||||
for true {
|
for true {
|
||||||
@@ -332,9 +428,7 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
s.OneOf = oneOf
|
s.OneOf = oneOf
|
||||||
s.AnyOf = anyOf
|
s.AnyOf = anyOf
|
||||||
s.AllOf = allOf
|
s.AllOf = allOf
|
||||||
if len(items) > 0 {
|
s.Items = items
|
||||||
s.Items = items[0]
|
|
||||||
}
|
|
||||||
s.PrefixItems = prefixItems
|
s.PrefixItems = prefixItems
|
||||||
s.Not = not
|
s.Not = not
|
||||||
return s
|
return s
|
||||||
|
|||||||
@@ -195,7 +195,26 @@ deprecated: true
|
|||||||
contains:
|
contains:
|
||||||
type: int
|
type: int
|
||||||
minContains: 1
|
minContains: 1
|
||||||
maxContains: 10`
|
maxContains: 10
|
||||||
|
if:
|
||||||
|
type: string
|
||||||
|
else:
|
||||||
|
type: integer
|
||||||
|
then:
|
||||||
|
type: boolean
|
||||||
|
dependentSchemas:
|
||||||
|
schemaOne:
|
||||||
|
type: string
|
||||||
|
patternProperties:
|
||||||
|
patternOne:
|
||||||
|
type: string
|
||||||
|
propertyNames:
|
||||||
|
type: string
|
||||||
|
unevaluatedItems:
|
||||||
|
type: boolean
|
||||||
|
unevaluatedProperties:
|
||||||
|
type: integer
|
||||||
|
`
|
||||||
|
|
||||||
var compNode yaml.Node
|
var compNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(testSpec), &compNode)
|
_ = yaml.Unmarshal([]byte(testSpec), &compNode)
|
||||||
@@ -217,10 +236,18 @@ maxContains: 10`
|
|||||||
assert.NotNil(t, compiled)
|
assert.NotNil(t, compiled)
|
||||||
assert.Nil(t, schemaProxy.GetBuildError())
|
assert.Nil(t, schemaProxy.GetBuildError())
|
||||||
|
|
||||||
// check contains
|
// check 3.1 properties
|
||||||
assert.Equal(t, "int", compiled.Contains.Schema().Type[0])
|
assert.Equal(t, "int", compiled.Contains.Schema().Type[0])
|
||||||
assert.Equal(t, int64(10), *compiled.MaxContains)
|
assert.Equal(t, int64(10), *compiled.MaxContains)
|
||||||
assert.Equal(t, int64(1), *compiled.MinContains)
|
assert.Equal(t, int64(1), *compiled.MinContains)
|
||||||
|
assert.Equal(t, "string", compiled.If.Schema().Type[0])
|
||||||
|
assert.Equal(t, "integer", compiled.Else.Schema().Type[0])
|
||||||
|
assert.Equal(t, "boolean", compiled.Then.Schema().Type[0])
|
||||||
|
assert.Equal(t, "string", compiled.PatternProperties["patternOne"].Schema().Type[0])
|
||||||
|
assert.Equal(t, "string", compiled.DependentSchemas["schemaOne"].Schema().Type[0])
|
||||||
|
assert.Equal(t, "string", compiled.PropertyNames.Schema().Type[0])
|
||||||
|
assert.Equal(t, "boolean", compiled.UnevaluatedItems.Schema().Type[0])
|
||||||
|
assert.Equal(t, "integer", compiled.UnevaluatedProperties.Schema().Type[0])
|
||||||
|
|
||||||
wentLow := compiled.GoLow()
|
wentLow := compiled.GoLow()
|
||||||
assert.Equal(t, 114, wentLow.AdditionalProperties.ValueNode.Line)
|
assert.Equal(t, 114, wentLow.AdditionalProperties.ValueNode.Line)
|
||||||
@@ -352,10 +379,9 @@ required: [cake, fish]`
|
|||||||
assert.NotNil(t, compiled)
|
assert.NotNil(t, compiled)
|
||||||
assert.Nil(t, schemaProxy.GetBuildError())
|
assert.Nil(t, schemaProxy.GetBuildError())
|
||||||
|
|
||||||
assert.True(t, *compiled.ExclusiveMaximumBool)
|
assert.True(t, compiled.ExclusiveMaximum.A)
|
||||||
assert.False(t, *compiled.ExclusiveMinimumBool)
|
assert.Equal(t, int64(123), compiled.Properties["somethingB"].Schema().ExclusiveMinimum.B)
|
||||||
assert.Equal(t, int64(123), *compiled.Properties["somethingB"].Schema().ExclusiveMinimum)
|
assert.Equal(t, int64(334), compiled.Properties["somethingB"].Schema().ExclusiveMaximum.B)
|
||||||
assert.Equal(t, int64(334), *compiled.Properties["somethingB"].Schema().ExclusiveMaximum)
|
|
||||||
assert.Len(t, compiled.Properties["somethingB"].Schema().Properties["somethingBProp"].Schema().Type, 2)
|
assert.Len(t, compiled.Properties["somethingB"].Schema().Properties["somethingBProp"].Schema().Type, 2)
|
||||||
|
|
||||||
wentLow := compiled.GoLow()
|
wentLow := compiled.GoLow()
|
||||||
@@ -433,10 +459,9 @@ type: number
|
|||||||
assert.Nil(t, highSchema.MultipleOf)
|
assert.Nil(t, highSchema.MultipleOf)
|
||||||
assert.Nil(t, highSchema.Minimum)
|
assert.Nil(t, highSchema.Minimum)
|
||||||
assert.Nil(t, highSchema.ExclusiveMinimum)
|
assert.Nil(t, highSchema.ExclusiveMinimum)
|
||||||
assert.Nil(t, highSchema.ExclusiveMinimumBool)
|
|
||||||
assert.Nil(t, highSchema.Maximum)
|
assert.Nil(t, highSchema.Maximum)
|
||||||
assert.Nil(t, highSchema.ExclusiveMaximum)
|
assert.Nil(t, highSchema.ExclusiveMaximum)
|
||||||
assert.Nil(t, highSchema.ExclusiveMaximumBool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchemaNumberMultipleOf(t *testing.T) {
|
func TestSchemaNumberMultipleOf(t *testing.T) {
|
||||||
@@ -480,7 +505,7 @@ exclusiveMinimum: 5
|
|||||||
highSchema := getHighSchema(t, yml)
|
highSchema := getHighSchema(t, yml)
|
||||||
|
|
||||||
value := int64(5)
|
value := int64(5)
|
||||||
assert.EqualValues(t, &value, highSchema.ExclusiveMinimum)
|
assert.EqualValues(t, value, highSchema.ExclusiveMinimum.B)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchemaNumberMaximum(t *testing.T) {
|
func TestSchemaNumberMaximum(t *testing.T) {
|
||||||
@@ -513,7 +538,7 @@ exclusiveMaximum: 5
|
|||||||
highSchema := getHighSchema(t, yml)
|
highSchema := getHighSchema(t, yml)
|
||||||
|
|
||||||
value := int64(5)
|
value := int64(5)
|
||||||
assert.EqualValues(t, &value, highSchema.ExclusiveMaximum)
|
assert.EqualValues(t, value, highSchema.ExclusiveMaximum.B)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchemaExamples(t *testing.T) {
|
func TestSchemaExamples(t *testing.T) {
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ func TestNewDocument_Components_Schemas(t *testing.T) {
|
|||||||
assert.Equal(t, 445, b.Schema().GoLow().FindProperty("name").ValueNode.Line)
|
assert.Equal(t, 445, b.Schema().GoLow().FindProperty("name").ValueNode.Line)
|
||||||
|
|
||||||
f := h.Components.Schemas["Fries"]
|
f := h.Components.Schemas["Fries"]
|
||||||
assert.Equal(t, "salt", f.Schema().Properties["seasoning"].Schema().Items.Schema().Example)
|
assert.Equal(t, "salt", f.Schema().Properties["seasoning"].Schema().Items.A.Schema().Example)
|
||||||
assert.Len(t, f.Schema().Properties["favoriteDrink"].Schema().Properties["drinkType"].Schema().Enum, 2)
|
assert.Len(t, f.Schema().Properties["favoriteDrink"].Schema().Properties["drinkType"].Schema().Enum, 2)
|
||||||
|
|
||||||
d := h.Components.Schemas["Drink"]
|
d := h.Components.Schemas["Drink"]
|
||||||
|
|||||||
@@ -5,28 +5,42 @@ package base
|
|||||||
|
|
||||||
// Constants for labels used to look up values within OpenAPI specifications.
|
// Constants for labels used to look up values within OpenAPI specifications.
|
||||||
const (
|
const (
|
||||||
TagsLabel = "tags"
|
TagsLabel = "tags"
|
||||||
ExternalDocsLabel = "externalDocs"
|
ExternalDocsLabel = "externalDocs"
|
||||||
ExamplesLabel = "examples"
|
ExamplesLabel = "examples"
|
||||||
ExampleLabel = "example"
|
ExampleLabel = "example"
|
||||||
ValueLabel = "value"
|
ValueLabel = "value"
|
||||||
InfoLabel = "info"
|
InfoLabel = "info"
|
||||||
ContactLabel = "contact"
|
ContactLabel = "contact"
|
||||||
LicenseLabel = "license"
|
LicenseLabel = "license"
|
||||||
PropertiesLabel = "properties"
|
PropertiesLabel = "properties"
|
||||||
AdditionalPropertiesLabel = "additionalProperties"
|
DependentSchemasLabel = "dependentSchemas"
|
||||||
XMLLabel = "xml"
|
PatternPropertiesLabel = "patternProperties"
|
||||||
ItemsLabel = "items"
|
IfLabel = "if"
|
||||||
PrefixItemsLabel = "prefixItems"
|
ElseLabel = "else"
|
||||||
ContainsLabel = "contains"
|
ThenLabel = "then"
|
||||||
AllOfLabel = "allOf"
|
PropertyNamesLabel = "propertyNames"
|
||||||
AnyOfLabel = "anyOf"
|
UnevaluatedItemsLabel = "unevaluatedItems"
|
||||||
OneOfLabel = "oneOf"
|
UnevaluatedPropertiesLabel = "unevaluatedProperties"
|
||||||
NotLabel = "not"
|
AdditionalPropertiesLabel = "additionalProperties"
|
||||||
TypeLabel = "type"
|
XMLLabel = "xml"
|
||||||
|
ItemsLabel = "items"
|
||||||
|
PrefixItemsLabel = "prefixItems"
|
||||||
|
ContainsLabel = "contains"
|
||||||
|
AllOfLabel = "allOf"
|
||||||
|
AnyOfLabel = "anyOf"
|
||||||
|
OneOfLabel = "oneOf"
|
||||||
|
NotLabel = "not"
|
||||||
|
TypeLabel = "type"
|
||||||
DiscriminatorLabel = "discriminator"
|
DiscriminatorLabel = "discriminator"
|
||||||
ExclusiveMinimumLabel = "exclusiveMinimum"
|
ExclusiveMinimumLabel = "exclusiveMinimum"
|
||||||
ExclusiveMaximumLabel = "exclusiveMaximum"
|
ExclusiveMaximumLabel = "exclusiveMaximum"
|
||||||
SchemaLabel = "schema"
|
SchemaLabel = "schema"
|
||||||
SchemaTypeLabel = "$schema"
|
SchemaTypeLabel = "$schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
PropertyNames low.NodeReference[*SchemaProxy]
|
||||||
|
UnevaluatedItems low.NodeReference[*SchemaProxy]
|
||||||
|
UnevaluatedProperties low.NodeReference[*SchemaProxy]
|
||||||
|
*/
|
||||||
@@ -51,10 +51,10 @@ type Schema struct {
|
|||||||
SchemaTypeRef low.NodeReference[string]
|
SchemaTypeRef low.NodeReference[string]
|
||||||
|
|
||||||
// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
|
// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
|
||||||
ExclusiveMaximum low.NodeReference[SchemaDynamicValue[bool, int64]]
|
ExclusiveMaximum low.NodeReference[*SchemaDynamicValue[bool, int64]]
|
||||||
|
|
||||||
// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
|
// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
|
||||||
ExclusiveMinimum low.NodeReference[SchemaDynamicValue[bool, int64]]
|
ExclusiveMinimum low.NodeReference[*SchemaDynamicValue[bool, int64]]
|
||||||
|
|
||||||
// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
|
// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
|
||||||
// in version 3.1, Type can be multiple values
|
// in version 3.1, Type can be multiple values
|
||||||
@@ -77,6 +77,19 @@ type Schema struct {
|
|||||||
MinContains low.NodeReference[int64]
|
MinContains low.NodeReference[int64]
|
||||||
MaxContains low.NodeReference[int64]
|
MaxContains low.NodeReference[int64]
|
||||||
|
|
||||||
|
// items can be a schema in 2.0, 3.0 and 3.1 or a bool in 3.1
|
||||||
|
Items low.NodeReference[*SchemaDynamicValue[*SchemaProxy, bool]]
|
||||||
|
|
||||||
|
// 3.1 only
|
||||||
|
If low.NodeReference[*SchemaProxy]
|
||||||
|
Else low.NodeReference[*SchemaProxy]
|
||||||
|
Then low.NodeReference[*SchemaProxy]
|
||||||
|
DependentSchemas low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
||||||
|
PatternProperties low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
||||||
|
PropertyNames low.NodeReference[*SchemaProxy]
|
||||||
|
UnevaluatedItems low.NodeReference[*SchemaProxy]
|
||||||
|
UnevaluatedProperties low.NodeReference[*SchemaProxy]
|
||||||
|
|
||||||
// Compatible with all versions
|
// Compatible with all versions
|
||||||
Title low.NodeReference[string]
|
Title low.NodeReference[string]
|
||||||
MultipleOf low.NodeReference[int64]
|
MultipleOf low.NodeReference[int64]
|
||||||
@@ -93,8 +106,7 @@ type Schema struct {
|
|||||||
MinProperties low.NodeReference[int64]
|
MinProperties low.NodeReference[int64]
|
||||||
Required low.NodeReference[[]low.ValueReference[string]]
|
Required low.NodeReference[[]low.ValueReference[string]]
|
||||||
Enum low.NodeReference[[]low.ValueReference[any]]
|
Enum low.NodeReference[[]low.ValueReference[any]]
|
||||||
Not low.NodeReference[[]low.ValueReference[*SchemaProxy]]
|
Not low.NodeReference[*SchemaProxy]
|
||||||
Items low.NodeReference[[]low.ValueReference[*SchemaProxy]]
|
|
||||||
Properties low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
Properties low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
||||||
AdditionalProperties low.NodeReference[any]
|
AdditionalProperties low.NodeReference[any]
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
@@ -229,18 +241,15 @@ func (s *Schema) Hash() [32]byte {
|
|||||||
for i := range s.Enum.Value {
|
for i := range s.Enum.Value {
|
||||||
d = append(d, fmt.Sprint(s.Enum.Value[i].Value))
|
d = append(d, fmt.Sprint(s.Enum.Value[i].Value))
|
||||||
}
|
}
|
||||||
propertyKeys := make([]string, len(s.Properties.Value))
|
propKeys := make([]string, len(s.Properties.Value))
|
||||||
z := 0
|
z := 0
|
||||||
for i := range s.Properties.Value {
|
for i := range s.Properties.Value {
|
||||||
propertyKeys[z] = i.Value
|
propKeys[z] = i.Value
|
||||||
z++
|
z++
|
||||||
}
|
}
|
||||||
sort.Strings(propertyKeys)
|
sort.Strings(propKeys)
|
||||||
for k := range propertyKeys {
|
for k := range propKeys {
|
||||||
prop := s.FindProperty(propertyKeys[k]).Value
|
d = append(d, low.GenerateHashString(s.FindProperty(propKeys[k]).Value))
|
||||||
if !prop.IsSchemaReference() {
|
|
||||||
d = append(d, low.GenerateHashString(prop.Schema()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if s.XML.Value != nil {
|
if s.XML.Value != nil {
|
||||||
d = append(d, low.GenerateHashString(s.XML.Value))
|
d = append(d, low.GenerateHashString(s.XML.Value))
|
||||||
@@ -307,39 +316,57 @@ func (s *Schema) Hash() [32]byte {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s.Not.Value) > 0 {
|
if !s.Not.IsEmpty() {
|
||||||
notKeys := make([]string, len(s.Not.Value))
|
d = append(d, low.GenerateHashString(s.Not.Value))
|
||||||
notEntities := make(map[string]*SchemaProxy)
|
|
||||||
z = 0
|
|
||||||
for i := range s.Not.Value {
|
|
||||||
g := s.Not.Value[i].Value
|
|
||||||
r := low.GenerateHashString(g)
|
|
||||||
notEntities[r] = g
|
|
||||||
notKeys[z] = r
|
|
||||||
z++
|
|
||||||
|
|
||||||
}
|
|
||||||
sort.Strings(notKeys)
|
|
||||||
for k := range notKeys {
|
|
||||||
d = append(d, low.GenerateHashString(notEntities[notKeys[k]]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s.Items.Value) > 0 {
|
// check if items is a schema or a bool.
|
||||||
itemsKeys := make([]string, len(s.Items.Value))
|
if !s.Items.IsEmpty() && s.Items.Value.IsA() {
|
||||||
itemsEntities := make(map[string]*SchemaProxy)
|
d = append(d, low.GenerateHashString(s.Items.Value.A))
|
||||||
z = 0
|
}
|
||||||
for i := range s.Items.Value {
|
if !s.Items.IsEmpty() && s.Items.Value.IsB() {
|
||||||
g := s.Items.Value[i].Value
|
d = append(d, fmt.Sprint(s.Items.Value.B))
|
||||||
r := low.GenerateHashString(g)
|
}
|
||||||
itemsEntities[r] = g
|
// 3.1 only props
|
||||||
itemsKeys[z] = r
|
if !s.If.IsEmpty() {
|
||||||
z++
|
d = append(d, low.GenerateHashString(s.If.Value))
|
||||||
}
|
}
|
||||||
sort.Strings(itemsKeys)
|
if !s.Else.IsEmpty() {
|
||||||
for k := range itemsKeys {
|
d = append(d, low.GenerateHashString(s.Else.Value))
|
||||||
d = append(d, low.GenerateHashString(itemsEntities[itemsKeys[k]]))
|
}
|
||||||
}
|
if !s.Then.IsEmpty() {
|
||||||
|
d = append(d, low.GenerateHashString(s.Then.Value))
|
||||||
|
}
|
||||||
|
if !s.PropertyNames.IsEmpty() {
|
||||||
|
d = append(d, low.GenerateHashString(s.PropertyNames.Value))
|
||||||
|
}
|
||||||
|
if !s.UnevaluatedProperties.IsEmpty() {
|
||||||
|
d = append(d, low.GenerateHashString(s.UnevaluatedProperties.Value))
|
||||||
|
}
|
||||||
|
if !s.UnevaluatedItems.IsEmpty() {
|
||||||
|
d = append(d, low.GenerateHashString(s.UnevaluatedItems.Value))
|
||||||
|
}
|
||||||
|
|
||||||
|
depSchemasKeys := make([]string, len(s.DependentSchemas.Value))
|
||||||
|
z = 0
|
||||||
|
for i := range s.DependentSchemas.Value {
|
||||||
|
depSchemasKeys[z] = i.Value
|
||||||
|
z++
|
||||||
|
}
|
||||||
|
sort.Strings(depSchemasKeys)
|
||||||
|
for k := range depSchemasKeys {
|
||||||
|
d = append(d, low.GenerateHashString(s.FindDependentSchema(depSchemasKeys[k]).Value))
|
||||||
|
}
|
||||||
|
|
||||||
|
patternPropsKeys := make([]string, len(s.PatternProperties.Value))
|
||||||
|
z = 0
|
||||||
|
for i := range s.PatternProperties.Value {
|
||||||
|
patternPropsKeys[z] = i.Value
|
||||||
|
z++
|
||||||
|
}
|
||||||
|
sort.Strings(patternPropsKeys)
|
||||||
|
for k := range patternPropsKeys {
|
||||||
|
d = append(d, low.GenerateHashString(s.FindPatternProperty(patternPropsKeys[k]).Value))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s.PrefixItems.Value) > 0 {
|
if len(s.PrefixItems.Value) > 0 {
|
||||||
@@ -399,6 +426,18 @@ func (s *Schema) FindProperty(name string) *low.ValueReference[*SchemaProxy] {
|
|||||||
return low.FindItemInMap[*SchemaProxy](name, s.Properties.Value)
|
return low.FindItemInMap[*SchemaProxy](name, s.Properties.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindDependentSchema will return a ValueReference pointer containing a SchemaProxy pointer
|
||||||
|
// from a dependent schema key name. if found (3.1+ only)
|
||||||
|
func (s *Schema) FindDependentSchema(name string) *low.ValueReference[*SchemaProxy] {
|
||||||
|
return low.FindItemInMap[*SchemaProxy](name, s.DependentSchemas.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindPatternProperty will return a ValueReference pointer containing a SchemaProxy pointer
|
||||||
|
// from a pattern property key name. if found (3.1+ only)
|
||||||
|
func (s *Schema) FindPatternProperty(name string) *low.ValueReference[*SchemaProxy] {
|
||||||
|
return low.FindItemInMap[*SchemaProxy](name, s.PatternProperties.Value)
|
||||||
|
}
|
||||||
|
|
||||||
// GetExtensions returns all extensions for Schema
|
// GetExtensions returns all extensions for Schema
|
||||||
func (s *Schema) GetExtensions() map[low.KeyReference[string]]low.ValueReference[any] {
|
func (s *Schema) GetExtensions() map[low.KeyReference[string]]low.ValueReference[any] {
|
||||||
return s.Extensions
|
return s.Extensions
|
||||||
@@ -419,6 +458,14 @@ func (s *Schema) GetExtensions() map[low.KeyReference[string]]low.ValueReference
|
|||||||
// - Not
|
// - Not
|
||||||
// - Items
|
// - Items
|
||||||
// - PrefixItems
|
// - PrefixItems
|
||||||
|
// - If
|
||||||
|
// - Else
|
||||||
|
// - Then
|
||||||
|
// - DependentSchemas
|
||||||
|
// - PatternProperties
|
||||||
|
// - PropertyNames
|
||||||
|
// - UnevaluatedItems
|
||||||
|
// - UnevaluatedProperties
|
||||||
func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
if h, _, _ := utils.IsNodeRefValue(root); h {
|
if h, _, _ := utils.IsNodeRefValue(root); h {
|
||||||
ref, err := low.LocateRefNode(root, idx)
|
ref, err := low.LocateRefNode(root, idx)
|
||||||
@@ -469,18 +516,18 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
if exMinValue != nil {
|
if exMinValue != nil {
|
||||||
if utils.IsNodeBoolValue(exMinValue) {
|
if utils.IsNodeBoolValue(exMinValue) {
|
||||||
val, _ := strconv.ParseBool(exMinValue.Value)
|
val, _ := strconv.ParseBool(exMinValue.Value)
|
||||||
s.ExclusiveMinimum = low.NodeReference[SchemaDynamicValue[bool, int64]]{
|
s.ExclusiveMinimum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
|
||||||
KeyNode: exMinLabel,
|
KeyNode: exMinLabel,
|
||||||
ValueNode: exMinValue,
|
ValueNode: exMinValue,
|
||||||
Value: SchemaDynamicValue[bool, int64]{N: 0, A: val},
|
Value: &SchemaDynamicValue[bool, int64]{N: 0, A: val},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if utils.IsNodeIntValue(exMinValue) {
|
if utils.IsNodeIntValue(exMinValue) {
|
||||||
val, _ := strconv.ParseInt(exMinValue.Value, 10, 64)
|
val, _ := strconv.ParseInt(exMinValue.Value, 10, 64)
|
||||||
s.ExclusiveMinimum = low.NodeReference[SchemaDynamicValue[bool, int64]]{
|
s.ExclusiveMinimum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
|
||||||
KeyNode: exMinLabel,
|
KeyNode: exMinLabel,
|
||||||
ValueNode: exMinValue,
|
ValueNode: exMinValue,
|
||||||
Value: SchemaDynamicValue[bool, int64]{N: 1, B: val},
|
Value: &SchemaDynamicValue[bool, int64]{N: 1, B: val},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,18 +537,18 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
if exMaxValue != nil {
|
if exMaxValue != nil {
|
||||||
if utils.IsNodeBoolValue(exMaxValue) {
|
if utils.IsNodeBoolValue(exMaxValue) {
|
||||||
val, _ := strconv.ParseBool(exMaxValue.Value)
|
val, _ := strconv.ParseBool(exMaxValue.Value)
|
||||||
s.ExclusiveMaximum = low.NodeReference[SchemaDynamicValue[bool, int64]]{
|
s.ExclusiveMaximum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
|
||||||
KeyNode: exMaxLabel,
|
KeyNode: exMaxLabel,
|
||||||
ValueNode: exMaxValue,
|
ValueNode: exMaxValue,
|
||||||
Value: SchemaDynamicValue[bool, int64]{N: 0, A: val},
|
Value: &SchemaDynamicValue[bool, int64]{N: 0, A: val},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if utils.IsNodeIntValue(exMaxValue) {
|
if utils.IsNodeIntValue(exMaxValue) {
|
||||||
val, _ := strconv.ParseInt(exMaxValue.Value, 10, 64)
|
val, _ := strconv.ParseInt(exMaxValue.Value, 10, 64)
|
||||||
s.ExclusiveMaximum = low.NodeReference[SchemaDynamicValue[bool, int64]]{
|
s.ExclusiveMaximum = low.NodeReference[*SchemaDynamicValue[bool, int64]]{
|
||||||
KeyNode: exMaxLabel,
|
KeyNode: exMaxLabel,
|
||||||
ValueNode: exMaxValue,
|
ValueNode: exMaxValue,
|
||||||
Value: SchemaDynamicValue[bool, int64]{N: 1, B: val},
|
Value: &SchemaDynamicValue[bool, int64]{N: 1, B: val},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -585,77 +632,84 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
s.XML = low.NodeReference[*XML]{Value: &xml, KeyNode: xmlLabel, ValueNode: xmlNode}
|
s.XML = low.NodeReference[*XML]{Value: &xml, KeyNode: xmlLabel, ValueNode: xmlNode}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for property, build in a new thread!
|
/*
|
||||||
bChan := make(chan schemaProxyBuildResult)
|
|
||||||
|
|
||||||
var buildProperty = func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
*/
|
||||||
refString string) {
|
|
||||||
c <- schemaProxyBuildResult{
|
|
||||||
k: low.KeyReference[string]{
|
|
||||||
KeyNode: label,
|
|
||||||
Value: label.Value,
|
|
||||||
},
|
|
||||||
v: low.ValueReference[*SchemaProxy]{
|
|
||||||
Value: &SchemaProxy{kn: label, vn: value, idx: idx, isReference: isRef, referenceLookup: refString},
|
|
||||||
ValueNode: value,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle properties
|
// handle properties
|
||||||
_, propLabel, propsNode := utils.FindKeyNodeFullTop(PropertiesLabel, root.Content)
|
props, err := buildPropertyMap(root, idx, PropertiesLabel)
|
||||||
if propsNode != nil {
|
if err != nil {
|
||||||
propertyMap := make(map[low.KeyReference[string]]low.ValueReference[*SchemaProxy])
|
return err
|
||||||
var currentProp *yaml.Node
|
}
|
||||||
totalProps := 0
|
if props != nil {
|
||||||
for i, prop := range propsNode.Content {
|
s.Properties = *props
|
||||||
if i%2 == 0 {
|
}
|
||||||
currentProp = prop
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// check our prop isn't reference
|
// handle dependent schemas
|
||||||
isRef := false
|
props, err = buildPropertyMap(root, idx, DependentSchemasLabel)
|
||||||
refString := ""
|
if err != nil {
|
||||||
if h, _, l := utils.IsNodeRefValue(prop); h {
|
return err
|
||||||
ref, _ := low.LocateRefNode(prop, idx)
|
}
|
||||||
if ref != nil {
|
if props != nil {
|
||||||
isRef = true
|
s.DependentSchemas = *props
|
||||||
prop = ref
|
}
|
||||||
refString = l
|
|
||||||
} else {
|
// handle pattern properties
|
||||||
return fmt.Errorf("schema properties build failed: cannot find reference %s, line %d, col %d",
|
props, err = buildPropertyMap(root, idx, PatternPropertiesLabel)
|
||||||
prop.Content[1].Value, prop.Content[1].Column, prop.Content[1].Line)
|
if err != nil {
|
||||||
}
|
return err
|
||||||
}
|
}
|
||||||
totalProps++
|
if props != nil {
|
||||||
go buildProperty(currentProp, prop, bChan, isRef, refString)
|
s.PatternProperties = *props
|
||||||
|
}
|
||||||
|
|
||||||
|
// check items type for schema or bool (3.1 only)
|
||||||
|
itemsIsBool := false
|
||||||
|
itemsBoolValue := false
|
||||||
|
_, itemsLabel, itemsValue := utils.FindKeyNodeFullTop(ItemsLabel, root.Content)
|
||||||
|
if itemsValue != nil {
|
||||||
|
if utils.IsNodeBoolValue(itemsValue) {
|
||||||
|
itemsIsBool = true
|
||||||
|
itemsBoolValue, _ = strconv.ParseBool(itemsValue.Value)
|
||||||
}
|
}
|
||||||
completedProps := 0
|
}
|
||||||
for completedProps < totalProps {
|
if itemsIsBool {
|
||||||
select {
|
s.Items = low.NodeReference[*SchemaDynamicValue[*SchemaProxy, bool]]{
|
||||||
case res := <-bChan:
|
Value: &SchemaDynamicValue[*SchemaProxy, bool]{
|
||||||
completedProps++
|
B: itemsBoolValue,
|
||||||
propertyMap[res.k] = res.v
|
N: 1,
|
||||||
}
|
},
|
||||||
}
|
KeyNode: itemsLabel,
|
||||||
s.Properties = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]{
|
ValueNode: itemsValue,
|
||||||
Value: propertyMap,
|
|
||||||
KeyNode: propLabel,
|
|
||||||
ValueNode: propsNode,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var allOf, anyOf, oneOf, not, items, prefixItems []low.ValueReference[*SchemaProxy]
|
/*
|
||||||
var contains low.ValueReference[*SchemaProxy]
|
If low.NodeReference[*SchemaProxy]
|
||||||
|
Else low.NodeReference[*SchemaProxy]
|
||||||
|
Then low.NodeReference[*SchemaProxy]
|
||||||
|
PropertyNames low.NodeReference[*SchemaProxy]
|
||||||
|
UnevaluatedItems low.NodeReference[*SchemaProxy]
|
||||||
|
UnevaluatedProperties low.NodeReference[*SchemaProxy]
|
||||||
|
*/
|
||||||
|
|
||||||
|
var allOf, anyOf, oneOf, prefixItems []low.ValueReference[*SchemaProxy]
|
||||||
|
|
||||||
|
var items, not, contains, sif, selse, sthen, propertyNames, unevalItems, unevalProperties low.ValueReference[*SchemaProxy]
|
||||||
|
|
||||||
_, allOfLabel, allOfValue := utils.FindKeyNodeFullTop(AllOfLabel, root.Content)
|
_, allOfLabel, allOfValue := utils.FindKeyNodeFullTop(AllOfLabel, root.Content)
|
||||||
_, anyOfLabel, anyOfValue := utils.FindKeyNodeFullTop(AnyOfLabel, root.Content)
|
_, anyOfLabel, anyOfValue := utils.FindKeyNodeFullTop(AnyOfLabel, root.Content)
|
||||||
_, oneOfLabel, oneOfValue := utils.FindKeyNodeFullTop(OneOfLabel, root.Content)
|
_, oneOfLabel, oneOfValue := utils.FindKeyNodeFullTop(OneOfLabel, root.Content)
|
||||||
_, notLabel, notValue := utils.FindKeyNodeFullTop(NotLabel, root.Content)
|
_, notLabel, notValue := utils.FindKeyNodeFullTop(NotLabel, root.Content)
|
||||||
_, itemsLabel, itemsValue := utils.FindKeyNodeFullTop(ItemsLabel, root.Content)
|
|
||||||
_, prefixItemsLabel, prefixItemsValue := utils.FindKeyNodeFullTop(PrefixItemsLabel, root.Content)
|
_, prefixItemsLabel, prefixItemsValue := utils.FindKeyNodeFullTop(PrefixItemsLabel, root.Content)
|
||||||
_, containsLabel, containsValue := utils.FindKeyNodeFullTop(ContainsLabel, root.Content)
|
_, containsLabel, containsValue := utils.FindKeyNodeFullTop(ContainsLabel, root.Content)
|
||||||
|
_, sifLabel, sifValue := utils.FindKeyNodeFullTop(IfLabel, root.Content)
|
||||||
|
_, selseLabel, selseValue := utils.FindKeyNodeFullTop(ElseLabel, root.Content)
|
||||||
|
_, sthenLabel, sthenValue := utils.FindKeyNodeFullTop(ThenLabel, root.Content)
|
||||||
|
_, propNamesLabel, propNamesValue := utils.FindKeyNodeFullTop(PropertyNamesLabel, root.Content)
|
||||||
|
|
||||||
|
_, unevalItemsLabel, unevalItemsValue := utils.FindKeyNodeFullTop(UnevaluatedItemsLabel, root.Content)
|
||||||
|
_, unevalPropsLabel, unevalPropsValue := utils.FindKeyNodeFullTop(UnevaluatedPropertiesLabel, root.Content)
|
||||||
|
|
||||||
errorChan := make(chan error)
|
errorChan := make(chan error)
|
||||||
allOfChan := make(chan schemaProxyBuildResult)
|
allOfChan := make(chan schemaProxyBuildResult)
|
||||||
@@ -665,12 +719,16 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
prefixItemsChan := make(chan schemaProxyBuildResult)
|
prefixItemsChan := make(chan schemaProxyBuildResult)
|
||||||
notChan := make(chan schemaProxyBuildResult)
|
notChan := make(chan schemaProxyBuildResult)
|
||||||
containsChan := make(chan schemaProxyBuildResult)
|
containsChan := make(chan schemaProxyBuildResult)
|
||||||
|
ifChan := make(chan schemaProxyBuildResult)
|
||||||
|
elseChan := make(chan schemaProxyBuildResult)
|
||||||
|
thenChan := make(chan schemaProxyBuildResult)
|
||||||
|
propNamesChan := make(chan schemaProxyBuildResult)
|
||||||
|
unevalItemsChan := make(chan schemaProxyBuildResult)
|
||||||
|
unevalPropsChan := make(chan schemaProxyBuildResult)
|
||||||
|
|
||||||
totalBuilds := countSubSchemaItems(allOfValue) +
|
totalBuilds := countSubSchemaItems(allOfValue) +
|
||||||
countSubSchemaItems(anyOfValue) +
|
countSubSchemaItems(anyOfValue) +
|
||||||
countSubSchemaItems(oneOfValue) +
|
countSubSchemaItems(oneOfValue) +
|
||||||
countSubSchemaItems(notValue) +
|
|
||||||
countSubSchemaItems(itemsValue) +
|
|
||||||
countSubSchemaItems(prefixItemsValue)
|
countSubSchemaItems(prefixItemsValue)
|
||||||
|
|
||||||
if allOfValue != nil {
|
if allOfValue != nil {
|
||||||
@@ -682,19 +740,45 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
if oneOfValue != nil {
|
if oneOfValue != nil {
|
||||||
go buildSchema(oneOfChan, oneOfLabel, oneOfValue, errorChan, idx)
|
go buildSchema(oneOfChan, oneOfLabel, oneOfValue, errorChan, idx)
|
||||||
}
|
}
|
||||||
if itemsValue != nil {
|
|
||||||
go buildSchema(itemsChan, itemsLabel, itemsValue, errorChan, idx)
|
|
||||||
}
|
|
||||||
if prefixItemsValue != nil {
|
if prefixItemsValue != nil {
|
||||||
go buildSchema(prefixItemsChan, prefixItemsLabel, prefixItemsValue, errorChan, idx)
|
go buildSchema(prefixItemsChan, prefixItemsLabel, prefixItemsValue, errorChan, idx)
|
||||||
}
|
}
|
||||||
if notValue != nil {
|
if notValue != nil {
|
||||||
|
totalBuilds++
|
||||||
go buildSchema(notChan, notLabel, notValue, errorChan, idx)
|
go buildSchema(notChan, notLabel, notValue, errorChan, idx)
|
||||||
}
|
}
|
||||||
if containsValue != nil {
|
if containsValue != nil {
|
||||||
totalBuilds++
|
totalBuilds++
|
||||||
go buildSchema(containsChan, containsLabel, containsValue, errorChan, idx)
|
go buildSchema(containsChan, containsLabel, containsValue, errorChan, idx)
|
||||||
}
|
}
|
||||||
|
if !itemsIsBool && itemsValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(itemsChan, itemsLabel, itemsValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
if sifValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(ifChan, sifLabel, sifValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
if selseValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(elseChan, selseLabel, selseValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
if sthenValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(thenChan, sthenLabel, sthenValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
if propNamesValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(propNamesChan, propNamesLabel, propNamesValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
if unevalItemsValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(unevalItemsChan, unevalItemsLabel, unevalItemsValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
if unevalPropsValue != nil {
|
||||||
|
totalBuilds++
|
||||||
|
go buildSchema(unevalPropsChan, unevalPropsLabel, unevalPropsValue, errorChan, idx)
|
||||||
|
}
|
||||||
|
|
||||||
completeCount := 0
|
completeCount := 0
|
||||||
for completeCount < totalBuilds {
|
for completeCount < totalBuilds {
|
||||||
@@ -712,16 +796,34 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
oneOf = append(oneOf, r.v)
|
oneOf = append(oneOf, r.v)
|
||||||
case r := <-itemsChan:
|
case r := <-itemsChan:
|
||||||
completeCount++
|
completeCount++
|
||||||
items = append(items, r.v)
|
items = r.v
|
||||||
case r := <-prefixItemsChan:
|
case r := <-prefixItemsChan:
|
||||||
completeCount++
|
completeCount++
|
||||||
prefixItems = append(prefixItems, r.v)
|
prefixItems = append(prefixItems, r.v)
|
||||||
case r := <-notChan:
|
case r := <-notChan:
|
||||||
completeCount++
|
completeCount++
|
||||||
not = append(not, r.v)
|
not = r.v
|
||||||
case r := <-containsChan:
|
case r := <-containsChan:
|
||||||
completeCount++
|
completeCount++
|
||||||
contains = r.v
|
contains = r.v
|
||||||
|
case r := <-ifChan:
|
||||||
|
completeCount++
|
||||||
|
sif = r.v
|
||||||
|
case r := <-elseChan:
|
||||||
|
completeCount++
|
||||||
|
selse = r.v
|
||||||
|
case r := <-thenChan:
|
||||||
|
completeCount++
|
||||||
|
sthen = r.v
|
||||||
|
case r := <-propNamesChan:
|
||||||
|
completeCount++
|
||||||
|
propertyNames = r.v
|
||||||
|
case r := <-unevalItemsChan:
|
||||||
|
completeCount++
|
||||||
|
unevalItems = r.v
|
||||||
|
case r := <-unevalPropsChan:
|
||||||
|
completeCount++
|
||||||
|
unevalProperties = r.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,17 +848,18 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
ValueNode: allOfValue,
|
ValueNode: allOfValue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(not) > 0 {
|
if !not.IsEmpty() {
|
||||||
s.Not = low.NodeReference[[]low.ValueReference[*SchemaProxy]]{
|
s.Not = low.NodeReference[*SchemaProxy]{
|
||||||
Value: not,
|
Value: not.Value,
|
||||||
KeyNode: notLabel,
|
KeyNode: notLabel,
|
||||||
ValueNode: notValue,
|
ValueNode: notValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if len(items) > 0 {
|
if !itemsIsBool && !items.IsEmpty() {
|
||||||
s.Items = low.NodeReference[[]low.ValueReference[*SchemaProxy]]{
|
s.Items = low.NodeReference[*SchemaDynamicValue[*SchemaProxy, bool]]{
|
||||||
Value: items,
|
Value: &SchemaDynamicValue[*SchemaProxy, bool]{
|
||||||
|
A: items.Value,
|
||||||
|
},
|
||||||
KeyNode: itemsLabel,
|
KeyNode: itemsLabel,
|
||||||
ValueNode: itemsValue,
|
ValueNode: itemsValue,
|
||||||
}
|
}
|
||||||
@@ -775,9 +878,115 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
ValueNode: containsValue,
|
ValueNode: containsValue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !sif.IsEmpty() {
|
||||||
|
s.If = low.NodeReference[*SchemaProxy]{
|
||||||
|
Value: sif.Value,
|
||||||
|
KeyNode: sifLabel,
|
||||||
|
ValueNode: sifValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !selse.IsEmpty() {
|
||||||
|
s.Else = low.NodeReference[*SchemaProxy]{
|
||||||
|
Value: selse.Value,
|
||||||
|
KeyNode: selseLabel,
|
||||||
|
ValueNode: selseValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !sthen.IsEmpty() {
|
||||||
|
s.Then = low.NodeReference[*SchemaProxy]{
|
||||||
|
Value: sthen.Value,
|
||||||
|
KeyNode: sthenLabel,
|
||||||
|
ValueNode: sthenValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !propertyNames.IsEmpty() {
|
||||||
|
s.PropertyNames = low.NodeReference[*SchemaProxy]{
|
||||||
|
Value: propertyNames.Value,
|
||||||
|
KeyNode: propNamesLabel,
|
||||||
|
ValueNode: propNamesValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !unevalItems.IsEmpty() {
|
||||||
|
s.UnevaluatedItems = low.NodeReference[*SchemaProxy]{
|
||||||
|
Value: unevalItems.Value,
|
||||||
|
KeyNode: unevalItemsLabel,
|
||||||
|
ValueNode: unevalItemsValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !unevalProperties.IsEmpty() {
|
||||||
|
s.UnevaluatedProperties = low.NodeReference[*SchemaProxy]{
|
||||||
|
Value: unevalProperties.Value,
|
||||||
|
KeyNode: unevalPropsLabel,
|
||||||
|
ValueNode: unevalPropsValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildPropertyMap(root *yaml.Node, idx *index.SpecIndex, label string) (*low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]], error) {
|
||||||
|
|
||||||
|
// for property, build in a new thread!
|
||||||
|
bChan := make(chan schemaProxyBuildResult)
|
||||||
|
|
||||||
|
var buildProperty = func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
||||||
|
refString string) {
|
||||||
|
c <- schemaProxyBuildResult{
|
||||||
|
k: low.KeyReference[string]{
|
||||||
|
KeyNode: label,
|
||||||
|
Value: label.Value,
|
||||||
|
},
|
||||||
|
v: low.ValueReference[*SchemaProxy]{
|
||||||
|
Value: &SchemaProxy{kn: label, vn: value, idx: idx, isReference: isRef, referenceLookup: refString},
|
||||||
|
ValueNode: value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, propLabel, propsNode := utils.FindKeyNodeFullTop(label, root.Content)
|
||||||
|
if propsNode != nil {
|
||||||
|
propertyMap := make(map[low.KeyReference[string]]low.ValueReference[*SchemaProxy])
|
||||||
|
var currentProp *yaml.Node
|
||||||
|
totalProps := 0
|
||||||
|
for i, prop := range propsNode.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
currentProp = prop
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// check our prop isn't reference
|
||||||
|
isRef := false
|
||||||
|
refString := ""
|
||||||
|
if h, _, l := utils.IsNodeRefValue(prop); h {
|
||||||
|
ref, _ := low.LocateRefNode(prop, idx)
|
||||||
|
if ref != nil {
|
||||||
|
isRef = true
|
||||||
|
prop = ref
|
||||||
|
refString = l
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("schema properties build failed: cannot find reference %s, line %d, col %d",
|
||||||
|
prop.Content[1].Value, prop.Content[1].Column, prop.Content[1].Line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalProps++
|
||||||
|
go buildProperty(currentProp, prop, bChan, isRef, refString)
|
||||||
|
}
|
||||||
|
completedProps := 0
|
||||||
|
for completedProps < totalProps {
|
||||||
|
select {
|
||||||
|
case res := <-bChan:
|
||||||
|
completedProps++
|
||||||
|
propertyMap[res.k] = res.v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]{
|
||||||
|
Value: propertyMap,
|
||||||
|
KeyNode: propLabel,
|
||||||
|
ValueNode: propsNode,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// count the number of sub-schemas in a node.
|
// count the number of sub-schemas in a node.
|
||||||
func countSubSchemaItems(node *yaml.Node) int {
|
func countSubSchemaItems(node *yaml.Node) int {
|
||||||
if utils.IsNodeMap(node) {
|
if utils.IsNodeMap(node) {
|
||||||
@@ -894,7 +1103,6 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,24 @@ import (
|
|||||||
func test_get_schema_blob() string {
|
func test_get_schema_blob() string {
|
||||||
return `type: object
|
return `type: object
|
||||||
description: something object
|
description: something object
|
||||||
|
if:
|
||||||
|
type: string
|
||||||
|
else:
|
||||||
|
type: integer
|
||||||
|
then:
|
||||||
|
type: boolean
|
||||||
|
dependentSchemas:
|
||||||
|
schemaOne:
|
||||||
|
type: string
|
||||||
|
patternProperties:
|
||||||
|
patternOne:
|
||||||
|
type: string
|
||||||
|
propertyNames:
|
||||||
|
type: string
|
||||||
|
unevaluatedItems:
|
||||||
|
type: boolean
|
||||||
|
unevaluatedProperties:
|
||||||
|
type: integer
|
||||||
discriminator:
|
discriminator:
|
||||||
propertyName: athing
|
propertyName: athing
|
||||||
mapping:
|
mapping:
|
||||||
@@ -226,29 +244,29 @@ func Test_Schema(t *testing.T) {
|
|||||||
assert.Equal(t, "oneOfBExp", v.Value.Schema().Example.Value)
|
assert.Equal(t, "oneOfBExp", v.Value.Schema().Example.Value)
|
||||||
|
|
||||||
// check values NOT
|
// check values NOT
|
||||||
assert.Equal(t, "a not thing", sch.Not.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, "a not thing", sch.Not.Value.Schema().Description.Value)
|
||||||
assert.Len(t, sch.Not.Value[0].Value.Schema().Properties.Value, 2)
|
assert.Len(t, sch.Not.Value.Schema().Properties.Value, 2)
|
||||||
|
|
||||||
v = sch.Not.Value[0].Value.Schema().FindProperty("notA")
|
v = sch.Not.Value.Schema().FindProperty("notA")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, "notA description", v.Value.Schema().Description.Value)
|
assert.Equal(t, "notA description", v.Value.Schema().Description.Value)
|
||||||
assert.Equal(t, "notAExp", v.Value.Schema().Example.Value)
|
assert.Equal(t, "notAExp", v.Value.Schema().Example.Value)
|
||||||
|
|
||||||
v = sch.Not.Value[0].Value.Schema().FindProperty("notB")
|
v = sch.Not.Value.Schema().FindProperty("notB")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, "notB description", v.Value.Schema().Description.Value)
|
assert.Equal(t, "notB description", v.Value.Schema().Description.Value)
|
||||||
assert.Equal(t, "notBExp", v.Value.Schema().Example.Value)
|
assert.Equal(t, "notBExp", v.Value.Schema().Example.Value)
|
||||||
|
|
||||||
// check values Items
|
// check values Items
|
||||||
assert.Equal(t, "an items thing", sch.Items.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, "an items thing", sch.Items.Value.A.Schema().Description.Value)
|
||||||
assert.Len(t, sch.Items.Value[0].Value.Schema().Properties.Value, 2)
|
assert.Len(t, sch.Items.Value.A.Schema().Properties.Value, 2)
|
||||||
|
|
||||||
v = sch.Items.Value[0].Value.Schema().FindProperty("itemsA")
|
v = sch.Items.Value.A.Schema().FindProperty("itemsA")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, "itemsA description", v.Value.Schema().Description.Value)
|
assert.Equal(t, "itemsA description", v.Value.Schema().Description.Value)
|
||||||
assert.Equal(t, "itemsAExp", v.Value.Schema().Example.Value)
|
assert.Equal(t, "itemsAExp", v.Value.Schema().Example.Value)
|
||||||
|
|
||||||
v = sch.Items.Value[0].Value.Schema().FindProperty("itemsB")
|
v = sch.Items.Value.A.Schema().FindProperty("itemsB")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, "itemsB description", v.Value.Schema().Description.Value)
|
assert.Equal(t, "itemsB description", v.Value.Schema().Description.Value)
|
||||||
assert.Equal(t, "itemsBExp", v.Value.Schema().Example.Value)
|
assert.Equal(t, "itemsBExp", v.Value.Schema().Example.Value)
|
||||||
@@ -276,10 +294,18 @@ func Test_Schema(t *testing.T) {
|
|||||||
mv = sch.Discriminator.Value.FindMappingValue("pizza")
|
mv = sch.Discriminator.Value.FindMappingValue("pizza")
|
||||||
assert.Equal(t, "party", mv.Value)
|
assert.Equal(t, "party", mv.Value)
|
||||||
|
|
||||||
// check contains
|
// check 3.1 properties.
|
||||||
assert.Equal(t, "int", sch.Contains.Value.Schema().Type.Value.A)
|
assert.Equal(t, "int", sch.Contains.Value.Schema().Type.Value.A)
|
||||||
assert.Equal(t, int64(1), sch.MinContains.Value)
|
assert.Equal(t, int64(1), sch.MinContains.Value)
|
||||||
assert.Equal(t, int64(10), sch.MaxContains.Value)
|
assert.Equal(t, int64(10), sch.MaxContains.Value)
|
||||||
|
assert.Equal(t, "string", sch.If.Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "integer", sch.Else.Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "boolean", sch.Then.Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "string", sch.FindDependentSchema("schemaOne").Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "string", sch.FindPatternProperty("patternOne").Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "string", sch.PropertyNames.Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "boolean", sch.UnevaluatedItems.Value.Schema().Type.Value.A)
|
||||||
|
assert.Equal(t, "integer", sch.UnevaluatedProperties.Value.Schema().Type.Value.A)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,8 +607,8 @@ items:
|
|||||||
assert.Equal(t, desc, sch.OneOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.OneOf.Value[0].Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.AnyOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.AnyOf.Value[0].Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.Not.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.Not.Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.Items.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.Items.Value.A.Schema().Description.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_Array_Ref_Fail(t *testing.T) {
|
func Test_Schema_Polymorphism_Array_Ref_Fail(t *testing.T) {
|
||||||
@@ -671,8 +697,8 @@ items:
|
|||||||
assert.Equal(t, desc, sch.OneOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.OneOf.Value[0].Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.AnyOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.AnyOf.Value[0].Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.Not.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.Not.Value.Schema().Description.Value)
|
||||||
assert.Equal(t, desc, sch.Items.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.Items.Value.A.Schema().Description.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_Map_Ref_Fail(t *testing.T) {
|
func Test_Schema_Polymorphism_Map_Ref_Fail(t *testing.T) {
|
||||||
|
|||||||
@@ -84,44 +84,55 @@ const (
|
|||||||
EnumLabel = "enum"
|
EnumLabel = "enum"
|
||||||
SchemaLabel = "schema"
|
SchemaLabel = "schema"
|
||||||
NotLabel = "not"
|
NotLabel = "not"
|
||||||
ItemsLabel = "items"
|
ItemsLabel = "items"
|
||||||
PropertiesLabel = "properties"
|
PropertiesLabel = "properties"
|
||||||
AllOfLabel = "allOf"
|
AllOfLabel = "allOf"
|
||||||
AnyOfLabel = "anyOf"
|
AnyOfLabel = "anyOf"
|
||||||
OneOfLabel = "oneOf"
|
OneOfLabel = "oneOf"
|
||||||
AdditionalPropertiesLabel = "additionalProperties"
|
AdditionalPropertiesLabel = "additionalProperties"
|
||||||
ContentEncodingLabel = "contentEncoding"
|
ContentEncodingLabel = "contentEncoding"
|
||||||
ContentMediaType = "contentMediaType"
|
ContentMediaType = "contentMediaType"
|
||||||
NullableLabel = "nullable"
|
NullableLabel = "nullable"
|
||||||
ReadOnlyLabel = "readOnly"
|
ReadOnlyLabel = "readOnly"
|
||||||
WriteOnlyLabel = "writeOnly"
|
WriteOnlyLabel = "writeOnly"
|
||||||
XMLLabel = "xml"
|
XMLLabel = "xml"
|
||||||
DeprecatedLabel = "deprecated"
|
DeprecatedLabel = "deprecated"
|
||||||
ExampleLabel = "example"
|
ExampleLabel = "example"
|
||||||
RefLabel = "$ref"
|
RefLabel = "$ref"
|
||||||
DiscriminatorLabel = "discriminator"
|
DiscriminatorLabel = "discriminator"
|
||||||
ExternalDocsLabel = "externalDocs"
|
ExternalDocsLabel = "externalDocs"
|
||||||
InLabel = "in"
|
InLabel = "in"
|
||||||
AllowEmptyValueLabel = "allowEmptyValue"
|
AllowEmptyValueLabel = "allowEmptyValue"
|
||||||
StyleLabel = "style"
|
StyleLabel = "style"
|
||||||
CollectionFormatLabel = "collectionFormat"
|
CollectionFormatLabel = "collectionFormat"
|
||||||
AllowReservedLabel = "allowReserved"
|
AllowReservedLabel = "allowReserved"
|
||||||
ExplodeLabel = "explode"
|
ExplodeLabel = "explode"
|
||||||
ContentTypeLabel = "contentType"
|
ContentTypeLabel = "contentType"
|
||||||
SecurityDefinitionLabel = "securityDefinition"
|
SecurityDefinitionLabel = "securityDefinition"
|
||||||
Scopes = "scopes"
|
Scopes = "scopes"
|
||||||
AuthorizationUrlLabel = "authorizationUrl"
|
AuthorizationUrlLabel = "authorizationUrl"
|
||||||
TokenUrlLabel = "tokenUrl"
|
TokenUrlLabel = "tokenUrl"
|
||||||
RefreshUrlLabel = "refreshUrl"
|
RefreshUrlLabel = "refreshUrl"
|
||||||
FlowLabel = "flow"
|
FlowLabel = "flow"
|
||||||
FlowsLabel = "flows"
|
FlowsLabel = "flows"
|
||||||
SchemeLabel = "scheme"
|
SchemeLabel = "scheme"
|
||||||
OpenIdConnectUrlLabel = "openIdConnectUrl"
|
OpenIdConnectUrlLabel = "openIdConnectUrl"
|
||||||
ScopesLabel = "scopes"
|
ScopesLabel = "scopes"
|
||||||
OperationRefLabel = "operationRef"
|
OperationRefLabel = "operationRef"
|
||||||
OperationIdLabel = "operationId"
|
OperationIdLabel = "operationId"
|
||||||
CodesLabel = "codes"
|
CodesLabel = "codes"
|
||||||
ProducesLabel = "produces"
|
ProducesLabel = "produces"
|
||||||
ConsumesLabel = "consumes"
|
ConsumesLabel = "consumes"
|
||||||
SchemesLabel = "schemes"
|
SchemesLabel = "schemes"
|
||||||
|
IfLabel = "if"
|
||||||
|
ElseLabel = "else"
|
||||||
|
ThenLabel = "then"
|
||||||
|
PropertyNamesLabel = "propertyNames"
|
||||||
|
ContainsLabel = "contains"
|
||||||
|
MinContainsLabel = "minContains"
|
||||||
|
MaxContainsLabel = "maxContains"
|
||||||
|
UnevaluatedItemsLabel = "unevaluatedItems"
|
||||||
|
UnevaluatedPropertiesLabel = "unevaluatedProperties"
|
||||||
|
DependentSchemasLabel = "dependentSchemas"
|
||||||
|
PatternPropertiesLabel = "patternProperties"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,12 +26,23 @@ type SchemaChanges struct {
|
|||||||
AllOfChanges []*SchemaChanges `json:"allOf,omitempty" yaml:"allOf,omitempty"`
|
AllOfChanges []*SchemaChanges `json:"allOf,omitempty" yaml:"allOf,omitempty"`
|
||||||
AnyOfChanges []*SchemaChanges `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
|
AnyOfChanges []*SchemaChanges `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
|
||||||
OneOfChanges []*SchemaChanges `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
|
OneOfChanges []*SchemaChanges `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
|
||||||
NotChanges []*SchemaChanges `json:"not,omitempty" yaml:"not,omitempty"`
|
NotChanges *SchemaChanges `json:"not,omitempty" yaml:"not,omitempty"`
|
||||||
ItemsChanges []*SchemaChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
ItemsChanges *SchemaChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
SchemaPropertyChanges map[string]*SchemaChanges `json:"properties,omitempty" yaml:"properties,omitempty"`
|
SchemaPropertyChanges map[string]*SchemaChanges `json:"properties,omitempty" yaml:"properties,omitempty"`
|
||||||
ExternalDocChanges *ExternalDocChanges `json:"externalDoc,omitempty" yaml:"externalDoc,omitempty"`
|
ExternalDocChanges *ExternalDocChanges `json:"externalDoc,omitempty" yaml:"externalDoc,omitempty"`
|
||||||
XMLChanges *XMLChanges `json:"xml,omitempty" yaml:"xml,omitempty"`
|
XMLChanges *XMLChanges `json:"xml,omitempty" yaml:"xml,omitempty"`
|
||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
|
|
||||||
|
// 3.1 specifics
|
||||||
|
IfChanges *SchemaChanges `json:"if,omitempty" yaml:"if,omitempty"`
|
||||||
|
ElseChanges *SchemaChanges `json:"else,omitempty" yaml:"else,omitempty"`
|
||||||
|
ThenChanges *SchemaChanges `json:"then,omitempty" yaml:"then,omitempty"`
|
||||||
|
PropertyNamesChanges *SchemaChanges `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
|
||||||
|
ContainsChanges *SchemaChanges `json:"contains,omitempty" yaml:"contains,omitempty"`
|
||||||
|
UnevaluatedItemsChanges *SchemaChanges `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
|
||||||
|
UnevaluatedPropertiesChanges *SchemaChanges `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
|
||||||
|
DependentSchemasChanges map[string]*SchemaChanges `json:"dependentSchemas,omitempty" yaml:"dependentSchemas,omitempty"`
|
||||||
|
PatternPropertiesChanges map[string]*SchemaChanges `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalChanges returns a count of the total number of changes made to this schema and all sub-schemas
|
// TotalChanges returns a count of the total number of changes made to this schema and all sub-schemas
|
||||||
@@ -55,21 +66,48 @@ func (s *SchemaChanges) TotalChanges() int {
|
|||||||
t += s.OneOfChanges[n].TotalChanges()
|
t += s.OneOfChanges[n].TotalChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.NotChanges) > 0 {
|
if s.NotChanges != nil {
|
||||||
for n := range s.NotChanges {
|
t += s.NotChanges.TotalChanges()
|
||||||
t += s.NotChanges[n].TotalChanges()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if len(s.ItemsChanges) > 0 {
|
if s.ItemsChanges != nil {
|
||||||
for n := range s.ItemsChanges {
|
t += s.ItemsChanges.TotalChanges()
|
||||||
t += s.ItemsChanges[n].TotalChanges()
|
}
|
||||||
}
|
if s.IfChanges != nil {
|
||||||
|
t += s.IfChanges.TotalChanges()
|
||||||
|
}
|
||||||
|
if s.ElseChanges != nil {
|
||||||
|
t += s.ElseChanges.TotalChanges()
|
||||||
|
}
|
||||||
|
if s.ThenChanges != nil {
|
||||||
|
t += s.ThenChanges.TotalChanges()
|
||||||
|
}
|
||||||
|
if s.PropertyNamesChanges != nil {
|
||||||
|
t += s.PropertyNamesChanges.TotalChanges()
|
||||||
|
}
|
||||||
|
if s.ContainsChanges != nil {
|
||||||
|
t += s.ContainsChanges.TotalChanges()
|
||||||
|
}
|
||||||
|
if s.UnevaluatedItemsChanges != nil {
|
||||||
|
t += s.UnevaluatedItemsChanges.TotalChanges()
|
||||||
|
}
|
||||||
|
if s.UnevaluatedPropertiesChanges != nil {
|
||||||
|
t += s.UnevaluatedPropertiesChanges.TotalChanges()
|
||||||
}
|
}
|
||||||
if s.SchemaPropertyChanges != nil {
|
if s.SchemaPropertyChanges != nil {
|
||||||
for n := range s.SchemaPropertyChanges {
|
for n := range s.SchemaPropertyChanges {
|
||||||
t += s.SchemaPropertyChanges[n].TotalChanges()
|
t += s.SchemaPropertyChanges[n].TotalChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if s.DependentSchemasChanges != nil {
|
||||||
|
for n := range s.DependentSchemasChanges {
|
||||||
|
t += s.DependentSchemasChanges[n].TotalChanges()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.PatternPropertiesChanges != nil {
|
||||||
|
for n := range s.PatternPropertiesChanges {
|
||||||
|
t += s.PatternPropertiesChanges[n].TotalChanges()
|
||||||
|
}
|
||||||
|
}
|
||||||
if s.ExternalDocChanges != nil {
|
if s.ExternalDocChanges != nil {
|
||||||
t += s.ExternalDocChanges.TotalChanges()
|
t += s.ExternalDocChanges.TotalChanges()
|
||||||
}
|
}
|
||||||
@@ -108,14 +146,41 @@ func (s *SchemaChanges) TotalBreakingChanges() int {
|
|||||||
t += s.OneOfChanges[n].TotalBreakingChanges()
|
t += s.OneOfChanges[n].TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.NotChanges) > 0 {
|
if s.NotChanges != nil {
|
||||||
for n := range s.NotChanges {
|
t += s.NotChanges.TotalBreakingChanges()
|
||||||
t += s.NotChanges[n].TotalBreakingChanges()
|
}
|
||||||
|
if s.ItemsChanges != nil {
|
||||||
|
t += s.ItemsChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.IfChanges != nil {
|
||||||
|
t += s.IfChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.ElseChanges != nil {
|
||||||
|
t += s.ElseChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.ThenChanges != nil {
|
||||||
|
t += s.ThenChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.PropertyNamesChanges != nil {
|
||||||
|
t += s.PropertyNamesChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.ContainsChanges != nil {
|
||||||
|
t += s.ContainsChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.UnevaluatedItemsChanges != nil {
|
||||||
|
t += s.UnevaluatedItemsChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.UnevaluatedPropertiesChanges != nil {
|
||||||
|
t += s.UnevaluatedPropertiesChanges.TotalBreakingChanges()
|
||||||
|
}
|
||||||
|
if s.DependentSchemasChanges != nil {
|
||||||
|
for n := range s.DependentSchemasChanges {
|
||||||
|
t += s.DependentSchemasChanges[n].TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.ItemsChanges) > 0 {
|
if s.PatternPropertiesChanges != nil {
|
||||||
for n := range s.ItemsChanges {
|
for n := range s.PatternPropertiesChanges {
|
||||||
t += s.ItemsChanges[n].TotalBreakingChanges()
|
t += s.PatternPropertiesChanges[n].TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.XMLChanges != nil {
|
if s.XMLChanges != nil {
|
||||||
@@ -215,13 +280,13 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
|||||||
go extractSchemaChanges(lSchema.AnyOf.Value, rSchema.AnyOf.Value, v3.AnyOfLabel,
|
go extractSchemaChanges(lSchema.AnyOf.Value, rSchema.AnyOf.Value, v3.AnyOfLabel,
|
||||||
&sc.AnyOfChanges, &changes, doneChan)
|
&sc.AnyOfChanges, &changes, doneChan)
|
||||||
|
|
||||||
go extractSchemaChanges(lSchema.Items.Value, rSchema.Items.Value, v3.ItemsLabel,
|
//go extractSchemaChanges(lSchema.Items.Value, rSchema.Items.Value, v3.ItemsLabel,
|
||||||
&sc.ItemsChanges, &changes, doneChan)
|
// &sc.ItemsChanges, &changes, doneChan)
|
||||||
|
//
|
||||||
|
//go extractSchemaChanges(lSchema.Not.Value, rSchema.Not.Value, v3.NotLabel,
|
||||||
|
// &sc.NotChanges, &changes, doneChan)
|
||||||
|
|
||||||
go extractSchemaChanges(lSchema.Not.Value, rSchema.Not.Value, v3.NotLabel,
|
totalChecks := totalProperties + 3
|
||||||
&sc.NotChanges, &changes, doneChan)
|
|
||||||
|
|
||||||
totalChecks := totalProperties + 5
|
|
||||||
completedChecks := 0
|
completedChecks := 0
|
||||||
for completedChecks < totalChecks {
|
for completedChecks < totalChecks {
|
||||||
select {
|
select {
|
||||||
@@ -752,6 +817,159 @@ func checkSchemaPropertyChanges(
|
|||||||
lSchema.ExternalDocs.ValueNode, nil, false, lSchema.ExternalDocs.Value, nil)
|
lSchema.ExternalDocs.ValueNode, nil, false, lSchema.ExternalDocs.Value, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3.1 properties
|
||||||
|
// If
|
||||||
|
if lSchema.If.Value != nil && rSchema.If.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.If.Value, rSchema.If.Value) {
|
||||||
|
sc.IfChanges = CompareSchemas(lSchema.If.Value, rSchema.If.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added If
|
||||||
|
if lSchema.If.Value == nil && rSchema.If.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.IfLabel,
|
||||||
|
nil, rSchema.If.ValueNode, true, nil, rSchema.If.Value)
|
||||||
|
}
|
||||||
|
// removed If
|
||||||
|
if lSchema.If.Value != nil && rSchema.If.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.IfLabel,
|
||||||
|
lSchema.If.ValueNode, nil, true, lSchema.If.Value, nil)
|
||||||
|
}
|
||||||
|
// Else
|
||||||
|
if lSchema.Else.Value != nil && rSchema.Else.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.Else.Value, rSchema.Else.Value) {
|
||||||
|
sc.ElseChanges = CompareSchemas(lSchema.Else.Value, rSchema.Else.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added Else
|
||||||
|
if lSchema.Else.Value == nil && rSchema.Else.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.ElseLabel,
|
||||||
|
nil, rSchema.Else.ValueNode, true, nil, rSchema.Else.Value)
|
||||||
|
}
|
||||||
|
// removed Else
|
||||||
|
if lSchema.Else.Value != nil && rSchema.Else.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.ElseLabel,
|
||||||
|
lSchema.Else.ValueNode, nil, true, lSchema.Else.Value, nil)
|
||||||
|
}
|
||||||
|
// Then
|
||||||
|
if lSchema.Then.Value != nil && rSchema.Then.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.Then.Value, rSchema.Then.Value) {
|
||||||
|
sc.ThenChanges = CompareSchemas(lSchema.Then.Value, rSchema.Then.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added Then
|
||||||
|
if lSchema.Then.Value == nil && rSchema.Then.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.ThenLabel,
|
||||||
|
nil, rSchema.Then.ValueNode, true, nil, rSchema.Then.Value)
|
||||||
|
}
|
||||||
|
// removed Then
|
||||||
|
if lSchema.Then.Value != nil && rSchema.Then.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.ThenLabel,
|
||||||
|
lSchema.Then.ValueNode, nil, true, lSchema.Then.Value, nil)
|
||||||
|
}
|
||||||
|
// PropertyNames
|
||||||
|
if lSchema.PropertyNames.Value != nil && rSchema.PropertyNames.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.PropertyNames.Value, rSchema.PropertyNames.Value) {
|
||||||
|
sc.PropertyNamesChanges = CompareSchemas(lSchema.PropertyNames.Value, rSchema.PropertyNames.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added PropertyNames
|
||||||
|
if lSchema.PropertyNames.Value == nil && rSchema.PropertyNames.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.PropertyNamesLabel,
|
||||||
|
nil, rSchema.PropertyNames.ValueNode, true, nil, rSchema.PropertyNames.Value)
|
||||||
|
}
|
||||||
|
// removed PropertyNames
|
||||||
|
if lSchema.PropertyNames.Value != nil && rSchema.PropertyNames.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.PropertyNamesLabel,
|
||||||
|
lSchema.PropertyNames.ValueNode, nil, true, lSchema.PropertyNames.Value, nil)
|
||||||
|
}
|
||||||
|
// Contains
|
||||||
|
if lSchema.Contains.Value != nil && rSchema.Contains.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.Contains.Value, rSchema.Contains.Value) {
|
||||||
|
sc.ContainsChanges = CompareSchemas(lSchema.Contains.Value, rSchema.Contains.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added Contains
|
||||||
|
if lSchema.Contains.Value == nil && rSchema.Contains.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.ContainsLabel,
|
||||||
|
nil, rSchema.Contains.ValueNode, true, nil, rSchema.Contains.Value)
|
||||||
|
}
|
||||||
|
// removed Contains
|
||||||
|
if lSchema.Contains.Value != nil && rSchema.Contains.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.ContainsLabel,
|
||||||
|
lSchema.Contains.ValueNode, nil, true, lSchema.Contains.Value, nil)
|
||||||
|
}
|
||||||
|
// UnevaluatedItems
|
||||||
|
if lSchema.UnevaluatedItems.Value != nil && rSchema.UnevaluatedItems.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.UnevaluatedItems.Value, rSchema.UnevaluatedItems.Value) {
|
||||||
|
sc.UnevaluatedItemsChanges = CompareSchemas(lSchema.UnevaluatedItems.Value, rSchema.UnevaluatedItems.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added UnevaluatedItems
|
||||||
|
if lSchema.UnevaluatedItems.Value == nil && rSchema.UnevaluatedItems.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.UnevaluatedItemsLabel,
|
||||||
|
nil, rSchema.UnevaluatedItems.ValueNode, true, nil, rSchema.UnevaluatedItems.Value)
|
||||||
|
}
|
||||||
|
// removed UnevaluatedItems
|
||||||
|
if lSchema.UnevaluatedItems.Value != nil && rSchema.UnevaluatedItems.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.UnevaluatedItemsLabel,
|
||||||
|
lSchema.UnevaluatedItems.ValueNode, nil, true, lSchema.UnevaluatedItems.Value, nil)
|
||||||
|
}
|
||||||
|
// UnevaluatedProperties
|
||||||
|
if lSchema.UnevaluatedProperties.Value != nil && rSchema.UnevaluatedProperties.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.UnevaluatedProperties.Value, rSchema.UnevaluatedProperties.Value) {
|
||||||
|
sc.UnevaluatedPropertiesChanges = CompareSchemas(lSchema.UnevaluatedProperties.Value, rSchema.UnevaluatedProperties.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added UnevaluatedProperties
|
||||||
|
if lSchema.UnevaluatedProperties.Value == nil && rSchema.UnevaluatedProperties.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.UnevaluatedPropertiesLabel,
|
||||||
|
nil, rSchema.UnevaluatedProperties.ValueNode, true, nil, rSchema.UnevaluatedProperties.Value)
|
||||||
|
}
|
||||||
|
// removed UnevaluatedProperties
|
||||||
|
if lSchema.UnevaluatedProperties.Value != nil && rSchema.UnevaluatedProperties.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.UnevaluatedPropertiesLabel,
|
||||||
|
lSchema.UnevaluatedProperties.ValueNode, nil, true, lSchema.UnevaluatedProperties.Value, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not
|
||||||
|
if lSchema.Not.Value != nil && rSchema.Not.Value != nil {
|
||||||
|
if !low.AreEqual(lSchema.Not.Value, rSchema.Not.Value) {
|
||||||
|
sc.NotChanges = CompareSchemas(lSchema.Not.Value, rSchema.Not.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added Not
|
||||||
|
if lSchema.Not.Value == nil && rSchema.Not.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.NotLabel,
|
||||||
|
nil, rSchema.Not.ValueNode, true, nil, rSchema.Not.Value)
|
||||||
|
}
|
||||||
|
// removed not
|
||||||
|
if lSchema.Not.Value != nil && rSchema.Not.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.NotLabel,
|
||||||
|
lSchema.Not.ValueNode, nil, true, lSchema.Not.Value, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// items
|
||||||
|
if lSchema.Items.Value != nil && rSchema.Items.Value != nil {
|
||||||
|
if lSchema.Items.Value.IsA() && rSchema.Items.Value.IsA() {
|
||||||
|
if !low.AreEqual(lSchema.Items.Value.A, rSchema.Items.Value.A) {
|
||||||
|
sc.ItemsChanges = CompareSchemas(lSchema.Items.Value.A, rSchema.Items.Value.A)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CreateChange(changes, Modified, v3.ItemsLabel,
|
||||||
|
lSchema.Items.ValueNode, rSchema.Items.ValueNode, true, lSchema.Items.Value.B, rSchema.Items.Value.B)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// added Items
|
||||||
|
if lSchema.Items.Value == nil && rSchema.Items.Value != nil {
|
||||||
|
CreateChange(changes, ObjectAdded, v3.ItemsLabel,
|
||||||
|
nil, rSchema.Items.ValueNode, true, nil, rSchema.Items.Value)
|
||||||
|
}
|
||||||
|
// removed Items
|
||||||
|
if lSchema.Items.Value != nil && rSchema.Items.Value == nil {
|
||||||
|
CreateChange(changes, ObjectRemoved, v3.ItemsLabel,
|
||||||
|
lSchema.Items.ValueNode, nil, true, lSchema.Items.Value, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// check extensions
|
// check extensions
|
||||||
sc.ExtensionChanges = CompareExtensions(lSchema.Extensions, rSchema.Extensions)
|
sc.ExtensionChanges = CompareExtensions(lSchema.Extensions, rSchema.Extensions)
|
||||||
|
|
||||||
|
|||||||
@@ -544,6 +544,473 @@ components:
|
|||||||
assert.Equal(t, v3.PropertiesLabel, changes.Changes[0].Property)
|
assert.Equal(t, v3.PropertiesLabel, changes.Changes[0].Property)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_PropertyNames(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
propertyNames:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
propertyNames:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, 1, changes.PropertyNamesChanges.PropertyChanges.TotalChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_PropertyNames_Added(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
propertyNames:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.PropertyNamesLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_PropertyNames_Removed(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
propertyNames:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.PropertyNamesLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_Contains(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
contains:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
contains:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, 1, changes.ContainsChanges.PropertyChanges.TotalChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_Contains_Added(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
contains:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.ContainsLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_Contains_Removed(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
contains:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.ContainsLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_UnevaluatedProperties(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
unevaluatedProperties:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
unevaluatedProperties:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, 1, changes.UnevaluatedPropertiesChanges.PropertyChanges.TotalChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_UnevaluatedProperties_Added(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
unevaluatedProperties:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.UnevaluatedPropertiesLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_UnevaluatedProperties_Removed(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
unevaluatedProperties:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.UnevaluatedPropertiesLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_UnevaluatedItems(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
unevaluatedItems:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
unevaluatedItems:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, 1, changes.UnevaluatedItemsChanges.PropertyChanges.TotalChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_UnevaluatedItems_Added(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
unevaluatedItems:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.UnevaluatedItemsLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_UnevaluatedItems_Removed(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
unevaluatedItems:
|
||||||
|
type: int`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
assert.Equal(t, v3.UnevaluatedItemsLabel, changes.Changes[0].Property)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_ItemsBoolean(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
items: true`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
items: false`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_ItemsAdded(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
items: true`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_ItemsRemoved(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
items: true`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_NotAdded(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
not:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareSchemas_NotRemoved(t *testing.T) {
|
||||||
|
left := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
right := `openapi: 3.1
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OK:
|
||||||
|
type: string
|
||||||
|
not:
|
||||||
|
type: string`
|
||||||
|
|
||||||
|
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||||
|
|
||||||
|
// extract left reference schema and non reference schema.
|
||||||
|
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||||
|
|
||||||
|
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||||
|
assert.NotNil(t, changes)
|
||||||
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
|
}
|
||||||
|
|
||||||
func TestCompareSchemas_PropertyChanged(t *testing.T) {
|
func TestCompareSchemas_PropertyChanged(t *testing.T) {
|
||||||
left := `openapi: 3.0
|
left := `openapi: 3.0
|
||||||
components:
|
components:
|
||||||
@@ -801,10 +1268,10 @@ components:
|
|||||||
assert.NotNil(t, changes)
|
assert.NotNil(t, changes)
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges[0].Changes[0].Property)
|
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges.Changes[0].Property)
|
||||||
assert.Equal(t, Modified, changes.ItemsChanges[0].Changes[0].ChangeType)
|
assert.Equal(t, Modified, changes.ItemsChanges.Changes[0].ChangeType)
|
||||||
assert.Equal(t, "string", changes.ItemsChanges[0].Changes[0].New)
|
assert.Equal(t, "string", changes.ItemsChanges.Changes[0].New)
|
||||||
assert.Equal(t, "bool", changes.ItemsChanges[0].Changes[0].Original)
|
assert.Equal(t, "bool", changes.ItemsChanges.Changes[0].Original)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareSchemas_ItemsModifyAndAddItemArray(t *testing.T) {
|
func TestCompareSchemas_ItemsModifyAndAddItemArray(t *testing.T) {
|
||||||
@@ -834,10 +1301,10 @@ components:
|
|||||||
assert.NotNil(t, changes)
|
assert.NotNil(t, changes)
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges[0].Changes[0].Property)
|
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges.Changes[0].Property)
|
||||||
assert.Equal(t, Modified, changes.ItemsChanges[0].Changes[0].ChangeType)
|
assert.Equal(t, Modified, changes.ItemsChanges.Changes[0].ChangeType)
|
||||||
assert.Equal(t, "string", changes.ItemsChanges[0].Changes[0].New)
|
assert.Equal(t, "string", changes.ItemsChanges.Changes[0].New)
|
||||||
assert.Equal(t, "bool", changes.ItemsChanges[0].Changes[0].Original)
|
assert.Equal(t, "bool", changes.ItemsChanges.Changes[0].Original)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareSchemas_NotModifyAndAddItem(t *testing.T) {
|
func TestCompareSchemas_NotModifyAndAddItem(t *testing.T) {
|
||||||
@@ -867,10 +1334,10 @@ components:
|
|||||||
assert.NotNil(t, changes)
|
assert.NotNil(t, changes)
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes.TotalChanges())
|
||||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||||
assert.Equal(t, v3.TypeLabel, changes.NotChanges[0].Changes[0].Property)
|
assert.Equal(t, v3.TypeLabel, changes.NotChanges.Changes[0].Property)
|
||||||
assert.Equal(t, Modified, changes.NotChanges[0].Changes[0].ChangeType)
|
assert.Equal(t, Modified, changes.NotChanges.Changes[0].ChangeType)
|
||||||
assert.Equal(t, "string", changes.NotChanges[0].Changes[0].New)
|
assert.Equal(t, "string", changes.NotChanges.Changes[0].New)
|
||||||
assert.Equal(t, "bool", changes.NotChanges[0].Changes[0].Original)
|
assert.Equal(t, "bool", changes.NotChanges.Changes[0].Original)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareSchemas_DiscriminatorChange(t *testing.T) {
|
func TestCompareSchemas_DiscriminatorChange(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user