Bumping test coverage

There are issues with circular references at scale, there may need to be a change after this commit.
This commit is contained in:
Dave Shanley
2022-08-26 09:49:48 -04:00
parent 081fc9be56
commit 6e0d25776a
13 changed files with 268 additions and 13 deletions

View File

@@ -39,9 +39,9 @@ func NewDocument(document *low.Document) *Document {
if !document.ExternalDocs.IsEmpty() { if !document.ExternalDocs.IsEmpty() {
d.ExternalDocs = NewExternalDoc(document.ExternalDocs.Value) d.ExternalDocs = NewExternalDoc(document.ExternalDocs.Value)
} }
d.Paths = NewPaths(document.Paths.Value)
d.Extensions = high.ExtractExtensions(document.Extensions) d.Extensions = high.ExtractExtensions(document.Extensions)
d.Components = NewComponents(document.Components.Value) d.Components = NewComponents(document.Components.Value)
d.Paths = NewPaths(document.Paths.Value)
return d return d
} }

View File

@@ -4,6 +4,7 @@
package v3 package v3
import ( import (
"fmt"
"github.com/pb33f/libopenapi/datamodel" "github.com/pb33f/libopenapi/datamodel"
lowv3 "github.com/pb33f/libopenapi/datamodel/low/3.0" lowv3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -183,6 +184,12 @@ func TestNewDocument_Components_Schemas(t *testing.T) {
assert.True(t, d.AdditionalProperties.(bool)) assert.True(t, d.AdditionalProperties.(bool))
assert.Equal(t, "drinkType", d.Discriminator.PropertyName) assert.Equal(t, "drinkType", d.Discriminator.PropertyName)
assert.Equal(t, "some value", d.Discriminator.Mapping["drink"]) assert.Equal(t, "some value", d.Discriminator.Mapping["drink"])
assert.Equal(t, 511, d.Discriminator.GoLow().PropertyName.ValueNode.Line)
assert.Equal(t, 23, d.Discriminator.GoLow().PropertyName.ValueNode.Column)
pl := h.Components.Schemas["SomePayload"]
assert.Equal(t, "is html programming? yes.", pl.XML.Name)
assert.Equal(t, 518, pl.XML.GoLow().Name.ValueNode.Line)
ext := h.Components.Extensions ext := h.Components.Extensions
assert.Equal(t, "loud", ext["x-screaming-baby"]) assert.Equal(t, "loud", ext["x-screaming-baby"])
@@ -220,7 +227,7 @@ func TestNewDocument_Components_Responses(t *testing.T) {
assert.Equal(t, "all the dressings for a burger.", h.Components.Responses["DressingResponse"].Description) assert.Equal(t, "all the dressings for a burger.", h.Components.Responses["DressingResponse"].Description)
assert.Equal(t, "array", h.Components.Responses["DressingResponse"].Content["application/json"].Schema.Type) assert.Equal(t, "array", h.Components.Responses["DressingResponse"].Content["application/json"].Schema.Type)
assert.Equal(t, 347, h.Components.Responses["DressingResponse"].GoLow().Description.KeyNode.Line) assert.Equal(t, 347, h.Components.Responses["DressingResponse"].GoLow().Description.KeyNode.Line)
assert.Equal(t, 7, h.Components.Examples["QuarterPounder"].GoLow().Summary.KeyNode.Column) assert.Equal(t, 7, h.Components.Responses["DressingResponse"].GoLow().Description.KeyNode.Column)
} }
func TestNewDocument_Components_SecuritySchemes(t *testing.T) { func TestNewDocument_Components_SecuritySchemes(t *testing.T) {
@@ -265,6 +272,8 @@ func TestNewDocument_Components_Parameters(t *testing.T) {
assert.Equal(t, "this is a header", assert.Equal(t, "this is a header",
bh.Content["application/json"].Encoding["burgerTheme"].Headers["someHeader"].Description) bh.Content["application/json"].Encoding["burgerTheme"].Headers["someHeader"].Description)
assert.Len(t, bh.Content["application/json"].Schema.Properties, 2) assert.Len(t, bh.Content["application/json"].Schema.Properties, 2)
assert.Equal(t, 404, bh.Content["application/json"].Encoding["burgerTheme"].GoLow().ContentType.ValueNode.Line)
} }
func TestNewDocument_Paths(t *testing.T) { func TestNewDocument_Paths(t *testing.T) {
@@ -285,6 +294,7 @@ func TestNewDocument_Paths(t *testing.T) {
assert.Equal(t, "A new burger for our menu, yummy yum yum.", burgersOp.Post.Description) assert.Equal(t, "A new burger for our menu, yummy yum yum.", burgersOp.Post.Description)
assert.Equal(t, "Give us the new burger!", burgersOp.Post.RequestBody.Description) assert.Equal(t, "Give us the new burger!", burgersOp.Post.RequestBody.Description)
assert.Len(t, burgersOp.Post.Responses.Codes, 3) assert.Len(t, burgersOp.Post.Responses.Codes, 3)
assert.Equal(t, 63, h.Paths.GoLow().FindPath("/burgers").ValueNode.Line)
okResp := burgersOp.Post.Responses.FindResponseByCode(200) okResp := burgersOp.Post.Responses.FindResponseByCode(200)
assert.Len(t, okResp.Headers, 1) assert.Len(t, okResp.Headers, 1)
@@ -293,6 +303,11 @@ func TestNewDocument_Paths(t *testing.T) {
assert.Len(t, okResp.Content["application/json"].Examples, 2) assert.Len(t, okResp.Content["application/json"].Examples, 2)
assert.Equal(t, "a cripsy fish sammich filled with ocean goodness.", assert.Equal(t, "a cripsy fish sammich filled with ocean goodness.",
okResp.Content["application/json"].Examples["filetOFish"].Summary) okResp.Content["application/json"].Examples["filetOFish"].Summary)
assert.Equal(t, 74, burgersOp.Post.Responses.GoLow().FindResponseByCode("200").ValueNode.Line)
assert.Equal(t, 80, okResp.Content["application/json"].GoLow().Schema.KeyNode.Line)
assert.Equal(t, 15, okResp.Content["application/json"].GoLow().Schema.KeyNode.Column)
assert.Equal(t, 77, okResp.GoLow().Description.KeyNode.Line) assert.Equal(t, 77, okResp.GoLow().Description.KeyNode.Line)
assert.Len(t, okResp.Links, 2) assert.Len(t, okResp.Links, 2)
assert.Equal(t, "locateBurger", okResp.Links["LocateBurger"].OperationId) assert.Equal(t, "locateBurger", okResp.Links["LocateBurger"].OperationId)
@@ -305,3 +320,16 @@ func TestNewDocument_Paths(t *testing.T) {
assert.Equal(t, "https://pb33f.io", burgersOp.Post.Servers[0].URL) assert.Equal(t, "https://pb33f.io", burgersOp.Post.Servers[0].URL)
} }
func TestStripeAsDoc(t *testing.T) {
data, _ := ioutil.ReadFile("../../../test_specs/stripe.yaml")
info, _ := datamodel.ExtractSpecInfo(data)
var err []error
doc, err = lowv3.CreateDocument(info)
if err != nil {
panic("broken something")
}
d := NewDocument(doc)
fmt.Println(d)
}

View File

@@ -21,8 +21,12 @@ func NewInfo(info *low.Info) *Info {
i.Title = info.Title.Value i.Title = info.Title.Value
i.Description = info.Description.Value i.Description = info.Description.Value
i.TermsOfService = info.TermsOfService.Value i.TermsOfService = info.TermsOfService.Value
i.Contact = NewContact(info.Contact.Value) if !info.Contact.IsEmpty() {
i.License = NewLicense(info.License.Value) i.Contact = NewContact(info.Contact.Value)
}
if !info.License.IsEmpty() {
i.License = NewLicense(info.License.Value)
}
i.Version = info.Version.Value i.Version = info.Version.Value
return i return i
} }

View File

@@ -14,8 +14,12 @@ type License struct {
func NewLicense(license *low.License) *License { func NewLicense(license *low.License) *License {
l := new(License) l := new(License)
l.low = license l.low = license
l.URL = license.URL.Value if !license.URL.IsEmpty() {
l.Name = license.Name.Value l.URL = license.URL.Value
}
if !license.Name.IsEmpty() {
l.Name = license.Name.Value
}
return l return l
} }

View File

@@ -0,0 +1,38 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
// this test exists because the sample contract doesn't contain an
// operation with *everything* populated, I had already written a ton of tests
// with hard coded line and column numbers in them, changing the spec above the bottom will
// create pointless test changes. So here is a standalone test. you know... for science.
func TestOperation(t *testing.T) {
yml := `externalDocs:
url: https://pb33f.io`
var idxNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &idxNode)
idx := index.NewSpecIndex(&idxNode)
var n v3.Operation
_ = low.BuildModel(&idxNode, &n)
_ = n.Build(idxNode.Content[0], idx)
r := NewOperation(&n)
assert.Equal(t, "https://pb33f.io", r.ExternalDocs.URL)
assert.Equal(t, 1, r.GoLow().ExternalDocs.KeyNode.Line)
}

View File

@@ -0,0 +1,37 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
// this test exists because the sample contract doesn't contain a
// response with *everything* populated, I had already written a ton of tests
// with hard coded line and column numbers in them, changing the spec above the bottom will
// create pointless test changes. So here is a standalone test. you know... for science.
func TestPathItem(t *testing.T) {
yml := `servers:
- description: so many options for things in places.`
var idxNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &idxNode)
idx := index.NewSpecIndex(&idxNode)
var n v3.PathItem
_ = low.BuildModel(&idxNode, &n)
_ = n.Build(idxNode.Content[0], idx)
r := NewPathItem(&n)
assert.Len(t, r.Servers, 1)
assert.Equal(t, "so many options for things in places.", r.Servers[0].Description)
assert.Equal(t, 1, r.GoLow().Servers.KeyNode.Line)
}

View File

@@ -0,0 +1,38 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
// this test exists because the sample contract doesn't contain a
// responses with *everything* populated, I had already written a ton of tests
// with hard coded line and column numbers in them, changing the spec above the bottom will
// create pointless test changes. So here is a standalone test. you know... for science.
func TestNewResponses(t *testing.T) {
yml := `default:
description: default response`
var idxNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &idxNode)
idx := index.NewSpecIndex(&idxNode)
var n v3.Responses
_ = low.BuildModel(&idxNode, &n)
_ = n.Build(idxNode.Content[0], idx)
r := NewResponses(&n)
assert.Equal(t, "default response", r.Default.Description)
assert.Equal(t, 1, r.GoLow().Default.KeyNode.Line)
}

View File

@@ -0,0 +1,53 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestNewSchema(t *testing.T) {
// tests async schema lookup, by essentially running it twice, without a cache cleanup.
yml := `components:
schemas:
rice:
type: string
nice:
properties:
rice:
$ref: '#/components/schemas/rice'
ice:
properties:
rice:
$ref: '#/components/schemas/rice'`
var idxNode, compNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
yml = `properties:
rice:
$ref: '#/components/schemas/rice'`
var n v3.Schema
_ = yaml.Unmarshal([]byte(yml), &compNode)
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.NoError(t, err)
sch1 := NewSchema(&n)
sch2 := NewSchema(&n)
assert.Equal(t, sch1, sch2)
}

View File

@@ -156,3 +156,24 @@ func TestComponents_Build_Fail_TypeFail(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
} }
func TestComponents_Build_ExtensionTest(t *testing.T) {
yml := `x-curry: seagull
headers:
x-curry-gull: vinadloo`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Components
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.NoError(t, err)
assert.Equal(t, "seagull", n.FindExtension("x-curry").Value)
}

View File

@@ -468,3 +468,17 @@ func TestCreateDocument_CheckAdditionalProperties_Bool(t *testing.T) {
assert.NotNil(t, d.Value.AdditionalProperties.Value) assert.NotNil(t, d.Value.AdditionalProperties.Value)
assert.True(t, d.Value.AdditionalProperties.Value.(bool)) assert.True(t, d.Value.AdditionalProperties.Value.(bool))
} }
func TestCreateDocument_Components_Error(t *testing.T) {
yml := `components:
schemas:
bork:
properties:
bark:
$ref: #bork`
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
assert.Len(t, err, 1)
}

View File

@@ -15,6 +15,5 @@ type License struct {
} }
func (l *License) Build(root *yaml.Node, idx *index.SpecIndex) error { func (l *License) Build(root *yaml.Node, idx *index.SpecIndex) error {
// not implemented.
return nil return nil
} }

