Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: improve code quality #1050

Merged
merged 3 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 88 additions & 83 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,25 +348,37 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
return nil
}

const (
defaultTag = "default"
enumsTag = "enums"
formatTag = "format"
minimumTag = "minimum"
maximumTag = "maximum"
minLengthTag = "minlength"
maxLengthTag = "maxlength"
extensionsTag = "extensions"
collectionFormatTag = "collectionFormat"
)

var regexAttributes = map[string]*regexp.Regexp{
// for Enums(A, B)
"enums": regexp.MustCompile(`(?i)\s+enums\(.*\)`),
enumsTag: regexp.MustCompile(`(?i)\s+enums\(.*\)`),
// for maximum(0)
"maximum": regexp.MustCompile(`(?i)\s+maxinum|maximum\(.*\)`),
maximumTag: regexp.MustCompile(`(?i)\s+maxinum|maximum\(.*\)`),
// for minimum(0)
"minimum": regexp.MustCompile(`(?i)\s+mininum|minimum\(.*\)`),
minimumTag: regexp.MustCompile(`(?i)\s+mininum|minimum\(.*\)`),
// for default(0)
"default": regexp.MustCompile(`(?i)\s+default\(.*\)`),
defaultTag: regexp.MustCompile(`(?i)\s+default\(.*\)`),
// for minlength(0)
"minlength": regexp.MustCompile(`(?i)\s+minlength\(.*\)`),
minLengthTag: regexp.MustCompile(`(?i)\s+minlength\(.*\)`),
// for maxlength(0)
"maxlength": regexp.MustCompile(`(?i)\s+maxlength\(.*\)`),
maxLengthTag: regexp.MustCompile(`(?i)\s+maxlength\(.*\)`),
// for format(email)
"format": regexp.MustCompile(`(?i)\s+format\(.*\)`),
formatTag: regexp.MustCompile(`(?i)\s+format\(.*\)`),
// for extensions(x-example=test)
"extensions": regexp.MustCompile(`(?i)\s+extensions\(.*\)`),
extensionsTag: regexp.MustCompile(`(?i)\s+extensions\(.*\)`),
// for collectionFormat(csv)
"collectionFormat": regexp.MustCompile(`(?i)\s+collectionFormat\(.*\)`),
collectionFormatTag: regexp.MustCompile(`(?i)\s+collectionFormat\(.*\)`),
}

func (operation *Operation) parseAndExtractionParamAttribute(commentLine, objectType, schemaType string, param *spec.Parameter) error {
Expand All @@ -377,52 +389,23 @@ func (operation *Operation) parseAndExtractionParamAttribute(commentLine, object
continue
}
switch attrKey {
case "enums":
err := setEnumParam(attr, objectType, schemaType, param)
if err != nil {
return err
}
case "maximum":
n, err := setNumberParam(attrKey, schemaType, attr, commentLine)
if err != nil {
return err
}
param.Maximum = &n
case "minimum":
n, err := setNumberParam(attrKey, schemaType, attr, commentLine)
if err != nil {
return err
}
param.Minimum = &n
case "default":
value, err := defineType(schemaType, attr)
if err != nil {
return nil
}
param.Default = value
case "maxlength":
n, err := setStringParam(attrKey, schemaType, attr, commentLine)
if err != nil {
return err
}
param.MaxLength = &n
case "minlength":
n, err := setStringParam(attrKey, schemaType, attr, commentLine)
if err != nil {
return err
}
param.MinLength = &n
case "format":
case enumsTag:
err = setEnumParam(param, attr, objectType, schemaType)
case minimumTag, maximumTag:
err = setNumberParam(param, attrKey, schemaType, attr, commentLine)
case defaultTag:
err = setDefault(param, schemaType, attr)
case minLengthTag, maxLengthTag:
err = setStringParam(param, attrKey, schemaType, attr, commentLine)
case formatTag:
param.Format = attr
case "extensions":
param.Extensions = map[string]interface{}{}
_ = setExtensionParam(attr, param)
case "collectionFormat":
n, err := setCollectionFormatParam(attrKey, objectType, attr, commentLine)
if err != nil {
return err
}
param.CollectionFormat = n
case extensionsTag:
_ = setExtensionParam(param, attr)
case collectionFormatTag:
err = setCollectionFormatParam(param, attrKey, objectType, attr, commentLine)
}
if err != nil {
return err
}
}

Expand All @@ -440,34 +423,46 @@ func findAttr(re *regexp.Regexp, commentLine string) (string, error) {
return strings.TrimSpace(attr[l+1 : r]), nil
}

