diff --git a/datamodel/high/base/schema.go b/datamodel/high/base/schema.go index edebf8c..712f365 100644 --- a/datamodel/high/base/schema.go +++ b/datamodel/high/base/schema.go @@ -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 @@ -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 // all variations into a single model that makes it easy to support multiple spec types. // -// - v2 schema: https://swagger.io/specification/v2/#schemaObject -// - v3 schema: https://swagger.io/specification/#schema-object -// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object +// - v2 schema: https://swagger.io/specification/v2/#schemaObject +// - 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) } diff --git a/datamodel/high/base/schema_test.go b/datamodel/high/base/schema_test.go index 76a1255..e806a44 100644 --- a/datamodel/high/base/schema_test.go +++ b/datamodel/high/base/schema_test.go @@ -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 +` } diff --git a/datamodel/low/base/schema.go b/datamodel/low/base/schema.go index df0fe41..4bbb246 100644 --- a/datamodel/low/base/schema.go +++ b/datamodel/low/base/schema.go @@ -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 @@ -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 // all variations into a single model that makes it easy to support multiple spec types. // -// - v2 schema: https://swagger.io/specification/v2/#schemaObject -// - v3 schema: https://swagger.io/specification/#schema-object -// - v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object +// - v2 schema: https://swagger.io/specification/v2/#schemaObject +// - 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] @@ -445,27 +445,27 @@ func (s *Schema) GetExtensions() map[low.KeyReference[string]]low.ValueReference // Build will perform a number of operations. // Extraction of the following happens in this method: -// - Extensions -// - Type -// - ExclusiveMinimum and ExclusiveMaximum -// - Examples -// - AdditionalProperties -// - Discriminator -// - ExternalDocs -// - XML -// - Properties -// - AllOf, OneOf, AnyOf -// - Not -// - Items -// - PrefixItems -// - If -// - Else -// - Then -// - DependentSchemas -// - PatternProperties -// - PropertyNames -// - UnevaluatedItems -// - UnevaluatedProperties +// - Extensions +// - Type +// - ExclusiveMinimum and ExclusiveMaximum +// - Examples +// - AdditionalProperties +// - Discriminator +// - ExternalDocs +// - XML +// - Properties +// - AllOf, OneOf, AnyOf +// - Not +// - Items +// - PrefixItems +// - If +// - Else +// - Then +// - DependentSchemas +// - PatternProperties +// - PropertyNames +// - UnevaluatedItems +// - UnevaluatedProperties func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error { if h, _, _ := utils.IsNodeRefValue(root); h { 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) 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++ - schemas <- schemaProxyBuildResult{ - k: low.KeyReference[string]{ - KeyNode: labelNode, - Value: labelNode.Value, - }, - v: *res, - } + results[res.idx] = res.res + } + } + + for _, r := range results { + schemas <- schemaProxyBuildResult{ + k: low.KeyReference[string]{ + KeyNode: labelNode, + Value: labelNode.Value, + }, + v: *r, } } } diff --git a/datamodel/low/base/schema_test.go b/datamodel/low/base/schema_test.go index 8409a42..2237554 100644 --- a/datamodel/low/base/schema_test.go +++ b/datamodel/low/base/schema_test.go @@ -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,12 +308,52 @@ 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 + // create two versions testSpec := test_get_schema_blob() var sc1n yaml.Node _ = yaml.Unmarshal([]byte(testSpec), &sc1n) @@ -326,12 +368,10 @@ 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 + // create two versions testSpec := test_get_schema_blob() var sc1n yaml.Node _ = yaml.Unmarshal([]byte(testSpec), &sc1n) @@ -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 +` }