mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* update vendor directory, add go.opencensus.io * update imports * oops * s/opentracing/opencensus/ & remove prometheus / zipkin stuff & remove old stats * the dep train rides again * fix gin build * deps from last guy * start in on the agent metrics * she builds * remove tags for now, cardinality error is fussing. subscribe instead of register * update to patched version of opencensus to proceed for now TODO switch to a release * meh fix imports * println debug the bad boys * lace it with the tags * update deps again * fix all inconsistent cardinality errors * add our own logger * fix init * fix oom measure * remove bugged removal code * fix s3 measures * fix prom handler nil
823 lines
31 KiB
Go
823 lines
31 KiB
Go
package analysis
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/go-openapi/jsonpointer"
|
|
"github.com/go-openapi/spec"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestSaveDefinition(t *testing.T) {
|
|
sp := &spec.Swagger{}
|
|
saveSchema(sp, "theName", spec.StringProperty())
|
|
assert.Contains(t, sp.Definitions, "theName")
|
|
}
|
|
|
|
func TestNameFromRef(t *testing.T) {
|
|
values := []struct{ Source, Expected string }{
|
|
{"#/definitions/errorModel", "errorModel"},
|
|
{"http://somewhere.com/definitions/errorModel", "errorModel"},
|
|
{"http://somewhere.com/definitions/errorModel.json", "errorModel"},
|
|
{"/definitions/errorModel", "errorModel"},
|
|
{"/definitions/errorModel.json", "errorModel"},
|
|
{"http://somewhere.com", "somewhereCom"},
|
|
{"#", ""},
|
|
}
|
|
|
|
for _, v := range values {
|
|
assert.Equal(t, v.Expected, nameFromRef(spec.MustCreateRef(v.Source)))
|
|
}
|
|
}
|
|
|
|
func TestDefinitionName(t *testing.T) {
|
|
values := []struct {
|
|
Source, Expected string
|
|
Definitions spec.Definitions
|
|
}{
|
|
{"#/definitions/errorModel", "errorModel", map[string]spec.Schema(nil)},
|
|
{"http://somewhere.com/definitions/errorModel", "errorModel", map[string]spec.Schema(nil)},
|
|
{"#/definitions/errorModel", "errorModel", map[string]spec.Schema{"apples": *spec.StringProperty()}},
|
|
{"#/definitions/errorModel", "errorModelOAIGen", map[string]spec.Schema{"errorModel": *spec.StringProperty()}},
|
|
{"#/definitions/errorModel", "errorModelOAIGen1", map[string]spec.Schema{"errorModel": *spec.StringProperty(), "errorModelOAIGen": *spec.StringProperty()}},
|
|
{"#", "oaiGen", nil},
|
|
}
|
|
|
|
for _, v := range values {
|
|
assert.Equal(t, v.Expected, uniqifyName(v.Definitions, nameFromRef(spec.MustCreateRef(v.Source))))
|
|
}
|
|
}
|
|
|
|
func TestUpdateRef(t *testing.T) {
|
|
bp := filepath.Join("fixtures", "external_definitions.yml")
|
|
sp, err := loadSpec(bp)
|
|
if assert.NoError(t, err) {
|
|
|
|
values := []struct {
|
|
Key string
|
|
Ref spec.Ref
|
|
}{
|
|
{"#/parameters/someParam/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/parameters/1/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/responses/someResponse/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/namedAgain", spec.MustCreateRef("#/definitions/named")},
|
|
{"#/definitions/datedTag/allOf/1", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/datedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/datedTaggedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/datedTaggedRecords/additionalItems", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/otherRecords/items", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/tags/additionalProperties", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/namedThing/properties/name", spec.MustCreateRef("#/definitions/named")},
|
|
}
|
|
|
|
for _, v := range values {
|
|
err := updateRef(sp, v.Key, v.Ref)
|
|
if assert.NoError(t, err) {
|
|
ptr, err := jsonpointer.New(v.Key[1:])
|
|
if assert.NoError(t, err) {
|
|
vv, _, err := ptr.Get(sp)
|
|
|
|
if assert.NoError(t, err) {
|
|
switch tv := vv.(type) {
|
|
case *spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String())
|
|
case spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String())
|
|
case *spec.SchemaOrBool:
|
|
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String())
|
|
case *spec.SchemaOrArray:
|
|
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String())
|
|
default:
|
|
assert.Fail(t, "unknown type", "got %T", vv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestImportExternalReferences(t *testing.T) {
|
|
bp := filepath.Join(".", "fixtures", "external_definitions.yml")
|
|
sp, err := loadSpec(bp)
|
|
if assert.NoError(t, err) {
|
|
|
|
values := []struct {
|
|
Key string
|
|
Ref spec.Ref
|
|
}{
|
|
{"#/parameters/someParam/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/parameters/1/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/responses/someResponse/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/namedAgain", spec.MustCreateRef("#/definitions/named")},
|
|
{"#/definitions/datedTag/allOf/1", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/datedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/datedTaggedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/datedTaggedRecords/additionalItems", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/otherRecords/items", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/tags/additionalProperties", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/namedThing/properties/name", spec.MustCreateRef("#/definitions/named")},
|
|
}
|
|
for _, v := range values {
|
|
// technically not necessary to run for each value, but if things go right
|
|
// this is idempotent, so having it repeat shouldn't matter
|
|
// this validates that behavior
|
|
err := importExternalReferences(&FlattenOpts{
|
|
Spec: New(sp),
|
|
BasePath: bp,
|
|
})
|
|
|
|
if assert.NoError(t, err) {
|
|
|
|
ptr, err := jsonpointer.New(v.Key[1:])
|
|
if assert.NoError(t, err) {
|
|
vv, _, err := ptr.Get(sp)
|
|
|
|
if assert.NoError(t, err) {
|
|
switch tv := vv.(type) {
|
|
case *spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "for %s", v.Key)
|
|
case spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "for %s", v.Key)
|
|
case *spec.SchemaOrBool:
|
|
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String(), "for %s", v.Key)
|
|
case *spec.SchemaOrArray:
|
|
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String(), "for %s", v.Key)
|
|
default:
|
|
assert.Fail(t, "unknown type", "got %T", vv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
assert.Len(t, sp.Definitions, 11)
|
|
assert.Contains(t, sp.Definitions, "tag")
|
|
assert.Contains(t, sp.Definitions, "named")
|
|
assert.Contains(t, sp.Definitions, "record")
|
|
}
|
|
}
|
|
|
|
func TestRewriteSchemaRef(t *testing.T) {
|
|
bp := filepath.Join("fixtures", "inline_schemas.yml")
|
|
sp, err := loadSpec(bp)
|
|
if assert.NoError(t, err) {
|
|
|
|
values := []struct {
|
|
Key string
|
|
Ref spec.Ref
|
|
}{
|
|
{"#/parameters/someParam/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/parameters/1/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/responses/someResponse/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/namedAgain", spec.MustCreateRef("#/definitions/named")},
|
|
{"#/definitions/datedTag/allOf/1", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/datedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/datedTaggedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/datedTaggedRecords/additionalItems", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/otherRecords/items", spec.MustCreateRef("#/definitions/record")},
|
|
{"#/definitions/tags/additionalProperties", spec.MustCreateRef("#/definitions/tag")},
|
|
{"#/definitions/namedThing/properties/name", spec.MustCreateRef("#/definitions/named")},
|
|
}
|
|
|
|
for i, v := range values {
|
|
err := rewriteSchemaToRef(sp, v.Key, v.Ref)
|
|
if assert.NoError(t, err) {
|
|
ptr, err := jsonpointer.New(v.Key[1:])
|
|
if assert.NoError(t, err) {
|
|
vv, _, err := ptr.Get(sp)
|
|
|
|
if assert.NoError(t, err) {
|
|
switch tv := vv.(type) {
|
|
case *spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "at %d for %s", i, v.Key)
|
|
case spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "at %d for %s", i, v.Key)
|
|
case *spec.SchemaOrBool:
|
|
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String(), "at %d for %s", i, v.Key)
|
|
case *spec.SchemaOrArray:
|
|
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String(), "at %d for %s", i, v.Key)
|
|
default:
|
|
assert.Fail(t, "unknown type", "got %T", vv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSplitKey(t *testing.T) {
|
|
|
|
type KeyFlag uint64
|
|
|
|
const (
|
|
isOperation KeyFlag = 1 << iota
|
|
isDefinition
|
|
isSharedOperationParam
|
|
isOperationParam
|
|
isOperationResponse
|
|
isDefaultResponse
|
|
isStatusCodeResponse
|
|
)
|
|
|
|
values := []struct {
|
|
Key string
|
|
Flags KeyFlag
|
|
PathItemRef spec.Ref
|
|
PathRef spec.Ref
|
|
Name string
|
|
}{
|
|
{
|
|
"#/paths/~1some~1where~1{id}/parameters/1/schema",
|
|
isOperation | isSharedOperationParam,
|
|
spec.Ref{},
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}"),
|
|
"",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/parameters/2/schema",
|
|
isOperation | isOperationParam,
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}/GET"),
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}"),
|
|
"",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/responses/default/schema",
|
|
isOperation | isOperationResponse | isDefaultResponse,
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}/GET"),
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}"),
|
|
"Default",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/responses/200/schema",
|
|
isOperation | isOperationResponse | isStatusCodeResponse,
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}/GET"),
|
|
spec.MustCreateRef("#/paths/~1some~1where~1{id}"),
|
|
"OK",
|
|
},
|
|
{
|
|
"#/definitions/namedAgain",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"namedAgain",
|
|
},
|
|
{
|
|
"#/definitions/datedRecords/items/1",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"datedRecords",
|
|
},
|
|
{
|
|
"#/definitions/datedRecords/items/1",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"datedRecords",
|
|
},
|
|
{
|
|
"#/definitions/datedTaggedRecords/items/1",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"datedTaggedRecords",
|
|
},
|
|
{
|
|
"#/definitions/datedTaggedRecords/additionalItems",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"datedTaggedRecords",
|
|
},
|
|
{
|
|
"#/definitions/otherRecords/items",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"otherRecords",
|
|
},
|
|
{
|
|
"#/definitions/tags/additionalProperties",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"tags",
|
|
},
|
|
{
|
|
"#/definitions/namedThing/properties/name",
|
|
isDefinition,
|
|
spec.Ref{},
|
|
spec.Ref{},
|
|
"namedThing",
|
|
},
|
|
}
|
|
|
|
for i, v := range values {
|
|
parts := keyParts(v.Key)
|
|
pref := parts.PathRef()
|
|
piref := parts.PathItemRef()
|
|
assert.Equal(t, v.PathRef.String(), pref.String(), "pathRef: %s at %d", v.Key, i)
|
|
assert.Equal(t, v.PathItemRef.String(), piref.String(), "pathItemRef: %s at %d", v.Key, i)
|
|
|
|
if v.Flags&isOperation != 0 {
|
|
assert.True(t, parts.IsOperation(), "isOperation: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsOperation(), "isOperation: %s at %d", v.Key, i)
|
|
}
|
|
if v.Flags&isDefinition != 0 {
|
|
assert.True(t, parts.IsDefinition(), "isDefinition: %s at %d", v.Key, i)
|
|
assert.Equal(t, v.Name, parts.DefinitionName(), "definition name: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsDefinition(), "isDefinition: %s at %d", v.Key, i)
|
|
if v.Name != "" {
|
|
assert.Equal(t, v.Name, parts.ResponseName(), "response name: %s at %d", v.Key, i)
|
|
}
|
|
}
|
|
if v.Flags&isOperationParam != 0 {
|
|
assert.True(t, parts.IsOperationParam(), "isOperationParam: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsOperationParam(), "isOperationParam: %s at %d", v.Key, i)
|
|
}
|
|
if v.Flags&isSharedOperationParam != 0 {
|
|
assert.True(t, parts.IsSharedOperationParam(), "isSharedOperationParam: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsSharedOperationParam(), "isSharedOperationParam: %s at %d", v.Key, i)
|
|
}
|
|
if v.Flags&isOperationResponse != 0 {
|
|
assert.True(t, parts.IsOperationResponse(), "isOperationResponse: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsOperationResponse(), "isOperationResponse: %s at %d", v.Key, i)
|
|
}
|
|
if v.Flags&isDefaultResponse != 0 {
|
|
assert.True(t, parts.IsDefaultResponse(), "isDefaultResponse: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsDefaultResponse(), "isDefaultResponse: %s at %d", v.Key, i)
|
|
}
|
|
if v.Flags&isStatusCodeResponse != 0 {
|
|
assert.True(t, parts.IsStatusCodeResponse(), "isStatusCodeResponse: %s at %d", v.Key, i)
|
|
} else {
|
|
assert.False(t, parts.IsStatusCodeResponse(), "isStatusCodeResponse: %s at %d", v.Key, i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func definitionPtr(key string) string {
|
|
if !strings.HasPrefix(key, "#/definitions") {
|
|
return key
|
|
}
|
|
return strings.Join(strings.Split(key, "/")[:3], "/")
|
|
}
|
|
|
|
func TestNamesFromKey(t *testing.T) {
|
|
bp := filepath.Join("fixtures", "inline_schemas.yml")
|
|
sp, err := loadSpec(bp)
|
|
if assert.NoError(t, err) {
|
|
|
|
values := []struct {
|
|
Key string
|
|
Names []string
|
|
}{
|
|
{"#/paths/~1some~1where~1{id}/parameters/1/schema", []string{"GetSomeWhereID params body", "PostSomeWhereID params body"}},
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema", []string{"GetSomeWhereID params body"}},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema", []string{"GetSomeWhereID Default body"}},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema", []string{"GetSomeWhereID OK body"}},
|
|
{"#/definitions/namedAgain", []string{"namedAgain"}},
|
|
{"#/definitions/datedTag/allOf/1", []string{"datedTag allOf 1"}},
|
|
{"#/definitions/datedRecords/items/1", []string{"datedRecords tuple 1"}},
|
|
{"#/definitions/datedTaggedRecords/items/1", []string{"datedTaggedRecords tuple 1"}},
|
|
{"#/definitions/datedTaggedRecords/additionalItems", []string{"datedTaggedRecords tuple additionalItems"}},
|
|
{"#/definitions/otherRecords/items", []string{"otherRecords items"}},
|
|
{"#/definitions/tags/additionalProperties", []string{"tags additionalProperties"}},
|
|
{"#/definitions/namedThing/properties/name", []string{"namedThing name"}},
|
|
}
|
|
|
|
for i, v := range values {
|
|
ptr, err := jsonpointer.New(definitionPtr(v.Key)[1:])
|
|
if assert.NoError(t, err) {
|
|
vv, _, err := ptr.Get(sp)
|
|
if assert.NoError(t, err) {
|
|
switch tv := vv.(type) {
|
|
case *spec.Schema:
|
|
aschema, err := Schema(SchemaOpts{Schema: tv, Root: sp, BasePath: bp})
|
|
if assert.NoError(t, err) {
|
|
names := namesFromKey(keyParts(v.Key), aschema, opRefsByRef(gatherOperations(New(sp), nil)))
|
|
assert.Equal(t, v.Names, names, "for %s at %d", v.Key, i)
|
|
}
|
|
case spec.Schema:
|
|
aschema, err := Schema(SchemaOpts{Schema: &tv, Root: sp, BasePath: bp})
|
|
if assert.NoError(t, err) {
|
|
names := namesFromKey(keyParts(v.Key), aschema, opRefsByRef(gatherOperations(New(sp), nil)))
|
|
assert.Equal(t, v.Names, names, "for %s at %d", v.Key, i)
|
|
}
|
|
default:
|
|
assert.Fail(t, "unknown type", "got %T", vv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDepthFirstSort(t *testing.T) {
|
|
bp := filepath.Join("fixtures", "inline_schemas.yml")
|
|
sp, err := loadSpec(bp)
|
|
values := []string{
|
|
"#/paths/~1some~1where~1{id}/parameters/1/schema/properties/createdAt",
|
|
"#/paths/~1some~1where~1{id}/parameters/1/schema",
|
|
"#/paths/~1some~1where~1{id}/get/parameters/2/schema/properties/createdAt",
|
|
"#/paths/~1some~1where~1{id}/get/parameters/2/schema",
|
|
"#/paths/~1some~1where~1{id}/get/responses/200/schema/properties/id",
|
|
"#/paths/~1some~1where~1{id}/get/responses/200/schema/properties/value",
|
|
"#/paths/~1some~1where~1{id}/get/responses/200/schema",
|
|
"#/paths/~1some~1where~1{id}/get/responses/404/schema",
|
|
"#/paths/~1some~1where~1{id}/get/responses/default/schema/properties/createdAt",
|
|
"#/paths/~1some~1where~1{id}/get/responses/default/schema",
|
|
"#/definitions/datedRecords/items/1/properties/createdAt",
|
|
"#/definitions/datedTaggedRecords/items/1/properties/createdAt",
|
|
"#/definitions/namedThing/properties/name/properties/id",
|
|
"#/definitions/records/items/0/properties/createdAt",
|
|
"#/definitions/datedTaggedRecords/additionalItems/properties/id",
|
|
"#/definitions/datedTaggedRecords/additionalItems/properties/value",
|
|
"#/definitions/otherRecords/items/properties/createdAt",
|
|
"#/definitions/tags/additionalProperties/properties/id",
|
|
"#/definitions/tags/additionalProperties/properties/value",
|
|
"#/definitions/datedRecords/items/0",
|
|
"#/definitions/datedRecords/items/1",
|
|
"#/definitions/datedTag/allOf/0",
|
|
"#/definitions/datedTag/allOf/1",
|
|
"#/definitions/datedTag/properties/id",
|
|
"#/definitions/datedTag/properties/value",
|
|
"#/definitions/datedTaggedRecords/items/0",
|
|
"#/definitions/datedTaggedRecords/items/1",
|
|
"#/definitions/namedAgain/properties/id",
|
|
"#/definitions/namedThing/properties/name",
|
|
"#/definitions/pneumonoultramicroscopicsilicovolcanoconiosisAntidisestablishmentarianism/properties/floccinaucinihilipilificationCreatedAt",
|
|
"#/definitions/records/items/0",
|
|
"#/definitions/datedTaggedRecords/additionalItems",
|
|
"#/definitions/otherRecords/items",
|
|
"#/definitions/tags/additionalProperties",
|
|
"#/definitions/datedRecords",
|
|
"#/definitions/datedTag",
|
|
"#/definitions/datedTaggedRecords",
|
|
"#/definitions/namedAgain",
|
|
"#/definitions/namedThing",
|
|
"#/definitions/otherRecords",
|
|
"#/definitions/pneumonoultramicroscopicsilicovolcanoconiosisAntidisestablishmentarianism",
|
|
"#/definitions/records",
|
|
"#/definitions/tags",
|
|
}
|
|
if assert.NoError(t, err) {
|
|
a := New(sp)
|
|
result := sortDepthFirst(a.allSchemas)
|
|
assert.Equal(t, values, result)
|
|
}
|
|
}
|
|
|
|
func TestBuildNameWithReservedKeyWord(t *testing.T) {
|
|
s := splitKey([]string{"definitions", "fullview", "properties", "properties"})
|
|
startIdx := 2
|
|
segments := []string{"fullview"}
|
|
newName := s.BuildName(segments, startIdx, nil)
|
|
assert.Equal(t, "fullview properties", newName)
|
|
s = splitKey([]string{"definitions", "fullview", "properties", "properties", "properties", "properties", "properties", "properties"})
|
|
newName = s.BuildName(segments, startIdx, nil)
|
|
assert.Equal(t, "fullview properties properties properties", newName)
|
|
}
|
|
|
|
func TestNameInlinedSchemas(t *testing.T) {
|
|
cwd, _ := os.Getwd()
|
|
bp := filepath.Join(cwd, "fixtures", "nested_inline_schemas.yml")
|
|
sp, err := loadSpec(bp)
|
|
err = spec.ExpandSpec(sp, &spec.ExpandOptions{
|
|
RelativeBase: bp,
|
|
SkipSchemas: true,
|
|
})
|
|
assert.NoError(t, err)
|
|
values := []struct {
|
|
Key string
|
|
Location string
|
|
Ref spec.Ref
|
|
}{
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema/properties/record/items/2/properties/name", "#/definitions/getSomeWhereIdParamsBodyRecordItems2/properties/name", spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecordItems2Name")},
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema/properties/record/items/1", "#/definitions/getSomeWhereIdParamsBodyRecord/items/1", spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecordItems1")},
|
|
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema/properties/record/items/2", "#/definitions/getSomeWhereIdParamsBodyRecord/items/2", spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecordItems2")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema/properties/record/items/2/properties/name", "#/definitions/getSomeWhereIdOKBodyRecordItems2/properties/name", spec.MustCreateRef("#/definitions/getSomeWhereIdOKBodyRecordItems2Name")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema/properties/record/items/1", "#/definitions/getSomeWhereIdOKBodyRecord/items/1", spec.MustCreateRef("#/definitions/getSomeWhereIdOKBodyRecordItems1")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema/properties/record/items/2", "#/definitions/getSomeWhereIdOKBodyRecord/items/2", spec.MustCreateRef("#/definitions/getSomeWhereIdOKBodyRecordItems2")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema/properties/record", "#/definitions/getSomeWhereIdOKBody/properties/record", spec.MustCreateRef("#/definitions/getSomeWhereIdOKBodyRecord")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/200/schema", "#/paths/~1some~1where~1{id}/get/responses/200/schema", spec.MustCreateRef("#/definitions/getSomeWhereIdOKBody")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema/properties/record/items/2/properties/name", "#/definitions/getSomeWhereIdDefaultBodyRecordItems2/properties/name", spec.MustCreateRef("#/definitions/getSomeWhereIdDefaultBodyRecordItems2Name")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema/properties/record/items/1", "#/definitions/getSomeWhereIdDefaultBodyRecord/items/1", spec.MustCreateRef("#/definitions/getSomeWhereIdDefaultBodyRecordItems1")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema/properties/record/items/2", "#/definitions/getSomeWhereIdDefaultBodyRecord/items/2", spec.MustCreateRef("#/definitions/getSomeWhereIdDefaultBodyRecordItems2")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema/properties/record", "#/definitions/getSomeWhereIdDefaultBody/properties/record", spec.MustCreateRef("#/definitions/getSomeWhereIdDefaultBodyRecord")},
|
|
{"#/paths/~1some~1where~1{id}/get/responses/default/schema", "#/paths/~1some~1where~1{id}/get/responses/default/schema", spec.MustCreateRef("#/definitions/getSomeWhereIdDefaultBody")},
|
|
{"#/definitions/nestedThing/properties/record/items/2/allOf/1/additionalProperties", "#/definitions/nestedThingRecordItems2AllOf1/additionalProperties", spec.MustCreateRef("#/definitions/nestedThingRecordItems2AllOf1AdditionalProperties")},
|
|
{"#/definitions/nestedThing/properties/record/items/2/allOf/1", "#/definitions/nestedThingRecordItems2/allOf/1", spec.MustCreateRef("#/definitions/nestedThingRecordItems2AllOf1")},
|
|
{"#/definitions/nestedThing/properties/record/items/2/properties/name", "#/definitions/nestedThingRecordItems2/properties/name", spec.MustCreateRef("#/definitions/nestedThingRecordItems2Name")},
|
|
{"#/definitions/nestedThing/properties/record/items/1", "#/definitions/nestedThingRecord/items/1", spec.MustCreateRef("#/definitions/nestedThingRecordItems1")},
|
|
{"#/definitions/nestedThing/properties/record/items/2", "#/definitions/nestedThingRecord/items/2", spec.MustCreateRef("#/definitions/nestedThingRecordItems2")},
|
|
{"#/definitions/datedRecords/items/1", "#/definitions/datedRecords/items/1", spec.MustCreateRef("#/definitions/datedRecordsItems1")},
|
|
{"#/definitions/datedTaggedRecords/items/1", "#/definitions/datedTaggedRecords/items/1", spec.MustCreateRef("#/definitions/datedTaggedRecordsItems1")},
|
|
{"#/definitions/namedThing/properties/name", "#/definitions/namedThing/properties/name", spec.MustCreateRef("#/definitions/namedThingName")},
|
|
{"#/definitions/nestedThing/properties/record", "#/definitions/nestedThing/properties/record", spec.MustCreateRef("#/definitions/nestedThingRecord")},
|
|
{"#/definitions/records/items/0", "#/definitions/records/items/0", spec.MustCreateRef("#/definitions/recordsItems0")},
|
|
{"#/definitions/datedTaggedRecords/additionalItems", "#/definitions/datedTaggedRecords/additionalItems", spec.MustCreateRef("#/definitions/datedTaggedRecordsItemsAdditionalItems")},
|
|
{"#/definitions/otherRecords/items", "#/definitions/otherRecords/items", spec.MustCreateRef("#/definitions/otherRecordsItems")},
|
|
{"#/definitions/tags/additionalProperties", "#/definitions/tags/additionalProperties", spec.MustCreateRef("#/definitions/tagsAdditionalProperties")},
|
|
}
|
|
if assert.NoError(t, err) {
|
|
err := nameInlinedSchemas(&FlattenOpts{
|
|
Spec: New(sp),
|
|
BasePath: bp,
|
|
})
|
|
|
|
if assert.NoError(t, err) {
|
|
for i, v := range values {
|
|
ptr, err := jsonpointer.New(v.Location[1:])
|
|
if assert.NoError(t, err, "at %d for %s", i, v.Key) {
|
|
vv, _, err := ptr.Get(sp)
|
|
|
|
if assert.NoError(t, err, "at %d for %s", i, v.Key) {
|
|
switch tv := vv.(type) {
|
|
case *spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "at %d for %s", i, v.Key)
|
|
case spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "at %d for %s", i, v.Key)
|
|
case *spec.SchemaOrBool:
|
|
var sRef spec.Ref
|
|
if tv != nil && tv.Schema != nil {
|
|
sRef = tv.Schema.Ref
|
|
}
|
|
assert.Equal(t, v.Ref.String(), sRef.String(), "at %d for %s", i, v.Key)
|
|
case *spec.SchemaOrArray:
|
|
var sRef spec.Ref
|
|
if tv != nil && tv.Schema != nil {
|
|
sRef = tv.Schema.Ref
|
|
}
|
|
assert.Equal(t, v.Ref.String(), sRef.String(), "at %d for %s", i, v.Key)
|
|
default:
|
|
assert.Fail(t, "unknown type", "got %T", vv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for k, rr := range New(sp).allSchemas {
|
|
if !strings.HasPrefix(k, "#/responses") && !strings.HasPrefix(k, "#/parameters") {
|
|
if rr.Schema != nil && rr.Schema.Ref.String() == "" && !rr.TopLevel {
|
|
asch, err := Schema(SchemaOpts{Schema: rr.Schema, Root: sp, BasePath: bp})
|
|
if assert.NoError(t, err, "for key: %s", k) {
|
|
if !asch.IsSimpleSchema && !asch.IsArray {
|
|
assert.Fail(t, "not a top level schema", "for key: %s", k)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFlatten(t *testing.T) {
|
|
cwd, _ := os.Getwd()
|
|
bp := filepath.Join(cwd, "fixtures", "flatten.yml")
|
|
sp, err := loadSpec(bp)
|
|
values := []struct {
|
|
Key string
|
|
Location string
|
|
Ref spec.Ref
|
|
Expected interface{}
|
|
}{
|
|
{
|
|
"#/responses/notFound/schema",
|
|
"#/responses/notFound/schema",
|
|
spec.MustCreateRef("#/definitions/error"),
|
|
nil,
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/parameters/0",
|
|
"#/paths/~1some~1where~1{id}/parameters/0/name",
|
|
spec.Ref{},
|
|
"id",
|
|
},
|
|
{
|
|
"#/paths/~1other~1place",
|
|
"#/paths/~1other~1place/get/operationId",
|
|
spec.Ref{},
|
|
"modelOp",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/parameters/0",
|
|
"#/paths/~1some~1where~1{id}/get/parameters/0/name",
|
|
spec.Ref{},
|
|
"limit",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/parameters/1",
|
|
"#/paths/~1some~1where~1{id}/get/parameters/1/name",
|
|
spec.Ref{},
|
|
"some",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/parameters/2",
|
|
"#/paths/~1some~1where~1{id}/get/parameters/2/name",
|
|
spec.Ref{},
|
|
"other",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/parameters/3",
|
|
"#/paths/~1some~1where~1{id}/get/parameters/3/schema",
|
|
spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBody"),
|
|
"",
|
|
},
|
|
{
|
|
"#/paths/~1some~1where~1{id}/get/responses/200",
|
|
"#/paths/~1some~1where~1{id}/get/responses/200/schema",
|
|
spec.MustCreateRef("#/definitions/getSomeWhereIdOKBody"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/namedAgain",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/named"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/namedThing/properties/name",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/named"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/namedThing/properties/namedAgain",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/namedAgain"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/datedRecords/items/1",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/record"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/otherRecords/items",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/record"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/tags/additionalProperties",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/tag"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/datedTag/allOf/1",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/tag"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/nestedThingRecordItems2/allOf/1",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/nestedThingRecordItems2AllOf1"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/nestedThingRecord/items/1",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/nestedThingRecordItems1"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/nestedThingRecord/items/2",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/nestedThingRecordItems2"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/nestedThing/properties/record",
|
|
"",
|
|
spec.MustCreateRef("#/definitions/nestedThingRecord"),
|
|
"",
|
|
},
|
|
{
|
|
"#/definitions/named",
|
|
"#/definitions/named/type",
|
|
spec.Ref{},
|
|
spec.StringOrArray{"string"},
|
|
},
|
|
{
|
|
"#/definitions/error",
|
|
"#/definitions/error/properties/id/type",
|
|
spec.Ref{},
|
|
spec.StringOrArray{"integer"},
|
|
},
|
|
{
|
|
"#/definitions/record",
|
|
"#/definitions/record/properties/createdAt/format",
|
|
spec.Ref{},
|
|
"date-time",
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdOKBody",
|
|
"#/definitions/getSomeWhereIdOKBody/properties/record",
|
|
spec.MustCreateRef("#/definitions/nestedThing"),
|
|
nil,
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdParamsBody",
|
|
"#/definitions/getSomeWhereIdParamsBody/properties/record",
|
|
spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecord"),
|
|
nil,
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdParamsBodyRecord",
|
|
"#/definitions/getSomeWhereIdParamsBodyRecord/items/1",
|
|
spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecordItems1"),
|
|
nil,
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdParamsBodyRecord",
|
|
"#/definitions/getSomeWhereIdParamsBodyRecord/items/2",
|
|
spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecordItems2"),
|
|
nil,
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdParamsBodyRecordItems2",
|
|
"#/definitions/getSomeWhereIdParamsBodyRecordItems2/allOf/0/format",
|
|
spec.Ref{},
|
|
"date",
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdParamsBodyRecordItems2Name",
|
|
"#/definitions/getSomeWhereIdParamsBodyRecordItems2Name/properties/createdAt/format",
|
|
spec.Ref{},
|
|
"date-time",
|
|
},
|
|
{
|
|
"#/definitions/getSomeWhereIdParamsBodyRecordItems2",
|
|
"#/definitions/getSomeWhereIdParamsBodyRecordItems2/properties/name",
|
|
spec.MustCreateRef("#/definitions/getSomeWhereIdParamsBodyRecordItems2Name"),
|
|
"date",
|
|
},
|
|
}
|
|
if assert.NoError(t, err) {
|
|
err := Flatten(FlattenOpts{Spec: New(sp), BasePath: bp})
|
|
//b, _ := sp.MarshalJSON()
|
|
//panic(string(b))
|
|
if assert.NoError(t, err) {
|
|
for i, v := range values {
|
|
pk := v.Key[1:]
|
|
if v.Location != "" {
|
|
pk = v.Location[1:]
|
|
}
|
|
ptr, err := jsonpointer.New(pk)
|
|
if assert.NoError(t, err, "at %d for %s", i, v.Key) {
|
|
d, _, err := ptr.Get(sp)
|
|
if assert.NoError(t, err) {
|
|
if v.Ref.String() != "" {
|
|
switch s := d.(type) {
|
|
case *spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), s.Ref.String(), "at %d for %s", i, v.Key)
|
|
case spec.Schema:
|
|
assert.Equal(t, v.Ref.String(), s.Ref.String(), "at %d for %s", i, v.Key)
|
|
case *spec.SchemaOrArray:
|
|
var sRef spec.Ref
|
|
if s != nil && s.Schema != nil {
|
|
sRef = s.Schema.Ref
|
|
}
|
|
assert.Equal(t, v.Ref.String(), sRef.String(), "at %d for %s", i, v.Key)
|
|
case *spec.SchemaOrBool:
|
|
var sRef spec.Ref
|
|
if s != nil && s.Schema != nil {
|
|
sRef = s.Schema.Ref
|
|
}
|
|
assert.Equal(t, v.Ref.String(), sRef.String(), "at %d for %s", i, v.Key)
|
|
default:
|
|
assert.Fail(t, "unknown type", "got %T at %d for %s", d, i, v.Key)
|
|
}
|
|
} else {
|
|
assert.Equal(t, v.Expected, d)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|