func setStringParam(name, schemaType, attr, commentLine string) (int64, error) {
func setStringParam(param *spec.Parameter, name, schemaType, attr, commentLine string) error {
if schemaType != STRING {
return 0, fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
return fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
}

n, err := strconv.ParseInt(attr, 10, 64)
if err != nil {
return 0, fmt.Errorf("%s is allow only a number got=%s", name, attr)
return fmt.Errorf("%s is allow only a number got=%s", name, attr)
}

switch name {
case minLengthTag:
param.MinLength = &n
case maxLengthTag:
param.MaxLength = &n
}

return n, nil
return nil
}

func setNumberParam(name, schemaType, attr, commentLine string) (float64, error) {
func setNumberParam(param *spec.Parameter, name, schemaType, attr, commentLine string) error {
switch schemaType {
case INTEGER, NUMBER:
n, err := strconv.ParseFloat(attr, 64)
if err != nil {
return 0, fmt.Errorf("maximum is allow only a number. comment=%s got=%s", commentLine, attr)
return fmt.Errorf("maximum is allow only a number. comment=%s got=%s", commentLine, attr)
}

return n, nil
switch name {
case minimumTag:
param.Minimum = &n
case maximumTag:
param.Maximum = &n
}
return nil
default:
return fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
}

return 0, fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
}

func setEnumParam(attr, objectType, schemaType string, param *spec.Parameter) error {
func setEnumParam(param *spec.Parameter, attr, objectType, schemaType string) error {
for _, e := range strings.Split(attr, ",") {
e = strings.TrimSpace(e)

Expand All @@ -487,7 +482,8 @@ func setEnumParam(attr, objectType, schemaType string, param *spec.Parameter) er
return nil
}

func setExtensionParam(attr string, param *spec.Parameter) error {
func setExtensionParam(param *spec.Parameter, attr string) error {
param.Extensions = map[string]interface{}{}
for _, val := range strings.Split(attr, ",") {
parts := strings.SplitN(val, "=", 2)
if len(parts) == 2 {
Expand All @@ -500,44 +496,50 @@ func setExtensionParam(attr string, param *spec.Parameter) error {
return nil
}

func setCollectionFormatParam(name, schemaType, attr, commentLine string) (string, error) {
func setCollectionFormatParam(param *spec.Parameter, name, schemaType, attr, commentLine string) error {
if schemaType == ARRAY {
return TransToValidCollectionFormat(attr), nil
param.CollectionFormat = TransToValidCollectionFormat(attr)
return nil
}

return "", fmt.Errorf("%s is attribute to set to an array. comment=%s got=%s", name, commentLine, schemaType)
return fmt.Errorf("%s is attribute to set to an array. comment=%s got=%s", name, commentLine, schemaType)
}

func setDefault(param *spec.Parameter, schemaType string, value string) error {
val, err := defineType(schemaType, value)
if err != nil {
return nil // Don't set a default value if it's not valid
}
param.Default = val
return nil
}

// defineType enum value define the type (object and array unsupported).
func defineType(schemaType string, value string) (interface{}, error) {
func defineType(schemaType string, value string) (v interface{}, err error) {
schemaType = TransToValidSchemeType(schemaType)
switch schemaType {
case STRING:
return value, nil
case NUMBER:
v, err := strconv.ParseFloat(value, 64)
v, err = strconv.ParseFloat(value, 64)
if err != nil {
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}

return v, nil
case INTEGER:
v, err := strconv.Atoi(value)
v, err = strconv.Atoi(value)
if err != nil {
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}

return v, nil
case BOOLEAN:
v, err := strconv.ParseBool(value)
v, err = strconv.ParseBool(value)
if err != nil {
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}

return v, nil
default:
return nil, fmt.Errorf("%s is unsupported type in enum value %s", schemaType, value)
}

return v, nil
}

// ParseTagsComment parses comment for given `tag` comment string.
Expand Down Expand Up @@ -836,7 +838,7 @@ func (operation *Operation) ParseResponseComment(commentLine string, astFile *as
}

for _, codeStr := range strings.Split(matches[1], ",") {
if strings.EqualFold(codeStr, "default") {
if strings.EqualFold(codeStr, defaultTag) {
operation.DefaultResponse().Schema = schema
operation.DefaultResponse().Description = responseDescription

Expand Down Expand Up @@ -901,7 +903,7 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
}

for _, codeStr := range strings.Split(matches[1], ",") {
if strings.EqualFold(codeStr, "default") {
if strings.EqualFold(codeStr, defaultTag) {
if operation.Responses.Default != nil {
operation.Responses.Default.Headers[headerKey] = header
}
Expand Down Expand Up @@ -940,7 +942,7 @@ func (operation *Operation) ParseEmptyResponseComment(commentLine string) error

responseDescription := strings.Trim(matches[2], "\"")
for _, codeStr := range strings.Split(matches[1], ",") {
if strings.EqualFold(codeStr, "default") {
if strings.EqualFold(codeStr, defaultTag) {
operation.DefaultResponse().Description = responseDescription

continue
Expand All @@ -962,7 +964,7 @@ func (operation *Operation) ParseEmptyResponseComment(commentLine string) error
// ParseEmptyResponseOnly parse only comment out status code ,eg: @Success 200.
func (operation *Operation) ParseEmptyResponseOnly(commentLine string) error {
for _, codeStr := range strings.Split(commentLine, ",") {
if strings.EqualFold(codeStr, "default") {
if strings.EqualFold(codeStr, defaultTag) {
_ = operation.DefaultResponse()

continue
Expand Down Expand Up @@ -998,6 +1000,7 @@ func (operation *Operation) AddResponse(code int, response *spec.Response) {
},
}
}

operation.Responses.StatusCodeResponses[code] = *response
}

Expand All @@ -1019,12 +1022,14 @@ func createParameter(paramType, description, paramName, schemaType string, requi
Type: []string{schemaType},
},
}

return result
}

result.SimpleSchema = spec.SimpleSchema{
Type: schemaType,
}

return result
}

Expand Down
8 changes: 8 additions & 0 deletions operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2216,4 +2216,12 @@ func TestParseCodeSamples(t *testing.T) {
err := operation.ParseComment(comment, nil)
assert.Error(t, err, "no error should be thrown")
})

t.Run(" broken dir", func(t *testing.T) {
operation := NewOperation(nil, SetCodeExampleFilesDirectory("testdata/fake_examples"))
operation.Summary = "code"

err := operation.ParseComment(comment, nil)
assert.Error(t, err, "no error should be thrown")
})
}