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

improve code quality #1049

Merged
merged 3 commits into from
Nov 11, 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
92 changes: 48 additions & 44 deletions field_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,36 +425,11 @@ func (ps *tagBaseFieldParser) parseValidTags(validTag string, sf *structField) {

switch valKey {
case "max", "lte":
maxValue, err := strconv.ParseFloat(valValue, 64)
if err != nil {
// ignore
continue
}
checkSchemaTypeAndSetValue(sf, maxValue, true)
sf.setMax(valValue)
case "min", "gte":
minValue, err := strconv.ParseFloat(valValue, 64)
if err != nil {
// ignore
continue
}
checkSchemaTypeAndSetValue(sf, minValue, false)
sf.setMin(valValue)
case "oneof":
if len(sf.enums) != 0 {
continue
}
enumType := sf.schemaType
if sf.schemaType == ARRAY {
enumType = sf.arrayType
}

valValues := parseOneOfParam2(valValue)
for i := range valValues {
value, err := defineType(enumType, valValues[i])
if err != nil {
continue
}
sf.enums = append(sf.enums, value)
}
sf.setOneOf(valValue)
case "unique":
if sf.schemaType == ARRAY {
sf.unique = true
Expand All @@ -468,28 +443,57 @@ func (ps *tagBaseFieldParser) parseValidTags(validTag string, sf *structField) {
}
}

func checkSchemaTypeAndSetValue(sf *structField, value float64, isMax bool) {
func (sf *structField) setOneOf(valValue string) {
if len(sf.enums) != 0 {
return
}

enumType := sf.schemaType
if sf.schemaType == ARRAY {
enumType = sf.arrayType
}

valValues := parseOneOfParam2(valValue)
for i := range valValues {
value, err := defineType(enumType, valValues[i])
if err != nil {
continue
}
sf.enums = append(sf.enums, value)
}
}

func (sf *structField) setMin(valValue string) {
value, err := strconv.ParseFloat(valValue, 64)
if err != nil {
return
}
switch sf.schemaType {
case INTEGER, NUMBER:
if isMax {
sf.maximum = &value
} else {
sf.minimum = &value
}
sf.minimum = &value
case STRING:
intValue := int64(value)
if isMax {
sf.maxLength = &intValue
} else {
sf.minLength = &intValue
}
sf.minLength = &intValue
case ARRAY:
intValue := int64(value)
if isMax {
sf.maxItems = &intValue
} else {
sf.minItems = &intValue
}
sf.minItems = &intValue
}
}

func (sf *structField) setMax(valValue string) {
value, err := strconv.ParseFloat(valValue, 64)
if err != nil {
return
}
switch sf.schemaType {
case INTEGER, NUMBER:
sf.maximum = &value
case STRING:
intValue := int64(value)
sf.maxLength = &intValue
case ARRAY:
intValue := int64(value)
sf.maxItems = &intValue
}
}

Expand Down
96 changes: 45 additions & 51 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,23 @@ func findInSlice(arr []string, target string) bool {
return false
}

func (operation *Operation) parseArrayParam(param *spec.Parameter, paramType, refType, objectType string) error {
if !IsPrimitiveType(refType) {
return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
}
param.SimpleSchema.Type = objectType
if operation.parser != nil {
param.CollectionFormat = TransToValidCollectionFormat(operation.parser.collectionFormatInQuery)
}
param.SimpleSchema.Items = &spec.Items{
SimpleSchema: spec.SimpleSchema{
Type: refType,
},
}

return nil
}

// ParseParamComment parses params return []string of param properties
// E.g. @Param queryText formData string true "The email for login"
// [param name] [paramType] [data type] [is mandatory?] [Comment]
Expand Down Expand Up @@ -234,35 +251,19 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
case "path", "header":
switch objectType {
case ARRAY:
if !IsPrimitiveType(refType) {
return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
}
param.SimpleSchema.Type = objectType
if operation.parser != nil {
param.CollectionFormat = TransToValidCollectionFormat(operation.parser.collectionFormatInQuery)
}
param.SimpleSchema.Items = &spec.Items{
SimpleSchema: spec.SimpleSchema{
Type: refType,
},
err := operation.parseArrayParam(&param, paramType, refType, objectType)
if err != nil {
return err
}
case OBJECT:
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
}
case "query", "formData":
switch objectType {
case ARRAY:
if !IsPrimitiveType(refType) {
return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
}
param.SimpleSchema.Type = objectType
if operation.parser != nil {
param.CollectionFormat = TransToValidCollectionFormat(operation.parser.collectionFormatInQuery)
}
param.SimpleSchema.Items = &spec.Items{
SimpleSchema: spec.SimpleSchema{
Type: refType,
},
err := operation.parseArrayParam(&param, paramType, refType, objectType)
if err != nil {
return err
}
case OBJECT:
schema, err := operation.parser.getTypeSchema(refType, astFile, false)
Expand Down Expand Up @@ -878,19 +879,19 @@ 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)
}
}

if strings.EqualFold(matches[1], "all") {
if operation.Responses.Default != nil {
if operation.Responses.Default.Headers == nil {
operation.Responses.Default.Headers = make(map[string]spec.Header)
}
operation.Responses.Default.Headers[headerKey] = header
}
if operation.Responses != nil && operation.Responses.StatusCodeResponses != nil {

if operation.Responses.StatusCodeResponses != nil {
for code, response := range operation.Responses.StatusCodeResponses {
if response.Headers == nil {
response.Headers = make(map[string]spec.Header)
}
response.Headers[headerKey] = header
operation.Responses.StatusCodeResponses[code] = response
}
Expand All @@ -902,9 +903,6 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
for _, codeStr := range strings.Split(matches[1], ",") {
if strings.EqualFold(codeStr, "default") {
if operation.Responses.Default != nil {
if operation.Responses.Default.Headers == nil {
operation.Responses.Default.Headers = make(map[string]spec.Header)
}
operation.Responses.Default.Headers[headerKey] = header
}

Expand All @@ -915,7 +913,7 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
if err != nil {
return fmt.Errorf("can not parse response comment \"%s\"", commentLine)
}
if operation.Responses != nil && operation.Responses.StatusCodeResponses != nil {
if operation.Responses.StatusCodeResponses != nil {
response, responseExist := operation.Responses.StatusCodeResponses[code]
if responseExist {
if response.Headers == nil {
Expand Down Expand Up @@ -1006,32 +1004,28 @@ func (operation *Operation) AddResponse(code int, response *spec.Response) {
// createParameter returns swagger spec.Parameter for given paramType, description, paramName, schemaType, required.
func createParameter(paramType, description, paramName, schemaType string, required bool) spec.Parameter {
// //five possible parameter types. query, path, body, header, form
paramProps := spec.ParamProps{
Name: paramName,
Description: description,
Required: required,
In: paramType,
result := spec.Parameter{
ParamProps: spec.ParamProps{
Name: paramName,
Description: description,
Required: required,
In: paramType,
},
}

if paramType == "body" {
paramProps.Schema = &spec.Schema{
result.ParamProps.Schema = &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{schemaType},
},
}
parameter := spec.Parameter{
ParamProps: paramProps,
}

return parameter
}
parameter := spec.Parameter{
ParamProps: paramProps,
SimpleSchema: spec.SimpleSchema{
Type: schemaType,
},
return result
}

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

func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error) {
Expand Down
60 changes: 50 additions & 10 deletions operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1039,28 +1039,68 @@ func TestParseResponseCommentParamMissing(t *testing.T) {
assert.EqualError(t, paramLenErr, `can not parse response comment "notIntCode "it ok""`)
}

// Test ParseParamComment
func TestParseParamCommentByParamType(t *testing.T) {
func TestOperation_ParseParamComment(t *testing.T) {
t.Parallel()

comment := `@Param some_id path int true "Some ID"`
operation := NewOperation(nil)
err := operation.ParseComment(comment, nil)
t.Run("integer", func(t *testing.T) {
t.Parallel()
for _, paramType := range []string{"header", "path", "query", "formData"} {
t.Run(paramType, func(t *testing.T) {
o := NewOperation(nil)
err := o.ParseComment(`@Param some_id `+paramType+` int true "Some ID"`, nil)

assert.NoError(t, err)
b, _ := json.MarshalIndent(operation, "", " ")
expected := `{
assert.NoError(t, err)
b, _ := json.MarshalIndent(o, "", " ")
expected := `{
"parameters": [
{
"type": "integer",
"description": "Some ID",
"name": "some_id",
"in": "path",
"in": "` + paramType + `",
"required": true
}
]
}`
assert.Equal(t, expected, string(b))
assert.Equal(t, expected, string(b))
})
}
})

t.Run("string", func(t *testing.T) {
t.Parallel()
for _, paramType := range []string{"header", "path", "query", "formData"} {
t.Run(paramType, func(t *testing.T) {
o := NewOperation(nil)
err := o.ParseComment(`@Param some_string `+paramType+` string true "Some String"`, nil)

assert.NoError(t, err)
b, _ := json.MarshalIndent(o, "", " ")
expected := `{
"parameters": [
{
"type": "string",
"description": "Some String",
"name": "some_string",
"in": "` + paramType + `",
"required": true
}
]
}`
assert.Equal(t, expected, string(b))
})
}
})

t.Run("object", func(t *testing.T) {
t.Parallel()
for _, paramType := range []string{"header", "path", "query", "formData"} {
t.Run(paramType, func(t *testing.T) {
assert.Error(t, NewOperation(nil).ParseComment(`@Param some_object `+paramType+` main.Object true "Some Object"`, nil))
})
}
})

}

// Test ParseParamComment Query Params
Expand Down