mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 12:37:49 +00:00
Merge branch 'main' into ordered-libopenapi
This commit is contained in:
@@ -435,7 +435,7 @@ func TestStripeAsDoc(t *testing.T) {
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
var err error
|
||||
lowDoc, err = lowv3.CreateDocumentFromConfig(info, datamodel.NewDocumentConfiguration())
|
||||
assert.Len(t, utils.UnwrapErrors(err), 3)
|
||||
assert.Len(t, utils.UnwrapErrors(err), 2)
|
||||
d := NewDocument(lowDoc)
|
||||
assert.NotNil(t, d)
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ func TestCreateDocumentStripe(t *testing.T) {
|
||||
data, _ := os.ReadFile("../../../test_specs/stripe.yaml")
|
||||
info, _ := datamodel.ExtractSpecInfo(data)
|
||||
d, err := CreateDocumentFromConfig(info, &datamodel.DocumentConfiguration{})
|
||||
assert.Len(t, utils.UnwrapErrors(err), 3)
|
||||
assert.Len(t, utils.UnwrapErrors(err), 2)
|
||||
|
||||
assert.Equal(t, "3.0.0", d.Version.Value)
|
||||
assert.Equal(t, "Stripe API", d.Info.Value.Title.Value)
|
||||
|
||||
@@ -262,6 +262,7 @@ func TestDocument_RenderAndReload_ChangeCheck_Burgershop(t *testing.T) {
|
||||
|
||||
// should noth be nil.
|
||||
assert.Nil(t, errs)
|
||||
assert.Nil(t, errs)
|
||||
assert.NotNil(t, rend)
|
||||
assert.Nil(t, compReport)
|
||||
}
|
||||
@@ -291,12 +292,28 @@ func TestDocument_RenderAndReload_ChangeCheck_Stripe(t *testing.T) {
|
||||
tc := compReport.TotalChanges()
|
||||
bc := compReport.TotalBreakingChanges()
|
||||
assert.Equal(t, 0, bc)
|
||||
assert.Equal(t, 519, tc)
|
||||
assert.Equal(t, 819, tc)
|
||||
|
||||
// there should be no other changes than the 519 descriptions.
|
||||
assert.Equal(t, 0, len(filtered))
|
||||
}
|
||||
|
||||
func TestDocument_ResolveStripe(t *testing.T) {
|
||||
bs, _ := os.ReadFile("test_specs/stripe.yaml")
|
||||
docConfig := datamodel.NewDocumentConfiguration()
|
||||
docConfig.SkipCircularReferenceCheck = true
|
||||
docConfig.BasePath = "."
|
||||
docConfig.AllowRemoteReferences = true
|
||||
docConfig.AllowFileReferences = true
|
||||
doc, _ := NewDocumentWithConfiguration(bs, docConfig)
|
||||
model, _ := doc.BuildV3Model()
|
||||
|
||||
rolo := model.Index.GetRolodex()
|
||||
rolo.Resolve()
|
||||
|
||||
assert.Equal(t, 2, len(model.Index.GetRolodex().GetCaughtErrors()))
|
||||
}
|
||||
|
||||
func TestDocument_RenderAndReload_ChangeCheck_Asana(t *testing.T) {
|
||||
bs, _ := os.ReadFile("test_specs/asana.yaml")
|
||||
doc, _ := NewDocument(bs)
|
||||
|
||||
@@ -332,7 +332,8 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
||||
loop := append(journey, foundDup)
|
||||
|
||||
visitedDefinitions := make(map[string]bool)
|
||||
isInfiniteLoop, _ := resolver.isInfiniteCircularDependency(foundDup, visitedDefinitions, nil)
|
||||
isInfiniteLoop, _ := resolver.isInfiniteCircularDependency(foundDup,
|
||||
visitedDefinitions, nil)
|
||||
|
||||
isArray := false
|
||||
if r.ParentNodeSchemaType == "array" || slices.Contains(r.ParentNodeTypes, "array") {
|
||||
@@ -382,11 +383,11 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
||||
return ref.Node.Content
|
||||
}
|
||||
|
||||
func (resolver *Resolver) isInfiniteCircularDependency(ref *Reference, visitedDefinitions map[string]bool, initialRef *Reference) (bool, map[string]bool) {
|
||||
func (resolver *Resolver) isInfiniteCircularDependency(ref *Reference, visitedDefinitions map[string]bool,
|
||||
initialRef *Reference) (bool, map[string]bool) {
|
||||
if ref == nil {
|
||||
return false, visitedDefinitions
|
||||
}
|
||||
|
||||
for refDefinition := range ref.RequiredRefProperties {
|
||||
r, _ := resolver.specIndex.SearchIndexForReference(refDefinition)
|
||||
if initialRef != nil && initialRef.FullDefinition == r.FullDefinition {
|
||||
@@ -400,7 +401,7 @@ func (resolver *Resolver) isInfiniteCircularDependency(ref *Reference, visitedDe
|
||||
continue
|
||||
}
|
||||
|
||||
visitedDefinitions[r.Definition] = true
|
||||
visitedDefinitions[r.FullDefinition] = true
|
||||
|
||||
ir := initialRef
|
||||
if ir == nil {
|
||||
@@ -408,6 +409,7 @@ func (resolver *Resolver) isInfiniteCircularDependency(ref *Reference, visitedDe
|
||||
}
|
||||
|
||||
var isChildICD bool
|
||||
|
||||
isChildICD, visitedDefinitions = resolver.isInfiniteCircularDependency(r, visitedDefinitions, ir)
|
||||
if isChildICD {
|
||||
return true, visitedDefinitions
|
||||
@@ -714,8 +716,19 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
||||
def = fmt.Sprintf("%s#/%s", u.String(), exp[1])
|
||||
|
||||
} else {
|
||||
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(ref.FullDefinition), exp[0]))
|
||||
def = fmt.Sprintf("%s#/%s", abs, exp[1])
|
||||
z := strings.Split(ref.FullDefinition, "#/")
|
||||
if len(z) == 2 {
|
||||
if len(z[0]) > 0 {
|
||||
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(z[0]), exp[0]))
|
||||
def = fmt.Sprintf("%s#/%s", abs, exp[1])
|
||||
} else {
|
||||
abs, _ := filepath.Abs(exp[0])
|
||||
def = fmt.Sprintf("%s#/%s", abs, exp[1])
|
||||
}
|
||||
} else {
|
||||
abs, _ := filepath.Abs(filepath.Join(filepath.Dir(ref.FullDefinition), exp[0]))
|
||||
def = fmt.Sprintf("%s#/%s", abs, exp[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -454,7 +454,7 @@ func TestResolver_ResolveComponents_Stripe_NoRolodex(t *testing.T) {
|
||||
assert.NotNil(t, resolver)
|
||||
|
||||
circ := resolver.CheckForCircularReferences()
|
||||
assert.Len(t, circ, 3)
|
||||
assert.Len(t, circ, 2)
|
||||
|
||||
_, err := yaml.Marshal(resolver.resolvedRoot)
|
||||
assert.NoError(t, err)
|
||||
@@ -483,8 +483,8 @@ func TestResolver_ResolveComponents_Stripe(t *testing.T) {
|
||||
// after resolving, the rolodex will have errors.
|
||||
rolo.Resolve()
|
||||
|
||||
assert.Len(t, rolo.GetCaughtErrors(), 3)
|
||||
assert.Len(t, rolo.GetRootIndex().GetResolver().GetNonPolymorphicCircularErrors(), 3)
|
||||
assert.Len(t, rolo.GetCaughtErrors(), 2)
|
||||
assert.Len(t, rolo.GetRootIndex().GetResolver().GetNonPolymorphicCircularErrors(), 2)
|
||||
assert.Len(t, rolo.GetRootIndex().GetResolver().GetPolymorphicCircularErrors(), 0)
|
||||
|
||||
}
|
||||
@@ -733,7 +733,7 @@ func ExampleNewResolver() {
|
||||
//
|
||||
fmt.Printf("There are %d circular reference errors, %d of them are polymorphic errors, %d are not",
|
||||
len(circularErrors), len(resolver.GetPolymorphicCircularErrors()), len(resolver.GetNonPolymorphicCircularErrors()))
|
||||
// Output: There are 3 circular reference errors, 0 of them are polymorphic errors, 3 are not
|
||||
// Output: There are 2 circular reference errors, 0 of them are polymorphic errors, 2 are not
|
||||
}
|
||||
|
||||
func ExampleResolvingError() {
|
||||
|
||||
@@ -437,6 +437,11 @@ func (r *Rolodex) Open(location string) (RolodexFile, error) {
|
||||
}
|
||||
|
||||
if !isUrl {
|
||||
if len(r.localFS) <= 0 {
|
||||
r.logger.Warn("[rolodex] no local file systems configured, cannot open local file", "location", location)
|
||||
return nil, fmt.Errorf("the rolodex has no local file systems configured, cannot open local file '%s'", location)
|
||||
}
|
||||
|
||||
for k, v := range r.localFS {
|
||||
|
||||
// check if this is a URL or an abs/rel reference.
|
||||
|
||||
@@ -87,6 +87,7 @@ func (l *LocalFS) Open(name string) (fs.File, error) {
|
||||
l.logger.Debug("[rolodex file loader]: waiting for existing OS load to complete", "file", name, "listeners", wait.listeners)
|
||||
|
||||
for !wait.done {
|
||||
l.logger.Debug("[rolodex file loader]: sleeping for 200ns", "file", name, "listeners", wait.listeners)
|
||||
time.Sleep(200 * time.Nanosecond) // breathe for a few nanoseconds.
|
||||
}
|
||||
wait.listeners--
|
||||
|
||||
@@ -42,6 +42,17 @@ func TestRolodex_NoFS(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestRolodex_NoFSButHasRemoteFS(t *testing.T) {
|
||||
|
||||
rolo := NewRolodex(CreateOpenAPIIndexConfig())
|
||||
rolo.AddRemoteFS("http://localhost", nil)
|
||||
rf, err := rolo.Open("spec.yaml")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "the rolodex has no local file systems configured, cannot open local file 'spec.yaml'", err.Error())
|
||||
assert.Nil(t, rf)
|
||||
|
||||
}
|
||||
|
||||
func TestRolodex_LocalNativeFS(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
|
||||
@@ -65,27 +65,27 @@ func TestSpecIndex_ExtractRefsStripe(t *testing.T) {
|
||||
|
||||
index := NewSpecIndexWithConfig(&rootNode, CreateOpenAPIIndexConfig())
|
||||
|
||||
assert.Len(t, index.allRefs, 385)
|
||||
assert.Equal(t, 537, len(index.allMappedRefs))
|
||||
assert.Equal(t, 626, len(index.allRefs))
|
||||
assert.Equal(t, 871, len(index.allMappedRefs))
|
||||
combined := index.GetAllCombinedReferences()
|
||||
assert.Equal(t, 537, len(combined))
|
||||
assert.Equal(t, 871, len(combined))
|
||||
|
||||
assert.Len(t, index.rawSequencedRefs, 1972)
|
||||
assert.Equal(t, 246, index.pathCount)
|
||||
assert.Equal(t, 402, index.operationCount)
|
||||
assert.Equal(t, 537, index.schemaCount)
|
||||
assert.Equal(t, len(index.rawSequencedRefs), 2712)
|
||||
assert.Equal(t, 336, index.pathCount)
|
||||
assert.Equal(t, 494, index.operationCount)
|
||||
assert.Equal(t, 871, index.schemaCount)
|
||||
assert.Equal(t, 0, index.globalTagsCount)
|
||||
assert.Equal(t, 0, index.globalLinksCount)
|
||||
assert.Equal(t, 0, index.componentParamCount)
|
||||
assert.Equal(t, 143, index.operationParamCount)
|
||||
assert.Equal(t, 88, index.componentsInlineParamDuplicateCount)
|
||||
assert.Equal(t, 55, index.componentsInlineParamUniqueCount)
|
||||
assert.Equal(t, 1516, index.enumCount)
|
||||
assert.Len(t, index.GetAllEnums(), 1516)
|
||||
assert.Equal(t, 162, index.operationParamCount)
|
||||
assert.Equal(t, 102, index.componentsInlineParamDuplicateCount)
|
||||
assert.Equal(t, 60, index.componentsInlineParamUniqueCount)
|
||||
assert.Equal(t, 2579, index.enumCount)
|
||||
assert.Equal(t, len(index.GetAllEnums()), 2579)
|
||||
assert.Len(t, index.GetPolyAllOfReferences(), 0)
|
||||
assert.Len(t, index.GetPolyOneOfReferences(), 275)
|
||||
assert.Len(t, index.GetPolyAnyOfReferences(), 553)
|
||||
assert.Len(t, index.GetAllReferenceSchemas(), 1972)
|
||||
assert.Len(t, index.GetPolyOneOfReferences(), 315)
|
||||
assert.Len(t, index.GetPolyAnyOfReferences(), 708)
|
||||
assert.Len(t, index.GetAllReferenceSchemas(), 2712)
|
||||
assert.NotNil(t, index.GetRootServersNode())
|
||||
assert.Len(t, index.GetAllRootServers(), 1)
|
||||
assert.Equal(t, "", index.GetSpecAbsolutePath())
|
||||
@@ -101,9 +101,9 @@ func TestSpecIndex_ExtractRefsStripe(t *testing.T) {
|
||||
index.SetCircularReferences([]*CircularReferenceResult{new(CircularReferenceResult)})
|
||||
assert.Len(t, index.GetCircularReferences(), 1)
|
||||
|
||||
assert.Len(t, index.GetRefsByLine(), 537)
|
||||
assert.Len(t, index.GetLinesWithReferences(), 1972)
|
||||
assert.Len(t, index.GetAllExternalDocuments(), 0)
|
||||
assert.Equal(t, 871, len(index.GetRefsByLine()))
|
||||
assert.Equal(t, 2712, len(index.GetLinesWithReferences()), 1972)
|
||||
assert.Equal(t, 0, len(index.GetAllExternalDocuments()))
|
||||
}
|
||||
|
||||
func TestSpecIndex_Asana(t *testing.T) {
|
||||
@@ -239,7 +239,7 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve(t *testing.T) {
|
||||
files := fileFS.GetFiles()
|
||||
fileLen := len(files)
|
||||
|
||||
assert.Equal(t, 1691, fileLen)
|
||||
assert.Equal(t, 1696, fileLen)
|
||||
|
||||
rolo.AddLocalFS(basePath, fileFS)
|
||||
|
||||
@@ -251,8 +251,8 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve(t *testing.T) {
|
||||
|
||||
assert.NotNil(t, index)
|
||||
|
||||
assert.Len(t, index.GetMappedReferencesSequenced(), 299)
|
||||
assert.Len(t, index.GetMappedReferences(), 299)
|
||||
assert.Len(t, index.GetMappedReferencesSequenced(), 300)
|
||||
assert.Len(t, index.GetMappedReferences(), 300)
|
||||
assert.Len(t, fileFS.GetErrors(), 0)
|
||||
|
||||
// check circular references
|
||||
@@ -260,9 +260,9 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve(t *testing.T) {
|
||||
assert.Len(t, rolo.GetCaughtErrors(), 0)
|
||||
assert.Len(t, rolo.GetIgnoredCircularReferences(), 0)
|
||||
|
||||
assert.Equal(t, int64(1328224), rolo.RolodexFileSize())
|
||||
assert.Equal(t, int64(1330184), rolo.RolodexFileSize())
|
||||
assert.Equal(t, "1.27 MB", rolo.RolodexFileSizeAsString())
|
||||
assert.Equal(t, 1691, rolo.RolodexTotalFiles())
|
||||
assert.Equal(t, 1696, rolo.RolodexTotalFiles())
|
||||
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve_RecursiveLookup(t *test
|
||||
files := fileFS.GetFiles()
|
||||
fileLen := len(files)
|
||||
|
||||
assert.Equal(t, 1677, fileLen)
|
||||
assert.Equal(t, 1682, fileLen)
|
||||
|
||||
assert.NoError(t, rErr)
|
||||
|
||||
@@ -325,8 +325,8 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve_RecursiveLookup(t *test
|
||||
|
||||
assert.NotNil(t, index)
|
||||
|
||||
assert.Len(t, index.GetMappedReferencesSequenced(), 299)
|
||||
assert.Len(t, index.GetMappedReferences(), 299)
|
||||
assert.Len(t, index.GetMappedReferencesSequenced(), 300)
|
||||
assert.Len(t, index.GetMappedReferences(), 300)
|
||||
assert.Len(t, fileFS.GetErrors(), 0)
|
||||
|
||||
// check circular references
|
||||
@@ -334,9 +334,9 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve_RecursiveLookup(t *test
|
||||
assert.Len(t, rolo.GetCaughtErrors(), 0)
|
||||
assert.Len(t, rolo.GetIgnoredCircularReferences(), 0)
|
||||
|
||||
assert.Equal(t, int64(1266728), rolo.RolodexFileSize())
|
||||
assert.Equal(t, int64(1270079), rolo.RolodexFileSize())
|
||||
assert.Equal(t, "1.21 MB", rolo.RolodexFileSizeAsString())
|
||||
assert.Equal(t, 1677, rolo.RolodexTotalFiles())
|
||||
assert.Equal(t, 1682, rolo.RolodexTotalFiles())
|
||||
|
||||
}
|
||||
|
||||
@@ -1469,16 +1469,16 @@ func ExampleNewSpecIndex() {
|
||||
len(index.GetAllSchemas()),
|
||||
len(index.GetAllEnums()),
|
||||
len(index.GetPolyOneOfReferences())+len(index.GetPolyAnyOfReferences()))
|
||||
// Output: There are 537 references
|
||||
// 246 paths
|
||||
// 402 operations
|
||||
// 537 component schemas
|
||||
// 1972 reference schemas
|
||||
// 11749 inline schemas
|
||||
// 2612 inline schemas that are objects or arrays
|
||||
// 14258 total schemas
|
||||
// 1516 enums
|
||||
// 828 polymorphic references
|
||||
// Output: There are 871 references
|
||||
// 336 paths
|
||||
// 494 operations
|
||||
// 871 component schemas
|
||||
// 2712 reference schemas
|
||||
// 15928 inline schemas
|
||||
// 3857 inline schemas that are objects or arrays
|
||||
// 19511 total schemas
|
||||
// 2579 enums
|
||||
// 1023 polymorphic references
|
||||
}
|
||||
|
||||
func TestSpecIndex_GetAllPathsHavePathAndParent(t *testing.T) {
|
||||
|
||||
@@ -68,6 +68,9 @@ func (mg *MockGenerator) SetPretty() {
|
||||
// The name parameter is optional, if provided, the mock generator will attempt to find an example with the given name.
|
||||
// If no name is provided, the first example will be used.
|
||||
func (mg *MockGenerator) GenerateMock(mock any, name string) ([]byte, error) {
|
||||
if mock == nil || !reflect.ValueOf(mock).IsValid() || reflect.ValueOf(mock).IsNil() {
|
||||
return nil, nil
|
||||
}
|
||||
v := reflect.ValueOf(mock).Elem()
|
||||
num := v.NumField()
|
||||
fieldCount := 0
|
||||
|
||||
@@ -99,6 +99,18 @@ func TestNewMockGeneratorWithDictionary(t *testing.T) {
|
||||
assert.NotNil(t, mg)
|
||||
}
|
||||
|
||||
func TestMockGenerator_GenerateJSONMock_NoObject(t *testing.T) {
|
||||
|
||||
mg := NewMockGenerator(JSON)
|
||||
|
||||
var isNil any
|
||||
isNil = nil
|
||||
|
||||
mock, err := mg.GenerateMock(isNil, "")
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, mock)
|
||||
}
|
||||
|
||||
func TestMockGenerator_GenerateJSONMock_BadObject(t *testing.T) {
|
||||
type NotMockable struct {
|
||||
pizza string
|
||||
|
||||
81630
test_specs/stripe-old.yaml
Normal file
81630
test_specs/stripe-old.yaml
Normal file
File diff suppressed because it is too large
Load Diff
147093
test_specs/stripe.yaml
147093
test_specs/stripe.yaml
File diff suppressed because it is too large
Load Diff
@@ -107,6 +107,38 @@ biscuit:
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
// codecov seems to get upset with this not being covered.
|
||||
// so lets run the damn thing a few hundred thousand times.
|
||||
func BenchmarkCompareSecurityRequirement_Remove(b *testing.B) {
|
||||
|
||||
left := `auth:
|
||||
- pizza
|
||||
- pie`
|
||||
|
||||
right := `auth:
|
||||
- pie
|
||||
- pizza
|
||||
biscuit:
|
||||
- digestive`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
var lDoc base.SecurityRequirement
|
||||
var rDoc base.SecurityRequirement
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(context.Background(), nil, lNode.Content[0], nil)
|
||||
_ = rDoc.Build(context.Background(), nil, rNode.Content[0], nil)
|
||||
extChanges := CompareSecurityRequirement(&rDoc, &lDoc)
|
||||
assert.Equal(b, 1, extChanges.TotalChanges())
|
||||
assert.Len(b, extChanges.GetAllChanges(), 1)
|
||||
assert.Equal(b, 1, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompareSecurityRequirement_SwapOut_V2(t *testing.T) {
|
||||
|
||||
left := `cheese:
|
||||
|
||||
Reference in New Issue
Block a user