Finalize v0.2.0
This commit is contained in:
parent
1368386584
commit
8e741fda64
9 changed files with 358 additions and 132 deletions
internal/spec
|
@ -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, "")}
|
||||
|
|
|
@ -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"}),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue