mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 20:47:44 +00:00
fix: fix handling of ordered arrays when processing them async
This commit is contained in:
committed by
Dave Shanley
parent
f269259fcf
commit
52f9868d96
@@ -5,10 +5,11 @@ package base
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/high"
|
"github.com/pb33f/libopenapi/datamodel/high"
|
||||||
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
|
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DynamicValue is used to hold multiple possible values for a schema property. There are two values, a left
|
// DynamicValue is used to hold multiple possible values for a schema property. There are two values, a left
|
||||||
@@ -41,11 +42,10 @@ func (s *DynamicValue[A, B]) IsB() bool {
|
|||||||
// mix, which has been confusing. So, instead of building a bunch of different models, we have compressed
|
// mix, which has been confusing. So, instead of building a bunch of different models, we have compressed
|
||||||
// all variations into a single model that makes it easy to support multiple spec types.
|
// all variations into a single model that makes it easy to support multiple spec types.
|
||||||
//
|
//
|
||||||
// - v2 schema: https://swagger.io/specification/v2/#schemaObject
|
// - v2 schema: https://swagger.io/specification/v2/#schemaObject
|
||||||
// - v3 schema: https://swagger.io/specification/#schema-object
|
// - v3 schema: https://swagger.io/specification/#schema-object
|
||||||
// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
|
// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
|
|
||||||
// 3.1 only, used to define a dialect for this schema, label is '$schema'.
|
// 3.1 only, used to define a dialect for this schema, label is '$schema'.
|
||||||
SchemaTypeRef string
|
SchemaTypeRef string
|
||||||
|
|
||||||
@@ -309,29 +309,40 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
propsChan := make(chan bool)
|
propsChan := make(chan bool)
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
|
||||||
|
type buildResult struct {
|
||||||
|
idx int
|
||||||
|
s *SchemaProxy
|
||||||
|
}
|
||||||
|
|
||||||
// for every item, build schema async
|
// for every item, build schema async
|
||||||
buildSchema := func(sch lowmodel.ValueReference[*base.SchemaProxy], bChan chan *SchemaProxy) {
|
buildSchema := func(sch lowmodel.ValueReference[*base.SchemaProxy], idx int, bChan chan buildResult) {
|
||||||
p := &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
p := &SchemaProxy{schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||||
ValueNode: sch.ValueNode,
|
ValueNode: sch.ValueNode,
|
||||||
Value: sch.Value,
|
Value: sch.Value,
|
||||||
}}
|
}}
|
||||||
bChan <- p
|
|
||||||
|
fmt.Println("building schema", idx, sch)
|
||||||
|
|
||||||
|
bChan <- buildResult{idx: idx, s: p}
|
||||||
}
|
}
|
||||||
|
|
||||||
// schema async
|
// schema async
|
||||||
buildOutSchemas := 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 buildResult)
|
||||||
totalSchemas := len(schemas)
|
totalSchemas := len(schemas)
|
||||||
for v := range schemas {
|
for i := range schemas {
|
||||||
go buildSchema(schemas[v], bChan)
|
fmt.Println("start build schema", i, schemas[i])
|
||||||
|
go buildSchema(schemas[i], i, bChan)
|
||||||
}
|
}
|
||||||
j := 0
|
j := 0
|
||||||
for j < totalSchemas {
|
for j < totalSchemas {
|
||||||
select {
|
select {
|
||||||
case t := <-bChan:
|
case r := <-bChan:
|
||||||
j++
|
j++
|
||||||
*items = append(*items, t)
|
fmt.Println("got schema", r.idx, "of", totalSchemas)
|
||||||
|
(*items)[r.idx] = r.s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doneChan <- true
|
doneChan <- true
|
||||||
@@ -339,8 +350,9 @@ 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,
|
buildProps := func(k lowmodel.KeyReference[string], v lowmodel.ValueReference[*base.SchemaProxy], c chan bool,
|
||||||
props map[string]*SchemaProxy, sw int) {
|
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]{
|
||||||
@@ -386,14 +398,17 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
children := 0
|
children := 0
|
||||||
if !schema.AllOf.IsEmpty() {
|
if !schema.AllOf.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
|
allOf = make([]*SchemaProxy, len(schema.AllOf.Value))
|
||||||
go buildOutSchemas(schema.AllOf.Value, &allOf, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.AllOf.Value, &allOf, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
if !schema.AnyOf.IsEmpty() {
|
if !schema.AnyOf.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
|
anyOf = make([]*SchemaProxy, len(schema.AnyOf.Value))
|
||||||
go buildOutSchemas(schema.AnyOf.Value, &anyOf, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.AnyOf.Value, &anyOf, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
if !schema.OneOf.IsEmpty() {
|
if !schema.OneOf.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
|
oneOf = make([]*SchemaProxy, len(schema.OneOf.Value))
|
||||||
go buildOutSchemas(schema.OneOf.Value, &oneOf, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.OneOf.Value, &oneOf, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
if !schema.Not.IsEmpty() {
|
if !schema.Not.IsEmpty() {
|
||||||
@@ -412,6 +427,7 @@ func NewSchema(schema *base.Schema) *Schema {
|
|||||||
}
|
}
|
||||||
if !schema.PrefixItems.IsEmpty() {
|
if !schema.PrefixItems.IsEmpty() {
|
||||||
children++
|
children++
|
||||||
|
prefixItems = make([]*SchemaProxy, len(schema.PrefixItems.Value))
|
||||||
go buildOutSchemas(schema.PrefixItems.Value, &prefixItems, polyCompletedChan, errChan)
|
go buildOutSchemas(schema.PrefixItems.Value, &prefixItems, polyCompletedChan, errChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -21,7 +22,6 @@ func TestDynamicValue_IsA(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewSchemaProxy(t *testing.T) {
|
func TestNewSchemaProxy(t *testing.T) {
|
||||||
|
|
||||||
// check proxy
|
// check proxy
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
@@ -63,11 +63,9 @@ func TestNewSchemaProxy(t *testing.T) {
|
|||||||
g, o := sch1.BuildSchema()
|
g, o := sch1.BuildSchema()
|
||||||
assert.Nil(t, g)
|
assert.Nil(t, g)
|
||||||
assert.Error(t, o)
|
assert.Error(t, o)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewSchemaProxy_WithObject(t *testing.T) {
|
func TestNewSchemaProxy_WithObject(t *testing.T) {
|
||||||
|
|
||||||
testSpec := `type: object
|
testSpec := `type: object
|
||||||
description: something object
|
description: something object
|
||||||
discriminator:
|
discriminator:
|
||||||
@@ -254,14 +252,64 @@ unevaluatedProperties:
|
|||||||
assert.Equal(t, "string", compiled.PropertyNames.Schema().Type[0])
|
assert.Equal(t, "string", compiled.PropertyNames.Schema().Type[0])
|
||||||
assert.Equal(t, "boolean", compiled.UnevaluatedItems.Schema().Type[0])
|
assert.Equal(t, "boolean", compiled.UnevaluatedItems.Schema().Type[0])
|
||||||
assert.Equal(t, "integer", compiled.UnevaluatedProperties.Schema().Type[0])
|
assert.Equal(t, "integer", compiled.UnevaluatedProperties.Schema().Type[0])
|
||||||
|
assert.NotNil(t, compiled.Nullable)
|
||||||
|
assert.True(t, *compiled.Nullable)
|
||||||
|
|
||||||
wentLow := compiled.GoLow()
|
wentLow := compiled.GoLow()
|
||||||
assert.Equal(t, 114, wentLow.AdditionalProperties.ValueNode.Line)
|
assert.Equal(t, 114, wentLow.AdditionalProperties.ValueNode.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSchemaObjectWithAllOfSequenceOrder(t *testing.T) {
|
||||||
|
testSpec := test_get_allOf_schema_blob()
|
||||||
|
|
||||||
|
var compNode yaml.Node
|
||||||
|
_ = yaml.Unmarshal([]byte(testSpec), &compNode)
|
||||||
|
|
||||||
|
// test data is a map with one node
|
||||||
|
mapContent := compNode.Content[0].Content
|
||||||
|
|
||||||
|
_, vn := utils.FindKeyNodeTop(lowbase.AllOfLabel, mapContent)
|
||||||
|
assert.True(t, utils.IsNodeArray(vn))
|
||||||
|
|
||||||
|
want := []string{}
|
||||||
|
|
||||||
|
// Go over every element in AllOf and grab description
|
||||||
|
// Odd: object
|
||||||
|
// Event: description
|
||||||
|
for i := range vn.Content {
|
||||||
|
assert.True(t, utils.IsNodeMap(vn.Content[i]))
|
||||||
|
_, vn := utils.FindKeyNodeTop("description", vn.Content[i].Content)
|
||||||
|
assert.True(t, utils.IsNodeStringValue(vn))
|
||||||
|
want = append(want, vn.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
sp := new(lowbase.SchemaProxy)
|
||||||
|
err := sp.Build(compNode.Content[0], nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
lowproxy := low.NodeReference[*lowbase.SchemaProxy]{
|
||||||
|
Value: sp,
|
||||||
|
ValueNode: compNode.Content[0],
|
||||||
|
}
|
||||||
|
|
||||||
|
schemaProxy := NewSchemaProxy(&lowproxy)
|
||||||
|
compiled := schemaProxy.Schema()
|
||||||
|
|
||||||
|
assert.Equal(t, schemaProxy, compiled.ParentProxy)
|
||||||
|
|
||||||
|
assert.NotNil(t, compiled)
|
||||||
|
assert.Nil(t, schemaProxy.GetBuildError())
|
||||||
|
|
||||||
|
got := []string{}
|
||||||
|
for i := range compiled.AllOf {
|
||||||
|
v := compiled.AllOf[i]
|
||||||
|
got = append(got, v.Schema().Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, want, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewSchemaProxy_WithObject_FinishPoly(t *testing.T) {
|
func TestNewSchemaProxy_WithObject_FinishPoly(t *testing.T) {
|
||||||
|
|
||||||
testSpec := `type: object
|
testSpec := `type: object
|
||||||
description: something object
|
description: something object
|
||||||
discriminator:
|
discriminator:
|
||||||
@@ -400,11 +448,9 @@ required: [cake, fish]`
|
|||||||
|
|
||||||
wentLower := compiled.XML.GoLow()
|
wentLower := compiled.XML.GoLow()
|
||||||
assert.Equal(t, 102, wentLower.Name.ValueNode.Line)
|
assert.Equal(t, 102, wentLower.Name.ValueNode.Line)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchemaProxy_GoLow(t *testing.T) {
|
func TestSchemaProxy_GoLow(t *testing.T) {
|
||||||
|
|
||||||
const ymlComponents = `components:
|
const ymlComponents = `components:
|
||||||
schemas:
|
schemas:
|
||||||
rice:
|
rice:
|
||||||
@@ -471,7 +517,6 @@ type: number
|
|||||||
assert.Nil(t, highSchema.ExclusiveMinimum)
|
assert.Nil(t, highSchema.ExclusiveMinimum)
|
||||||
assert.Nil(t, highSchema.Maximum)
|
assert.Nil(t, highSchema.Maximum)
|
||||||
assert.Nil(t, highSchema.ExclusiveMaximum)
|
assert.Nil(t, highSchema.ExclusiveMaximum)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchemaNumberMultipleOf(t *testing.T) {
|
func TestSchemaNumberMultipleOf(t *testing.T) {
|
||||||
@@ -574,7 +619,6 @@ examples:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleNewSchema() {
|
func ExampleNewSchema() {
|
||||||
|
|
||||||
// create an example schema object
|
// create an example schema object
|
||||||
// this can be either JSON or YAML.
|
// this can be either JSON or YAML.
|
||||||
yml := `
|
yml := `
|
||||||
@@ -601,11 +645,9 @@ properties:
|
|||||||
// print out the description of 'aProperty'
|
// print out the description of 'aProperty'
|
||||||
fmt.Print(highSchema.Properties["aProperty"].Schema().Description)
|
fmt.Print(highSchema.Properties["aProperty"].Schema().Description)
|
||||||
// Output: this is an integer property
|
// Output: this is an integer property
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleNewSchemaProxy() {
|
func ExampleNewSchemaProxy() {
|
||||||
|
|
||||||
// create an example schema object
|
// create an example schema object
|
||||||
// this can be either JSON or YAML.
|
// this can be either JSON or YAML.
|
||||||
yml := `
|
yml := `
|
||||||
@@ -634,5 +676,26 @@ properties:
|
|||||||
// print out the description of 'aProperty'
|
// print out the description of 'aProperty'
|
||||||
fmt.Print(highSchema.Schema().Properties["aProperty"].Schema().Description)
|
fmt.Print(highSchema.Schema().Properties["aProperty"].Schema().Description)
|
||||||
// Output: this is an integer property
|
// Output: this is an integer property
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_get_allOf_schema_blob() string {
|
||||||
|
return `type: object
|
||||||
|
description: allOf sequence check
|
||||||
|
allOf:
|
||||||
|
- type: object
|
||||||
|
description: allOf sequence check 1
|
||||||
|
- description: allOf sequence check 2
|
||||||
|
- type: object
|
||||||
|
description: allOf sequence check 3
|
||||||
|
- description: allOf sequence check 4
|
||||||
|
properties:
|
||||||
|
somethingBee:
|
||||||
|
type: number
|
||||||
|
somethingThree:
|
||||||
|
type: number
|
||||||
|
somethingTwo:
|
||||||
|
type: number
|
||||||
|
somethingOne:
|
||||||
|
type: number
|
||||||
|
`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package base
|
|||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SchemaDynamicValue is used to hold multiple possible values for a schema property. There are two values, a left
|
// SchemaDynamicValue is used to hold multiple possible values for a schema property. There are two values, a left
|
||||||
@@ -42,11 +43,10 @@ func (s SchemaDynamicValue[A, B]) IsB() bool {
|
|||||||
// mix, which has been confusing. So, instead of building a bunch of different models, we have compressed
|
// mix, which has been confusing. So, instead of building a bunch of different models, we have compressed
|
||||||
// all variations into a single model that makes it easy to support multiple spec types.
|
// all variations into a single model that makes it easy to support multiple spec types.
|
||||||
//
|
//
|
||||||
// - v2 schema: https://swagger.io/specification/v2/#schemaObject
|
// - v2 schema: https://swagger.io/specification/v2/#schemaObject
|
||||||
// - v3 schema: https://swagger.io/specification/#schema-object
|
// - v3 schema: https://swagger.io/specification/#schema-object
|
||||||
// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
|
// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
|
|
||||||
// Reference to the '$schema' dialect setting (3.1 only)
|
// Reference to the '$schema' dialect setting (3.1 only)
|
||||||
SchemaTypeRef low.NodeReference[string]
|
SchemaTypeRef low.NodeReference[string]
|
||||||
|
|
||||||
@@ -445,27 +445,27 @@ func (s *Schema) GetExtensions() map[low.KeyReference[string]]low.ValueReference
|
|||||||
|
|
||||||
// Build will perform a number of operations.
|
// Build will perform a number of operations.
|
||||||
// Extraction of the following happens in this method:
|
// Extraction of the following happens in this method:
|
||||||
// - Extensions
|
// - Extensions
|
||||||
// - Type
|
// - Type
|
||||||
// - ExclusiveMinimum and ExclusiveMaximum
|
// - ExclusiveMinimum and ExclusiveMaximum
|
||||||
// - Examples
|
// - Examples
|
||||||
// - AdditionalProperties
|
// - AdditionalProperties
|
||||||
// - Discriminator
|
// - Discriminator
|
||||||
// - ExternalDocs
|
// - ExternalDocs
|
||||||
// - XML
|
// - XML
|
||||||
// - Properties
|
// - Properties
|
||||||
// - AllOf, OneOf, AnyOf
|
// - AllOf, OneOf, AnyOf
|
||||||
// - Not
|
// - Not
|
||||||
// - Items
|
// - Items
|
||||||
// - PrefixItems
|
// - PrefixItems
|
||||||
// - If
|
// - If
|
||||||
// - Else
|
// - Else
|
||||||
// - Then
|
// - Then
|
||||||
// - DependentSchemas
|
// - DependentSchemas
|
||||||
// - PatternProperties
|
// - PatternProperties
|
||||||
// - PropertyNames
|
// - PropertyNames
|
||||||
// - UnevaluatedItems
|
// - UnevaluatedItems
|
||||||
// - UnevaluatedProperties
|
// - 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)
|
||||||
@@ -557,7 +557,8 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
_, schemaRefLabel, schemaRefNode := utils.FindKeyNodeFullTop(SchemaTypeLabel, root.Content)
|
_, schemaRefLabel, schemaRefNode := utils.FindKeyNodeFullTop(SchemaTypeLabel, root.Content)
|
||||||
if schemaRefNode != nil {
|
if schemaRefNode != nil {
|
||||||
s.SchemaTypeRef = low.NodeReference[string]{
|
s.SchemaTypeRef = low.NodeReference[string]{
|
||||||
Value: schemaRefNode.Value, KeyNode: schemaRefLabel, ValueNode: schemaRefLabel}
|
Value: schemaRefNode.Value, KeyNode: schemaRefLabel, ValueNode: schemaRefLabel,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle example if set. (3.0)
|
// handle example if set. (3.0)
|
||||||
@@ -914,12 +915,12 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildPropertyMap(root *yaml.Node, idx *index.SpecIndex, label string) (*low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]], error) {
|
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!
|
// for property, build in a new thread!
|
||||||
bChan := make(chan schemaProxyBuildResult)
|
bChan := make(chan schemaProxyBuildResult)
|
||||||
|
|
||||||
var buildProperty = func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
buildProperty := func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
||||||
refString string) {
|
refString string,
|
||||||
|
) {
|
||||||
c <- schemaProxyBuildResult{
|
c <- schemaProxyBuildResult{
|
||||||
k: low.KeyReference[string]{
|
k: low.KeyReference[string]{
|
||||||
KeyNode: label,
|
KeyNode: label,
|
||||||
@@ -1001,13 +1002,18 @@ func (s *Schema) extractExtensions(root *yaml.Node) {
|
|||||||
|
|
||||||
// build out a child schema for parent schema.
|
// build out a child schema for parent schema.
|
||||||
func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml.Node, errors chan error, idx *index.SpecIndex) {
|
func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml.Node, errors chan error, idx *index.SpecIndex) {
|
||||||
|
|
||||||
if valueNode != nil {
|
if valueNode != nil {
|
||||||
syncChan := make(chan *low.ValueReference[*SchemaProxy])
|
type buildResult struct {
|
||||||
|
res *low.ValueReference[*SchemaProxy]
|
||||||
|
idx int
|
||||||
|
}
|
||||||
|
|
||||||
|
syncChan := make(chan buildResult)
|
||||||
|
|
||||||
// build out a SchemaProxy for every sub-schema.
|
// build out a SchemaProxy for every sub-schema.
|
||||||
build := func(kn *yaml.Node, vn *yaml.Node, c chan *low.ValueReference[*SchemaProxy],
|
build := func(kn *yaml.Node, vn *yaml.Node, schemaIdx int, c chan buildResult,
|
||||||
isRef bool, refLocation string) {
|
isRef bool, refLocation string,
|
||||||
|
) {
|
||||||
// a proxy design works best here. polymorphism, pretty much guarantees that a sub-schema can
|
// a proxy design works best here. polymorphism, pretty much guarantees that a sub-schema can
|
||||||
// take on circular references through polymorphism. Like the resolver, if we try and follow these
|
// take on circular references through polymorphism. Like the resolver, if we try and follow these
|
||||||
// journey's through hyperspace, we will end up creating endless amounts of threads, spinning off
|
// journey's through hyperspace, we will end up creating endless amounts of threads, spinning off
|
||||||
@@ -1026,7 +1032,10 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
|||||||
Value: sp,
|
Value: sp,
|
||||||
ValueNode: vn,
|
ValueNode: vn,
|
||||||
}
|
}
|
||||||
c <- res
|
c <- buildResult{
|
||||||
|
res: res,
|
||||||
|
idx: schemaIdx,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isRef := false
|
isRef := false
|
||||||
@@ -1046,7 +1055,7 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
|||||||
|
|
||||||
// this only runs once, however to keep things consistent, it makes sense to use the same async method
|
// this only runs once, however to keep things consistent, it makes sense to use the same async method
|
||||||
// that arrays will use.
|
// that arrays will use.
|
||||||
go build(labelNode, valueNode, syncChan, isRef, refLocation)
|
go build(labelNode, valueNode, -1, syncChan, isRef, refLocation)
|
||||||
select {
|
select {
|
||||||
case r := <-syncChan:
|
case r := <-syncChan:
|
||||||
schemas <- schemaProxyBuildResult{
|
schemas <- schemaProxyBuildResult{
|
||||||
@@ -1054,13 +1063,15 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
|||||||
KeyNode: labelNode,
|
KeyNode: labelNode,
|
||||||
Value: labelNode.Value,
|
Value: labelNode.Value,
|
||||||
},
|
},
|
||||||
v: *r,
|
v: *r.res,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if utils.IsNodeArray(valueNode) {
|
if utils.IsNodeArray(valueNode) {
|
||||||
refBuilds := 0
|
refBuilds := 0
|
||||||
for _, vn := range valueNode.Content {
|
results := make([]*low.ValueReference[*SchemaProxy], len(valueNode.Content))
|
||||||
|
|
||||||
|
for i, vn := range valueNode.Content {
|
||||||
isRef = false
|
isRef = false
|
||||||
h := false
|
h := false
|
||||||
if h, _, refLocation = utils.IsNodeRefValue(vn); h {
|
if h, _, refLocation = utils.IsNodeRefValue(vn); h {
|
||||||
@@ -1076,20 +1087,25 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
refBuilds++
|
refBuilds++
|
||||||
go build(vn, vn, syncChan, isRef, refLocation)
|
go build(vn, vn, i, syncChan, isRef, refLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
completedBuilds := 0
|
completedBuilds := 0
|
||||||
for completedBuilds < refBuilds {
|
for completedBuilds < refBuilds {
|
||||||
select {
|
select {
|
||||||
case res := <-syncChan:
|
case res := <-syncChan:
|
||||||
completedBuilds++
|
completedBuilds++
|
||||||
schemas <- schemaProxyBuildResult{
|
results[res.idx] = res.res
|
||||||
k: low.KeyReference[string]{
|
}
|
||||||
KeyNode: labelNode,
|
}
|
||||||
Value: labelNode.Value,
|
|
||||||
},
|
for _, r := range results {
|
||||||
v: *res,
|
schemas <- schemaProxyBuildResult{
|
||||||
}
|
k: low.KeyReference[string]{
|
||||||
|
KeyNode: labelNode,
|
||||||
|
Value: labelNode.Value,
|
||||||
|
},
|
||||||
|
v: *r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package base
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"github.com/pb33f/libopenapi/resolver"
|
"github.com/pb33f/libopenapi/resolver"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func test_get_schema_blob() string {
|
func test_get_schema_blob() string {
|
||||||
@@ -306,12 +308,52 @@ func Test_Schema(t *testing.T) {
|
|||||||
assert.Equal(t, "string", sch.PropertyNames.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, "boolean", sch.UnevaluatedItems.Value.Schema().Type.Value.A)
|
||||||
assert.Equal(t, "integer", sch.UnevaluatedProperties.Value.Schema().Type.Value.A)
|
assert.Equal(t, "integer", sch.UnevaluatedProperties.Value.Schema().Type.Value.A)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSchemaAllOfSequenceOrder(t *testing.T) {
|
||||||
|
testSpec := test_get_allOf_schema_blob()
|
||||||
|
|
||||||
|
var rootNode yaml.Node
|
||||||
|
mErr := yaml.Unmarshal([]byte(testSpec), &rootNode)
|
||||||
|
assert.NoError(t, mErr)
|
||||||
|
|
||||||
|
// test data is a map with one node
|
||||||
|
mapContent := rootNode.Content[0].Content
|
||||||
|
|
||||||
|
_, vn := utils.FindKeyNodeTop(AllOfLabel, mapContent)
|
||||||
|
assert.True(t, utils.IsNodeArray(vn))
|
||||||
|
|
||||||
|
want := []string{}
|
||||||
|
|
||||||
|
// Go over every element in AllOf and grab description
|
||||||
|
// Odd: object
|
||||||
|
// Event: description
|
||||||
|
for i := range vn.Content {
|
||||||
|
assert.True(t, utils.IsNodeMap(vn.Content[i]))
|
||||||
|
_, vn := utils.FindKeyNodeTop("description", vn.Content[i].Content)
|
||||||
|
assert.True(t, utils.IsNodeStringValue(vn))
|
||||||
|
want = append(want, vn.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
sch := Schema{}
|
||||||
|
mbErr := low.BuildModel(rootNode.Content[0], &sch)
|
||||||
|
assert.NoError(t, mbErr)
|
||||||
|
|
||||||
|
schErr := sch.Build(rootNode.Content[0], nil)
|
||||||
|
assert.NoError(t, schErr)
|
||||||
|
assert.Equal(t, "allOf sequence check", sch.Description.Value)
|
||||||
|
|
||||||
|
got := []string{}
|
||||||
|
for i := range sch.AllOf.Value {
|
||||||
|
v := sch.AllOf.Value[i]
|
||||||
|
got = append(got, v.Value.Schema().Description.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, want, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Hash(t *testing.T) {
|
func TestSchema_Hash(t *testing.T) {
|
||||||
|
// create two versions
|
||||||
//create two versions
|
|
||||||
testSpec := test_get_schema_blob()
|
testSpec := test_get_schema_blob()
|
||||||
var sc1n yaml.Node
|
var sc1n yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(testSpec), &sc1n)
|
_ = yaml.Unmarshal([]byte(testSpec), &sc1n)
|
||||||
@@ -326,12 +368,10 @@ func TestSchema_Hash(t *testing.T) {
|
|||||||
_ = sch2.Build(sc2n.Content[0], nil)
|
_ = sch2.Build(sc2n.Content[0], nil)
|
||||||
|
|
||||||
assert.Equal(t, sch1.Hash(), sch2.Hash())
|
assert.Equal(t, sch1.Hash(), sch2.Hash())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSchema_Hash(b *testing.B) {
|
func BenchmarkSchema_Hash(b *testing.B) {
|
||||||
|
// create two versions
|
||||||
//create two versions
|
|
||||||
testSpec := test_get_schema_blob()
|
testSpec := test_get_schema_blob()
|
||||||
var sc1n yaml.Node
|
var sc1n yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(testSpec), &sc1n)
|
_ = yaml.Unmarshal([]byte(testSpec), &sc1n)
|
||||||
@@ -348,7 +388,6 @@ func BenchmarkSchema_Hash(b *testing.B) {
|
|||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
assert.Equal(b, sch1.Hash(), sch2.Hash())
|
assert.Equal(b, sch1.Hash(), sch2.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_31(t *testing.T) {
|
func Test_Schema_31(t *testing.T) {
|
||||||
@@ -390,7 +429,6 @@ examples:
|
|||||||
assert.Equal(t, "fish/paste", sch.ContentMediaType.Value)
|
assert.Equal(t, "fish/paste", sch.ContentMediaType.Value)
|
||||||
assert.True(t, sch.Items.Value.IsB())
|
assert.True(t, sch.Items.Value.IsB())
|
||||||
assert.True(t, sch.Items.Value.B)
|
assert.True(t, sch.Items.Value.B)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//func TestSchema_BuildLevel_TooDeep(t *testing.T) {
|
//func TestSchema_BuildLevel_TooDeep(t *testing.T) {
|
||||||
@@ -512,7 +550,6 @@ examples:
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
func TestSchema_Build_PropsLookup(t *testing.T) {
|
func TestSchema_Build_PropsLookup(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -536,11 +573,9 @@ properties:
|
|||||||
err := n.Build(idxNode.Content[0], idx)
|
err := n.Build(idxNode.Content[0], idx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "this is something", n.FindProperty("aValue").Value.Schema().Description.Value)
|
assert.Equal(t, "this is something", n.FindProperty("aValue").Value.Schema().Description.Value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Build_PropsLookup_Fail(t *testing.T) {
|
func TestSchema_Build_PropsLookup_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -563,11 +598,9 @@ properties:
|
|||||||
var n Schema
|
var n Schema
|
||||||
err := n.Build(idxNode.Content[0], idx)
|
err := n.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Build_DependentSchemas_Fail(t *testing.T) {
|
func TestSchema_Build_DependentSchemas_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -590,11 +623,9 @@ dependentSchemas:
|
|||||||
var n Schema
|
var n Schema
|
||||||
err := n.Build(idxNode.Content[0], idx)
|
err := n.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Build_PatternProperties_Fail(t *testing.T) {
|
func TestSchema_Build_PatternProperties_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -617,11 +648,9 @@ patternProperties:
|
|||||||
var n Schema
|
var n Schema
|
||||||
err := n.Build(idxNode.Content[0], idx)
|
err := n.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_Array_Ref(t *testing.T) {
|
func Test_Schema_Polymorphism_Array_Ref(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -669,7 +698,6 @@ items:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_Array_Ref_Fail(t *testing.T) {
|
func Test_Schema_Polymorphism_Array_Ref_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -707,11 +735,9 @@ items:
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, schErr)
|
assert.Error(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_Map_Ref(t *testing.T) {
|
func Test_Schema_Polymorphism_Map_Ref(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -759,7 +785,6 @@ items:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_Map_Ref_Fail(t *testing.T) {
|
func Test_Schema_Polymorphism_Map_Ref_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -797,11 +822,9 @@ items:
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, schErr)
|
assert.Error(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_BorkParent(t *testing.T) {
|
func Test_Schema_Polymorphism_BorkParent(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -825,11 +848,9 @@ allOf:
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, schErr)
|
assert.Error(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_BorkChild(t *testing.T) {
|
func Test_Schema_Polymorphism_BorkChild(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -853,11 +874,9 @@ allOf:
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, schErr)
|
assert.Error(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_BorkChild_Array(t *testing.T) {
|
func Test_Schema_Polymorphism_BorkChild_Array(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -885,11 +904,9 @@ allOf:
|
|||||||
assert.NoError(t, schErr)
|
assert.NoError(t, schErr)
|
||||||
assert.Nil(t, sch.AllOf.Value[0].Value.Schema()) // child can't be resolved, so this will be nil.
|
assert.Nil(t, sch.AllOf.Value[0].Value.Schema()) // child can't be resolved, so this will be nil.
|
||||||
assert.Error(t, sch.AllOf.Value[0].Value.GetBuildError())
|
assert.Error(t, sch.AllOf.Value[0].Value.GetBuildError())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_RefMadness(t *testing.T) {
|
func Test_Schema_Polymorphism_RefMadness(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -918,11 +935,9 @@ allOf:
|
|||||||
|
|
||||||
desc := "madness"
|
desc := "madness"
|
||||||
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_RefMadnessBork(t *testing.T) {
|
func Test_Schema_Polymorphism_RefMadnessBork(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -948,11 +963,9 @@ allOf:
|
|||||||
|
|
||||||
err = sch.Build(idxNode.Content[0], idx)
|
err = sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
||||||
|
|
||||||
// this does not work, but it won't error out.
|
// this does not work, but it won't error out.
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
@@ -978,11 +991,9 @@ func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.NoError(t, schErr)
|
assert.NoError(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_RefMadnessIllegal_Circular(t *testing.T) {
|
func Test_Schema_RefMadnessIllegal_Circular(t *testing.T) {
|
||||||
|
|
||||||
// this does not work, but it won't error out.
|
// this does not work, but it won't error out.
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
@@ -1012,11 +1023,9 @@ func Test_Schema_RefMadnessIllegal_Circular(t *testing.T) {
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, schErr)
|
assert.Error(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Schema_RefMadnessIllegal_Nonexist(t *testing.T) {
|
func Test_Schema_RefMadnessIllegal_Nonexist(t *testing.T) {
|
||||||
|
|
||||||
// this does not work, but it won't error out.
|
// this does not work, but it won't error out.
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
@@ -1046,11 +1055,9 @@ func Test_Schema_RefMadnessIllegal_Nonexist(t *testing.T) {
|
|||||||
|
|
||||||
schErr := sch.Build(idxNode.Content[0], idx)
|
schErr := sch.Build(idxNode.Content[0], idx)
|
||||||
assert.Error(t, schErr)
|
assert.Error(t, schErr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema(t *testing.T) {
|
func TestExtractSchema(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1079,7 +1086,6 @@ func TestExtractSchema(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_DefaultPrimitive(t *testing.T) {
|
func TestExtractSchema_DefaultPrimitive(t *testing.T) {
|
||||||
|
|
||||||
yml := `
|
yml := `
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
@@ -1096,7 +1102,6 @@ schema:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_Ref(t *testing.T) {
|
func TestExtractSchema_Ref(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1121,7 +1126,6 @@ func TestExtractSchema_Ref(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_Ref_Fail(t *testing.T) {
|
func TestExtractSchema_Ref_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1144,7 +1148,6 @@ func TestExtractSchema_Ref_Fail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_CheckChildPropCircular(t *testing.T) {
|
func TestExtractSchema_CheckChildPropCircular(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1176,11 +1179,9 @@ func TestExtractSchema_CheckChildPropCircular(t *testing.T) {
|
|||||||
|
|
||||||
props := res.Value.Schema().FindProperty("nothing")
|
props := res.Value.Schema().FindProperty("nothing")
|
||||||
assert.NotNil(t, props)
|
assert.NotNil(t, props)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_RefRoot(t *testing.T) {
|
func TestExtractSchema_RefRoot(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1204,7 +1205,6 @@ func TestExtractSchema_RefRoot(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1223,11 +1223,9 @@ func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
|||||||
|
|
||||||
_, err := ExtractSchema(idxNode.Content[0], idx)
|
_, err := ExtractSchema(idxNode.Content[0], idx)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1248,7 +1246,6 @@ func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_DoNothing(t *testing.T) {
|
func TestExtractSchema_DoNothing(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Something:
|
Something:
|
||||||
@@ -1267,11 +1264,9 @@ func TestExtractSchema_DoNothing(t *testing.T) {
|
|||||||
res, err := ExtractSchema(idxNode.Content[0], idx)
|
res, err := ExtractSchema(idxNode.Content[0], idx)
|
||||||
assert.Nil(t, res)
|
assert.Nil(t, res)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_AdditionalProperties_Ref(t *testing.T) {
|
func TestExtractSchema_AdditionalProperties_Ref(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Nothing:
|
Nothing:
|
||||||
@@ -1297,11 +1292,9 @@ func TestExtractSchema_AdditionalProperties_Ref(t *testing.T) {
|
|||||||
res, err := ExtractSchema(idxNode.Content[0], idx)
|
res, err := ExtractSchema(idxNode.Content[0], idx)
|
||||||
assert.NotNil(t, res.Value.Schema().AdditionalProperties.Value.(*SchemaProxy).Schema())
|
assert.NotNil(t, res.Value.Schema().AdditionalProperties.Value.(*SchemaProxy).Schema())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractSchema_OneOfRef(t *testing.T) {
|
func TestExtractSchema_OneOfRef(t *testing.T) {
|
||||||
|
|
||||||
yml := `components:
|
yml := `components:
|
||||||
schemas:
|
schemas:
|
||||||
Error:
|
Error:
|
||||||
@@ -1414,11 +1407,9 @@ func TestExtractSchema_OneOfRef(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
||||||
res.Value.Schema().OneOf.Value[0].Value.Schema().Description.Value)
|
res.Value.Schema().OneOf.Value[0].Value.Schema().Description.Value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Hash_Equal(t *testing.T) {
|
func TestSchema_Hash_Equal(t *testing.T) {
|
||||||
|
|
||||||
left := `schema:
|
left := `schema:
|
||||||
$schema: https://athing.com
|
$schema: https://athing.com
|
||||||
multipleOf: 1
|
multipleOf: 1
|
||||||
@@ -1515,11 +1506,9 @@ func TestSchema_Hash_Equal(t *testing.T) {
|
|||||||
rHash := rDoc.Value.Schema().Hash()
|
rHash := rDoc.Value.Schema().Hash()
|
||||||
|
|
||||||
assert.Equal(t, lHash, rHash)
|
assert.Equal(t, lHash, rHash)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Hash_NotEqual(t *testing.T) {
|
func TestSchema_Hash_NotEqual(t *testing.T) {
|
||||||
|
|
||||||
left := `schema:
|
left := `schema:
|
||||||
title: an OK message - but different
|
title: an OK message - but different
|
||||||
items: true
|
items: true
|
||||||
@@ -1551,7 +1540,6 @@ func TestSchema_Hash_NotEqual(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSchema_Hash_EqualJumbled(t *testing.T) {
|
func TestSchema_Hash_EqualJumbled(t *testing.T) {
|
||||||
|
|
||||||
left := `schema:
|
left := `schema:
|
||||||
title: an OK message
|
title: an OK message
|
||||||
description: a nice thing.
|
description: a nice thing.
|
||||||
@@ -1585,5 +1573,17 @@ func TestSchema_Hash_EqualJumbled(t *testing.T) {
|
|||||||
lDoc, _ := ExtractSchema(lNode.Content[0], nil)
|
lDoc, _ := ExtractSchema(lNode.Content[0], nil)
|
||||||
rDoc, _ := ExtractSchema(rNode.Content[0], nil)
|
rDoc, _ := ExtractSchema(rNode.Content[0], nil)
|
||||||
assert.True(t, low.AreEqual(lDoc.Value.Schema(), rDoc.Value.Schema()))
|
assert.True(t, low.AreEqual(lDoc.Value.Schema(), rDoc.Value.Schema()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_get_allOf_schema_blob() string {
|
||||||
|
return `type: object
|
||||||
|
description: allOf sequence check
|
||||||
|
allOf:
|
||||||
|
- type: object
|
||||||
|
description: allOf sequence check 1
|
||||||
|
- description: allOf sequence check 2
|
||||||
|
- type: object
|
||||||
|
description: allOf sequence check 3
|
||||||
|
- description: allOf sequence check 4
|
||||||
|
`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user