Skip to content

Commit

Permalink
chore: improve code quality (#1086)
Browse files Browse the repository at this point in the history
  • Loading branch information
ubogdan authored Dec 23, 2021
1 parent 54c9ff9 commit f631188
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 44 deletions.
15 changes: 8 additions & 7 deletions formater.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,11 @@ func formatFuncDoc(commentList []*ast.Comment, formatedComments *bytes.Buffer, o

// Check of @Param @Success @Failure @Response @Header
var specialTagForSplit = map[string]byte{
"@param": 1,
"@success": 1,
"@failure": 1,
"@response": 1,
"@header": 1,
paramAttr: 1,
successAttr: 1,
failureAttr: 1,
responseAttr: 1,
headerAttr: 1,
}

var skipChar = map[byte]byte{
Expand Down Expand Up @@ -276,9 +276,10 @@ func replaceRange(s []byte, start, end int, new byte) []byte {
return s
}

var swagCommentExpression = regexp.MustCompile("@[A-z]+")

func isSwagComment(comment string) bool {
lc := strings.ToLower(comment)
return regexp.MustCompile("@[A-z]+").MatchString(lc)
return swagCommentExpression.MatchString(strings.ToLower(comment))
}

func isBlankComment(comment string) bool {
Expand Down
44 changes: 19 additions & 25 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,35 +100,35 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro

var err error
switch lowerAttribute {
case "@description":
case descriptionAttr:
operation.ParseDescriptionComment(lineRemainder)
case "@description.markdown":
case descriptionMarkdownAttr:
commentInfo, err := getMarkdownForTag(lineRemainder, operation.parser.markdownFileDir)
if err != nil {
return err
}
operation.ParseDescriptionComment(string(commentInfo))
case "@summary":
case summaryAttr:
operation.Summary = lineRemainder
case "@id":
case idAttr:
operation.ID = lineRemainder
case "@tags":
case tagsAttr:
operation.ParseTagsComment(lineRemainder)
case acceptAttr:
err = operation.ParseAcceptComment(lineRemainder)
case produceAttr:
err = operation.ParseProduceComment(lineRemainder)
case "@param":
case paramAttr:
err = operation.ParseParamComment(lineRemainder, astFile)
case "@success", "@failure", "@response":
case successAttr, failureAttr, responseAttr:
err = operation.ParseResponseComment(lineRemainder, astFile)
case "@header":
case headerAttr:
err = operation.ParseResponseHeaderComment(lineRemainder, astFile)
case "@router":
case routerAttr:
err = operation.ParseRouterComment(lineRemainder)
case "@security":
case securityAttr:
err = operation.ParseSecurityComment(lineRemainder)
case "@deprecated":
case deprecatedAttr:
operation.Deprecate()
case xCodeSamplesAttr:
err = operation.ParseCodeSample(attribute, commentLine, lineRemainder)
Expand Down Expand Up @@ -886,19 +886,6 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
header := newHeaderSpec(strings.Trim(matches[2], "{}"), strings.Trim(matches[4], "\""))

headerKey := matches[3]
if operation.Responses.Default != nil {
if operation.Responses.Default.Headers == nil {
operation.Responses.Default.Headers = make(map[string]spec.Header)
}
}

for code, response := range operation.Responses.StatusCodeResponses {
if response.Headers == nil {
r := operation.Responses.StatusCodeResponses[code]
r.Headers = make(map[string]spec.Header)
operation.Responses.StatusCodeResponses[code] = r
}
}

if strings.EqualFold(matches[1], "all") {
if operation.Responses.Default != nil {
Expand Down Expand Up @@ -991,14 +978,21 @@ func (operation *Operation) ParseEmptyResponseOnly(commentLine string) error {
// DefaultResponse return the default response member pointer.
func (operation *Operation) DefaultResponse() *spec.Response {
if operation.Responses.Default == nil {
operation.Responses.Default = spec.NewResponse()
operation.Responses.Default = &spec.Response{
ResponseProps: spec.ResponseProps{
Headers: make(map[string]spec.Header),
},
}
}

return operation.Responses.Default
}

// AddResponse add a response for a code.
func (operation *Operation) AddResponse(code int, response *spec.Response) {
if response.Headers == nil {
response.Headers = make(map[string]spec.Header)
}
operation.Responses.StatusCodeResponses[code] = *response
}

Expand Down
6 changes: 3 additions & 3 deletions packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ func (pkgs *PackagesDefinitions) CollectAstFile(packageDir, path string, astFile
}

// RangeFiles for range the collection of ast.File in alphabetic order.
func (pkgs *PackagesDefinitions) RangeFiles(handle func(filename string, file *ast.File) error) error {
sortedFiles := make([]*AstFileInfo, 0, len(pkgs.files))
for _, info := range pkgs.files {
func rangeFiles(files map[*ast.File]*AstFileInfo, handle func(filename string, file *ast.File) error) error {
sortedFiles := make([]*AstFileInfo, 0, len(files))
for _, info := range files {
sortedFiles = append(sortedFiles, info)
}

Expand Down
134 changes: 134 additions & 0 deletions packages_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package swag

import (
"go/ast"
"go/token"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestPackagesDefinitions_CollectAstFile(t *testing.T) {
pd := PackagesDefinitions{}
assert.NoError(t, pd.CollectAstFile("", "", nil))

firstFile := &ast.File{
Name: &ast.Ident{Name: "main.go"},
}

packageDir := "github.com/swaggo/swag/testdata/simple"
assert.NoError(t, pd.CollectAstFile(packageDir, "testdata/simple/"+firstFile.Name.String(), firstFile))
assert.NotEmpty(t, pd.packages[packageDir])

absPath, _ := filepath.Abs("testdata/simple/" + firstFile.Name.String())
astFileInfo := &AstFileInfo{
File: firstFile,
Path: absPath,
PackagePath: packageDir,
}
assert.Equal(t, pd.files[firstFile], astFileInfo)

// Override
assert.NoError(t, pd.CollectAstFile(packageDir, "testdata/simple/"+firstFile.Name.String(), firstFile))
assert.Equal(t, pd.files[firstFile], astFileInfo)

// Another file
secondFile := &ast.File{
Name: &ast.Ident{Name: "api.go"},
}
assert.NoError(t, pd.CollectAstFile(packageDir, "testdata/simple/"+secondFile.Name.String(), secondFile))
}

func TestPackagesDefinitions_rangeFiles(t *testing.T) {
pd := PackagesDefinitions{
files: map[*ast.File]*AstFileInfo{
{
Name: &ast.Ident{Name: "main.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "main.go"}},
Path: "testdata/simple/main.go",
PackagePath: "main",
},
{
Name: &ast.Ident{Name: "api.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "api.go"}},
Path: "testdata/simple/api/api.go",
PackagePath: "api",
},
},
}

i, expect := 0, []string{"testdata/simple/api/api.go", "testdata/simple/main.go"}
_ = rangeFiles(pd.files, func(filename string, file *ast.File) error {
assert.Equal(t, expect[i], filename)
i++
return nil
})
}

func TestPackagesDefinitions_ParseTypes(t *testing.T) {
absPath, _ := filepath.Abs("")

mainAST := ast.File{
Name: &ast.Ident{Name: "main.go"},
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.TYPE,
Specs: []ast.Spec{
&ast.TypeSpec{
Name: &ast.Ident{Name: "Test"},
Type: &ast.Ident{
Name: "string",
},
},
},
},
},
}

pd := PackagesDefinitions{
files: map[*ast.File]*AstFileInfo{
&mainAST: {
File: &mainAST,
Path: filepath.Join(absPath, "testdata/simple/main.go"),
PackagePath: "main",
},
{
Name: &ast.Ident{Name: "api.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "api.go"}},
Path: filepath.Join(absPath, "testdata/simple/api/api.go"),
PackagePath: "api",
},
},
packages: make(map[string]*PackageDefinitions),
}

_, err := pd.ParseTypes()
assert.NoError(t, err)
}

func TestPackagesDefinitions_findTypeSpec(t *testing.T) {
pd := PackagesDefinitions{}
var nilTypeSpec *TypeSpecDef
assert.Equal(t, nilTypeSpec, pd.findTypeSpec("model", "User"))

userTypeSpec := TypeSpecDef{
File: &ast.File{},
TypeSpec: &ast.TypeSpec{},
PkgPath: "model",
}
pd = PackagesDefinitions{
packages: map[string]*PackageDefinitions{
"model": {
TypeDefinitions: map[string]*TypeSpecDef{
"User": &userTypeSpec,
},
},
},
}
assert.Equal(t, &userTypeSpec, pd.findTypeSpec("model", "User"))
assert.Equal(t, nilTypeSpec, pd.findTypeSpec("others", "User"))
}
33 changes: 24 additions & 9 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,25 @@ const (
// SnakeCase indicates using SnakeCase strategy for struct field.
SnakeCase = "snakecase"

acceptAttr = "@accept"
produceAttr = "@produce"
xCodeSamplesAttr = "@x-codesamples"
scopeAttrPrefix = "@scope."
idAttr = "@id"
acceptAttr = "@accept"
produceAttr = "@produce"
paramAttr = "@param"
successAttr = "@success"
failureAttr = "@failure"
responseAttr = "@response"
headerAttr = "@header"
tagsAttr = "@tags"
routerAttr = "@router"
summaryAttr = "@summary"
deprecatedAttr = "@deprecated"
securityAttr = "@security"
titleAttr = "@title"
versionAttr = "@version"
descriptionAttr = "@description"
descriptionMarkdownAttr = "@description.markdown"
xCodeSamplesAttr = "@x-codesamples"
scopeAttrPrefix = "@scope."
)

var (
Expand Down Expand Up @@ -301,7 +316,7 @@ func (parser *Parser) ParseAPIMultiSearchDir(searchDirs []string, mainAPIFile st
return err
}

err = parser.packages.RangeFiles(parser.ParseRouterAPIInfo)
err = rangeFiles(parser.packages.files, parser.ParseRouterAPIInfo)
if err != nil {
return err
}
Expand Down Expand Up @@ -376,11 +391,11 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
multilineBlock = true
}
switch strings.ToLower(attribute) {
case "@version":
case versionAttr:
parser.swagger.Info.Version = value
case "@title":
case titleAttr:
parser.swagger.Info.Title = value
case "@description":
case descriptionAttr:
if multilineBlock {
parser.swagger.Info.Description += "\n" + value

Expand Down Expand Up @@ -549,7 +564,7 @@ func isGeneralAPIComment(comments []string) bool {
attribute := strings.ToLower(strings.Split(commentLine, " ")[0])
switch attribute {
// The @summary, @router, @success, @failure annotation belongs to Operation
case "@summary", "@router", "@success", "@failure", "@response":
case summaryAttr, routerAttr, successAttr, failureAttr, responseAttr:
return false
}
}
Expand Down

0 comments on commit f631188

Please sign in to comment.