View File

@@ -56,6 +56,29 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
} }
_, ln, vn = utils.FindKeyNodeFull(ServersLabel, root.Content)
if vn != nil {
if utils.IsNodeArray(vn) {
var servers []low.ValueReference[*Server]
for _, srvN := range vn.Content {
if utils.IsNodeMap(srvN) {
srvr := new(Server)
_ = low.BuildModel(srvN, srvr)
srvr.Build(srvN, idx)
servers = append(servers, low.ValueReference[*Server]{
Value: srvr,
ValueNode: srvN,
})
}
}
p.Servers = low.NodeReference[[]low.ValueReference[*Server]]{
Value: servers,
KeyNode: ln,
ValueNode: vn,
}
}
}
for i, pathNode := range root.Content { for i, pathNode := range root.Content {
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") { if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
skip = true skip = true

View File

@@ -29,11 +29,7 @@ func (t *Tag) Build(root *yaml.Node, idx *index.SpecIndex) error {
t.Extensions = low.ExtractExtensions(root) t.Extensions = low.ExtractExtensions(root)
// extract externalDocs // extract externalDocs
extDocs, dErr := low.ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx) extDocs, err := low.ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx)
if dErr != nil {
return dErr
}
t.ExternalDocs = extDocs t.ExternalDocs = extDocs
return err
return nil
} }