Finalize v0.2.0

This commit is contained in:
sunboyy 2021-06-02 18:39:15 +07:00
parent 1368386584
commit 8e741fda64
9 changed files with 358 additions and 132 deletions

View file

@ -12,8 +12,6 @@ type ParsingError string
func (err ParsingError) Error() string {
switch err {
case UnsupportedReturnError:
return "this type of return is not supported"
case QueryRequiredError:
return "query is required"
case InvalidParamError:
@ -28,13 +26,44 @@ func (err ParsingError) Error() string {
// parsing error constants
const (
UnsupportedReturnError ParsingError = "ERROR_UNSUPPORTED_RETURN"
QueryRequiredError ParsingError = "ERROR_QUERY_REQUIRED"
InvalidParamError ParsingError = "ERROR_INVALID_PARAM"
InvalidUpdateFieldsError ParsingError = "ERROR_INVALID_UPDATE_FIELDS"
ContextParamRequiredError ParsingError = "ERROR_CONTEXT_PARAM_REQUIRED"
)
// NewUnsupportedReturnError creates unsupportedReturnError
func NewUnsupportedReturnError(givenType code.Type, index int) error {
return unsupportedReturnError{
GivenType: givenType,
Index: index,
}
}
type unsupportedReturnError struct {
GivenType code.Type
Index int
}
func (err unsupportedReturnError) Error() string {
return fmt.Sprintf("return type '%s' at index %d is not supported", err.GivenType.Code(), err.Index)
}
// NewOperationReturnCountUnmatchedError creates operationReturnCountUnmatchedError
func NewOperationReturnCountUnmatchedError(returnCount int) error {
return operationReturnCountUnmatchedError{
ReturnCount: returnCount,
}
}
type operationReturnCountUnmatchedError struct {
ReturnCount int
}
func (err operationReturnCountUnmatchedError) Error() string {
return fmt.Sprintf("operation requires return count of %d", err.ReturnCount)
}
// NewInvalidQueryError creates invalidQueryError
func NewInvalidQueryError(queryTokens []string) error {
return invalidQueryError{QueryString: strings.Join(queryTokens, "")}

View file

@ -25,6 +25,16 @@ func TestError(t *testing.T) {
Error: spec.NewStructFieldNotFoundError([]string{"Phone", "Number"}),
ExpectedString: "struct field 'PhoneNumber' not found",
},
{
Name: "UnsupportedReturnError",
Error: spec.NewUnsupportedReturnError(code.SimpleType("User"), 0),
ExpectedString: "return type 'User' at index 0 is not supported",
},
{
Name: "OperationReturnCountUnmatchedError",
Error: spec.NewOperationReturnCountUnmatchedError(2),
ExpectedString: "operation requires return count of 2",
},
{
Name: "InvalidQueryError",
Error: spec.NewInvalidQueryError([]string{"And"}),

View file

@ -82,31 +82,27 @@ func (p interfaceMethodParser) parseInsertOperation(tokens []string) (Operation,
func (p interfaceMethodParser) extractInsertReturns(returns []code.Type) (QueryMode, error) {
if len(returns) != 2 {
return "", UnsupportedReturnError
return "", NewOperationReturnCountUnmatchedError(2)
}
if returns[1] != code.SimpleType("error") {
return "", UnsupportedReturnError
return "", NewUnsupportedReturnError(returns[1], 1)
}
interfaceType, ok := returns[0].(code.InterfaceType)
if ok {
if len(interfaceType.Methods) != 0 {
return "", UnsupportedReturnError
switch t := returns[0].(type) {
case code.InterfaceType:
if len(t.Methods) == 0 {
return QueryModeOne, nil
}
return QueryModeOne, nil
}
arrayType, ok := returns[0].(code.ArrayType)
if ok {
interfaceType, ok := arrayType.ContainedType.(code.InterfaceType)
if !ok || len(interfaceType.Methods) != 0 {
return "", UnsupportedReturnError
case code.ArrayType:
interfaceType, ok := t.ContainedType.(code.InterfaceType)
if ok && len(interfaceType.Methods) == 0 {
return QueryModeMany, nil
}
return QueryModeMany, nil
}
return "", UnsupportedReturnError
return "", NewUnsupportedReturnError(returns[0], 0)
}
func (p interfaceMethodParser) parseFindOperation(tokens []string) (Operation, error) {
@ -204,35 +200,31 @@ func (p interfaceMethodParser) splitQueryAndSortTokens(tokens []string) ([]strin
func (p interfaceMethodParser) extractModelOrSliceReturns(returns []code.Type) (QueryMode, error) {
if len(returns) != 2 {
return "", UnsupportedReturnError
return "", NewOperationReturnCountUnmatchedError(2)
}
if returns[1] != code.SimpleType("error") {
return "", UnsupportedReturnError
return "", NewUnsupportedReturnError(returns[1], 1)
}
pointerType, ok := returns[0].(code.PointerType)
if ok {
simpleType := pointerType.ContainedType
switch t := returns[0].(type) {
case code.PointerType:
simpleType := t.ContainedType
if simpleType == code.SimpleType(p.StructModel.Name) {
return QueryModeOne, nil
}
return "", UnsupportedReturnError
}
arrayType, ok := returns[0].(code.ArrayType)
if ok {
pointerType, ok := arrayType.ContainedType.(code.PointerType)
case code.ArrayType:
pointerType, ok := t.ContainedType.(code.PointerType)
if ok {
simpleType := pointerType.ContainedType
if simpleType == code.SimpleType(p.StructModel.Name) {
return QueryModeMany, nil
}
return "", UnsupportedReturnError
}
}
return "", UnsupportedReturnError
return "", NewUnsupportedReturnError(returns[0], 0)
}
func splitByAnd(tokens []string) ([][]string, bool) {
@ -323,15 +315,15 @@ func (p interfaceMethodParser) parseCountOperation(tokens []string) (Operation,
func (p interfaceMethodParser) validateCountReturns(returns []code.Type) error {
if len(returns) != 2 {
return UnsupportedReturnError
return NewOperationReturnCountUnmatchedError(2)
}
if returns[0] != code.SimpleType("int") {
return UnsupportedReturnError
return NewUnsupportedReturnError(returns[0], 0)
}
if returns[1] != code.SimpleType("error") {
return UnsupportedReturnError
return NewUnsupportedReturnError(returns[1], 1)
}
return nil
@ -339,11 +331,11 @@ func (p interfaceMethodParser) validateCountReturns(returns []code.Type) error {
func (p interfaceMethodParser) extractIntOrBoolReturns(returns []code.Type) (QueryMode, error) {
if len(returns) != 2 {
return "", UnsupportedReturnError
return "", NewOperationReturnCountUnmatchedError(2)
}
if returns[1] != code.SimpleType("error") {
return "", UnsupportedReturnError
return "", NewUnsupportedReturnError(returns[1], 1)
}
simpleType, ok := returns[0].(code.SimpleType)
@ -356,7 +348,7 @@ func (p interfaceMethodParser) extractIntOrBoolReturns(returns []code.Type) (Que
}
}
return "", UnsupportedReturnError
return "", NewUnsupportedReturnError(returns[0], 0)
}
func (p interfaceMethodParser) validateContextParam() error {

View file

@ -1264,7 +1264,7 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewOperationReturnCountUnmatchedError(2),
},
{
Name: "unsupported return types from insert method",
@ -1275,7 +1275,7 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.PointerType{ContainedType: code.SimpleType("UserModel")}, 0),
},
{
Name: "unempty interface return from insert method",
@ -1290,7 +1290,7 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.InterfaceType{}, 0),
},
{
Name: "error return not provided",
@ -1301,7 +1301,7 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) {
code.InterfaceType{},
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.InterfaceType{}, 1),
},
{
Name: "no context parameter",
@ -1353,7 +1353,7 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) {
t.Run(testCase.Name, func(t *testing.T) {
_, err := spec.ParseInterfaceMethod(structs, structModel, testCase.Method)
if err != testCase.ExpectedError {
if err.Error() != testCase.ExpectedError.Error() {
t.Errorf("\nExpected = %+v\nReceived = %+v", testCase.ExpectedError, err)
}
})
@ -1372,7 +1372,7 @@ func TestParseInterfaceMethod_Find_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewOperationReturnCountUnmatchedError(2),
},
{
Name: "unsupported return types from find method",
@ -1383,7 +1383,7 @@ func TestParseInterfaceMethod_Find_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("UserModel"), 0),
},
{
Name: "error return not provided",
@ -1394,7 +1394,7 @@ func TestParseInterfaceMethod_Find_Invalid(t *testing.T) {
code.SimpleType("int"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("int"), 1),
},
{
Name: "find method without query",
@ -1675,7 +1675,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewOperationReturnCountUnmatchedError(2),
},
{
Name: "unsupported return types from update method",
@ -1686,7 +1686,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("float64"), 0),
},
{
Name: "error return not provided",
@ -1697,7 +1697,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) {
code.SimpleType("bool"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("bool"), 1),
},
{
Name: "update with no field provided",
@ -1911,7 +1911,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) {
t.Run(testCase.Name, func(t *testing.T) {
_, err := spec.ParseInterfaceMethod(structs, structModel, testCase.Method)
if err != testCase.ExpectedError {
if err.Error() != testCase.ExpectedError.Error() {
t.Errorf("\nExpected = %+v\nReceived = %+v", testCase.ExpectedError, err)
}
})
@ -1930,7 +1930,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewOperationReturnCountUnmatchedError(2),
},
{
Name: "unsupported return types from delete method",
@ -1941,7 +1941,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("float64"), 0),
},
{
Name: "error return not provided",
@ -1952,7 +1952,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) {
code.SimpleType("bool"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("bool"), 1),
},
{
Name: "delete method without query",
@ -2091,7 +2091,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) {
t.Run(testCase.Name, func(t *testing.T) {
_, err := spec.ParseInterfaceMethod(structs, structModel, testCase.Method)
if err != testCase.ExpectedError {
if err.Error() != testCase.ExpectedError.Error() {
t.Errorf("\nExpected = %+v\nReceived = %+v", testCase.ExpectedError, err)
}
})
@ -2110,7 +2110,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) {
code.SimpleType("bool"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewOperationReturnCountUnmatchedError(2),
},
{
Name: "invalid integer return",
@ -2121,7 +2121,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) {
code.SimpleType("error"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("int64"), 0),
},
{
Name: "error return not provided",
@ -2132,7 +2132,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) {
code.SimpleType("bool"),
},
},
ExpectedError: spec.UnsupportedReturnError,
ExpectedError: spec.NewUnsupportedReturnError(code.SimpleType("bool"), 1),
},
{
Name: "count method without query",
@ -2222,7 +2222,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) {
t.Run(testCase.Name, func(t *testing.T) {
_, err := spec.ParseInterfaceMethod(structs, structModel, testCase.Method)
if err != testCase.ExpectedError {
if err.Error() != testCase.ExpectedError.Error() {
t.Errorf("\nExpected = %+v\nReceived = %+v", testCase.ExpectedError, err)
}
})