Add delete operation
This commit is contained in:
parent
c5c4542a80
commit
e78f9180da
8 changed files with 1278 additions and 88 deletions
internal/spec
|
@ -33,6 +33,12 @@ type FindOperation struct {
|
|||
Query QuerySpec
|
||||
}
|
||||
|
||||
// DeleteOperation is a method specification for delete operations
|
||||
type DeleteOperation struct {
|
||||
Mode QueryMode
|
||||
Query QuerySpec
|
||||
}
|
||||
|
||||
// QuerySpec is a set of conditions of querying the database
|
||||
type QuerySpec struct {
|
||||
Operator Operator
|
||||
|
|
|
@ -25,6 +25,8 @@ func (p interfaceMethodParser) Parse() (MethodSpec, error) {
|
|||
switch methodNameTokens[0] {
|
||||
case "Find":
|
||||
return p.parseFindMethod(methodNameTokens[1:])
|
||||
case "Delete":
|
||||
return p.parseDeleteMethod(methodNameTokens[1:])
|
||||
}
|
||||
return MethodSpec{}, UnknownOperationError
|
||||
}
|
||||
|
@ -92,6 +94,58 @@ func (p interfaceMethodParser) extractFindReturns(returns []code.Type) (QueryMod
|
|||
return "", UnsupportedReturnError
|
||||
}
|
||||
|
||||
func (p interfaceMethodParser) parseDeleteMethod(tokens []string) (MethodSpec, error) {
|
||||
if len(tokens) == 0 {
|
||||
return MethodSpec{}, UnsupportedNameError
|
||||
}
|
||||
|
||||
mode, err := p.extractDeleteReturns(p.Method.Returns)
|
||||
if err != nil {
|
||||
return MethodSpec{}, err
|
||||
}
|
||||
|
||||
querySpec, err := p.parseQuery(tokens)
|
||||
if err != nil {
|
||||
return MethodSpec{}, err
|
||||
}
|
||||
|
||||
if err := p.validateMethodSignature(querySpec); err != nil {
|
||||
return MethodSpec{}, err
|
||||
}
|
||||
|
||||
return MethodSpec{
|
||||
Name: p.Method.Name,
|
||||
Params: p.Method.Params,
|
||||
Returns: p.Method.Returns,
|
||||
Operation: DeleteOperation{
|
||||
Mode: mode,
|
||||
Query: querySpec,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p interfaceMethodParser) extractDeleteReturns(returns []code.Type) (QueryMode, error) {
|
||||
if len(returns) != 2 {
|
||||
return "", UnsupportedReturnError
|
||||
}
|
||||
|
||||
if returns[1] != code.SimpleType("error") {
|
||||
return "", UnsupportedReturnError
|
||||
}
|
||||
|
||||
simpleType, ok := returns[0].(code.SimpleType)
|
||||
if ok {
|
||||
if simpleType == code.SimpleType("bool") {
|
||||
return QueryModeOne, nil
|
||||
}
|
||||
if simpleType == code.SimpleType("int") {
|
||||
return QueryModeMany, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", UnsupportedReturnError
|
||||
}
|
||||
|
||||
func (p interfaceMethodParser) parseQuery(tokens []string) (QuerySpec, error) {
|
||||
if len(tokens) == 0 {
|
||||
return QuerySpec{}, InvalidQueryError
|
||||
|
|
|
@ -40,7 +40,7 @@ type ParseInterfaceMethodTestCase struct {
|
|||
ExpectedOutput spec.MethodSpec
|
||||
}
|
||||
|
||||
func TestParseInterfaceMethod(t *testing.T) {
|
||||
func TestParseInterfaceMethod_Find(t *testing.T) {
|
||||
testTable := []ParseInterfaceMethodTestCase{
|
||||
{
|
||||
Name: "FindOneByArg method",
|
||||
|
@ -470,21 +470,454 @@ func TestParseInterfaceMethod(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestParseInterfaceMethod_Delete(t *testing.T) {
|
||||
testTable := []ParseInterfaceMethodTestCase{
|
||||
{
|
||||
Name: "DeleteOneByArg method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteOneByID",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("bool"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteOneByID",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("bool"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "ID", Comparator: spec.ComparatorEqual},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteOneByMultiWordArg method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteOneByPhoneNumber",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("bool"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteOneByPhoneNumber",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("bool"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "PhoneNumber", Comparator: spec.ComparatorEqual},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArg method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCity",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByCity",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "City", Comparator: spec.ComparatorEqual},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteAll method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteAll",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteAll",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgAndArg method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCityAndGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByCityAndGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{
|
||||
Operator: spec.OperatorAnd,
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "City", Comparator: spec.ComparatorEqual},
|
||||
{Field: "Gender", Comparator: spec.ComparatorEqual},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgOrArg method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCityOrGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByCityOrGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{
|
||||
Operator: spec.OperatorOr,
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "City", Comparator: spec.ComparatorEqual},
|
||||
{Field: "Gender", Comparator: spec.ComparatorEqual},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgNot method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCityNot",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByCityNot",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "City", Comparator: spec.ComparatorNot},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgLessThan method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByAgeLessThan",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByAgeLessThan",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorLessThan},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgLessThanEqual method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByAgeLessThanEqual",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByAgeLessThanEqual",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorLessThanEqual},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgGreaterThan method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByAgeGreaterThan",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByAgeGreaterThan",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorGreaterThan},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgGreaterThanEqual method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByAgeGreaterThanEqual",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByAgeGreaterThanEqual",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorGreaterThanEqual},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgBetween method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByAgeBetween",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByAgeBetween",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorBetween},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DeleteByArgIn method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCityIn",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.ArrayType{ContainedType: code.SimpleType("string")}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedOutput: spec.MethodSpec{
|
||||
Name: "DeleteByCityIn",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.ArrayType{ContainedType: code.SimpleType("string")}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.DeleteOperation{
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
{Field: "City", Comparator: spec.ComparatorIn},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testTable {
|
||||
t.Run(testCase.Name, func(t *testing.T) {
|
||||
actualSpec, err := spec.ParseInterfaceMethod(structModel, testCase.Method)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error = %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(actualSpec, testCase.ExpectedOutput) {
|
||||
t.Errorf("Expected = %v\nReceived = %v", testCase.ExpectedOutput, actualSpec)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type ParseInterfaceMethodInvalidTestCase struct {
|
||||
Name string
|
||||
Method code.Method
|
||||
ExpectedError error
|
||||
}
|
||||
|
||||
func TestParseInterfaceMethodInvalid(t *testing.T) {
|
||||
func TestParseInterfaceMethod_Invalid(t *testing.T) {
|
||||
_, err := spec.ParseInterfaceMethod(structModel, code.Method{
|
||||
Name: "SearchByID",
|
||||
})
|
||||
|
||||
if err != spec.UnknownOperationError {
|
||||
t.Errorf("\nExpected = %v\nReceived = %v", spec.UnknownOperationError, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseInterfaceMethod_Find_Invalid(t *testing.T) {
|
||||
testTable := []ParseInterfaceMethodInvalidTestCase{
|
||||
{
|
||||
Name: "unknown operation",
|
||||
Method: code.Method{
|
||||
Name: "SearchByID",
|
||||
},
|
||||
ExpectedError: spec.UnknownOperationError,
|
||||
},
|
||||
{
|
||||
Name: "unsupported find method name",
|
||||
Method: code.Method{
|
||||
|
@ -657,3 +1090,178 @@ func TestParseInterfaceMethodInvalid(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) {
|
||||
testTable := []ParseInterfaceMethodInvalidTestCase{
|
||||
{
|
||||
Name: "unsupported delete method name",
|
||||
Method: code.Method{
|
||||
Name: "Delete",
|
||||
},
|
||||
ExpectedError: spec.UnsupportedNameError,
|
||||
},
|
||||
{
|
||||
Name: "invalid number of returns",
|
||||
Method: code.Method{
|
||||
Name: "DeleteOneByID",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("UserModel"),
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.UnsupportedReturnError,
|
||||
},
|
||||
{
|
||||
Name: "unsupported return values from find method",
|
||||
Method: code.Method{
|
||||
Name: "DeleteOneByID",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("float64"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.UnsupportedReturnError,
|
||||
},
|
||||
{
|
||||
Name: "error return not provided",
|
||||
Method: code.Method{
|
||||
Name: "DeleteOneByID",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("bool"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.UnsupportedReturnError,
|
||||
},
|
||||
{
|
||||
Name: "misplaced operator token (leftmost)",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByAndGender",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidQueryError,
|
||||
},
|
||||
{
|
||||
Name: "misplaced operator token (rightmost)",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByGenderAnd",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidQueryError,
|
||||
},
|
||||
{
|
||||
Name: "misplaced operator token (double operator)",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByGenderAndAndCity",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidQueryError,
|
||||
},
|
||||
{
|
||||
Name: "ambiguous query",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByGenderAndCityOrAge",
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidQueryError,
|
||||
},
|
||||
{
|
||||
Name: "no context parameter",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.ContextParamRequiredError,
|
||||
},
|
||||
{
|
||||
Name: "mismatched number of parameters",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCountry",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidParamError,
|
||||
},
|
||||
{
|
||||
Name: "struct field not found",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCountry",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.StructFieldNotFoundError,
|
||||
},
|
||||
{
|
||||
Name: "mismatched method parameter type",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidParamError,
|
||||
},
|
||||
{
|
||||
Name: "mismatched method parameter type for special case",
|
||||
Method: code.Method{
|
||||
Name: "DeleteByCityIn",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("string")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.InvalidParamError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testTable {
|
||||
t.Run(testCase.Name, func(t *testing.T) {
|
||||
_, err := spec.ParseInterfaceMethod(structModel, testCase.Method)
|
||||
|
||||
if err != testCase.ExpectedError {
|
||||
t.Errorf("\nExpected = %v\nReceived = %v", testCase.ExpectedError, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue