diff --git a/index/resolver.go b/index/resolver.go index cad15f1..e8412fa 100644 --- a/index/resolver.go +++ b/index/resolver.go @@ -489,7 +489,12 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No var found []*Reference if len(node.Content) > 0 { + skip := false for i, n := range node.Content { + if skip { + skip = false + continue + } if utils.IsNodeMap(n) || utils.IsNodeArray(n) { depth++ @@ -790,7 +795,8 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No } } } - break + skip = true + continue } } } diff --git a/index/resolver_test.go b/index/resolver_test.go index 6c9c258..38120b0 100644 --- a/index/resolver_test.go +++ b/index/resolver_test.go @@ -98,7 +98,7 @@ func Benchmark_ResolveDocumentStripe(b *testing.B) { rolo.SetRootNode(&rootNode) indexedErr := rolo.IndexTheRolodex() - assert.Len(b, utils.UnwrapErrors(indexedErr), 3) + assert.Len(b, utils.UnwrapErrors(indexedErr), 1) } } @@ -1270,3 +1270,106 @@ paths: assert.Equal(t, nodes[0].Content[1].Value, "message") } + +func TestDocument_LoopThroughAnArray(t *testing.T) { + + var d = `openapi: "3.0.1" +components: + schemas: + B: + type: object + properties: + children: + type: array + items: + $ref: '#/components/schemas/B'` + + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) + + config := CreateClosedAPIIndexConfig() + config.IgnoreArrayCircularReferences = true + idx := NewSpecIndexWithConfig(&rootNode, config) + + resolver := NewResolver(idx) + resolver.IgnoreArrayCircularReferences() + assert.NotNil(t, resolver) + + circ := resolver.Resolve() + assert.Len(t, circ, 0) + assert.Len(t, resolver.GetIgnoredCircularArrayReferences(), 1) + +} + +func TestDocument_ObjectWithPolyAndArray(t *testing.T) { + + var d = `openapi: "3.0.1" +components: + schemas: + A: + type: object + properties: {} + B: + type: object + allOf: + - $ref: '#/components/schemas/A' + properties: + children: + type: array + items: + $ref: '#/components/schemas/B'` + + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) + + config := CreateClosedAPIIndexConfig() + config.IgnoreArrayCircularReferences = true + idx := NewSpecIndexWithConfig(&rootNode, config) + + resolver := NewResolver(idx) + resolver.IgnoreArrayCircularReferences() + assert.NotNil(t, resolver) + + circ := resolver.Resolve() + assert.Len(t, circ, 0) + assert.Len(t, resolver.GetIgnoredCircularArrayReferences(), 1) + +} + +func TestDocument_ObjectWithMultiPolyAndArray(t *testing.T) { + + var d = `openapi: "3.0.1" +components: + schemas: + A: + type: object + properties: {} + B: + type: object + allOf: + - $ref: '#/components/schemas/A' + oneOf: + - $ref: '#/components/schemas/B' + properties: + children: + type: array + items: + $ref: '#/components/schemas/B'` + + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) + + config := CreateClosedAPIIndexConfig() + config.IgnoreArrayCircularReferences = true + idx := NewSpecIndexWithConfig(&rootNode, config) + + resolver := NewResolver(idx) + resolver.IgnoreArrayCircularReferences() + assert.NotNil(t, resolver) + + circ := resolver.Resolve() + assert.Len(t, circ, 0) + assert.Len(t, resolver.GetSafeCircularReferences(), 1) + assert.Len(t, resolver.GetIgnoredCircularArrayReferences(), 0) + +} diff --git a/index/rolodex_test.go b/index/rolodex_test.go index 47a3116..5cb20b1 100644 --- a/index/rolodex_test.go +++ b/index/rolodex_test.go @@ -1233,13 +1233,13 @@ components: tmp := "tmp-g" _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + firstFile, fErr = os.CreateTemp(tmp, "first-*.yaml") assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + secondFile, fErr = os.CreateTemp(tmp, "second-*.yaml") assert.NoError(t, fErr) - thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") + thirdFile, fErr = os.CreateTemp(tmp, "third-*.yaml") assert.NoError(t, fErr) first = strings.ReplaceAll(first, "$2", secondFile.Name()) @@ -1257,6 +1257,7 @@ components: cf := CreateOpenAPIIndexConfig() cf.IgnorePolymorphicCircularReferences = true + cf.ExtractRefsSequentially = true rolodex := NewRolodex(cf) baseDir := tmp