mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Test coverage for v3 model is now at 100%
This should be very easy to duplicate to 2.0 and 3.1, now extraction code needs testing. Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
# libopenapi
|
||||
|
||||
A place for up to date, modern golang OpenAPI models and utilities.
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/pb33f/libopenapi/datamodel/high"
|
||||
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
|
||||
low "github.com/pb33f/libopenapi/datamodel/low/3.0"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,31 +20,6 @@ const (
|
||||
callbacks
|
||||
)
|
||||
|
||||
var seenSchemas map[string]*Schema
|
||||
|
||||
func init() {
|
||||
clearSchemas()
|
||||
}
|
||||
|
||||
func clearSchemas() {
|
||||
seenSchemas = make(map[string]*Schema)
|
||||
}
|
||||
|
||||
var seenSchemaLock sync.RWMutex
|
||||
|
||||
func addSeenSchema(key string, schema *Schema) {
|
||||
defer seenSchemaLock.Unlock()
|
||||
seenSchemaLock.Lock()
|
||||
if seenSchemas[key] == nil {
|
||||
seenSchemas[key] = schema
|
||||
}
|
||||
}
|
||||
func getSeenSchema(key string) *Schema {
|
||||
defer seenSchemaLock.Unlock()
|
||||
seenSchemaLock.Lock()
|
||||
return seenSchemas[key]
|
||||
}
|
||||
|
||||
type Components struct {
|
||||
Schemas map[string]*SchemaProxy
|
||||
Responses map[string]*Response
|
||||
@@ -110,7 +84,6 @@ func NewComponents(comp *low.Components) *Components {
|
||||
go buildComponent[*SecurityScheme, *low.SecurityScheme](securitySchemes, k.Value, v.Value,
|
||||
securitySchemeChan, NewSecurityScheme)
|
||||
}
|
||||
|
||||
for k, v := range comp.Schemas.Value {
|
||||
go buildSchema(k, v, schemaChan)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package v3
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/high"
|
||||
low "github.com/pb33f/libopenapi/datamodel/low/3.0"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
)
|
||||
|
||||
type Document struct {
|
||||
@@ -18,14 +19,19 @@ type Document struct {
|
||||
Tags []*Tag
|
||||
ExternalDocs *ExternalDoc
|
||||
Extensions map[string]any
|
||||
Index *index.SpecIndex
|
||||
low *low.Document
|
||||
}
|
||||
|
||||
func NewDocument(document *low.Document) *Document {
|
||||
d := new(Document)
|
||||
d.low = document
|
||||
d.Info = NewInfo(document.Info.Value)
|
||||
d.Version = document.Version.Value
|
||||
if !document.Info.IsEmpty() {
|
||||
d.Info = NewInfo(document.Info.Value)
|
||||
}
|
||||
if !document.Version.IsEmpty() {
|
||||
d.Version = document.Version.Value
|
||||
}
|
||||
var servers []*Server
|
||||
for _, ser := range document.Servers.Value {
|
||||
servers = append(servers, NewServer(ser.Value))
|
||||
@@ -42,6 +48,7 @@ func NewDocument(document *low.Document) *Document {
|
||||
d.Extensions = high.ExtractExtensions(document.Extensions)
|
||||
d.Components = NewComponents(document.Components.Value)
|
||||
d.Paths = NewPaths(document.Paths.Value)
|
||||
d.Index = document.Index
|
||||
return d
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
var doc *lowv3.Document
|
||||
|
||||
func init() {
|
||||
func initTest() {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/burgershop.openapi.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
var err []error
|
||||
@@ -25,22 +25,26 @@ func init() {
|
||||
}
|
||||
|
||||
func BenchmarkNewDocument(b *testing.B) {
|
||||
initTest()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = NewDocument(doc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDocument_Extensions(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Equal(t, "darkside", h.Extensions["x-something-something"])
|
||||
}
|
||||
|
||||
func TestNewDocument_ExternalDocs(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Equal(t, "https://pb33f.io", h.ExternalDocs.URL)
|
||||
}
|
||||
|
||||
func TestNewDocument_Info(t *testing.T) {
|
||||
initTest()
|
||||
highDoc := NewDocument(doc)
|
||||
assert.Equal(t, "3.0.1", highDoc.Version)
|
||||
assert.Equal(t, "Burger Shop", highDoc.Info.Title)
|
||||
@@ -71,6 +75,7 @@ func TestNewDocument_Info(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Servers(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Servers, 2)
|
||||
assert.Equal(t, "{scheme}://api.pb33f.io", h.Servers[0].URL)
|
||||
@@ -102,6 +107,7 @@ func TestNewDocument_Servers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Tags(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Tags, 2)
|
||||
assert.Equal(t, "Burgers", h.Tags[0].Name)
|
||||
@@ -123,6 +129,7 @@ func TestNewDocument_Tags(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Links(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Links, 2)
|
||||
assert.Equal(t, "locateBurger", h.Components.Links["LocateBurger"].OperationId)
|
||||
@@ -135,6 +142,7 @@ func TestNewDocument_Components_Links(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Callbacks(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Callbacks, 1)
|
||||
assert.Equal(t, "Callback payload",
|
||||
@@ -156,6 +164,7 @@ func TestNewDocument_Components_Callbacks(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Schemas(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Schemas, 6)
|
||||
|
||||
@@ -197,6 +206,7 @@ func TestNewDocument_Components_Schemas(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Headers(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Headers, 1)
|
||||
assert.Equal(t, "this is a header", h.Components.Headers["UseOil"].Description)
|
||||
@@ -205,6 +215,7 @@ func TestNewDocument_Components_Headers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_RequestBodies(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.RequestBodies, 1)
|
||||
assert.Equal(t, "Give us the new burger!", h.Components.RequestBodies["BurgerRequest"].Description)
|
||||
@@ -214,6 +225,7 @@ func TestNewDocument_Components_RequestBodies(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Examples(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Examples, 1)
|
||||
assert.Equal(t, "A juicy two hander sammich", h.Components.Examples["QuarterPounder"].Summary)
|
||||
@@ -223,6 +235,7 @@ func TestNewDocument_Components_Examples(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Responses(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Responses, 1)
|
||||
assert.Equal(t, "all the dressings for a burger.", h.Components.Responses["DressingResponse"].Description)
|
||||
@@ -232,6 +245,7 @@ func TestNewDocument_Components_Responses(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_SecuritySchemes(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.SecuritySchemes, 3)
|
||||
|
||||
@@ -262,6 +276,7 @@ func TestNewDocument_Components_SecuritySchemes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Components_Parameters(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Components.Parameters, 2)
|
||||
bh := h.Components.Parameters["BurgerHeader"]
|
||||
@@ -278,6 +293,7 @@ func TestNewDocument_Components_Parameters(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDocument_Paths(t *testing.T) {
|
||||
initTest()
|
||||
h := NewDocument(doc)
|
||||
assert.Len(t, h.Paths.PathItems, 5)
|
||||
|
||||
@@ -323,7 +339,6 @@ func TestNewDocument_Paths(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStripeAsDoc(t *testing.T) {
|
||||
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/stripe.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
var err []error
|
||||
@@ -334,3 +349,16 @@ func TestStripeAsDoc(t *testing.T) {
|
||||
d := NewDocument(doc)
|
||||
fmt.Println(d)
|
||||
}
|
||||
|
||||
func TestCircularReferencesDoc(t *testing.T) {
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/circular-tests.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
var err []error
|
||||
doc, err = lowv3.CreateDocument(info)
|
||||
if err != nil {
|
||||
panic("broken something")
|
||||
}
|
||||
d := NewDocument(doc)
|
||||
assert.Len(t, d.Components.Schemas, 9)
|
||||
assert.Len(t, d.Index.GetCircularReferences(), 3)
|
||||
}
|
||||
|
||||
@@ -18,16 +18,24 @@ type Info struct {
|
||||
func NewInfo(info *low.Info) *Info {
|
||||
i := new(Info)
|
||||
i.low = info
|
||||
i.Title = info.Title.Value
|
||||
i.Description = info.Description.Value
|
||||
i.TermsOfService = info.TermsOfService.Value
|
||||
if !info.Title.IsEmpty() {
|
||||
i.Title = info.Title.Value
|
||||
}
|
||||
if !info.Description.IsEmpty() {
|
||||
i.Description = info.Description.Value
|
||||
}
|
||||
if !info.TermsOfService.IsEmpty() {
|
||||
i.TermsOfService = info.TermsOfService.Value
|
||||
}
|
||||
if !info.Contact.IsEmpty() {
|
||||
i.Contact = NewContact(info.Contact.Value)
|
||||
}
|
||||
if !info.License.IsEmpty() {
|
||||
i.License = NewLicense(info.License.Value)
|
||||
}
|
||||
i.Version = info.Version.Value
|
||||
if !info.Version.IsEmpty() {
|
||||
i.Version = info.Version.Value
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
|
||||
@@ -111,10 +111,9 @@ func NewSchema(schema *low.Schema) *Schema {
|
||||
buildOutSchema := func(schemas []lowmodel.ValueReference[*low.SchemaProxy], items *[]*SchemaProxy,
|
||||
doneChan chan bool, e chan error) {
|
||||
bChan := make(chan *SchemaProxy)
|
||||
eChan := make(chan error)
|
||||
|
||||
// for every item, build schema async
|
||||
buildSchemaChild := func(sch lowmodel.ValueReference[*low.SchemaProxy], bChan chan *SchemaProxy, e chan error) {
|
||||
buildSchemaChild := func(sch lowmodel.ValueReference[*low.SchemaProxy], bChan chan *SchemaProxy) {
|
||||
p := &SchemaProxy{schema: &lowmodel.NodeReference[*low.SchemaProxy]{
|
||||
ValueNode: sch.ValueNode,
|
||||
Value: sch.Value,
|
||||
@@ -123,14 +122,11 @@ func NewSchema(schema *low.Schema) *Schema {
|
||||
}
|
||||
totalSchemas := len(schemas)
|
||||
for v := range schemas {
|
||||
go buildSchemaChild(schemas[v], bChan, eChan)
|
||||
go buildSchemaChild(schemas[v], bChan)
|
||||
}
|
||||
j := 0
|
||||
for j < totalSchemas {
|
||||
select {
|
||||
case er := <-eChan:
|
||||
e <- er
|
||||
return
|
||||
case t := <-bChan:
|
||||
j++
|
||||
*items = append(*items, t)
|
||||
|
||||
@@ -16,7 +16,7 @@ type SchemaProxy struct {
|
||||
func (sp *SchemaProxy) Schema() *Schema {
|
||||
s := sp.schema.Value.Schema()
|
||||
if s == nil {
|
||||
sp.buildError = sp.GetBuildError()
|
||||
sp.buildError = sp.schema.Value.GetBuildError()
|
||||
return nil
|
||||
}
|
||||
return NewSchema(s)
|
||||
|
||||
@@ -4,50 +4,52 @@
|
||||
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"
|
||||
"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) {
|
||||
func TestNewSchemaProxy(t *testing.T) {
|
||||
|
||||
// tests async schema lookup, by essentially running it twice, without a cache cleanup.
|
||||
yml := `components:
|
||||
schemas:
|
||||
// check proxy
|
||||
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:
|
||||
type: string
|
||||
nice:
|
||||
properties:
|
||||
rice:
|
||||
$ref: '#/components/schemas/rice'
|
||||
ice:
|
||||
properties:
|
||||
rice:
|
||||
$ref: '#/components/schemas/rice'`
|
||||
$ref: '#/components/schemas/I-do-not-exist'`
|
||||
|
||||
var idxNode, compNode yaml.Node
|
||||
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
|
||||
assert.NoError(t, mErr)
|
||||
idx := index.NewSpecIndex(&idxNode)
|
||||
_ = yaml.Unmarshal([]byte(yml), &compNode)
|
||||
|
||||
yml = `properties:
|
||||
rice:
|
||||
$ref: '#/components/schemas/rice'`
|
||||
sp := new(v3.SchemaProxy)
|
||||
err := sp.Build(compNode.Content[0], idx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var n v3.Schema
|
||||
_ = yaml.Unmarshal([]byte(yml), &compNode)
|
||||
err := low.BuildModel(&idxNode, &n)
|
||||
assert.NoError(t, err)
|
||||
lowproxy := low.NodeReference[*v3.SchemaProxy]{
|
||||
Value: sp,
|
||||
ValueNode: idxNode.Content[0],
|
||||
}
|
||||
|
||||
err = n.Build(idxNode.Content[0], idx)
|
||||
assert.NoError(t, err)
|
||||
sch1 := SchemaProxy{schema: &lowproxy}
|
||||
assert.Nil(t, sch1.Schema())
|
||||
assert.Error(t, sch1.GetBuildError())
|
||||
|
||||
sch1 := NewSchema(&n)
|
||||
sch2 := NewSchema(&n)
|
||||
|
||||
assert.Equal(t, sch1, sch2)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -18,31 +17,6 @@ const (
|
||||
SchemasLabel = "schemas"
|
||||
)
|
||||
|
||||
var seenSchemas map[string]*Schema
|
||||
|
||||
func init() {
|
||||
clearSchemas()
|
||||
}
|
||||
|
||||
func clearSchemas() {
|
||||
seenSchemas = make(map[string]*Schema)
|
||||
}
|
||||
|
||||
var seenSchemaLock sync.RWMutex
|
||||
|
||||
func addSeenSchema(key string, schema *Schema) {
|
||||
defer seenSchemaLock.Unlock()
|
||||
seenSchemaLock.Lock()
|
||||
if seenSchemas[key] == nil {
|
||||
seenSchemas[key] = schema
|
||||
}
|
||||
}
|
||||
func getSeenSchema(key string) *Schema {
|
||||
defer seenSchemaLock.Unlock()
|
||||
seenSchemaLock.Lock()
|
||||
return seenSchemas[key]
|
||||
}
|
||||
|
||||
type Components struct {
|
||||
Schemas low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*SchemaProxy]]
|
||||
Responses low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Response]]
|
||||
@@ -163,12 +137,6 @@ func (co *Components) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func cacheSchemas(sch map[low.KeyReference[string]]low.ValueReference[*Schema]) {
|
||||
for _, v := range sch {
|
||||
addSeenSchema(v.GenerateMapKey(), v.Value)
|
||||
}
|
||||
}
|
||||
|
||||
type componentBuildResult[T any] struct {
|
||||
k low.KeyReference[string]
|
||||
v low.ValueReference[T]
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
func CreateDocument(info *datamodel.SpecInfo) (*Document, []error) {
|
||||
|
||||
// clean state
|
||||
clearSchemas()
|
||||
doc := Document{Version: low.ValueReference[string]{Value: info.Version, ValueNode: info.RootNode}}
|
||||
|
||||
// build an index
|
||||
|
||||
@@ -188,8 +188,8 @@ func TestCreateDocument_Paths(t *testing.T) {
|
||||
assert.Len(t, burgerId.Value.Get.Value.Parameters.Value, 2)
|
||||
param := burgerId.Value.Get.Value.Parameters.Value[1]
|
||||
assert.Equal(t, "burgerHeader", param.Value.Name.Value)
|
||||
prop := param.Value.Schema.Value.Schema().FindProperty("burgerTheme")
|
||||
assert.Equal(t, "something about a theme?", prop.Value.Schema().Description.Value)
|
||||
prop := param.Value.Schema.Value.Schema().FindProperty("burgerTheme").Value
|
||||
assert.Equal(t, "something about a theme?", prop.Schema().Description.Value)
|
||||
assert.Equal(t, "big-mac", param.Value.Example.Value)
|
||||
|
||||
// check content
|
||||
@@ -502,6 +502,19 @@ func TestCreateDocument_Components_Error(t *testing.T) {
|
||||
assert.Error(t, ob.GetBuildError())
|
||||
}
|
||||
|
||||
func TestCreateDocument_Components_Error_Extract(t *testing.T) {
|
||||
yml := `components:
|
||||
parameters:
|
||||
bork:
|
||||
$ref: #bork`
|
||||
|
||||
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
|
||||
var err []error
|
||||
doc, err = CreateDocument(info)
|
||||
assert.Len(t, err, 1)
|
||||
|
||||
}
|
||||
|
||||
func TestCreateDocument_Paths_Errors(t *testing.T) {
|
||||
yml := `paths:
|
||||
/p:
|
||||
|
||||
@@ -65,19 +65,6 @@ func (s *Schema) FindProperty(name string) *low.ValueReference[*SchemaProxy] {
|
||||
}
|
||||
|
||||
func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
return s.BuildLevel(root, idx, 0)
|
||||
}
|
||||
|
||||
func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) error {
|
||||
|
||||
if low.IsCircular(root, idx) {
|
||||
return nil // circular references cannot be built.
|
||||
}
|
||||
|
||||
if level > 30 {
|
||||
return fmt.Errorf("schema is too nested to continue: %d levels deep, is too deep", level) // we're done, son! too fricken deep.
|
||||
}
|
||||
level++
|
||||
if h, _, _ := utils.IsNodeRefValue(root); h {
|
||||
ref := low.LocateRefNode(root, idx)
|
||||
if ref != nil {
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
)
|
||||
|
||||
func Test_Schema(t *testing.T) {
|
||||
clearSchemas()
|
||||
testSpec := `type: object
|
||||
description: something object
|
||||
discriminator:
|
||||
@@ -225,7 +224,7 @@ additionalProperties: true `
|
||||
}
|
||||
|
||||
//func TestSchema_BuildLevel_TooDeep(t *testing.T) {
|
||||
// clearSchemas()
|
||||
//
|
||||
// // if you design data models like this, you're doing it fucking wrong. Seriously. why, what is so complex about a model
|
||||
// // that it needs to be 30+ levels deep? I have seen this shit in the wild, it's unreadable, un-parsable garbage.
|
||||
// yml := `type: object
|
||||
@@ -343,7 +342,7 @@ additionalProperties: true `
|
||||
//}
|
||||
|
||||
func TestSchema_Build_ErrorAdditionalProps(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `additionalProperties:
|
||||
$ref: #borko`
|
||||
|
||||
@@ -361,7 +360,7 @@ func TestSchema_Build_ErrorAdditionalProps(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSchema_Build_PropsLookup(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -389,7 +388,7 @@ properties:
|
||||
}
|
||||
|
||||
func TestSchema_Build_PropsLookup_Fail(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -416,7 +415,7 @@ properties:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Array_Ref(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -464,7 +463,7 @@ items:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Array_Ref_Fail(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -506,7 +505,7 @@ items:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Map_Ref(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -554,7 +553,7 @@ items:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_Map_Ref_Fail(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -596,7 +595,6 @@ items:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_BorkParent(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -625,7 +623,6 @@ allOf:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_BorkChild(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -654,7 +651,6 @@ allOf:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_BorkChild_Array(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -687,7 +683,6 @@ allOf:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_RefMadness(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -721,7 +716,6 @@ allOf:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_RefMadnessBork(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -752,7 +746,6 @@ allOf:
|
||||
}
|
||||
|
||||
func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
// this does not work, but it won't error out.
|
||||
|
||||
@@ -783,7 +776,6 @@ func Test_Schema_Polymorphism_RefMadnessIllegal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -813,7 +805,6 @@ func TestExtractSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_Ref(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -839,7 +830,6 @@ func TestExtractSchema_Ref(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_Ref_Fail(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -863,7 +853,6 @@ func TestExtractSchema_Ref_Fail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_RefRoot(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -888,7 +877,6 @@ func TestExtractSchema_RefRoot(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -912,7 +900,6 @@ func TestExtractSchema_RefRoot_Fail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
@@ -939,8 +926,6 @@ func TestExtractSchema_RefRoot_Child_Fail(t *testing.T) {
|
||||
|
||||
func TestExtractSchema_DoNothing(t *testing.T) {
|
||||
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Something:
|
||||
@@ -964,8 +949,6 @@ func TestExtractSchema_DoNothing(t *testing.T) {
|
||||
|
||||
func TestExtractSchema_OneOfRef(t *testing.T) {
|
||||
|
||||
clearSchemas()
|
||||
|
||||
yml := `components:
|
||||
schemas:
|
||||
Error:
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package v3
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
)
|
||||
|
||||
type ServerVariable struct {
|
||||
Enum []low.NodeReference[string]
|
||||
Default low.NodeReference[string]
|
||||
Description low.NodeReference[string]
|
||||
Enum []low.NodeReference[string]
|
||||
Default low.NodeReference[string]
|
||||
Description low.NodeReference[string]
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package datamodel
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"strings"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
OAS2 = "oas2"
|
||||
OAS3 = "oas3"
|
||||
OAS31 = "oas3_1"
|
||||
OAS2 = "oas2"
|
||||
OAS3 = "oas3"
|
||||
OAS31 = "oas3_1"
|
||||
)
|
||||
|
||||
//go:embed schemas/oas3-schema.json
|
||||
@@ -32,181 +32,181 @@ var AllFormats = []string{OAS3, OAS31, OAS2}
|
||||
// if the spec cannot be parsed correctly.
|
||||
func ExtractSpecInfo(spec []byte) (*SpecInfo, error) {
|
||||
|
||||
var parsedSpec yaml.Node
|
||||
var parsedSpec yaml.Node
|
||||
|
||||
specVersion := &SpecInfo{}
|
||||
specVersion.JsonParsingChannel = make(chan bool)
|
||||
specVersion := &SpecInfo{}
|
||||
specVersion.JsonParsingChannel = make(chan bool)
|
||||
|
||||
// set original bytes
|
||||
specVersion.SpecBytes = &spec
|
||||
// set original bytes
|
||||
specVersion.SpecBytes = &spec
|
||||
|
||||
runes := []rune(strings.TrimSpace(string(spec)))
|
||||
if len(runes) <= 0 {
|
||||
return specVersion, errors.New("there are no runes in the spec")
|
||||
}
|
||||
runes := []rune(strings.TrimSpace(string(spec)))
|
||||
if len(runes) <= 0 {
|
||||
return specVersion, errors.New("there are no runes in the spec")
|
||||
}
|
||||
|
||||
if runes[0] == '{' && runes[len(runes)-1] == '}' {
|
||||
specVersion.SpecFileType = "json"
|
||||
} else {
|
||||
specVersion.SpecFileType = "yaml"
|
||||
}
|
||||
if runes[0] == '{' && runes[len(runes)-1] == '}' {
|
||||
specVersion.SpecFileType = "json"
|
||||
} else {
|
||||
specVersion.SpecFileType = "yaml"
|
||||
}
|
||||
|
||||
err := yaml.Unmarshal(spec, &parsedSpec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse specification: %s", err.Error())
|
||||
}
|
||||
err := yaml.Unmarshal(spec, &parsedSpec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse specification: %s", err.Error())
|
||||
}
|
||||
|
||||
specVersion.RootNode = &parsedSpec
|
||||
specVersion.RootNode = &parsedSpec
|
||||
|
||||
_, openAPI3 := utils.FindKeyNode(utils.OpenApi3, parsedSpec.Content)
|
||||
_, openAPI2 := utils.FindKeyNode(utils.OpenApi2, parsedSpec.Content)
|
||||
_, asyncAPI := utils.FindKeyNode(utils.AsyncApi, parsedSpec.Content)
|
||||
_, openAPI3 := utils.FindKeyNode(utils.OpenApi3, parsedSpec.Content)
|
||||
_, openAPI2 := utils.FindKeyNode(utils.OpenApi2, parsedSpec.Content)
|
||||
_, asyncAPI := utils.FindKeyNode(utils.AsyncApi, parsedSpec.Content)
|
||||
|
||||
parseJSON := func(bytes []byte, spec *SpecInfo) {
|
||||
var jsonSpec map[string]interface{}
|
||||
parseJSON := func(bytes []byte, spec *SpecInfo) {
|
||||
var jsonSpec map[string]interface{}
|
||||
|
||||
// no point in worrying about errors here, extract JSON friendly format.
|
||||
// run in a separate thread, don't block.
|
||||
// no point in worrying about errors here, extract JSON friendly format.
|
||||
// run in a separate thread, don't block.
|
||||
|
||||
if spec.SpecType == utils.OpenApi3 {
|
||||
spec.APISchema = OpenAPI3SchemaData
|
||||
}
|
||||
if spec.SpecType == utils.OpenApi2 {
|
||||
spec.APISchema = OpenAPI2SchemaData
|
||||
}
|
||||
if spec.SpecType == utils.OpenApi3 {
|
||||
spec.APISchema = OpenAPI3SchemaData
|
||||
}
|
||||
if spec.SpecType == utils.OpenApi2 {
|
||||
spec.APISchema = OpenAPI2SchemaData
|
||||
}
|
||||
|
||||
if utils.IsYAML(string(bytes)) {
|
||||
yaml.Unmarshal(bytes, &jsonSpec)
|
||||
jsonData, _ := json.Marshal(jsonSpec)
|
||||
spec.SpecJSONBytes = &jsonData
|
||||
spec.SpecJSON = &jsonSpec
|
||||
} else {
|
||||
json.Unmarshal(bytes, &jsonSpec)
|
||||
spec.SpecJSONBytes = &bytes
|
||||
spec.SpecJSON = &jsonSpec
|
||||
}
|
||||
spec.JsonParsingChannel <- true
|
||||
close(spec.JsonParsingChannel)
|
||||
}
|
||||
// check for specific keys
|
||||
if openAPI3 != nil {
|
||||
specVersion.SpecType = utils.OpenApi3
|
||||
version, majorVersion := parseVersionTypeData(openAPI3.Value)
|
||||
if utils.IsYAML(string(bytes)) {
|
||||
yaml.Unmarshal(bytes, &jsonSpec)
|
||||
jsonData, _ := json.Marshal(jsonSpec)
|
||||
spec.SpecJSONBytes = &jsonData
|
||||
spec.SpecJSON = &jsonSpec
|
||||
} else {
|
||||
json.Unmarshal(bytes, &jsonSpec)
|
||||
spec.SpecJSONBytes = &bytes
|
||||
spec.SpecJSON = &jsonSpec
|
||||
}
|
||||
spec.JsonParsingChannel <- true
|
||||
close(spec.JsonParsingChannel)
|
||||
}
|
||||
// check for specific keys
|
||||
if openAPI3 != nil {
|
||||
specVersion.SpecType = utils.OpenApi3
|
||||
version, majorVersion := parseVersionTypeData(openAPI3.Value)
|
||||
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
|
||||
// double check for the right version, people mix this up.
|
||||
if majorVersion < 3 {
|
||||
specVersion.Error = errors.New("spec is defined as an openapi spec, but is using a swagger (2.0), or unknown version")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Version = version
|
||||
specVersion.SpecFormat = OAS3
|
||||
}
|
||||
if openAPI2 != nil {
|
||||
specVersion.SpecType = utils.OpenApi2
|
||||
version, majorVersion := parseVersionTypeData(openAPI2.Value)
|
||||
// double check for the right version, people mix this up.
|
||||
if majorVersion < 3 {
|
||||
specVersion.Error = errors.New("spec is defined as an openapi spec, but is using a swagger (2.0), or unknown version")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Version = version
|
||||
specVersion.SpecFormat = OAS3
|
||||
}
|
||||
if openAPI2 != nil {
|
||||
specVersion.SpecType = utils.OpenApi2
|
||||
version, majorVersion := parseVersionTypeData(openAPI2.Value)
|
||||
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
|
||||
// I am not certain this edge-case is very frequent, but let's make sure we handle it anyway.
|
||||
if majorVersion > 2 {
|
||||
specVersion.Error = errors.New("spec is defined as a swagger (openapi 2.0) spec, but is an openapi 3 or unknown version")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Version = version
|
||||
specVersion.SpecFormat = OAS2
|
||||
}
|
||||
if asyncAPI != nil {
|
||||
specVersion.SpecType = utils.AsyncApi
|
||||
version, majorVersion := parseVersionTypeData(asyncAPI.Value)
|
||||
// I am not certain this edge-case is very frequent, but let's make sure we handle it anyway.
|
||||
if majorVersion > 2 {
|
||||
specVersion.Error = errors.New("spec is defined as a swagger (openapi 2.0) spec, but is an openapi 3 or unknown version")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Version = version
|
||||
specVersion.SpecFormat = OAS2
|
||||
}
|
||||
if asyncAPI != nil {
|
||||
specVersion.SpecType = utils.AsyncApi
|
||||
version, majorVersion := parseVersionTypeData(asyncAPI.Value)
|
||||
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
|
||||
// so far there is only 2 as a major release of AsyncAPI
|
||||
if majorVersion > 2 {
|
||||
specVersion.Error = errors.New("spec is defined as asyncapi, but has a major version that is invalid")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Version = version
|
||||
// TODO: format for AsyncAPI.
|
||||
// so far there is only 2 as a major release of AsyncAPI
|
||||
if majorVersion > 2 {
|
||||
specVersion.Error = errors.New("spec is defined as asyncapi, but has a major version that is invalid")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Version = version
|
||||
// TODO: format for AsyncAPI.
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if specVersion.SpecType == "" {
|
||||
if specVersion.SpecType == "" {
|
||||
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
// parse JSON
|
||||
go parseJSON(spec, specVersion)
|
||||
|
||||
specVersion.Error = errors.New("spec type not supported by vacuum, sorry")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
specVersion.Error = errors.New("spec type not supported by vacuum, sorry")
|
||||
return specVersion, specVersion.Error
|
||||
}
|
||||
|
||||
return specVersion, nil
|
||||
return specVersion, nil
|
||||
}
|
||||
|
||||
func parseVersionTypeData(d interface{}) (string, int) {
|
||||
r := []rune(strings.TrimSpace(fmt.Sprintf("%v", d)))
|
||||
return string(r), int(r[0]) - '0'
|
||||
r := []rune(strings.TrimSpace(fmt.Sprintf("%v", d)))
|
||||
return string(r), int(r[0]) - '0'
|
||||
}
|
||||
|
||||
// AreValuesCorrectlyTyped will look through an array of unknown values and check they match
|
||||
// against the supplied type as a string. The return value is empty if everything is OK, or it
|
||||
// contains failures in the form of a value as a key and a message as to why it's not valid
|
||||
func AreValuesCorrectlyTyped(valType string, values interface{}) map[string]string {
|
||||
var arr []interface{}
|
||||
if _, ok := values.([]interface{}); !ok {
|
||||
return nil
|
||||
}
|
||||
arr = values.([]interface{})
|
||||
var arr []interface{}
|
||||
if _, ok := values.([]interface{}); !ok {
|
||||
return nil
|
||||
}
|
||||
arr = values.([]interface{})
|
||||
|
||||
results := make(map[string]string)
|
||||
for _, v := range arr {
|
||||
switch v.(type) {
|
||||
case string:
|
||||
if valType != "string" {
|
||||
results[v.(string)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"string, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case int64:
|
||||
if valType != "integer" && valType != "number" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"integer, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case int:
|
||||
if valType != "integer" && valType != "number" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"integer, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case float64:
|
||||
if valType != "number" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"number, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case bool:
|
||||
if valType != "boolean" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"boolean, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
results := make(map[string]string)
|
||||
for _, v := range arr {
|
||||
switch v.(type) {
|
||||
case string:
|
||||
if valType != "string" {
|
||||
results[v.(string)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"string, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case int64:
|
||||
if valType != "integer" && valType != "number" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"integer, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case int:
|
||||
if valType != "integer" && valType != "number" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"integer, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case float64:
|
||||
if valType != "number" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"number, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
case bool:
|
||||
if valType != "boolean" {
|
||||
results[fmt.Sprintf("%v", v)] = fmt.Sprintf("enum value '%v' is a "+
|
||||
"boolean, but it's defined as a '%v'", v, valType)
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CheckEnumForDuplicates will check an array of nodes to check if there are any duplicates.
|
||||
func CheckEnumForDuplicates(seq []*yaml.Node) []*yaml.Node {
|
||||
var res []*yaml.Node
|
||||
seen := make(map[string]*yaml.Node)
|
||||
var res []*yaml.Node
|
||||
seen := make(map[string]*yaml.Node)
|
||||
|
||||
for _, enum := range seq {
|
||||
if seen[enum.Value] != nil {
|
||||
res = append(res, enum)
|
||||
continue
|
||||
}
|
||||
seen[enum.Value] = enum
|
||||
}
|
||||
return res
|
||||
for _, enum := range seq {
|
||||
if seen[enum.Value] != nil {
|
||||
res = append(res, enum)
|
||||
continue
|
||||
}
|
||||
seen[enum.Value] = enum
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package datamodel
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
"testing"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
// OpenApi3 is used by all OpenAPI 3+ docs
|
||||
OpenApi3 = "openapi"
|
||||
// OpenApi3 is used by all OpenAPI 3+ docs
|
||||
OpenApi3 = "openapi"
|
||||
|
||||
// OpenApi2 is used by all OpenAPI 2 docs, formerly known as swagger.
|
||||
OpenApi2 = "swagger"
|
||||
// OpenApi2 is used by all OpenAPI 2 docs, formerly known as swagger.
|
||||
OpenApi2 = "swagger"
|
||||
|
||||
// AsyncApi is used by akk AsyncAPI docs, all versions.
|
||||
AsyncApi = "asyncapi"
|
||||
// AsyncApi is used by akk AsyncAPI docs, all versions.
|
||||
AsyncApi = "asyncapi"
|
||||
)
|
||||
|
||||
var goodJSON = `{"name":"kitty", "noises":["meow","purrrr","gggrrraaaaaooooww"]}`
|
||||
@@ -95,140 +95,140 @@ info:
|
||||
version: '0.1.0'`
|
||||
|
||||
func TestExtractSpecInfo_ValidJSON(t *testing.T) {
|
||||
_, e := ExtractSpecInfo([]byte(goodJSON))
|
||||
assert.Error(t, e)
|
||||
_, e := ExtractSpecInfo([]byte(goodJSON))
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_InvalidJSON(t *testing.T) {
|
||||
_, e := ExtractSpecInfo([]byte(badJSON))
|
||||
assert.Error(t, e)
|
||||
_, e := ExtractSpecInfo([]byte(badJSON))
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_Nothing(t *testing.T) {
|
||||
_, e := ExtractSpecInfo([]byte(""))
|
||||
assert.Error(t, e)
|
||||
_, e := ExtractSpecInfo([]byte(""))
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_ValidYAML(t *testing.T) {
|
||||
_, e := ExtractSpecInfo([]byte(goodYAML))
|
||||
assert.Error(t, e)
|
||||
_, e := ExtractSpecInfo([]byte(goodYAML))
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_InvalidYAML(t *testing.T) {
|
||||
_, e := ExtractSpecInfo([]byte(badYAML))
|
||||
assert.Error(t, e)
|
||||
_, e := ExtractSpecInfo([]byte(badYAML))
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_InvalidOpenAPIVersion(t *testing.T) {
|
||||
_, e := ExtractSpecInfo([]byte(OpenApiOne))
|
||||
assert.Error(t, e)
|
||||
_, e := ExtractSpecInfo([]byte(OpenApiOne))
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_OpenAPI3(t *testing.T) {
|
||||
|
||||
r, e := ExtractSpecInfo([]byte(OpenApi3Spec))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, utils.OpenApi3, r.SpecType)
|
||||
assert.Equal(t, "3.0.1", r.Version)
|
||||
r, e := ExtractSpecInfo([]byte(OpenApi3Spec))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, utils.OpenApi3, r.SpecType)
|
||||
assert.Equal(t, "3.0.1", r.Version)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_OpenAPIWat(t *testing.T) {
|
||||
|
||||
r, e := ExtractSpecInfo([]byte(OpenApiWat))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, OpenApi3, r.SpecType)
|
||||
assert.Equal(t, "3.2", r.Version)
|
||||
r, e := ExtractSpecInfo([]byte(OpenApiWat))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, OpenApi3, r.SpecType)
|
||||
assert.Equal(t, "3.2", r.Version)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_OpenAPIFalse(t *testing.T) {
|
||||
|
||||
spec, e := ExtractSpecInfo([]byte(OpenApiFalse))
|
||||
assert.NoError(t, e)
|
||||
assert.Equal(t, "false", spec.Version)
|
||||
spec, e := ExtractSpecInfo([]byte(OpenApiFalse))
|
||||
assert.NoError(t, e)
|
||||
assert.Equal(t, "false", spec.Version)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_OpenAPI2(t *testing.T) {
|
||||
|
||||
r, e := ExtractSpecInfo([]byte(OpenApi2Spec))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, OpenApi2, r.SpecType)
|
||||
assert.Equal(t, "2.0.1", r.Version)
|
||||
r, e := ExtractSpecInfo([]byte(OpenApi2Spec))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, OpenApi2, r.SpecType)
|
||||
assert.Equal(t, "2.0.1", r.Version)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_OpenAPI2_OddVersion(t *testing.T) {
|
||||
|
||||
_, e := ExtractSpecInfo([]byte(OpenApi2SpecOdd))
|
||||
assert.NotNil(t, e)
|
||||
assert.Equal(t,
|
||||
"spec is defined as a swagger (openapi 2.0) spec, but is an openapi 3 or unknown version", e.Error())
|
||||
_, e := ExtractSpecInfo([]byte(OpenApi2SpecOdd))
|
||||
assert.NotNil(t, e)
|
||||
assert.Equal(t,
|
||||
"spec is defined as a swagger (openapi 2.0) spec, but is an openapi 3 or unknown version", e.Error())
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_AsyncAPI(t *testing.T) {
|
||||
|
||||
r, e := ExtractSpecInfo([]byte(AsyncAPISpec))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, AsyncApi, r.SpecType)
|
||||
assert.Equal(t, "2.0.0", r.Version)
|
||||
r, e := ExtractSpecInfo([]byte(AsyncAPISpec))
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, AsyncApi, r.SpecType)
|
||||
assert.Equal(t, "2.0.0", r.Version)
|
||||
}
|
||||
|
||||
func TestExtractSpecInfo_AsyncAPI_OddVersion(t *testing.T) {
|
||||
|
||||
_, e := ExtractSpecInfo([]byte(AsyncAPISpecOdd))
|
||||
assert.NotNil(t, e)
|
||||
assert.Equal(t,
|
||||
"spec is defined as asyncapi, but has a major version that is invalid", e.Error())
|
||||
_, e := ExtractSpecInfo([]byte(AsyncAPISpecOdd))
|
||||
assert.NotNil(t, e)
|
||||
assert.Equal(t,
|
||||
"spec is defined as asyncapi, but has a major version that is invalid", e.Error())
|
||||
}
|
||||
|
||||
func TestAreValuesCorrectlyTyped(t *testing.T) {
|
||||
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{"hi"}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{1}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{"nice", 123, int64(12345)}), 2)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{1.2, "burgers"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{true, false, "what"}), 2)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{"hi"}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{1}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{"nice", 123, int64(12345)}), 2)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{1.2, "burgers"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("string", []interface{}{true, false, "what"}), 2)
|
||||
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{1, 2, 3, 4}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{"no way!"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{"nice", 123, int64(12345)}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{999, 1.2, "burgers"}), 2)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{true, false, "what"}), 3)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{1, 2, 3, 4}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{"no way!"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{"nice", 123, int64(12345)}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{999, 1.2, "burgers"}), 2)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("integer", []interface{}{true, false, "what"}), 3)
|
||||
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{1.2345}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{"no way!"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{"nice", 123, 2.353}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{999, 1.2, "burgers"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{true, false, "what"}), 3)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{1.2345}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{"no way!"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{"nice", 123, 2.353}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{999, 1.2, "burgers"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("number", []interface{}{true, false, "what"}), 3)
|
||||
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{true, false, true}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{"no way!"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{"nice", 123, 2.353, true}), 3)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{true, true, "burgers"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{true, false, "what", 1.2, 4}), 3)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{true, false, true}), 0)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{"no way!"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{"nice", 123, 2.353, true}), 3)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{true, true, "burgers"}), 1)
|
||||
assert.Len(t, AreValuesCorrectlyTyped("boolean", []interface{}{true, false, "what", 1.2, 4}), 3)
|
||||
|
||||
assert.Nil(t, AreValuesCorrectlyTyped("boolean", []string{"hi"}))
|
||||
assert.Nil(t, AreValuesCorrectlyTyped("boolean", []string{"hi"}))
|
||||
|
||||
}
|
||||
|
||||
func TestCheckEnumForDuplicates_Success(t *testing.T) {
|
||||
yml := "- yes\n- no\n- crisps"
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 0)
|
||||
yml := "- yes\n- no\n- crisps"
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 0)
|
||||
|
||||
}
|
||||
|
||||
func TestCheckEnumForDuplicates_Fail(t *testing.T) {
|
||||
yml := "- yes\n- no\n- crisps\n- no"
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 1)
|
||||
yml := "- yes\n- no\n- crisps\n- no"
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 1)
|
||||
|
||||
}
|
||||
|
||||
func TestCheckEnumForDuplicates_FailMultiple(t *testing.T) {
|
||||
yml := "- yes\n- no\n- crisps\n- no\n- rice\n- yes\n- no"
|
||||
yml := "- yes\n- no\n- crisps\n- no\n- rice\n- yes\n- no"
|
||||
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 3)
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
assert.Len(t, CheckEnumForDuplicates(rootNode.Content[0].Content), 3)
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
package datamodel
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
"time"
|
||||
"gopkg.in/yaml.v3"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SpecInfo represents information about a supplied specification.
|
||||
type SpecInfo struct {
|
||||
SpecType string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
SpecFormat string `json:"format"`
|
||||
SpecFileType string `json:"fileType"`
|
||||
RootNode *yaml.Node `json:"-"` // reference to the root node of the spec.
|
||||
SpecBytes *[]byte `json:"bytes"` // the original bytes
|
||||
SpecJSONBytes *[]byte `json:"-"` // original bytes converted to JSON
|
||||
SpecJSON *map[string]interface{} `json:"-"` // standard JSON map of original bytes
|
||||
Error error `json:"-"` // something go wrong?
|
||||
APISchema string `json:"-"` // API Schema for supplied spec type (2 or 3)
|
||||
Generated time.Time `json:"-"`
|
||||
JsonParsingChannel chan bool `json:"-"`
|
||||
SpecType string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
SpecFormat string `json:"format"`
|
||||
SpecFileType string `json:"fileType"`
|
||||
RootNode *yaml.Node `json:"-"` // reference to the root node of the spec.
|
||||
SpecBytes *[]byte `json:"bytes"` // the original bytes
|
||||
SpecJSONBytes *[]byte `json:"-"` // original bytes converted to JSON
|
||||
SpecJSON *map[string]interface{} `json:"-"` // standard JSON map of original bytes
|
||||
Error error `json:"-"` // something go wrong?
|
||||
APISchema string `json:"-"` // API Schema for supplied spec type (2 or 3)
|
||||
Generated time.Time `json:"-"`
|
||||
JsonParsingChannel chan bool `json:"-"`
|
||||
}
|
||||
|
||||
// GetJSONParsingChannel returns a channel that will close once async JSON parsing is completed.
|
||||
// This is required as rules may start executing before we're even done reading in the spec to JSON.
|
||||
func (si SpecInfo) GetJSONParsingChannel() chan bool {
|
||||
return si.JsonParsingChannel
|
||||
return si.JsonParsingChannel
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ package main
|
||||
import "github.com/pb33f/libopenapi/utils"
|
||||
|
||||
func main() {
|
||||
utils.BuildPath("nope", []string{"one"})
|
||||
utils.BuildPath("nope", []string{"one"})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type petstore []byte
|
||||
@@ -13,429 +13,429 @@ type petstore []byte
|
||||
var once sync.Once
|
||||
|
||||
var (
|
||||
psBytes petstore
|
||||
psBytes petstore
|
||||
)
|
||||
|
||||
func getPetstore() petstore {
|
||||
once.Do(func() {
|
||||
psBytes, _ = ioutil.ReadFile("../test_specs/petstorev3.json")
|
||||
})
|
||||
return psBytes
|
||||
once.Do(func() {
|
||||
psBytes, _ = ioutil.ReadFile("../test_specs/petstorev3.json")
|
||||
})
|
||||
return psBytes
|
||||
}
|
||||
|
||||
func TestRenderCodeSnippet(t *testing.T) {
|
||||
code := []string{"hey", "ho", "let's", "go!"}
|
||||
startNode := &yaml.Node{
|
||||
Line: 1,
|
||||
}
|
||||
rendered := RenderCodeSnippet(startNode, code, 1, 3)
|
||||
assert.Equal(t, "hey\nho\nlet's\n", rendered)
|
||||
code := []string{"hey", "ho", "let's", "go!"}
|
||||
startNode := &yaml.Node{
|
||||
Line: 1,
|
||||
}
|
||||
rendered := RenderCodeSnippet(startNode, code, 1, 3)
|
||||
assert.Equal(t, "hey\nho\nlet's\n", rendered)
|
||||
|
||||
}
|
||||
|
||||
func TestFindNodes(t *testing.T) {
|
||||
nodes, err := FindNodes(getPetstore(), "$.info.contact")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, nodes)
|
||||
assert.Len(t, nodes, 1)
|
||||
nodes, err := FindNodes(getPetstore(), "$.info.contact")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, nodes)
|
||||
assert.Len(t, nodes, 1)
|
||||
}
|
||||
|
||||
func TestFindNodes_BadPath(t *testing.T) {
|
||||
nodes, err := FindNodes(getPetstore(), "I am not valid")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, nodes)
|
||||
nodes, err := FindNodes(getPetstore(), "I am not valid")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, nodes)
|
||||
}
|
||||
|
||||
func TestFindLastChildNode(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$.info")
|
||||
lastNode := FindLastChildNode(nodes[0])
|
||||
assert.Equal(t, "1.0.11", lastNode.Value) // should be the version.
|
||||
nodes, _ := FindNodes(getPetstore(), "$.info")
|
||||
lastNode := FindLastChildNode(nodes[0])
|
||||
assert.Equal(t, "1.0.11", lastNode.Value) // should be the version.
|
||||
}
|
||||
|
||||
func TestFindLastChildNode_WithKids(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$.paths./pet")
|
||||
lastNode := FindLastChildNode(nodes[0])
|
||||
assert.Equal(t, "read:pets", lastNode.Value)
|
||||
nodes, _ := FindNodes(getPetstore(), "$.paths./pet")
|
||||
lastNode := FindLastChildNode(nodes[0])
|
||||
assert.Equal(t, "read:pets", lastNode.Value)
|
||||
}
|
||||
|
||||
func TestFindLastChildNode_NotFound(t *testing.T) {
|
||||
node := &yaml.Node{
|
||||
Value: "same",
|
||||
}
|
||||
lastNode := FindLastChildNode(node)
|
||||
assert.Equal(t, "same", lastNode.Value) // should be the same node
|
||||
node := &yaml.Node{
|
||||
Value: "same",
|
||||
}
|
||||
lastNode := FindLastChildNode(node)
|
||||
assert.Equal(t, "same", lastNode.Value) // should be the same node
|
||||
}
|
||||
|
||||
func TestBuildPath(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "$.fresh.fish.and.chicken.nuggets",
|
||||
BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets"}))
|
||||
assert.Equal(t, "$.fresh.fish.and.chicken.nuggets",
|
||||
BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets"}))
|
||||
}
|
||||
|
||||
func TestBuildPath_WithTrailingPeriod(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "$.fresh.fish.and.chicken.nuggets",
|
||||
BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets", ""}))
|
||||
assert.Equal(t, "$.fresh.fish.and.chicken.nuggets",
|
||||
BuildPath("$.fresh.fish", []string{"and", "chicken", "nuggets", ""}))
|
||||
}
|
||||
|
||||
func TestFindNodesWithoutDeserializing(t *testing.T) {
|
||||
root, err := FindNodes(getPetstore(), "$")
|
||||
nodes, err := FindNodesWithoutDeserializing(root[0], "$.info.contact")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, nodes)
|
||||
assert.Len(t, nodes, 1)
|
||||
root, err := FindNodes(getPetstore(), "$")
|
||||
nodes, err := FindNodesWithoutDeserializing(root[0], "$.info.contact")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, nodes)
|
||||
assert.Len(t, nodes, 1)
|
||||
}
|
||||
|
||||
func TestFindNodesWithoutDeserializing_InvalidPath(t *testing.T) {
|
||||
root, err := FindNodes(getPetstore(), "$")
|
||||
nodes, err := FindNodesWithoutDeserializing(root[0], "I love a good curry")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, nodes)
|
||||
root, err := FindNodes(getPetstore(), "$")
|
||||
nodes, err := FindNodesWithoutDeserializing(root[0], "I love a good curry")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, nodes)
|
||||
}
|
||||
|
||||
func TestConvertInterfaceIntoStringMap(t *testing.T) {
|
||||
var d interface{}
|
||||
n := make(map[string]string)
|
||||
n["melody"] = "baby girl"
|
||||
d = n
|
||||
parsed := ConvertInterfaceIntoStringMap(d)
|
||||
assert.Equal(t, "baby girl", parsed["melody"])
|
||||
var d interface{}
|
||||
n := make(map[string]string)
|
||||
n["melody"] = "baby girl"
|
||||
d = n
|
||||
parsed := ConvertInterfaceIntoStringMap(d)
|
||||
assert.Equal(t, "baby girl", parsed["melody"])
|
||||
}
|
||||
|
||||
func TestConvertInterfaceIntoStringMap_NoType(t *testing.T) {
|
||||
var d interface{}
|
||||
n := make(map[string]interface{})
|
||||
n["melody"] = "baby girl"
|
||||
d = n
|
||||
parsed := ConvertInterfaceIntoStringMap(d)
|
||||
assert.Equal(t, "baby girl", parsed["melody"])
|
||||
var d interface{}
|
||||
n := make(map[string]interface{})
|
||||
n["melody"] = "baby girl"
|
||||
d = n
|
||||
parsed := ConvertInterfaceIntoStringMap(d)
|
||||
assert.Equal(t, "baby girl", parsed["melody"])
|
||||
}
|
||||
|
||||
func TestConvertInterfaceToStringArray(t *testing.T) {
|
||||
var d interface{}
|
||||
n := make(map[string][]string)
|
||||
n["melody"] = []string{"melody", "is", "my", "baby"}
|
||||
d = n
|
||||
parsed := ConvertInterfaceToStringArray(d)
|
||||
assert.Equal(t, "baby", parsed[3])
|
||||
var d interface{}
|
||||
n := make(map[string][]string)
|
||||
n["melody"] = []string{"melody", "is", "my", "baby"}
|
||||
d = n
|
||||
parsed := ConvertInterfaceToStringArray(d)
|
||||
assert.Equal(t, "baby", parsed[3])
|
||||
}
|
||||
|
||||
func TestConvertInterfaceToStringArray_NoType(t *testing.T) {
|
||||
var d interface{}
|
||||
m := make([]interface{}, 4)
|
||||
n := make(map[string]interface{})
|
||||
m[0] = "melody"
|
||||
m[1] = "is"
|
||||
m[2] = "my"
|
||||
m[3] = "baby"
|
||||
n["melody"] = m
|
||||
d = n
|
||||
parsed := ConvertInterfaceToStringArray(d)
|
||||
assert.Equal(t, "baby", parsed[3])
|
||||
var d interface{}
|
||||
m := make([]interface{}, 4)
|
||||
n := make(map[string]interface{})
|
||||
m[0] = "melody"
|
||||
m[1] = "is"
|
||||
m[2] = "my"
|
||||
m[3] = "baby"
|
||||
n["melody"] = m
|
||||
d = n
|
||||
parsed := ConvertInterfaceToStringArray(d)
|
||||
assert.Equal(t, "baby", parsed[3])
|
||||
}
|
||||
|
||||
func TestConvertInterfaceToStringArray_Invalid(t *testing.T) {
|
||||
var d interface{}
|
||||
d = "I am a carrot"
|
||||
parsed := ConvertInterfaceToStringArray(d)
|
||||
assert.Nil(t, parsed)
|
||||
var d interface{}
|
||||
d = "I am a carrot"
|
||||
parsed := ConvertInterfaceToStringArray(d)
|
||||
assert.Nil(t, parsed)
|
||||
}
|
||||
|
||||
func TestConvertInterfaceArrayToStringArray(t *testing.T) {
|
||||
var d interface{}
|
||||
m := []string{"maddox", "is", "my", "little", "champion"}
|
||||
d = m
|
||||
parsed := ConvertInterfaceArrayToStringArray(d)
|
||||
assert.Equal(t, "little", parsed[3])
|
||||
var d interface{}
|
||||
m := []string{"maddox", "is", "my", "little", "champion"}
|
||||
d = m
|
||||
parsed := ConvertInterfaceArrayToStringArray(d)
|
||||
assert.Equal(t, "little", parsed[3])
|
||||
}
|
||||
|
||||
func TestConvertInterfaceArrayToStringArray_NoType(t *testing.T) {
|
||||
var d interface{}
|
||||
m := make([]interface{}, 4)
|
||||
m[0] = "melody"
|
||||
m[1] = "is"
|
||||
m[2] = "my"
|
||||
m[3] = "baby"
|
||||
d = m
|
||||
parsed := ConvertInterfaceArrayToStringArray(d)
|
||||
assert.Equal(t, "baby", parsed[3])
|
||||
var d interface{}
|
||||
m := make([]interface{}, 4)
|
||||
m[0] = "melody"
|
||||
m[1] = "is"
|
||||
m[2] = "my"
|
||||
m[3] = "baby"
|
||||
d = m
|
||||
parsed := ConvertInterfaceArrayToStringArray(d)
|
||||
assert.Equal(t, "baby", parsed[3])
|
||||
}
|
||||
|
||||
func TestConvertInterfaceArrayToStringArray_Invalid(t *testing.T) {
|
||||
var d interface{}
|
||||
d = "weed is good"
|
||||
parsed := ConvertInterfaceArrayToStringArray(d)
|
||||
assert.Nil(t, parsed)
|
||||
var d interface{}
|
||||
d = "weed is good"
|
||||
parsed := ConvertInterfaceArrayToStringArray(d)
|
||||
assert.Nil(t, parsed)
|
||||
}
|
||||
|
||||
func TestExtractValueFromInterfaceMap(t *testing.T) {
|
||||
var d interface{}
|
||||
m := make(map[string][]string)
|
||||
m["melody"] = []string{"is", "my", "baby"}
|
||||
d = m
|
||||
parsed := ExtractValueFromInterfaceMap("melody", d)
|
||||
assert.Equal(t, "baby", parsed.([]string)[2])
|
||||
var d interface{}
|
||||
m := make(map[string][]string)
|
||||
m["melody"] = []string{"is", "my", "baby"}
|
||||
d = m
|
||||
parsed := ExtractValueFromInterfaceMap("melody", d)
|
||||
assert.Equal(t, "baby", parsed.([]string)[2])
|
||||
}
|
||||
|
||||
func TestExtractValueFromInterfaceMap_NoType(t *testing.T) {
|
||||
var d interface{}
|
||||
m := make(map[string]interface{})
|
||||
n := make([]interface{}, 3)
|
||||
n[0] = "maddy"
|
||||
n[1] = "the"
|
||||
n[2] = "champion"
|
||||
m["maddy"] = n
|
||||
d = m
|
||||
parsed := ExtractValueFromInterfaceMap("maddy", d)
|
||||
assert.Equal(t, "champion", parsed.([]interface{})[2])
|
||||
var d interface{}
|
||||
m := make(map[string]interface{})
|
||||
n := make([]interface{}, 3)
|
||||
n[0] = "maddy"
|
||||
n[1] = "the"
|
||||
n[2] = "champion"
|
||||
m["maddy"] = n
|
||||
d = m
|
||||
parsed := ExtractValueFromInterfaceMap("maddy", d)
|
||||
assert.Equal(t, "champion", parsed.([]interface{})[2])
|
||||
}
|
||||
|
||||
func TestExtractValueFromInterfaceMap_Flat(t *testing.T) {
|
||||
var d interface{}
|
||||
m := make(map[string]interface{})
|
||||
m["maddy"] = "niblet"
|
||||
d = m
|
||||
parsed := ExtractValueFromInterfaceMap("maddy", d)
|
||||
assert.Equal(t, "niblet", parsed.(interface{}))
|
||||
var d interface{}
|
||||
m := make(map[string]interface{})
|
||||
m["maddy"] = "niblet"
|
||||
d = m
|
||||
parsed := ExtractValueFromInterfaceMap("maddy", d)
|
||||
assert.Equal(t, "niblet", parsed.(interface{}))
|
||||
}
|
||||
|
||||
func TestExtractValueFromInterfaceMap_NotFound(t *testing.T) {
|
||||
var d interface{}
|
||||
d = "not a map"
|
||||
parsed := ExtractValueFromInterfaceMap("melody", d)
|
||||
assert.Nil(t, parsed)
|
||||
var d interface{}
|
||||
d = "not a map"
|
||||
parsed := ExtractValueFromInterfaceMap("melody", d)
|
||||
assert.Nil(t, parsed)
|
||||
}
|
||||
|
||||
func TestFindFirstKeyNode(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
key, value := FindFirstKeyNode("operationId", nodes, 0)
|
||||
assert.NotNil(t, key)
|
||||
assert.NotNil(t, value)
|
||||
assert.Equal(t, 55, key.Line)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
key, value := FindFirstKeyNode("operationId", nodes, 0)
|
||||
assert.NotNil(t, key)
|
||||
assert.NotNil(t, value)
|
||||
assert.Equal(t, 55, key.Line)
|
||||
}
|
||||
|
||||
func TestFindFirstKeyNode_NotFound(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
key, value := FindFirstKeyNode("i-do-not-exist-in-the-doc", nodes, 0)
|
||||
assert.Nil(t, key)
|
||||
assert.Nil(t, value)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
key, value := FindFirstKeyNode("i-do-not-exist-in-the-doc", nodes, 0)
|
||||
assert.Nil(t, key)
|
||||
assert.Nil(t, value)
|
||||
}
|
||||
|
||||
func TestFindFirstKeyNode_Map(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
key, value := FindFirstKeyNode("pet", nodes, 0)
|
||||
assert.NotNil(t, key)
|
||||
assert.NotNil(t, value)
|
||||
assert.Equal(t, 27, key.Line)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
key, value := FindFirstKeyNode("pet", nodes, 0)
|
||||
assert.NotNil(t, key)
|
||||
assert.NotNil(t, value)
|
||||
assert.Equal(t, 27, key.Line)
|
||||
}
|
||||
|
||||
func TestFindKeyNodeTop(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNodeTop("info", nodes[0].Content)
|
||||
assert.NotNil(t, k)
|
||||
assert.NotNil(t, v)
|
||||
assert.Equal(t, 3, k.Line)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNodeTop("info", nodes[0].Content)
|
||||
assert.NotNil(t, k)
|
||||
assert.NotNil(t, v)
|
||||
assert.Equal(t, 3, k.Line)
|
||||
}
|
||||
|
||||
func TestFindKeyNodeTop_NotFound(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNodeTop("i am a giant potato", nodes[0].Content)
|
||||
assert.Nil(t, k)
|
||||
assert.Nil(t, v)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNodeTop("i am a giant potato", nodes[0].Content)
|
||||
assert.Nil(t, k)
|
||||
assert.Nil(t, v)
|
||||
}
|
||||
|
||||
func TestFindKeyNode(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNode("/pet", nodes[0].Content)
|
||||
assert.NotNil(t, k)
|
||||
assert.NotNil(t, v)
|
||||
assert.Equal(t, 47, k.Line)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNode("/pet", nodes[0].Content)
|
||||
assert.NotNil(t, k)
|
||||
assert.NotNil(t, v)
|
||||
assert.Equal(t, 47, k.Line)
|
||||
}
|
||||
|
||||
func TestFindKeyNode_NotFound(t *testing.T) {
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNode("I am not anything at all", nodes[0].Content)
|
||||
assert.Nil(t, k)
|
||||
assert.Nil(t, v)
|
||||
nodes, _ := FindNodes(getPetstore(), "$")
|
||||
k, v := FindKeyNode("I am not anything at all", nodes[0].Content)
|
||||
assert.Nil(t, k)
|
||||
assert.Nil(t, v)
|
||||
}
|
||||
|
||||
func TestMakeTagReadable(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!map",
|
||||
}
|
||||
assert.Equal(t, ObjectLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!seq"
|
||||
assert.Equal(t, ArrayLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!str"
|
||||
assert.Equal(t, StringLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!int"
|
||||
assert.Equal(t, IntegerLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!float"
|
||||
assert.Equal(t, NumberLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!bool"
|
||||
assert.Equal(t, BooleanLabel, MakeTagReadable(n))
|
||||
n.Tag = "mr potato man is here"
|
||||
assert.Equal(t, "unknown", MakeTagReadable(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!map",
|
||||
}
|
||||
assert.Equal(t, ObjectLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!seq"
|
||||
assert.Equal(t, ArrayLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!str"
|
||||
assert.Equal(t, StringLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!int"
|
||||
assert.Equal(t, IntegerLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!float"
|
||||
assert.Equal(t, NumberLabel, MakeTagReadable(n))
|
||||
n.Tag = "!!bool"
|
||||
assert.Equal(t, BooleanLabel, MakeTagReadable(n))
|
||||
n.Tag = "mr potato man is here"
|
||||
assert.Equal(t, "unknown", MakeTagReadable(n))
|
||||
}
|
||||
|
||||
func TestIsNodeMap(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!map",
|
||||
}
|
||||
assert.True(t, IsNodeMap(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeMap(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!map",
|
||||
}
|
||||
assert.True(t, IsNodeMap(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeMap(n))
|
||||
}
|
||||
|
||||
func TestIsNodeMap_Nil(t *testing.T) {
|
||||
assert.False(t, IsNodeMap(nil))
|
||||
assert.False(t, IsNodeMap(nil))
|
||||
}
|
||||
|
||||
func TestIsNodePolyMorphic(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Content: []*yaml.Node{
|
||||
{
|
||||
Value: "anyOf",
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.True(t, IsNodePolyMorphic(n))
|
||||
n.Content[0].Value = "cakes"
|
||||
assert.False(t, IsNodePolyMorphic(n))
|
||||
n := &yaml.Node{
|
||||
Content: []*yaml.Node{
|
||||
{
|
||||
Value: "anyOf",
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.True(t, IsNodePolyMorphic(n))
|
||||
n.Content[0].Value = "cakes"
|
||||
assert.False(t, IsNodePolyMorphic(n))
|
||||
}
|
||||
|
||||
func TestIsNodeArray(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!seq",
|
||||
}
|
||||
assert.True(t, IsNodeArray(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeArray(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!seq",
|
||||
}
|
||||
assert.True(t, IsNodeArray(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeArray(n))
|
||||
}
|
||||
|
||||
func TestIsNodeArray_Nil(t *testing.T) {
|
||||
assert.False(t, IsNodeArray(nil))
|
||||
assert.False(t, IsNodeArray(nil))
|
||||
}
|
||||
|
||||
func TestIsNodeStringValue(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!str",
|
||||
}
|
||||
assert.True(t, IsNodeStringValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeStringValue(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!str",
|
||||
}
|
||||
assert.True(t, IsNodeStringValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeStringValue(n))
|
||||
}
|
||||
|
||||
func TestIsNodeStringValue_Nil(t *testing.T) {
|
||||
assert.False(t, IsNodeStringValue(nil))
|
||||
assert.False(t, IsNodeStringValue(nil))
|
||||
}
|
||||
|
||||
func TestIsNodeIntValue(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!int",
|
||||
}
|
||||
assert.True(t, IsNodeIntValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeIntValue(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!int",
|
||||
}
|
||||
assert.True(t, IsNodeIntValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeIntValue(n))
|
||||
}
|
||||
|
||||
func TestIsNodeIntValue_Nil(t *testing.T) {
|
||||
assert.False(t, IsNodeIntValue(nil))
|
||||
assert.False(t, IsNodeIntValue(nil))
|
||||
}
|
||||
|
||||
func TestIsNodeFloatValue(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!float",
|
||||
}
|
||||
assert.True(t, IsNodeFloatValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeFloatValue(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!float",
|
||||
}
|
||||
assert.True(t, IsNodeFloatValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeFloatValue(n))
|
||||
}
|
||||
|
||||
func TestIsNodeFloatValue_Nil(t *testing.T) {
|
||||
assert.False(t, IsNodeFloatValue(nil))
|
||||
assert.False(t, IsNodeFloatValue(nil))
|
||||
}
|
||||
|
||||
func TestIsNodeBoolValue(t *testing.T) {
|
||||
n := &yaml.Node{
|
||||
Tag: "!!bool",
|
||||
}
|
||||
assert.True(t, IsNodeBoolValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeBoolValue(n))
|
||||
n := &yaml.Node{
|
||||
Tag: "!!bool",
|
||||
}
|
||||
assert.True(t, IsNodeBoolValue(n))
|
||||
n.Tag = "!!pizza"
|
||||
assert.False(t, IsNodeBoolValue(n))
|
||||
}
|
||||
|
||||
func TestIsNodeBoolValue_Nil(t *testing.T) {
|
||||
assert.False(t, IsNodeBoolValue(nil))
|
||||
assert.False(t, IsNodeBoolValue(nil))
|
||||
}
|
||||
|
||||
func TestFixContext(t *testing.T) {
|
||||
assert.Equal(t, "$.nuggets[12].name", FixContext("(root).nuggets.12.name"))
|
||||
assert.Equal(t, "$.nuggets[12].name", FixContext("(root).nuggets.12.name"))
|
||||
}
|
||||
|
||||
func TestFixContext_HttpCode(t *testing.T) {
|
||||
assert.Equal(t, "$.nuggets.404.name", FixContext("(root).nuggets.404.name"))
|
||||
assert.Equal(t, "$.nuggets.404.name", FixContext("(root).nuggets.404.name"))
|
||||
}
|
||||
|
||||
func TestIsJSON(t *testing.T) {
|
||||
assert.True(t, IsJSON("{'hello':'there'}"))
|
||||
assert.False(t, IsJSON("potato shoes"))
|
||||
assert.False(t, IsJSON(""))
|
||||
assert.True(t, IsJSON("{'hello':'there'}"))
|
||||
assert.False(t, IsJSON("potato shoes"))
|
||||
assert.False(t, IsJSON(""))
|
||||
}
|
||||
|
||||
func TestIsYAML(t *testing.T) {
|
||||
assert.True(t, IsYAML("hello:\n there:\n my-name: is quobix"))
|
||||
assert.True(t, IsYAML("potato shoes"))
|
||||
assert.False(t, IsYAML("{'hello':'there'}"))
|
||||
assert.False(t, IsYAML(""))
|
||||
assert.False(t, IsYAML("8908: hello: yeah: \n12309812: :123"))
|
||||
assert.True(t, IsYAML("hello:\n there:\n my-name: is quobix"))
|
||||
assert.True(t, IsYAML("potato shoes"))
|
||||
assert.False(t, IsYAML("{'hello':'there'}"))
|
||||
assert.False(t, IsYAML(""))
|
||||
assert.False(t, IsYAML("8908: hello: yeah: \n12309812: :123"))
|
||||
}
|
||||
|
||||
func TestConvertYAMLtoJSON(t *testing.T) {
|
||||
str, err := ConvertYAMLtoJSON([]byte("hello: there"))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, str)
|
||||
assert.Equal(t, "{\"hello\":\"there\"}", string(str))
|
||||
str, err := ConvertYAMLtoJSON([]byte("hello: there"))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, str)
|
||||
assert.Equal(t, "{\"hello\":\"there\"}", string(str))
|
||||
|
||||
str, err = ConvertYAMLtoJSON([]byte("gonna: break: you:\nyeah:yeah:yeah"))
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, str)
|
||||
str, err = ConvertYAMLtoJSON([]byte("gonna: break: you:\nyeah:yeah:yeah"))
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, str)
|
||||
}
|
||||
|
||||
func TestIsHttpVerb(t *testing.T) {
|
||||
assert.True(t, IsHttpVerb("get"))
|
||||
assert.True(t, IsHttpVerb("post"))
|
||||
assert.False(t, IsHttpVerb("nuggets"))
|
||||
assert.True(t, IsHttpVerb("get"))
|
||||
assert.True(t, IsHttpVerb("post"))
|
||||
assert.False(t, IsHttpVerb("nuggets"))
|
||||
}
|
||||
|
||||
func TestConvertComponentIdIntoFriendlyPathSearch(t *testing.T) {
|
||||
segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/chicken/chips/pizza/cake")
|
||||
assert.Equal(t, "$.chicken.chips.pizza['cake']", path)
|
||||
assert.Equal(t, "cake", segment)
|
||||
segment, path := ConvertComponentIdIntoFriendlyPathSearch("#/chicken/chips/pizza/cake")
|
||||
assert.Equal(t, "$.chicken.chips.pizza['cake']", path)
|
||||
assert.Equal(t, "cake", segment)
|
||||
}
|
||||
|
||||
func TestConvertComponentIdIntoPath(t *testing.T) {
|
||||
segment, path := ConvertComponentIdIntoPath("#/chicken/chips/pizza/cake")
|
||||
assert.Equal(t, "$.chicken.chips.pizza.cake", path)
|
||||
assert.Equal(t, "cake", segment)
|
||||
segment, path := ConvertComponentIdIntoPath("#/chicken/chips/pizza/cake")
|
||||
assert.Equal(t, "$.chicken.chips.pizza.cake", path)
|
||||
assert.Equal(t, "cake", segment)
|
||||
}
|
||||
|
||||
func TestDetectCase(t *testing.T) {
|
||||
assert.Equal(t, PascalCase, DetectCase("PizzaPie"))
|
||||
assert.Equal(t, CamelCase, DetectCase("anyoneForTennis"))
|
||||
assert.Equal(t, ScreamingSnakeCase, DetectCase("I_LOVE_BEER"))
|
||||
assert.Equal(t, ScreamingKebabCase, DetectCase("I-LOVE-BURGERS"))
|
||||
assert.Equal(t, SnakeCase, DetectCase("snakes_on_a_plane"))
|
||||
assert.Equal(t, KebabCase, DetectCase("chicken-be-be-beef-or-pork"))
|
||||
assert.Equal(t, RegularCase, DetectCase("kebab-TimeIn_london-TOWN"))
|
||||
assert.Equal(t, PascalCase, DetectCase("PizzaPie"))
|
||||
assert.Equal(t, CamelCase, DetectCase("anyoneForTennis"))
|
||||
assert.Equal(t, ScreamingSnakeCase, DetectCase("I_LOVE_BEER"))
|
||||
assert.Equal(t, ScreamingKebabCase, DetectCase("I-LOVE-BURGERS"))
|
||||
assert.Equal(t, SnakeCase, DetectCase("snakes_on_a_plane"))
|
||||
assert.Equal(t, KebabCase, DetectCase("chicken-be-be-beef-or-pork"))
|
||||
assert.Equal(t, RegularCase, DetectCase("kebab-TimeIn_london-TOWN"))
|
||||
}
|
||||
|
||||
func TestConvertCase(t *testing.T) {
|
||||
str1 := "chicken-nuggets-chicken-soup"
|
||||
assert.Equal(t, "chickenNuggetsChickenSoup", ConvertCase(str1, CamelCase))
|
||||
assert.Equal(t, "ChickenNuggetsChickenSoup", ConvertCase(str1, PascalCase))
|
||||
assert.Equal(t, "chicken_nuggets_chicken_soup", ConvertCase(str1, SnakeCase))
|
||||
assert.Equal(t, str1, ConvertCase(str1, KebabCase))
|
||||
assert.Equal(t, "CHICKEN-NUGGETS-CHICKEN-SOUP", ConvertCase(str1, ScreamingKebabCase))
|
||||
assert.Equal(t, "CHICKEN_NUGGETS_CHICKEN_SOUP", ConvertCase(str1, ScreamingSnakeCase))
|
||||
str1 := "chicken-nuggets-chicken-soup"
|
||||
assert.Equal(t, "chickenNuggetsChickenSoup", ConvertCase(str1, CamelCase))
|
||||
assert.Equal(t, "ChickenNuggetsChickenSoup", ConvertCase(str1, PascalCase))
|
||||
assert.Equal(t, "chicken_nuggets_chicken_soup", ConvertCase(str1, SnakeCase))
|
||||
assert.Equal(t, str1, ConvertCase(str1, KebabCase))
|
||||
assert.Equal(t, "CHICKEN-NUGGETS-CHICKEN-SOUP", ConvertCase(str1, ScreamingKebabCase))
|
||||
assert.Equal(t, "CHICKEN_NUGGETS_CHICKEN_SOUP", ConvertCase(str1, ScreamingSnakeCase))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user