mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 12:37:49 +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 (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/pb33f/libopenapi/datamodel/high"
|
||||
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
|
||||
"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
|
||||
@@ -45,7 +46,6 @@ func (s *DynamicValue[A, B]) IsB() bool {
|
||||
// - v3 schema: https://swagger.io/specification/#schema-object
|
||||
// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
|
||||
type Schema struct {
|
||||
|
||||
// 3.1 only, used to define a dialect for this schema, label is '$schema'.
|
||||
SchemaTypeRef string
|
||||
|
||||
@@ -309,29 +309,40 @@ func NewSchema(schema *base.Schema) *Schema {
|
||||
propsChan := make(chan bool)
|
||||
errChan := make(chan error)
|
||||
|
||||
type buildResult struct {
|
||||
idx int
|
||||
s *SchemaProxy
|
||||
}
|
||||
|
||||
// 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]{
|
||||
ValueNode: sch.ValueNode,
|
||||
Value: sch.Value,
|
||||
}}
|
||||
bChan <- p
|
||||
|
||||
fmt.Println("building schema", idx, sch)
|
||||
|
||||
bChan <- buildResult{idx: idx, s: p}
|
||||
}
|
||||
|
||||
// schema async
|
||||
buildOutSchemas := func(schemas []lowmodel.ValueReference[*base.SchemaProxy], items *[]*SchemaProxy,
|
||||
doneChan chan bool, e chan error) {
|
||||
bChan := make(chan *SchemaProxy)
|
||||
doneChan chan bool, e chan error,
|
||||
) {
|
||||
bChan := make(chan buildResult)
|
||||
totalSchemas := len(schemas)
|
||||
for v := range schemas {
|
||||
go buildSchema(schemas[v], bChan)
|
||||
for i := range schemas {
|
||||
fmt.Println("start build schema", i, schemas[i])
|
||||
go buildSchema(schemas[i], i, bChan)
|
||||
}
|
||||
j := 0
|
||||
for j < totalSchemas {
|
||||
select {
|
||||
case t := <-bChan:
|
||||
case r := <-bChan:
|
||||
j++
|
||||
*items = append(*items, t)
|
||||
fmt.Println("got schema", r.idx, "of", totalSchemas)
|
||||
(*items)[r.idx] = r.s
|
||||
}
|
||||
}
|
||||
doneChan <- true
|
||||
@@ -339,8 +350,9 @@ func NewSchema(schema *base.Schema) *Schema {
|
||||
|
||||
// props async
|
||||
var plock sync.Mutex
|
||||
var buildProps = func(k lowmodel.KeyReference[string], v lowmodel.ValueReference[*base.SchemaProxy], c chan bool,
|
||||
props map[string]*SchemaProxy, sw int) {
|
||||
buildProps := func(k lowmodel.KeyReference[string], v lowmodel.ValueReference[*base.SchemaProxy], c chan bool,
|
||||
props map[string]*SchemaProxy, sw int,
|
||||
) {
|
||||
plock.Lock()
|
||||
props[k.Value] = &SchemaProxy{
|
||||
schema: &lowmodel.NodeReference[*base.SchemaProxy]{
|
||||
@@ -386,14 +398,17 @@ func NewSchema(schema *base.Schema) *Schema {
|
||||
children := 0
|
||||
if !schema.AllOf.IsEmpty() {
|
||||
children++
|
||||
allOf = make([]*SchemaProxy, len(schema.AllOf.Value))
|
||||
go buildOutSchemas(schema.AllOf.Value, &allOf, polyCompletedChan, errChan)
|
||||
}
|
||||
if !schema.AnyOf.IsEmpty() {
|
||||
children++
|
||||
anyOf = make([]*SchemaProxy, len(schema.AnyOf.Value))
|
||||
go buildOutSchemas(schema.AnyOf.Value, &anyOf, polyCompletedChan, errChan)
|
||||
}
|
||||
if !schema.OneOf.IsEmpty() {
|
||||
children++
|
||||
oneOf = make([]*SchemaProxy, len(schema.OneOf.Value))
|
||||
go buildOutSchemas(schema.OneOf.Value, &oneOf, polyCompletedChan, errChan)
|
||||
}
|
||||
if !schema.Not.IsEmpty() {
|
||||
@@ -412,6 +427,7 @@ func NewSchema(schema *base.Schema) *Schema {
|
||||
}
|
||||
if !schema.PrefixItems.IsEmpty() {
|
||||
children++
|
||||
prefixItems = make([]*SchemaProxy, len(schema.PrefixItems.Value))
|
||||
go buildOutSchemas(schema.PrefixItems.Value, &prefixItems, polyCompletedChan, errChan)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@@ -21,7 +22,6 @@ func TestDynamicValue_IsA(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewSchemaProxy(t *testing.T) {
|
||||
|
||||
// check proxy
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -63,11 +63,9 @@ func TestNewSchemaProxy(t *testing.T) {
|
||||
g, o := sch1.BuildSchema()
|
||||
assert.Nil(t, g)
|
||||
assert.Error(t, o)
|
||||
|
||||
}
|
||||
|
||||
func TestNewSchemaProxy_WithObject(t *testing.T) {
|
||||
|
||||
testSpec := `type: object
|
||||
description: something object
|
||||
discriminator:
|
||||
@@ -254,14 +252,64 @@ unevaluatedProperties:
|
||||
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])
|
||||
assert.NotNil(t, compiled.Nullable)
|
||||
assert.True(t, *compiled.Nullable)
|
||||
|
||||
wentLow := compiled.GoLow()
|
||||
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) {
|
||||
|
||||
testSpec := `type: object
|
||||
description: something object
|
||||
discriminator:
|
||||
@@ -400,11 +448,9 @@ required: [cake, fish]`
|
||||
|
||||
wentLower := compiled.XML.GoLow()
|
||||
assert.Equal(t, 102, wentLower.Name.ValueNode.Line)
|
||||
|
||||
}
|
||||
|
||||
func TestSchemaProxy_GoLow(t *testing.T) {
|
||||
|
||||
const ymlComponents = `components:
|
||||
schemas:
|
||||
rice:
|
||||
@@ -471,7 +517,6 @@ type: number
|
||||
assert.Nil(t, highSchema.ExclusiveMinimum)
|
||||
assert.Nil(t, highSchema.Maximum)
|
||||
assert.Nil(t, highSchema.ExclusiveMaximum)
|
||||
|
||||
}
|
||||
|
||||
func TestSchemaNumberMultipleOf(t *testing.T) {
|
||||
@@ -574,7 +619,6 @@ examples:
|
||||
}
|
||||
|
||||
func ExampleNewSchema() {
|
||||
|
||||
// create an example schema object
|
||||
// this can be either JSON or YAML.
|
||||
yml := `
|
||||
@@ -601,11 +645,9 @@ properties:
|
||||
// print out the description of 'aProperty'
|
||||
fmt.Print(highSchema.Properties["aProperty"].Schema().Description)
|
||||
// Output: this is an integer property
|
||||
|
||||
}
|
||||
|
||||
func ExampleNewSchemaProxy() {
|
||||
|
||||
// create an example schema object
|
||||
// this can be either JSON or YAML.
|
||||
yml := `
|
||||
@@ -634,5 +676,26 @@ properties:
|
||||
// print out the description of 'aProperty'
|
||||
fmt.Print(highSchema.Schema().Properties["aProperty"].Schema().Description)
|
||||
// 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 (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"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
|
||||
@@ -46,7 +47,6 @@ func (s SchemaDynamicValue[A, B]) IsB() bool {
|
||||
// - v3 schema: https://swagger.io/specification/#schema-object
|
||||
// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
|
||||
type Schema struct {
|
||||
|
||||
// Reference to the '$schema' dialect setting (3.1 only)
|
||||
SchemaTypeRef low.NodeReference[string]
|
||||
|
||||
@@ -557,7 +557,8 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
_, schemaRefLabel, schemaRefNode := utils.FindKeyNodeFullTop(SchemaTypeLabel, root.Content)
|
||||
if schemaRefNode != nil {
|
||||
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)
|
||||
@@ -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) {
|
||||
|
||||
// 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) {
|
||||
buildProperty := func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
||||
refString string,
|
||||
) {
|
||||
c <- schemaProxyBuildResult{
|
||||
k: low.KeyReference[string]{
|
||||
KeyNode: label,
|
||||
@@ -1001,13 +1002,18 @@ func (s *Schema) extractExtensions(root *yaml.Node) {
|
||||
|
||||
// build out a child schema for parent schema.
|
||||
func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml.Node, errors chan error, idx *index.SpecIndex) {
|
||||
|
||||
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 := func(kn *yaml.Node, vn *yaml.Node, c chan *low.ValueReference[*SchemaProxy],
|
||||
isRef bool, refLocation string) {
|
||||
build := func(kn *yaml.Node, vn *yaml.Node, schemaIdx int, c chan buildResult,
|
||||
isRef bool, refLocation string,
|
||||
) {
|
||||
// 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
|
||||
// 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,
|
||||
ValueNode: vn,
|
||||
}
|
||||
c <- res
|
||||
c <- buildResult{
|
||||
res: res,
|
||||
idx: schemaIdx,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// that arrays will use.
|
||||
go build(labelNode, valueNode, syncChan, isRef, refLocation)
|
||||
go build(labelNode, valueNode, -1, syncChan, isRef, refLocation)
|
||||
select {
|
||||
case r := <-syncChan:
|
||||
schemas <- schemaProxyBuildResult{
|
||||
@@ -1054,13 +1063,15 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
||||
KeyNode: labelNode,
|
||||
Value: labelNode.Value,
|
||||
},
|
||||
v: *r,
|
||||
v: *r.res,
|
||||
}
|
||||
}
|
||||
}
|
||||
if utils.IsNodeArray(valueNode) {
|
||||
refBuilds := 0
|
||||
for _, vn := range valueNode.Content {
|
||||
results := make([]*low.ValueReference[*SchemaProxy], len(valueNode.Content))
|
||||
|
||||
for i, vn := range valueNode.Content {
|
||||
isRef = false
|
||||
h := false
|
||||
if h, _, refLocation = utils.IsNodeRefValue(vn); h {
|
||||
@@ -1076,20 +1087,25 @@ func buildSchema(schemas chan schemaProxyBuildResult, labelNode, valueNode *yaml
|
||||
}
|
||||
}
|
||||
refBuilds++
|
||||
go build(vn, vn, syncChan, isRef, refLocation)
|
||||
go build(vn, vn, i, syncChan, isRef, refLocation)
|
||||
}
|
||||
|
||||
completedBuilds := 0
|
||||
for completedBuilds < refBuilds {
|
||||
select {
|
||||
case res := <-syncChan:
|
||||
completedBuilds++
|
||||
results[res.idx] = res.res
|
||||
}
|
||||
}
|
||||
|
||||
for _, r := range results {
|
||||
schemas <- schemaProxyBuildResult{
|
||||
k: low.KeyReference[string]{
|
||||
KeyNode: labelNode,
|
||||
Value: labelNode.Value,
|
||||
},
|
||||
v: *res,
|
||||
}
|
||||
v: *r,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/pb33f/libopenapi/resolver"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func test_get_schema_blob() string {
|
||||
@@ -306,11 +308,51 @@ func Test_Schema(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
// create two versions
|
||||
testSpec := test_get_schema_blob()
|
||||
var sc1n yaml.Node
|
||||
@@ -326,11 +368,9 @@ func TestSchema_Hash(t *testing.T) {
|
||||
_ = sch2.Build(sc2n.Content[0], nil)
|
||||
|
||||
assert.Equal(t, sch1.Hash(), sch2.Hash())
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkSchema_Hash(b *testing.B) {
|
||||
|
||||
// create two versions
|
||||
testSpec := test_get_schema_blob()
|
||||
var sc1n yaml.Node
|
||||
@@ -348,7 +388,6 @@ func BenchmarkSchema_Hash(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
assert.Equal(b, sch1.Hash(), sch2.Hash())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_31(t *testing.T) {
|
||||
@@ -390,7 +429,6 @@ examples:
|
||||
assert.Equal(t, "fish/paste", sch.ContentMediaType.Value)
|
||||
assert.True(t, sch.Items.Value.IsB())
|
||||
assert.True(t, sch.Items.Value.B)
|
||||
|
||||
}
|
||||
|
||||
//func TestSchema_BuildLevel_TooDeep(t *testing.T) {
|
||||
@@ -512,7 +550,6 @@ examples:
|
||||
//}
|
||||
|
||||
func TestSchema_Build_PropsLookup(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -536,11 +573,9 @@ properties:
|
||||
err := n.Build(idxNode.Content[0], idx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "this is something", n.FindProperty("aValue").Value.Schema().Description.Value)
|
||||
|
||||
}
|
||||
|
||||
func TestSchema_Build_PropsLookup_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -563,11 +598,9 @@ properties:
|
||||
var n Schema
|
||||
err := n.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestSchema_Build_DependentSchemas_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -590,11 +623,9 @@ dependentSchemas:
|
||||
var n Schema
|
||||
err := n.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestSchema_Build_PatternProperties_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -617,11 +648,9 @@ patternProperties:
|
||||
var n Schema
|
||||
err := n.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Array_Ref(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -669,7 +698,6 @@ items:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Array_Ref_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -707,11 +735,9 @@ items:
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Map_Ref(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -759,7 +785,6 @@ items:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Map_Ref_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -797,11 +822,9 @@ items:
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_BorkParent(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -825,11 +848,9 @@ allOf:
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_BorkChild(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -853,11 +874,9 @@ allOf:
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_BorkChild_Array(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -885,11 +904,9 @@ allOf:
|
||||
assert.NoError(t, schErr)
|
||||
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())
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_RefMadness(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -918,11 +935,9 @@ allOf:
|
||||
|
||||
desc := "madness"
|
||||
assert.Equal(t, desc, sch.AllOf.Value[0].Value.Schema().Description.Value)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_RefMadnessBork(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -948,11 +963,9 @@ allOf:
|
||||
|
||||
err = sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
||||
|
||||
// this does not work, but it won't error out.
|
||||
|
||||
yml := `components:
|
||||
@@ -978,11 +991,9 @@ func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.NoError(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_RefMadnessIllegal_Circular(t *testing.T) {
|
||||
|
||||
// this does not work, but it won't error out.
|
||||
|
||||
yml := `components:
|
||||
@@ -1012,11 +1023,9 @@ func Test_Schema_RefMadnessIllegal_Circular(t *testing.T) {
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func Test_Schema_RefMadnessIllegal_Nonexist(t *testing.T) {
|
||||
|
||||
// this does not work, but it won't error out.
|
||||
|
||||
yml := `components:
|
||||
@@ -1046,11 +1055,9 @@ func Test_Schema_RefMadnessIllegal_Nonexist(t *testing.T) {
|
||||
|
||||
schErr := sch.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, schErr)
|
||||
|
||||
}
|
||||
|
||||
func TestExtractSchema(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1079,7 +1086,6 @@ func TestExtractSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_DefaultPrimitive(t *testing.T) {
|
||||
|
||||
yml := `
|
||||
schema:
|
||||
type: object
|
||||
@@ -1096,7 +1102,6 @@ schema:
|
||||
}
|
||||
|
||||
func TestExtractSchema_Ref(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1121,7 +1126,6 @@ func TestExtractSchema_Ref(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_Ref_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1144,7 +1148,6 @@ func TestExtractSchema_Ref_Fail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_CheckChildPropCircular(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1176,11 +1179,9 @@ func TestExtractSchema_CheckChildPropCircular(t *testing.T) {
|
||||
|
||||
props := res.Value.Schema().FindProperty("nothing")
|
||||
assert.NotNil(t, props)
|
||||
|
||||
}
|
||||
|
||||
func TestExtractSchema_RefRoot(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1204,7 +1205,6 @@ func TestExtractSchema_RefRoot(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1223,11 +1223,9 @@ func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
||||
|
||||
_, err := ExtractSchema(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1248,7 +1246,6 @@ func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_DoNothing(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -1267,11 +1264,9 @@ func TestExtractSchema_DoNothing(t *testing.T) {
|
||||
res, err := ExtractSchema(idxNode.Content[0], idx)
|
||||
assert.Nil(t, res)
|
||||
assert.Nil(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestExtractSchema_AdditionalProperties_Ref(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Nothing:
|
||||
@@ -1297,11 +1292,9 @@ func TestExtractSchema_AdditionalProperties_Ref(t *testing.T) {
|
||||
res, err := ExtractSchema(idxNode.Content[0], idx)
|
||||
assert.NotNil(t, res.Value.Schema().AdditionalProperties.Value.(*SchemaProxy).Schema())
|
||||
assert.Nil(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestExtractSchema_OneOfRef(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Error:
|
||||
@@ -1414,11 +1407,9 @@ func TestExtractSchema_OneOfRef(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
||||
res.Value.Schema().OneOf.Value[0].Value.Schema().Description.Value)
|
||||
|
||||
}
|
||||
|
||||
func TestSchema_Hash_Equal(t *testing.T) {
|
||||
|
||||
left := `schema:
|
||||
$schema: https://athing.com
|
||||
multipleOf: 1
|
||||
@@ -1515,11 +1506,9 @@ func TestSchema_Hash_Equal(t *testing.T) {
|
||||
rHash := rDoc.Value.Schema().Hash()
|
||||
|
||||
assert.Equal(t, lHash, rHash)
|
||||
|
||||
}
|
||||
|
||||
func TestSchema_Hash_NotEqual(t *testing.T) {
|
||||
|
||||
left := `schema:
|
||||
title: an OK message - but different
|
||||
items: true
|
||||
@@ -1551,7 +1540,6 @@ func TestSchema_Hash_NotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSchema_Hash_EqualJumbled(t *testing.T) {
|
||||
|
||||
left := `schema:
|
||||
title: an OK message
|
||||
description: a nice thing.
|
||||
@@ -1585,5 +1573,17 @@ func TestSchema_Hash_EqualJumbled(t *testing.T) {
|
||||
lDoc, _ := ExtractSchema(lNode.Content[0], nil)
|
||||
rDoc, _ := ExtractSchema(rNode.Content[0], nil)
|
||||
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