diff --git a/datamodel/high/base/schema_proxy_test.go b/datamodel/high/base/schema_proxy_test.go index b52ddbe..46dcac6 100644 --- a/datamodel/high/base/schema_proxy_test.go +++ b/datamodel/high/base/schema_proxy_test.go @@ -4,21 +4,21 @@ package base import ( - "context" - "strings" - "testing" + "context" + "strings" + "testing" - "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" - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" + "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" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" ) func TestSchemaProxy_MarshalYAML(t *testing.T) { - const ymlComponents = `components: + const ymlComponents = `components: schemas: rice: type: string @@ -31,99 +31,99 @@ func TestSchemaProxy_MarshalYAML(t *testing.T) { rice: $ref: '#/components/schemas/rice'` - idx := func() *index.SpecIndex { - var idxNode yaml.Node - err := yaml.Unmarshal([]byte(ymlComponents), &idxNode) - assert.NoError(t, err) - return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig()) - }() + idx := func() *index.SpecIndex { + var idxNode yaml.Node + err := yaml.Unmarshal([]byte(ymlComponents), &idxNode) + assert.NoError(t, err) + return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig()) + }() - const ref = "#/components/schemas/nice" - const ymlSchema = `$ref: '` + ref + `'` - var node yaml.Node - _ = yaml.Unmarshal([]byte(ymlSchema), &node) + const ref = "#/components/schemas/nice" + const ymlSchema = `$ref: '` + ref + `'` + var node yaml.Node + _ = yaml.Unmarshal([]byte(ymlSchema), &node) - lowProxy := new(lowbase.SchemaProxy) - err := lowProxy.Build(context.Background(), nil, node.Content[0], idx) - assert.NoError(t, err) + lowProxy := new(lowbase.SchemaProxy) + err := lowProxy.Build(context.Background(), nil, node.Content[0], idx) + assert.NoError(t, err) - lowRef := low.NodeReference[*lowbase.SchemaProxy]{ - Value: lowProxy, - } + lowRef := low.NodeReference[*lowbase.SchemaProxy]{ + Value: lowProxy, + } - sp := NewSchemaProxy(&lowRef) + sp := NewSchemaProxy(&lowRef) - origin := sp.GetReferenceOrigin() - assert.Nil(t, origin) + origin := sp.GetReferenceOrigin() + assert.Nil(t, origin) - rend, _ := sp.Render() - assert.Equal(t, "$ref: '#/components/schemas/nice'", strings.TrimSpace(string(rend))) + rend, _ := sp.Render() + assert.Equal(t, "$ref: '#/components/schemas/nice'", strings.TrimSpace(string(rend))) } func TestCreateSchemaProxy(t *testing.T) { - sp := CreateSchemaProxy(&Schema{Description: "iAmASchema"}) - assert.Equal(t, "iAmASchema", sp.rendered.Description) - assert.False(t, sp.IsReference()) + sp := CreateSchemaProxy(&Schema{Description: "iAmASchema"}) + assert.Equal(t, "iAmASchema", sp.rendered.Description) + assert.False(t, sp.IsReference()) } func TestCreateSchemaProxyRef(t *testing.T) { - sp := CreateSchemaProxyRef("#/components/schemas/MySchema") - assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference()) - assert.True(t, sp.IsReference()) + sp := CreateSchemaProxyRef("#/components/schemas/MySchema") + assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference()) + assert.True(t, sp.IsReference()) } func TestSchemaProxy_GetReference(t *testing.T) { - refNode := utils.CreateStringNode("#/components/schemas/MySchema") + refNode := utils.CreateStringNode("#/components/schemas/MySchema") - ref := low.Reference{} - ref.SetReference("#/components/schemas/MySchema", refNode) + ref := low.Reference{} + ref.SetReference("#/components/schemas/MySchema", refNode) - sp := &SchemaProxy{ - schema: &low.NodeReference[*lowbase.SchemaProxy]{ - Value: &lowbase.SchemaProxy{ - Reference: ref, - }, - }, - } - assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference()) - assert.Equal(t, refNode, sp.GetReferenceNode()) + sp := &SchemaProxy{ + schema: &low.NodeReference[*lowbase.SchemaProxy]{ + Value: &lowbase.SchemaProxy{ + Reference: ref, + }, + }, + } + assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference()) + assert.Equal(t, refNode, sp.GetReferenceNode()) } func TestSchemaProxy_IsReference_Nil(t *testing.T) { - var sp *SchemaProxy - assert.False(t, sp.IsReference()) + var sp *SchemaProxy + assert.False(t, sp.IsReference()) } func TestSchemaProxy_NoSchema_GetOrigin(t *testing.T) { - sp := &SchemaProxy{} - assert.Nil(t, sp.GetReferenceOrigin()) + sp := &SchemaProxy{} + assert.Nil(t, sp.GetReferenceOrigin()) } func TestCreateSchemaProxyRef_GetReferenceNode(t *testing.T) { - refNode := utils.CreateRefNode("#/components/schemas/MySchema") + refNode := utils.CreateRefNode("#/components/schemas/MySchema") - sp := CreateSchemaProxyRef("#/components/schemas/MySchema") - assert.Equal(t, refNode, sp.GetReferenceNode()) + sp := CreateSchemaProxyRef("#/components/schemas/MySchema") + assert.Equal(t, refNode, sp.GetReferenceNode()) } func TestCreateRefNode_MarshalYAML(t *testing.T) { - ref := low.Reference{} - ref.SetReference("#/components/schemas/MySchema", nil) + ref := low.Reference{} + ref.SetReference("#/components/schemas/MySchema", nil) - sp := &SchemaProxy{ - schema: &low.NodeReference[*lowbase.SchemaProxy]{ - Value: &lowbase.SchemaProxy{ - Reference: ref, - }, - }, - } - node, err := sp.MarshalYAML() - require.NoError(t, err) - assert.Equal(t, node, utils.CreateRefNode("#/components/schemas/MySchema")) + sp := &SchemaProxy{ + schema: &low.NodeReference[*lowbase.SchemaProxy]{ + Value: &lowbase.SchemaProxy{ + Reference: ref, + }, + }, + } + node, err := sp.MarshalYAML() + require.NoError(t, err) + assert.Equal(t, node, utils.CreateRefNode("#/components/schemas/MySchema")) } func TestSchemaProxy_MarshalYAML_InlineCircular(t *testing.T) { - const ymlComponents = `openapi: 3.1 + const ymlComponents = `openapi: 3.1 components: schemas: spice: @@ -135,37 +135,37 @@ components: rice: $ref: '#/components/schemas/nice'` - idx := func() *index.SpecIndex { - var idxNode yaml.Node - err := yaml.Unmarshal([]byte(ymlComponents), &idxNode) - assert.NoError(t, err) - return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig()) - }() + idx := func() *index.SpecIndex { + var idxNode yaml.Node + err := yaml.Unmarshal([]byte(ymlComponents), &idxNode) + assert.NoError(t, err) + return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig()) + }() - resolver := index.NewResolver(idx) - resolver.CheckForCircularReferences() + resolver := index.NewResolver(idx) + resolver.CheckForCircularReferences() - const ymlSchema = `properties: + const ymlSchema = `properties: rice: $ref: '#/components/schemas/nice'` - var node yaml.Node - _ = yaml.Unmarshal([]byte(ymlSchema), &node) + var node yaml.Node + _ = yaml.Unmarshal([]byte(ymlSchema), &node) - lowProxy := new(lowbase.SchemaProxy) - err := lowProxy.Build(context.Background(), &node, node.Content[0], idx) - assert.NoError(t, err) + lowProxy := new(lowbase.SchemaProxy) + err := lowProxy.Build(context.Background(), &node, node.Content[0], idx) + assert.NoError(t, err) - lowRef := low.NodeReference[*lowbase.SchemaProxy]{ - Value: lowProxy, - KeyNode: &node, - } + lowRef := low.NodeReference[*lowbase.SchemaProxy]{ + Value: lowProxy, + KeyNode: &node, + } - spEmpty := NewSchemaProxy(nil) - assert.Nil(t, spEmpty.GetSchemaKeyNode()) + spEmpty := NewSchemaProxy(nil) + assert.Nil(t, spEmpty.GetSchemaKeyNode()) - sp := NewSchemaProxy(&lowRef) - assert.NotNil(t, sp.GetSchemaKeyNode()) + sp := NewSchemaProxy(&lowRef) + assert.NotNil(t, sp.GetSchemaKeyNode()) - rend, _ := sp.MarshalYAMLInline() - assert.NotNil(t, rend) + rend, _ := sp.MarshalYAMLInline() + assert.NotNil(t, rend) } diff --git a/utils/utils.go b/utils/utils.go index 8acb272..ddcf997 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -114,24 +114,17 @@ func FindNodesWithoutDeserializing(node *yaml.Node, jsonPath string) ([]*yaml.No // this can spin out, to lets gatekeep it. done := make(chan bool) - eChan := make(chan error) var results []*yaml.Node timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() - go func(d chan bool, e chan error) { - var er error - results, er = path.Find(node) - if er != nil { - e <- er - } + go func(d chan bool) { + results, _ = path.Find(node) done <- true - }(done, eChan) + }(done) select { case <-done: return results, nil - case er := <-eChan: - return nil, er case <-timeout.Done(): return nil, fmt.Errorf("node lookup timeout exceeded") } diff --git a/utils/utils_test.go b/utils/utils_test.go index 97a53b8..9243930 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -913,3 +913,20 @@ func TestDetermineJSONWhitespaceLength_None(t *testing.T) { someBytes := []byte(`{"hello": "world"}`) assert.Equal(t, 0, DetermineWhitespaceLength(string(someBytes))) } + +func TestTimeoutFind(t *testing.T) { + a := &yaml.Node{ + Value: "chicken", + } + b := &yaml.Node{ + Value: "nuggets", + } + + // loopy loop. + a.Content = append(a.Content, b) + b.Content = append(b.Content, a) + + nodes, err := FindNodesWithoutDeserializing(a, "$..nuggets") + assert.Error(t, err) + assert.Nil(t, nodes) +}