mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 12:37:49 +00:00
Full model is now in place,
Time to revisit each model and build individual tests to ensure all error handling is in place across the model. Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
@@ -10,6 +10,10 @@ type Callback struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
func (cb *Callback) FindExpression(exp string) *low.ValueReference[*PathItem] {
|
||||
return FindItemInMap[*PathItem](exp, cb.Expression.Value)
|
||||
}
|
||||
|
||||
func (cb *Callback) Build(root *yaml.Node) error {
|
||||
extensionMap, err := ExtractExtensions(root)
|
||||
if err != nil {
|
||||
|
||||
@@ -36,6 +36,26 @@ func (co *Components) FindSecurityScheme(sScheme string) *low.ValueReference[*Se
|
||||
return FindItemInMap[*SecurityScheme](sScheme, co.SecuritySchemes.Value)
|
||||
}
|
||||
|
||||
func (co *Components) FindExample(example string) *low.ValueReference[*Example] {
|
||||
return FindItemInMap[*Example](example, co.Examples.Value)
|
||||
}
|
||||
|
||||
func (co *Components) FindRequestBody(requestBody string) *low.ValueReference[*RequestBody] {
|
||||
return FindItemInMap[*RequestBody](requestBody, co.RequestBodies.Value)
|
||||
}
|
||||
|
||||
func (co *Components) FindHeader(header string) *low.ValueReference[*Header] {
|
||||
return FindItemInMap[*Header](header, co.Headers.Value)
|
||||
}
|
||||
|
||||
func (co *Components) FindLink(link string) *low.ValueReference[*Link] {
|
||||
return FindItemInMap[*Link](link, co.Links.Value)
|
||||
}
|
||||
|
||||
func (co *Components) FindCallback(callback string) *low.ValueReference[*Callback] {
|
||||
return FindItemInMap[*Callback](callback, co.Callbacks.Value)
|
||||
}
|
||||
|
||||
func (co *Components) Build(root *yaml.Node) error {
|
||||
extensionMap, err := ExtractExtensions(root)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
|
||||
type Discriminator struct {
|
||||
PropertyName low.NodeReference[string]
|
||||
Mapping map[low.NodeReference[string]]low.NodeReference[string]
|
||||
Mapping map[low.KeyReference[string]]low.ValueReference[string]
|
||||
}
|
||||
|
||||
func (d *Discriminator) FindMappingValue(key string) *low.NodeReference[string] {
|
||||
func (d *Discriminator) FindMappingValue(key string) *low.ValueReference[string] {
|
||||
for k, v := range d.Mapping {
|
||||
if k.Value == key {
|
||||
return &v
|
||||
|
||||
@@ -10,8 +10,8 @@ type Document struct {
|
||||
Servers low.NodeReference[[]low.ValueReference[*Server]]
|
||||
Paths low.NodeReference[*Paths]
|
||||
Components low.NodeReference[*Components]
|
||||
Security []*SecurityRequirement
|
||||
Tags []low.NodeReference[*Tag]
|
||||
ExternalDocs *ExternalDoc
|
||||
Security low.NodeReference[*SecurityRequirement]
|
||||
Tags low.NodeReference[[]low.ValueReference[*Tag]]
|
||||
ExternalDocs low.NodeReference[*ExternalDoc]
|
||||
Extensions map[low.NodeReference[string]]low.NodeReference[any]
|
||||
}
|
||||
|
||||
@@ -9,17 +9,6 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func FindItemInCollection[T any](item string, collection map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[T]) *low.ValueReference[T] {
|
||||
for _, c := range collection {
|
||||
for n, o := range c {
|
||||
if n.Value == item {
|
||||
return &o
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]low.ValueReference[T]) *low.ValueReference[T] {
|
||||
for n, o := range collection {
|
||||
if n.Value == item {
|
||||
|
||||
@@ -61,11 +61,11 @@ func BuildModel(node *yaml.Node, model interface{}) error {
|
||||
func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) error {
|
||||
switch field.Type() {
|
||||
|
||||
case reflect.TypeOf(map[string]low.ObjectReference{}):
|
||||
case reflect.TypeOf(map[string]low.NodeReference[any]{}):
|
||||
if valueNode != nil {
|
||||
if utils.IsNodeMap(valueNode) {
|
||||
if field.CanSet() {
|
||||
items := make(map[string]low.ObjectReference)
|
||||
items := make(map[string]low.NodeReference[any])
|
||||
var currentLabel string
|
||||
for i, sliceItem := range valueNode.Content {
|
||||
if i%2 == 0 {
|
||||
@@ -77,7 +77,7 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items[currentLabel] = low.ObjectReference{
|
||||
items[currentLabel] = low.NodeReference[any]{
|
||||
Value: decoded,
|
||||
ValueNode: sliceItem,
|
||||
KeyNode: valueNode,
|
||||
@@ -111,33 +111,33 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
|
||||
}
|
||||
}
|
||||
break
|
||||
case reflect.TypeOf(low.ObjectReference{}):
|
||||
case reflect.TypeOf(low.NodeReference[any]{}):
|
||||
if valueNode != nil {
|
||||
var decoded map[string]interface{}
|
||||
var decoded interface{}
|
||||
err := valueNode.Decode(&decoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if utils.IsNodeMap(valueNode) {
|
||||
if field.CanSet() {
|
||||
or := low.ObjectReference{Value: decoded, ValueNode: valueNode}
|
||||
or := low.NodeReference[any]{Value: decoded, ValueNode: valueNode}
|
||||
field.Set(reflect.ValueOf(or))
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
case reflect.TypeOf([]low.ObjectReference{}):
|
||||
case reflect.TypeOf([]low.NodeReference[any]{}):
|
||||
if valueNode != nil {
|
||||
if utils.IsNodeArray(valueNode) {
|
||||
if field.CanSet() {
|
||||
var items []low.ObjectReference
|
||||
var items []low.NodeReference[any]
|
||||
for _, sliceItem := range valueNode.Content {
|
||||
var decoded map[string]interface{}
|
||||
err := sliceItem.Decode(&decoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items = append(items, low.ObjectReference{
|
||||
items = append(items, low.NodeReference[any]{
|
||||
Value: decoded,
|
||||
ValueNode: sliceItem,
|
||||
KeyNode: valueNode,
|
||||
@@ -341,21 +341,21 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
|
||||
}
|
||||
break
|
||||
// helper for unpacking string maps.
|
||||
case reflect.TypeOf(map[low.NodeReference[string]]low.NodeReference[string]{}):
|
||||
case reflect.TypeOf(map[low.KeyReference[string]]low.ValueReference[string]{}):
|
||||
if valueNode != nil {
|
||||
if utils.IsNodeMap(valueNode) {
|
||||
if field.CanSet() {
|
||||
items := make(map[low.NodeReference[string]]low.NodeReference[string])
|
||||
items := make(map[low.KeyReference[string]]low.ValueReference[string])
|
||||
var cf *yaml.Node
|
||||
for i, sliceItem := range valueNode.Content {
|
||||
if i%2 == 0 {
|
||||
cf = sliceItem
|
||||
continue
|
||||
}
|
||||
items[low.NodeReference[string]{
|
||||
items[low.KeyReference[string]{
|
||||
Value: cf.Value,
|
||||
KeyNode: cf,
|
||||
}] = low.NodeReference[string]{
|
||||
}] = low.ValueReference[string]{
|
||||
Value: sliceItem.Value,
|
||||
ValueNode: sliceItem,
|
||||
}
|
||||
@@ -364,19 +364,18 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.TypeOf(low.NodeReference[[]low.NodeReference[string]]{}):
|
||||
case reflect.TypeOf(low.NodeReference[[]low.ValueReference[string]]{}):
|
||||
if valueNode != nil {
|
||||
if utils.IsNodeArray(valueNode) {
|
||||
if field.CanSet() {
|
||||
var items []low.NodeReference[string]
|
||||
var items []low.ValueReference[string]
|
||||
for _, sliceItem := range valueNode.Content {
|
||||
items = append(items, low.NodeReference[string]{
|
||||
items = append(items, low.ValueReference[string]{
|
||||
Value: sliceItem.Value,
|
||||
ValueNode: sliceItem,
|
||||
KeyNode: valueNode,
|
||||
})
|
||||
}
|
||||
n := low.NodeReference[[]low.NodeReference[string]]{
|
||||
n := low.NodeReference[[]low.ValueReference[string]]{
|
||||
Value: items,
|
||||
KeyNode: keyNode,
|
||||
ValueNode: valueNode,
|
||||
|
||||
@@ -22,9 +22,9 @@ type hotdog struct {
|
||||
Temps []low.NodeReference[int]
|
||||
HighTemps []low.NodeReference[int64]
|
||||
Buns []low.NodeReference[bool]
|
||||
UnknownElements low.ObjectReference
|
||||
LotsOfUnknowns []low.ObjectReference
|
||||
Where map[string]low.ObjectReference
|
||||
UnknownElements low.NodeReference[any]
|
||||
LotsOfUnknowns []low.NodeReference[any]
|
||||
Where map[string]low.NodeReference[any]
|
||||
There map[string]low.NodeReference[string]
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ type Schema struct {
|
||||
UniqueItems low.NodeReference[int]
|
||||
MaxProperties low.NodeReference[int]
|
||||
MinProperties low.NodeReference[int]
|
||||
Required low.NodeReference[[]low.NodeReference[string]]
|
||||
Enum low.NodeReference[[]low.NodeReference[string]]
|
||||
Required low.NodeReference[[]low.ValueReference[string]]
|
||||
Enum low.NodeReference[[]low.ValueReference[string]]
|
||||
Type low.NodeReference[string]
|
||||
AllOf low.NodeReference[[]low.NodeReference[*Schema]]
|
||||
OneOf low.NodeReference[[]low.NodeReference[*Schema]]
|
||||
@@ -85,12 +85,11 @@ func (s *Schema) BuildLevel(root *yaml.Node, level int) error {
|
||||
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
|
||||
if addPNode != nil {
|
||||
if utils.IsNodeMap(addPNode) {
|
||||
var props map[string]interface{}
|
||||
err = addPNode.Decode(&props)
|
||||
if err != nil {
|
||||
return err
|
||||
schema, serr := ExtractObjectRaw[*Schema](addPNode)
|
||||
if serr != nil {
|
||||
return serr
|
||||
}
|
||||
s.AdditionalProperties = low.NodeReference[any]{Value: props, KeyNode: addPLabel, ValueNode: addPNode}
|
||||
s.AdditionalProperties = low.NodeReference[any]{Value: schema, KeyNode: addPLabel, ValueNode: addPNode}
|
||||
}
|
||||
|
||||
if utils.IsNodeBoolValue(addPNode) {
|
||||
|
||||
@@ -24,6 +24,10 @@ type SecurityScheme struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
type SecurityRequirement struct {
|
||||
Value []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
||||
}
|
||||
|
||||
func (ss *SecurityScheme) Build(root *yaml.Node) error {
|
||||
extensionMap, err := ExtractExtensions(root)
|
||||
if err != nil {
|
||||
@@ -42,10 +46,6 @@ func (ss *SecurityScheme) Build(root *yaml.Node) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type SecurityRequirement struct {
|
||||
Value []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
||||
}
|
||||
|
||||
func (sr *SecurityRequirement) FindRequirement(name string) []low.ValueReference[string] {
|
||||
for _, r := range sr.Value {
|
||||
for k, v := range r.Value {
|
||||
|
||||
@@ -27,12 +27,6 @@ type ValueReference[T any] struct {
|
||||
ValueNode *yaml.Node
|
||||
}
|
||||
|
||||
type ObjectReference struct {
|
||||
Value interface{}
|
||||
ValueNode *yaml.Node
|
||||
KeyNode *yaml.Node
|
||||
}
|
||||
|
||||
func (n NodeReference[T]) IsEmpty() bool {
|
||||
return n.KeyNode == nil && n.ValueNode == nil
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ func TestSpecIndex_PetstoreV3(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
var mappedRefs = 9
|
||||
var mappedRefs = 16
|
||||
|
||||
func TestSpecIndex_BurgerShop(t *testing.T) {
|
||||
|
||||
@@ -182,7 +182,7 @@ func TestSpecIndex_BurgerShop(t *testing.T) {
|
||||
|
||||
assert.Equal(t, 5, len(index.GetAllSchemas()))
|
||||
|
||||
assert.Equal(t, 22, len(index.GetAllSequencedReferences()))
|
||||
assert.Equal(t, 30, len(index.GetAllSequencedReferences()))
|
||||
assert.NotNil(t, index.GetSchemasNode())
|
||||
assert.NotNil(t, index.GetParametersNode())
|
||||
|
||||
@@ -214,7 +214,7 @@ func TestSpecIndex_BurgerShop(t *testing.T) {
|
||||
assert.Equal(t, 2, index.componentsInlineParamUniqueCount)
|
||||
assert.Equal(t, 2, index.GetInlineUniqueParamCount())
|
||||
|
||||
assert.Equal(t, 0, len(index.GetAllRequestBodies()))
|
||||
assert.Equal(t, 1, len(index.GetAllRequestBodies()))
|
||||
assert.NotNil(t, index.GetRootNode())
|
||||
assert.NotNil(t, index.GetGlobalTagsNode())
|
||||
assert.NotNil(t, index.GetPathsNode())
|
||||
@@ -223,7 +223,7 @@ func TestSpecIndex_BurgerShop(t *testing.T) {
|
||||
assert.NotNil(t, index.GetOperationParameterReferences())
|
||||
assert.Equal(t, 3, len(index.GetAllSecuritySchemes()))
|
||||
assert.Equal(t, 2, len(index.GetAllParameters()))
|
||||
assert.Equal(t, 0, len(index.GetAllResponses()))
|
||||
assert.Equal(t, 1, len(index.GetAllResponses()))
|
||||
assert.Equal(t, 2, len(index.GetInlineOperationDuplicateParameters()))
|
||||
assert.Equal(t, 0, len(index.GetReferencesWithSiblings()))
|
||||
assert.Equal(t, mappedRefs, len(index.GetAllReferences()))
|
||||
|
||||
@@ -40,6 +40,8 @@ func CreateDocument(info *datamodel.SpecInfo) (*v3.Document, error) {
|
||||
extractTags,
|
||||
extractPaths,
|
||||
extractComponents,
|
||||
extractSecurity,
|
||||
extractExternalDocs,
|
||||
}
|
||||
wg.Add(len(extractionFuncs))
|
||||
for _, f := range extractionFuncs {
|
||||
@@ -69,6 +71,24 @@ func extractInfo(info *datamodel.SpecInfo, doc *v3.Document) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document) error {
|
||||
sec, sErr := v3.ExtractObject[*v3.SecurityRequirement](v3.SecurityLabel, info.RootNode)
|
||||
if sErr != nil {
|
||||
return sErr
|
||||
}
|
||||
doc.Security = sec
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractExternalDocs(info *datamodel.SpecInfo, doc *v3.Document) error {
|
||||
extDocs, dErr := v3.ExtractObject[*v3.ExternalDoc](v3.ExternalDocsLabel, info.RootNode)
|
||||
if dErr != nil {
|
||||
return dErr
|
||||
}
|
||||
doc.ExternalDocs = extDocs
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractComponents(info *datamodel.SpecInfo, doc *v3.Document) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(v3.ComponentsLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
@@ -117,7 +137,7 @@ func extractTags(info *datamodel.SpecInfo, doc *v3.Document) error {
|
||||
_, ln, vn := utils.FindKeyNodeFull(v3.TagsLabel, info.RootNode.Content)
|
||||
if vn != nil {
|
||||
if utils.IsNodeArray(vn) {
|
||||
var tags []low.NodeReference[*v3.Tag]
|
||||
var tags []low.ValueReference[*v3.Tag]
|
||||
for _, tagN := range vn.Content {
|
||||
if utils.IsNodeMap(tagN) {
|
||||
tag := v3.Tag{}
|
||||
@@ -126,14 +146,17 @@ func extractTags(info *datamodel.SpecInfo, doc *v3.Document) error {
|
||||
return err
|
||||
}
|
||||
tag.Build(tagN)
|
||||
tags = append(tags, low.NodeReference[*v3.Tag]{
|
||||
tags = append(tags, low.ValueReference[*v3.Tag]{
|
||||
Value: &tag,
|
||||
ValueNode: tagN,
|
||||
KeyNode: ln,
|
||||
})
|
||||
}
|
||||
}
|
||||
doc.Tags = tags
|
||||
doc.Tags = low.NodeReference[[]low.ValueReference[*v3.Tag]]{
|
||||
Value: tags,
|
||||
KeyNode: ln,
|
||||
ValueNode: vn,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -64,17 +64,17 @@ func TestCreateDocument_Servers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateDocument_Tags(t *testing.T) {
|
||||
assert.Len(t, doc.Tags, 2)
|
||||
assert.Len(t, doc.Tags.Value, 2)
|
||||
|
||||
// tag1
|
||||
assert.Equal(t, "Burgers", doc.Tags[0].Value.Name.Value)
|
||||
assert.NotEmpty(t, doc.Tags[0].Value.Description.Value)
|
||||
assert.NotNil(t, doc.Tags[0].Value.ExternalDocs.Value)
|
||||
assert.Equal(t, "https://pb33f.io", doc.Tags[0].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.NotEmpty(t, doc.Tags[0].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.Len(t, doc.Tags[0].Value.Extensions, 7)
|
||||
assert.Equal(t, "Burgers", doc.Tags.Value[0].Value.Name.Value)
|
||||
assert.NotEmpty(t, doc.Tags.Value[0].Value.Description.Value)
|
||||
assert.NotNil(t, doc.Tags.Value[0].Value.ExternalDocs.Value)
|
||||
assert.Equal(t, "https://pb33f.io", doc.Tags.Value[0].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.NotEmpty(t, doc.Tags.Value[0].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.Len(t, doc.Tags.Value[0].Value.Extensions, 7)
|
||||
|
||||
for key, extension := range doc.Tags[0].Value.Extensions {
|
||||
for key, extension := range doc.Tags.Value[0].Value.Extensions {
|
||||
switch key.Value {
|
||||
case "x-internal-ting":
|
||||
assert.Equal(t, "somethingSpecial", extension.Value)
|
||||
@@ -99,12 +99,12 @@ func TestCreateDocument_Tags(t *testing.T) {
|
||||
}
|
||||
|
||||
/// tag2
|
||||
assert.Equal(t, "Dressing", doc.Tags[1].Value.Name.Value)
|
||||
assert.NotEmpty(t, doc.Tags[1].Value.Description.Value)
|
||||
assert.NotNil(t, doc.Tags[1].Value.ExternalDocs.Value)
|
||||
assert.Equal(t, "https://pb33f.io", doc.Tags[1].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.NotEmpty(t, doc.Tags[1].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.Len(t, doc.Tags[1].Value.Extensions, 0)
|
||||
assert.Equal(t, "Dressing", doc.Tags.Value[1].Value.Name.Value)
|
||||
assert.NotEmpty(t, doc.Tags.Value[1].Value.Description.Value)
|
||||
assert.NotNil(t, doc.Tags.Value[1].Value.ExternalDocs.Value)
|
||||
assert.Equal(t, "https://pb33f.io", doc.Tags.Value[1].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.NotEmpty(t, doc.Tags.Value[1].Value.ExternalDocs.Value.URL.Value)
|
||||
assert.Len(t, doc.Tags.Value[1].Value.Extensions, 0)
|
||||
|
||||
}
|
||||
|
||||
@@ -257,7 +257,10 @@ func TestCreateDocument_Components_Schemas(t *testing.T) {
|
||||
assert.Equal(t, "a frosty cold beverage can be coke or sprite",
|
||||
fries.Value.FindProperty("favoriteDrink").Value.Description.Value)
|
||||
|
||||
// check security schemes
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_SecuritySchemes(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
securitySchemes := components.SecuritySchemes.Value
|
||||
assert.Len(t, securitySchemes, 3)
|
||||
|
||||
@@ -283,3 +286,113 @@ func TestCreateDocument_Components_Schemas(t *testing.T) {
|
||||
assert.Equal(t, "modify burgers and stuff", readScope.Value)
|
||||
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_Responses(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
responses := components.Responses.Value
|
||||
assert.Len(t, responses, 1)
|
||||
|
||||
dressingResponse := components.FindResponse("DressingResponse")
|
||||
assert.NotNil(t, dressingResponse.Value)
|
||||
assert.Equal(t, "all the dressings for a burger.", dressingResponse.Value.Description.Value)
|
||||
assert.Len(t, dressingResponse.Value.Content.Value, 1)
|
||||
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_Examples(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
examples := components.Examples.Value
|
||||
assert.Len(t, examples, 1)
|
||||
|
||||
quarterPounder := components.FindExample("QuarterPounder")
|
||||
assert.NotNil(t, quarterPounder.Value)
|
||||
assert.Equal(t, "A juicy two hander sammich", quarterPounder.Value.Summary.Value)
|
||||
assert.NotNil(t, quarterPounder.Value.Value.Value)
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_RequestBodies(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
requestBodies := components.RequestBodies.Value
|
||||
assert.Len(t, requestBodies, 1)
|
||||
|
||||
burgerRequest := components.FindRequestBody("BurgerRequest")
|
||||
assert.NotNil(t, burgerRequest.Value)
|
||||
assert.Equal(t, "Give us the new burger!", burgerRequest.Value.Description.Value)
|
||||
assert.Len(t, burgerRequest.Value.Content.Value, 1)
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_Headers(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
headers := components.Headers.Value
|
||||
assert.Len(t, headers, 1)
|
||||
|
||||
useOil := components.FindHeader("UseOil")
|
||||
assert.NotNil(t, useOil.Value)
|
||||
assert.Equal(t, "this is a header", useOil.Value.Description.Value)
|
||||
assert.Equal(t, "string", useOil.Value.Schema.Value.Type.Value)
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_Links(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
links := components.Links.Value
|
||||
assert.Len(t, links, 2)
|
||||
|
||||
locateBurger := components.FindLink("LocateBurger")
|
||||
assert.NotNil(t, locateBurger.Value)
|
||||
assert.Equal(t, "Go and get a tasty burger", locateBurger.Value.Description.Value)
|
||||
|
||||
anotherLocateBurger := components.FindLink("AnotherLocateBurger")
|
||||
assert.NotNil(t, anotherLocateBurger.Value)
|
||||
assert.Equal(t, "Go and get another really tasty burger", anotherLocateBurger.Value.Description.Value)
|
||||
}
|
||||
|
||||
func TestCreateDocument_Doc_Security(t *testing.T) {
|
||||
security := doc.Security.Value
|
||||
assert.NotNil(t, security)
|
||||
assert.Len(t, security.Value, 1)
|
||||
|
||||
oAuth := security.FindRequirement("OAuthScheme")
|
||||
assert.Len(t, oAuth, 2)
|
||||
}
|
||||
|
||||
func TestCreateDocument_Callbacks(t *testing.T) {
|
||||
callbacks := doc.Components.Value.Callbacks.Value
|
||||
assert.Len(t, callbacks, 1)
|
||||
|
||||
bCallback := doc.Components.Value.FindCallback("BurgerCallback")
|
||||
assert.NotNil(t, bCallback.Value)
|
||||
assert.Len(t, callbacks, 1)
|
||||
|
||||
exp := bCallback.Value.FindExpression("{$request.query.queryUrl}")
|
||||
assert.NotNil(t, exp.Value)
|
||||
assert.NotNil(t, exp.Value.Post.Value)
|
||||
assert.Equal(t, "Callback payload", exp.Value.Post.Value.RequestBody.Value.Description.Value)
|
||||
}
|
||||
|
||||
func TestCreateDocument_Component_Discriminator(t *testing.T) {
|
||||
|
||||
components := doc.Components.Value
|
||||
dsc := components.FindSchema("Drink").Value.Discriminator.Value
|
||||
assert.NotNil(t, dsc)
|
||||
assert.Equal(t, "drinkType", dsc.PropertyName.Value)
|
||||
assert.Equal(t, "some value", dsc.FindMappingValue("drink").Value)
|
||||
assert.Nil(t, dsc.FindMappingValue("don't exist"))
|
||||
}
|
||||
|
||||
func TestCreateDocument_CheckAdditionalProperties_Schema(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
d := components.FindSchema("Dressing")
|
||||
assert.NotNil(t, d.Value.AdditionalProperties.Value)
|
||||
if n, ok := d.Value.AdditionalProperties.Value.(*v3.Schema); ok {
|
||||
assert.Equal(t, "something in here.", n.Description.Value)
|
||||
} else {
|
||||
assert.Fail(t, "should be a schema")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDocument_CheckAdditionalProperties_Bool(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
d := components.FindSchema("Drink")
|
||||
assert.NotNil(t, d.Value.AdditionalProperties.Value)
|
||||
assert.True(t, d.Value.AdditionalProperties.Value.(bool))
|
||||
}
|
||||
|
||||
@@ -12,6 +12,10 @@ info:
|
||||
name: pb33f
|
||||
url: https://pb33f.io/made-up
|
||||
version: "1.2"
|
||||
security:
|
||||
- OAuthScheme:
|
||||
- read:burgers
|
||||
- write:burgers
|
||||
tags:
|
||||
- name: "Burgers"
|
||||
description: "All kinds of yummy burgers."
|
||||
@@ -66,29 +70,12 @@ paths:
|
||||
summary: Create a new burger
|
||||
description: A new burger for our menu, yummy yum yum.
|
||||
requestBody:
|
||||
description: Give us the new burger!
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Burger'
|
||||
examples:
|
||||
pbjBurger:
|
||||
summary: A horrible, nutty, sticky mess.
|
||||
value:
|
||||
name: Peanut And Jelly
|
||||
numPatties: 3
|
||||
cakeBurger:
|
||||
summary: A sickly, sweet, atrocity
|
||||
value:
|
||||
name: Chocolate Cake Burger
|
||||
numPatties: 5
|
||||
$ref: '#/components/requestBodies/BurgerRequest'
|
||||
responses:
|
||||
"200":
|
||||
headers:
|
||||
UseOil:
|
||||
description: this is a header
|
||||
schema:
|
||||
type: string
|
||||
$ref: '#/components/headers/UseOil'
|
||||
description: A tasty burger for you to eat.
|
||||
content:
|
||||
application/json:
|
||||
@@ -96,10 +83,7 @@ paths:
|
||||
$ref: '#/components/schemas/Burger'
|
||||
examples:
|
||||
quarterPounder:
|
||||
summary: a yummy tasty two patty burger, filled with beefy goodness.
|
||||
value:
|
||||
name: Quarter Pounder with Cheese
|
||||
numPatties: 1
|
||||
$ref: '#/components/examples/QuarterPounder'
|
||||
filetOFish:
|
||||
summary: a cripsy fish sammich filled with ocean goodness.
|
||||
value:
|
||||
@@ -107,15 +91,9 @@ paths:
|
||||
numPatties: 1
|
||||
links:
|
||||
LocateBurger:
|
||||
operationId: locateBurger
|
||||
parameters:
|
||||
burgerId: '$response.body#/id'
|
||||
description: Go and get a tasty burger
|
||||
$ref: '#/components/links/LocateBurger'
|
||||
AnotherLocateBurger:
|
||||
operationId: locateBurger
|
||||
parameters:
|
||||
burgerId: '$response.body#/id'
|
||||
description: Go and get a another really tasty burger
|
||||
$ref: '#/components/links/AnotherLocateBurger'
|
||||
"500":
|
||||
description: Unexpected error creating a new burger. Sorry.
|
||||
content:
|
||||
@@ -149,17 +127,7 @@ paths:
|
||||
get:
|
||||
callbacks:
|
||||
burgerCallback:
|
||||
"{$request.query.queryUrl}":
|
||||
post:
|
||||
requestBody:
|
||||
description: Callback payload
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
$ref: '#/components/schemas/SomePayload'
|
||||
responses:
|
||||
'200':
|
||||
description: callback successfully processed
|
||||
$ref: '#/components/callbacks/BurgerCallback'
|
||||
operationId: locateBurger
|
||||
tags:
|
||||
- "Burgers"
|
||||
@@ -177,10 +145,7 @@ paths:
|
||||
$ref: '#/components/schemas/Burger'
|
||||
examples:
|
||||
quarterPounder:
|
||||
summary: A juicy two handler sammich
|
||||
value:
|
||||
name: Quarter Pounder with Cheese
|
||||
numPatties: 1
|
||||
$ref: '#/components/examples/QuarterPounder'
|
||||
filetOFish:
|
||||
summary: A tasty treat from the sea
|
||||
value:
|
||||
@@ -231,15 +196,7 @@ paths:
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: all the dressings for a burger.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Dressing'
|
||||
example:
|
||||
- name: Thousand Island
|
||||
$ref: '#/components/responses/DressingResponse'
|
||||
"404":
|
||||
description: Cannot find your burger in which to list dressings. Sorry
|
||||
content:
|
||||
@@ -331,6 +288,70 @@ paths:
|
||||
example:
|
||||
message: "failed looking up all dressings, something went wrong."
|
||||
components:
|
||||
callbacks:
|
||||
BurgerCallback:
|
||||
"{$request.query.queryUrl}":
|
||||
post:
|
||||
requestBody:
|
||||
description: Callback payload
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
$ref: '#/components/schemas/SomePayload'
|
||||
responses:
|
||||
'200':
|
||||
description: callback successfully processes
|
||||
links:
|
||||
LocateBurger:
|
||||
operationId: locateBurger
|
||||
parameters:
|
||||
burgerId: '$response.body#/id'
|
||||
description: Go and get a tasty burger
|
||||
AnotherLocateBurger:
|
||||
operationId: locateBurger
|
||||
parameters:
|
||||
burgerId: '$response.body#/id'
|
||||
description: Go and get another really tasty burger
|
||||
headers:
|
||||
UseOil:
|
||||
description: this is a header
|
||||
schema:
|
||||
type: string
|
||||
requestBodies:
|
||||
BurgerRequest:
|
||||
description: Give us the new burger!
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Burger'
|
||||
examples:
|
||||
pbjBurger:
|
||||
summary: A horrible, nutty, sticky mess.
|
||||
value:
|
||||
name: Peanut And Jelly
|
||||
numPatties: 3
|
||||
cakeBurger:
|
||||
summary: A sickly, sweet, atrocity
|
||||
value:
|
||||
name: Chocolate Cake Burger
|
||||
numPatties: 5
|
||||
examples:
|
||||
QuarterPounder:
|
||||
summary: A juicy two hander sammich
|
||||
value:
|
||||
name: Quarter Pounder with Cheese
|
||||
numPatties: 1
|
||||
responses:
|
||||
DressingResponse:
|
||||
description: all the dressings for a burger.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Dressing'
|
||||
example:
|
||||
- name: Thousand Island
|
||||
securitySchemes:
|
||||
APIKeyScheme:
|
||||
type: apiKey
|
||||
@@ -463,6 +484,9 @@ components:
|
||||
type: string
|
||||
description: The name of your dressing you can pick up from the menu
|
||||
example: Cheese
|
||||
additionalProperties:
|
||||
type: object
|
||||
description: something in here.
|
||||
Drink:
|
||||
type: object
|
||||
description: a frosty cold beverage can be coke or sprite
|
||||
@@ -481,4 +505,8 @@ components:
|
||||
type: string
|
||||
description: what size man? S/M/L
|
||||
example: M
|
||||
|
||||
additionalProperties: true
|
||||
discriminator:
|
||||
propertyName: drinkType
|
||||
mapping:
|
||||
drink: some value
|
||||
Reference in New Issue
Block a user