From 482dd095a62b499895b57859523c97b8e6c755ff Mon Sep 17 00:00:00 2001 From: sunboyy Date: Wed, 9 Nov 2022 11:21:11 +0700 Subject: [PATCH] Enforce new linting rules: errname, errorlint, lll, stylecheck (#32) --- .golangci.yml | 9 + CONTRIBUTING.md | 73 ++++- internal/code/extractor_test.go | 56 +++- internal/code/package.go | 2 +- internal/generator/generator_test.go | 195 ++++---------- internal/mongo/generator.go | 3 +- internal/mongo/generator_test.go | 374 +++++++++++++++++++++----- internal/spec/errors.go | 31 +-- internal/spec/field.go | 3 +- internal/spec/parser.go | 19 +- internal/spec/parser_test.go | 286 +++++++++++++++----- internal/spec/query.go | 8 +- internal/spec/update.go | 20 +- internal/testutils/multilines.go | 9 +- internal/testutils/multilines_test.go | 12 +- test/generator_test_expected.txt | 127 +++++++++ 16 files changed, 891 insertions(+), 336 deletions(-) create mode 100644 .golangci.yml create mode 100644 test/generator_test_expected.txt diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..f481709 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,9 @@ +linters: + enable: + - errname + - errorlint + - lll + - stylecheck +linters-settings: + lll: + tab-width: 4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 882d3cf..c2a005f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,72 @@ # Contributing -## Styleguides +## Development guidelines -- Use default `goimports` for code formatting. -- Use default `golint`, `golangci-lint` and `go vet` for linting. -- Do not use boolean flag in function arguments. +### Formatter + +We use `golangci-lint` to validate the code formatting. Make sure to have your code formatted before opening pull requests. + +### Line length limit + +Every code line should not exceed 80 characters when possible, but the hard limit is at 120 characters. Lines with documentation have an exception with the hard limit at 80 characters. A tab is treated as 4 spaces. It is recommended to set ruler guide at 80 and 120 characters on your editor. + +### Wrapping long struct initialization + +If the struct initialization is too long for the 80 character limit, wrap the initialization by assigning each field on its own line and end the initialization on its own line. + +**WRONG** + +```go +a := User{ + Firstname: "John", Lastname: "Doe", +} + +a := User{ + Firstname: "John", + Lastname: "Doe"} + +a := User{Firstname: "John", + Lastname: "Doe", +} +``` + +**RIGHT** + +```go +a := User{ + Firstname: "John", + Lastname: "Doe", +} +``` + +### Wrapping long function definitions + +If the function definition is too long for the 80 character limit, wrap the function definition by writing with as few lines as possible while avoiding trailing open parenthesis and traling commas after the last parameter and the last return type. + +**WRONG** + +```go +func doSomething( + a, + b, + c, +) (d, error) { + +func doSomething(a, b, c, +) (d, error) { + +func doSomething(a, b, c) ( + d, error) { +``` + +**RIGHT** + +```go +func doSomething(a, b, + c) (d, error) { + +func doSomething(a, b, c) (d, + error) { +``` + +If the function definition spans multiple lines, the function body should start with an empty line to help distinguishing two elements. diff --git a/internal/code/extractor_test.go b/internal/code/extractor_test.go index 18551e5..7bc8e85 100644 --- a/internal/code/extractor_test.go +++ b/internal/code/extractor_test.go @@ -129,27 +129,50 @@ type UserRepository interface { {Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, }, Returns: []code.Type{ - code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}}, + code.ArrayType{ + ContainedType: code.PointerType{ + ContainedType: code.SimpleType("UserModel"), + }, + }, code.TypeError, }, }, { Name: "FindByAgeBetween", Params: []code.Param{ - {Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, - {Name: "fromAge", Type: code.TypeInt}, - {Name: "toAge", Type: code.TypeInt}, + { + Name: "ctx", + Type: code.ExternalType{PackageAlias: "context", Name: "Context"}, + }, + { + Name: "fromAge", + Type: code.TypeInt, + }, + { + Name: "toAge", + Type: code.TypeInt, + }, }, Returns: []code.Type{ - code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}}, + code.ArrayType{ + ContainedType: code.PointerType{ + ContainedType: code.SimpleType("UserModel"), + }, + }, code.TypeError, }, }, { Name: "InsertOne", Params: []code.Param{ - {Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, - {Name: "user", Type: code.PointerType{ContainedType: code.SimpleType("UserModel")}}, + { + Name: "ctx", + Type: code.ExternalType{PackageAlias: "context", Name: "Context"}, + }, + { + Name: "user", + Type: code.PointerType{ContainedType: code.SimpleType("UserModel")}, + }, }, Returns: []code.Type{ code.InterfaceType{}, @@ -159,9 +182,18 @@ type UserRepository interface { { Name: "UpdateAgreementByID", Params: []code.Param{ - {Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, - {Name: "agreement", Type: code.MapType{KeyType: code.TypeString, ValueType: code.TypeBool}}, - {Name: "id", Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}}, + { + Name: "ctx", + Type: code.ExternalType{PackageAlias: "context", Name: "Context"}, + }, + { + Name: "agreement", + Type: code.MapType{KeyType: code.TypeString, ValueType: code.TypeBool}, + }, + { + Name: "id", + Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}, + }, }, Returns: []code.Type{ code.TypeBool, @@ -273,7 +305,9 @@ type UserRepository interface { {Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, }, Returns: []code.Type{ - code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}}, + code.ArrayType{ + ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}, + }, code.TypeError, }, }, diff --git a/internal/code/package.go b/internal/code/package.go index 3a1e3fa..8eda9b4 100644 --- a/internal/code/package.go +++ b/internal/code/package.go @@ -24,7 +24,7 @@ func ParsePackage(pkgs map[string]*ast.Package) (Package, error) { } // Package stores package name, struct and interface implementations as a result -// from ParsePackage +// from ParsePackage. type Package struct { Name string Structs map[string]Struct diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index e0b67e7..35506fd 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -1,12 +1,13 @@ package generator_test import ( - "strings" + "os" "testing" "github.com/sunboyy/repogen/internal/code" "github.com/sunboyy/repogen/internal/generator" "github.com/sunboyy/repogen/internal/spec" + "github.com/sunboyy/repogen/internal/testutils" ) var ( @@ -76,8 +77,16 @@ func TestGenerateMongoRepository(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorAnd, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorNot, ParamIndex: 1}, - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorLessThan, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorNot, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorLessThan, + ParamIndex: 2, + }, }, }, }, @@ -96,7 +105,11 @@ func TestGenerateMongoRepository(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorLessThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorLessThanEqual, + ParamIndex: 1, + }, }, }, Sorts: []spec.Sort{ @@ -118,7 +131,11 @@ func TestGenerateMongoRepository(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThan, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThan, + ParamIndex: 1, + }, }, }, Sorts: []spec.Sort{ @@ -140,7 +157,11 @@ func TestGenerateMongoRepository(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThanEqual, + ParamIndex: 1, + }, }, }, Sorts: []spec.Sort{ @@ -163,7 +184,11 @@ func TestGenerateMongoRepository(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorBetween, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorBetween, + ParamIndex: 1, + }, }, }, }, @@ -184,153 +209,33 @@ func TestGenerateMongoRepository(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorOr, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, }, } + expectedBytes, err := os.ReadFile("../../test/generator_test_expected.txt") + if err != nil { + t.Fatal(err) + } + expectedCode := string(expectedBytes) code, err := generator.GenerateRepository("user", userModel, "UserRepository", methods) if err != nil { + t.Fatal(err) + } + if err := testutils.ExpectMultiLineString(expectedCode, code); err != nil { t.Error(err) } - expectedCode := `// Code generated by repogen. DO NOT EDIT. -package user - -import ( - "context" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -func NewUserRepository(collection *mongo.Collection) UserRepository { - return &UserRepositoryMongo{ - collection: collection, - } -} - -type UserRepositoryMongo struct { - collection *mongo.Collection -} - -func (r *UserRepositoryMongo) FindByID(arg0 context.Context, arg1 primitive.ObjectID) (*UserModel, error) { - var entity UserModel - if err := r.collection.FindOne(arg0, bson.M{ - "_id": arg1, - }, options.FindOne().SetSort(bson.M{})).Decode(&entity); err != nil { - return nil, err - } - return &entity, nil -} - -func (r *UserRepositoryMongo) FindByGenderNotAndAgeLessThan(arg0 context.Context, arg1 Gender, arg2 int) (*UserModel, error) { - cursor, err := r.collection.Find(arg0, bson.M{ - "$and": []bson.M{ - {"gender": bson.M{"$ne": arg1}}, - {"age": bson.M{"$lt": arg2}}, - }, - }, options.Find().SetSort(bson.M{})) - if err != nil { - return nil, err - } - var entities []*UserModel - if err := cursor.All(arg0, &entities); err != nil { - return nil, err - } - return entities, nil -} - -func (r *UserRepositoryMongo) FindByAgeLessThanEqualOrderByAge(arg0 context.Context, arg1 int) ([]*UserModel, error) { - cursor, err := r.collection.Find(arg0, bson.M{ - "age": bson.M{"$lte": arg1}, - }, options.Find().SetSort(bson.M{ - "age": 1, - })) - if err != nil { - return nil, err - } - var entities []*UserModel - if err := cursor.All(arg0, &entities); err != nil { - return nil, err - } - return entities, nil -} - -func (r *UserRepositoryMongo) FindByAgeGreaterThanOrderByAgeAsc(arg0 context.Context, arg1 int) ([]*UserModel, error) { - cursor, err := r.collection.Find(arg0, bson.M{ - "age": bson.M{"$gt": arg1}, - }, options.Find().SetSort(bson.M{ - "age": 1, - })) - if err != nil { - return nil, err - } - var entities []*UserModel - if err := cursor.All(arg0, &entities); err != nil { - return nil, err - } - return entities, nil -} - -func (r *UserRepositoryMongo) FindByAgeGreaterThanEqualOrderByAgeDesc(arg0 context.Context, arg1 int) ([]*UserModel, error) { - cursor, err := r.collection.Find(arg0, bson.M{ - "age": bson.M{"$gte": arg1}, - }, options.Find().SetSort(bson.M{ - "age": -1, - })) - if err != nil { - return nil, err - } - var entities []*UserModel - if err := cursor.All(arg0, &entities); err != nil { - return nil, err - } - return entities, nil -} - -func (r *UserRepositoryMongo) FindByAgeBetween(arg0 context.Context, arg1 int, arg2 int) ([]*UserModel, error) { - cursor, err := r.collection.Find(arg0, bson.M{ - "age": bson.M{"$gte": arg1, "$lte": arg2}, - }, options.Find().SetSort(bson.M{})) - if err != nil { - return nil, err - } - var entities []*UserModel - if err := cursor.All(arg0, &entities); err != nil { - return nil, err - } - return entities, nil -} - -func (r *UserRepositoryMongo) FindByGenderOrAge(arg0 context.Context, arg1 Gender, arg2 int) ([]*UserModel, error) { - cursor, err := r.collection.Find(arg0, bson.M{ - "$or": []bson.M{ - {"gender": arg1}, - {"age": arg2}, - }, - }, options.Find().SetSort(bson.M{})) - if err != nil { - return nil, err - } - var entities []*UserModel - if err := cursor.All(arg0, &entities); err != nil { - return nil, err - } - return entities, nil -} -` - expectedCodeLines := strings.Split(expectedCode, "\n") - actualCodeLines := strings.Split(code, "\n") - - for i, line := range expectedCodeLines { - if line != actualCodeLines[i] { - t.Errorf("On line %d\nExpected = %v\nActual = %v", i, line, actualCodeLines[i]) - } - } } diff --git a/internal/mongo/generator.go b/internal/mongo/generator.go index 19d3b85..3265a74 100644 --- a/internal/mongo/generator.go +++ b/internal/mongo/generator.go @@ -19,7 +19,8 @@ func NewGenerator(structModel code.Struct, interfaceName string) RepositoryGener } } -// RepositoryGenerator provides repository constructor and method generation from provided specification +// RepositoryGenerator is a MongoDB repository generator that provides +// necessary information required to construct an implementation. type RepositoryGenerator struct { StructModel code.Struct InterfaceName string diff --git a/internal/mongo/generator_test.go b/internal/mongo/generator_test.go index bc9490f..cc0323c 100644 --- a/internal/mongo/generator_test.go +++ b/internal/mongo/generator_test.go @@ -1,6 +1,7 @@ package mongo_test import ( + "errors" "fmt" "reflect" "testing" @@ -318,7 +319,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{idField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{idField}, + ParamIndex: 1, + }, }, }, }, @@ -348,7 +353,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -418,8 +427,16 @@ func TestGenerateMethod_Find(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorAnd, Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 2}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 2, + }, }, }, }, @@ -458,8 +475,16 @@ func TestGenerateMethod_Find(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorOr, Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 2}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 2, + }, }, }, }, @@ -496,7 +521,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorNot, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorNot, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -530,7 +559,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorLessThan, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorLessThan, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -564,7 +597,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorLessThanEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorLessThanEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -598,7 +635,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorGreaterThan, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorGreaterThan, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -632,7 +673,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorGreaterThanEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorGreaterThanEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -667,7 +712,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorBetween, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorBetween, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -701,7 +750,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorIn, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorIn, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -735,7 +788,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorNotIn, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorNotIn, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -768,7 +825,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorTrue, FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorTrue, + FieldReference: spec.FieldReference{enabledField}, + ParamIndex: 1, + }, }, }, }, @@ -801,7 +862,11 @@ func TestGenerateMethod_Find(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorFalse, FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorFalse, + FieldReference: spec.FieldReference{enabledField}, + ParamIndex: 1, + }, }, }, }, @@ -897,7 +962,10 @@ func TestGenerateMethod_Find(t *testing.T) { Operation: spec.FindOperation{ Mode: spec.QueryModeMany, Sorts: []spec.Sort{ - {FieldReference: spec.FieldReference{nameField, firstNameField}, Ordering: spec.OrderingAscending}, + { + FieldReference: spec.FieldReference{nameField, firstNameField}, + Ordering: spec.OrderingAscending, + }, }, }, }, @@ -1033,7 +1101,11 @@ func TestGenerateMethod_Update(t *testing.T) { Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1063,12 +1135,20 @@ func TestGenerateMethod_Update(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1100,12 +1180,20 @@ func TestGenerateMethod_Update(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1137,12 +1225,20 @@ func TestGenerateMethod_Update(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: spec.UpdateOperatorPush}, + spec.UpdateField{ + FieldReference: spec.FieldReference{consentHistoryField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorPush, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1174,12 +1270,20 @@ func TestGenerateMethod_Update(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorInc}, + spec.UpdateField{ + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorInc, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1212,13 +1316,25 @@ func TestGenerateMethod_Update(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, - spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 2, Operator: spec.UpdateOperatorPush}, + spec.UpdateField{ + FieldReference: spec.FieldReference{enabledField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, + spec.UpdateField{ + FieldReference: spec.FieldReference{consentHistoryField}, + ParamIndex: 2, + Operator: spec.UpdateOperatorPush, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 3}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 3, + }, }, }, }, @@ -1253,12 +1369,20 @@ func TestGenerateMethod_Update(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{nameField, firstNameField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{nameField, firstNameField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1354,7 +1478,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{idField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{idField}, + ParamIndex: 1, + }, }, }, }, @@ -1383,7 +1511,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -1414,8 +1546,16 @@ func TestGenerateMethod_Delete(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorAnd, Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 2}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 2, + }, }, }, }, @@ -1449,8 +1589,16 @@ func TestGenerateMethod_Delete(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorOr, Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, - {Comparator: spec.ComparatorEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 2}, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, + { + Comparator: spec.ComparatorEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 2, + }, }, }, }, @@ -1482,7 +1630,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorNot, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorNot, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -1511,7 +1663,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorLessThan, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorLessThan, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -1540,7 +1696,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorLessThanEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorLessThanEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -1569,7 +1729,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorGreaterThan, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorGreaterThan, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -1598,7 +1762,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorGreaterThanEqual, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorGreaterThanEqual, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -1628,7 +1796,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorBetween, FieldReference: spec.FieldReference{ageField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorBetween, + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + }, }, }, }, @@ -1657,7 +1829,11 @@ func TestGenerateMethod_Delete(t *testing.T) { Mode: spec.QueryModeMany, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {Comparator: spec.ComparatorIn, FieldReference: spec.FieldReference{genderField}, ParamIndex: 1}, + { + Comparator: spec.ComparatorIn, + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + }, }, }, }, @@ -1751,7 +1927,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }, }, }, @@ -1781,8 +1961,16 @@ func TestGenerateMethod_Count(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorAnd, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1815,8 +2003,16 @@ func TestGenerateMethod_Count(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorOr, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1847,7 +2043,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorNot, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorNot, + ParamIndex: 1, + }, }, }, }, @@ -1875,7 +2075,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorLessThan, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorLessThan, + ParamIndex: 1, + }, }, }, }, @@ -1903,7 +2107,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorLessThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorLessThanEqual, + ParamIndex: 1, + }, }, }, }, @@ -1931,7 +2139,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThan, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThan, + ParamIndex: 1, + }, }, }, }, @@ -1959,7 +2171,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThanEqual, + ParamIndex: 1, + }, }, }, }, @@ -1988,7 +2204,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorBetween, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorBetween, + ParamIndex: 1, + }, }, }, }, @@ -2016,7 +2236,11 @@ func TestGenerateMethod_Count(t *testing.T) { Operation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorIn, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorIn, + ParamIndex: 1, + }, }, }, }, @@ -2140,7 +2364,11 @@ func TestGenerateMethod_Invalid(t *testing.T) { Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{accessTokenField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{accessTokenField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }, }, }, @@ -2182,12 +2410,20 @@ func TestGenerateMethod_Invalid(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{accessTokenField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{accessTokenField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -2212,7 +2448,11 @@ func TestGenerateMethod_Invalid(t *testing.T) { Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -2234,12 +2474,20 @@ func TestGenerateMethod_Invalid(t *testing.T) { }, Operation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: "APPEND"}, + spec.UpdateField{ + FieldReference: spec.FieldReference{consentHistoryField}, + ParamIndex: 1, + Operator: "APPEND", + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -2254,7 +2502,7 @@ func TestGenerateMethod_Invalid(t *testing.T) { _, err := generator.GenerateMethod(testCase.Method) - if err != testCase.ExpectedError { + if !errors.Is(err, testCase.ExpectedError) { t.Errorf("\nExpected = %+v\nReceived = %+v", testCase.ExpectedError, err) } }) diff --git a/internal/spec/errors.go b/internal/spec/errors.go index a2c16b4..11189b9 100644 --- a/internal/spec/errors.go +++ b/internal/spec/errors.go @@ -1,35 +1,19 @@ package spec import ( + "errors" "fmt" "strings" "github.com/sunboyy/repogen/internal/code" ) -// ParsingError is an error from parsing interface methods -type ParsingError string - -func (err ParsingError) Error() string { - switch err { - case QueryRequiredError: - return "query is required" - case InvalidParamError: - return "parameters do not match the query" - case InvalidUpdateFieldsError: - return "update fields are invalid" - case ContextParamRequiredError: - return "context parameter is required" - } - return string(err) -} - // parsing error constants -const ( - QueryRequiredError ParsingError = "ERROR_QUERY_REQUIRED" - InvalidParamError ParsingError = "ERROR_INVALID_PARAM" - InvalidUpdateFieldsError ParsingError = "ERROR_INVALID_UPDATE_FIELDS" - ContextParamRequiredError ParsingError = "ERROR_CONTEXT_PARAM_REQUIRED" +var ( + ErrQueryRequired = errors.New("spec: query is required") + ErrInvalidParam = errors.New("spec: parameters do not match the query") + ErrInvalidUpdateFields = errors.New("spec: update fields are invalid") + ErrContextParamRequired = errors.New("spec: context parameter is required") ) // NewUnsupportedReturnError creates unsupportedReturnError @@ -49,7 +33,8 @@ 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 +// NewOperationReturnCountUnmatchedError creates +// operationReturnCountUnmatchedError. func NewOperationReturnCountUnmatchedError(returnCount int) error { return operationReturnCountUnmatchedError{ ReturnCount: returnCount, diff --git a/internal/spec/field.go b/internal/spec/field.go index 4d52726..0d4d4a7 100644 --- a/internal/spec/field.go +++ b/internal/spec/field.go @@ -14,7 +14,8 @@ func (r FieldReference) ReferencedField() code.StructField { return r[len(r)-1] } -// ReferencingCode returns a string containing name of the referenced fields concatenating with period (.). +// ReferencingCode returns a string containing name of the referenced fields +// concatenating with period (.). func (r FieldReference) ReferencingCode() string { var fieldNames []string for _, field := range r { diff --git a/internal/spec/parser.go b/internal/spec/parser.go index d64546c..1bfa9eb 100644 --- a/internal/spec/parser.go +++ b/internal/spec/parser.go @@ -5,8 +5,11 @@ import ( "github.com/sunboyy/repogen/internal/code" ) -// ParseInterfaceMethod returns repository method spec from declared interface method -func ParseInterfaceMethod(structs map[string]code.Struct, structModel code.Struct, method code.Method) (MethodSpec, error) { +// ParseInterfaceMethod returns repository method spec from declared interface +// method. +func ParseInterfaceMethod(structs map[string]code.Struct, structModel code.Struct, + method code.Method) (MethodSpec, error) { + parser := interfaceMethodParser{ fieldResolver: fieldResolver{ Structs: structs, @@ -67,12 +70,12 @@ func (p interfaceMethodParser) parseInsertOperation(tokens []string) (Operation, pointerType := code.PointerType{ContainedType: p.StructModel.ReferencedType()} if mode == QueryModeOne && p.Method.Params[1].Type != pointerType { - return nil, InvalidParamError + return nil, ErrInvalidParam } arrayType := code.ArrayType{ContainedType: pointerType} if mode == QueryModeMany && p.Method.Params[1].Type != arrayType { - return nil, InvalidParamError + return nil, ErrInvalidParam } return InsertOperation{ @@ -354,14 +357,14 @@ func (p interfaceMethodParser) extractIntOrBoolReturns(returns []code.Type) (Que func (p interfaceMethodParser) validateContextParam() error { contextType := code.ExternalType{PackageAlias: "context", Name: "Context"} if len(p.Method.Params) == 0 || p.Method.Params[0].Type != contextType { - return ContextParamRequiredError + return ErrContextParamRequired } return nil } func (p interfaceMethodParser) validateQueryFromParams(params []code.Param, querySpec QuerySpec) error { if querySpec.NumberOfArguments() != len(params) { - return InvalidParamError + return ErrInvalidParam } var currentParamIndex int @@ -373,7 +376,9 @@ func (p interfaceMethodParser) validateQueryFromParams(params []code.Param, quer } for i := 0; i < predicate.Comparator.NumberOfArguments(); i++ { - requiredType := predicate.Comparator.ArgumentTypeFromFieldType(predicate.FieldReference.ReferencedField().Type) + requiredType := predicate.Comparator.ArgumentTypeFromFieldType( + predicate.FieldReference.ReferencedField().Type, + ) if params[currentParamIndex].Type != requiredType { return NewArgumentTypeNotMatchedError(predicate.FieldReference.ReferencingCode(), requiredType, diff --git a/internal/spec/parser_test.go b/internal/spec/parser_test.go index 866dd18..e0e8756 100644 --- a/internal/spec/parser_test.go +++ b/internal/spec/parser_test.go @@ -1,6 +1,7 @@ package spec_test import ( + "errors" "reflect" "testing" @@ -126,8 +127,19 @@ func TestParseInterfaceMethod_Insert(t *testing.T) { Method: code.Method{ Name: "InsertMany", Params: []code.Param{ - {Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, - {Type: code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}}}, + { + Type: code.ExternalType{ + PackageAlias: "context", + Name: "Context", + }, + }, + { + Type: code.ArrayType{ + ContainedType: code.PointerType{ + ContainedType: code.SimpleType("UserModel"), + }, + }, + }, }, Returns: []code.Type{ code.ArrayType{ContainedType: code.InterfaceType{}}, @@ -198,7 +210,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeOne, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{phoneNumberField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{phoneNumberField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }}, }, }, @@ -238,7 +254,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{nameField, firstNameField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{nameField, firstNameField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }}, }, }, @@ -258,7 +278,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{referrerField, idField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{referrerField, idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }}, }, }, @@ -297,8 +321,16 @@ func TestParseInterfaceMethod_Find(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorAnd, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{cityField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{cityField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -322,8 +354,16 @@ func TestParseInterfaceMethod_Find(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorOr, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{cityField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{cityField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -384,7 +424,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorLessThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorLessThanEqual, + ParamIndex: 1, + }, }}, }, }, @@ -404,7 +448,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThan, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThan, + ParamIndex: 1, + }, }}, }, }, @@ -424,7 +472,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThanEqual, + ParamIndex: 1, + }, }}, }, }, @@ -523,7 +575,11 @@ func TestParseInterfaceMethod_Find(t *testing.T) { ExpectedOperation: spec.FindOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{enabledField}, Comparator: spec.ComparatorFalse, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{enabledField}, + Comparator: spec.ComparatorFalse, + ParamIndex: 1, + }, }}, }, }, @@ -705,11 +761,19 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }}, }, }, @@ -729,11 +793,19 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }}, }, }, @@ -753,11 +825,19 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{nameField, firstNameField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{nameField, firstNameField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }}, }, }, @@ -778,8 +858,16 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, - spec.UpdateField{FieldReference: spec.FieldReference{cityField}, ParamIndex: 2, Operator: spec.UpdateOperatorSet}, + spec.UpdateField{ + FieldReference: spec.FieldReference{genderField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, + spec.UpdateField{ + FieldReference: spec.FieldReference{cityField}, + ParamIndex: 2, + Operator: spec.UpdateOperatorSet, + }, }, Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ @@ -803,11 +891,19 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: spec.UpdateOperatorPush}, + spec.UpdateField{ + FieldReference: spec.FieldReference{consentHistoryField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorPush, + }, }, Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }}, }, }, @@ -827,11 +923,19 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorInc}, + spec.UpdateField{ + FieldReference: spec.FieldReference{ageField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorInc, + }, }, Mode: spec.QueryModeOne, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{idField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{idField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }}, }, }, @@ -852,8 +956,16 @@ func TestParseInterfaceMethod_Update(t *testing.T) { }, ExpectedOperation: spec.UpdateOperation{ Update: spec.UpdateFields{ - spec.UpdateField{FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet}, - spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 2, Operator: spec.UpdateOperatorPush}, + spec.UpdateField{ + FieldReference: spec.FieldReference{enabledField}, + ParamIndex: 1, + Operator: spec.UpdateOperatorSet, + }, + spec.UpdateField{ + FieldReference: spec.FieldReference{consentHistoryField}, + ParamIndex: 2, + Operator: spec.UpdateOperatorPush, + }, }, Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ @@ -921,7 +1033,11 @@ func TestParseInterfaceMethod_Delete(t *testing.T) { ExpectedOperation: spec.DeleteOperation{ Mode: spec.QueryModeOne, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{phoneNumberField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{phoneNumberField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }}, }, }, @@ -980,8 +1096,16 @@ func TestParseInterfaceMethod_Delete(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorAnd, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{cityField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{cityField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1005,8 +1129,16 @@ func TestParseInterfaceMethod_Delete(t *testing.T) { Query: spec.QuerySpec{ Operator: spec.OperatorOr, Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{cityField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 2}, + { + FieldReference: spec.FieldReference{cityField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 2, + }, }, }, }, @@ -1067,7 +1199,11 @@ func TestParseInterfaceMethod_Delete(t *testing.T) { ExpectedOperation: spec.DeleteOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorLessThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorLessThanEqual, + ParamIndex: 1, + }, }}, }, }, @@ -1087,7 +1223,11 @@ func TestParseInterfaceMethod_Delete(t *testing.T) { ExpectedOperation: spec.DeleteOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThan, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThan, + ParamIndex: 1, + }, }}, }, }, @@ -1107,7 +1247,11 @@ func TestParseInterfaceMethod_Delete(t *testing.T) { ExpectedOperation: spec.DeleteOperation{ Mode: spec.QueryModeMany, Query: spec.QuerySpec{Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{ageField}, Comparator: spec.ComparatorGreaterThanEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{ageField}, + Comparator: spec.ComparatorGreaterThanEqual, + ParamIndex: 1, + }, }}, }, }, @@ -1208,7 +1352,11 @@ func TestParseInterfaceMethod_Count(t *testing.T) { ExpectedOperation: spec.CountOperation{ Query: spec.QuerySpec{ Predicates: []spec.Predicate{ - {FieldReference: spec.FieldReference{genderField}, Comparator: spec.ComparatorEqual, ParamIndex: 1}, + { + FieldReference: spec.FieldReference{genderField}, + Comparator: spec.ComparatorEqual, + ParamIndex: 1, + }, }, }, }, @@ -1247,7 +1395,7 @@ func TestParseInterfaceMethod_Invalid(t *testing.T) { }) expectedError := spec.NewUnknownOperationError("Search") - if err != expectedError { + if !errors.Is(err, expectedError) { t.Errorf("\nExpected = %+v\nReceived = %+v", expectedError, err) } } @@ -1275,7 +1423,10 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.NewUnsupportedReturnError(code.PointerType{ContainedType: code.SimpleType("UserModel")}, 0), + ExpectedError: spec.NewUnsupportedReturnError( + code.PointerType{ContainedType: code.SimpleType("UserModel")}, + 0, + ), }, { Name: "unempty interface return from insert method", @@ -1315,22 +1466,32 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.ContextParamRequiredError, + ExpectedError: spec.ErrContextParamRequired, }, { Name: "mismatched model parameter for one mode", Method: code.Method{ Name: "Insert", Params: []code.Param{ - {Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}}, - {Name: "userModel", Type: code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}}}, + { + Name: "ctx", + Type: code.ExternalType{PackageAlias: "context", Name: "Context"}, + }, + { + Name: "userModel", + Type: code.ArrayType{ + ContainedType: code.PointerType{ + ContainedType: code.SimpleType("UserModel"), + }, + }, + }, }, Returns: []code.Type{ code.InterfaceType{}, code.TypeError, }, }, - ExpectedError: spec.InvalidParamError, + ExpectedError: spec.ErrInvalidParam, }, { Name: "mismatched model parameter for many mode", @@ -1345,7 +1506,7 @@ func TestParseInterfaceMethod_Insert_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidParamError, + ExpectedError: spec.ErrInvalidParam, }, } @@ -1405,7 +1566,7 @@ func TestParseInterfaceMethod_Find_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.QueryRequiredError, + ExpectedError: spec.ErrQueryRequired, }, { Name: "misplaced operator token (leftmost)", @@ -1463,7 +1624,7 @@ func TestParseInterfaceMethod_Find_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.ContextParamRequiredError, + ExpectedError: spec.ErrContextParamRequired, }, { Name: "mismatched number of parameters", @@ -1479,7 +1640,7 @@ func TestParseInterfaceMethod_Find_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidParamError, + ExpectedError: spec.ErrInvalidParam, }, { Name: "struct field not found", @@ -1711,7 +1872,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidUpdateFieldsError, + ExpectedError: spec.ErrInvalidUpdateFields, }, { Name: "misplaced And token in update fields", @@ -1725,7 +1886,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidUpdateFieldsError, + ExpectedError: spec.ErrInvalidUpdateFields, }, { Name: "push operator in non-array field", @@ -1782,7 +1943,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.QueryRequiredError, + ExpectedError: spec.ErrQueryRequired, }, { Name: "ambiguous query", @@ -1813,8 +1974,13 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.NewArgumentTypeNotMatchedError(consentHistoryField.Name, code.SimpleType("ConsentHistoryItem"), - code.ArrayType{ContainedType: code.SimpleType("ConsentHistoryItem")}), + ExpectedError: spec.NewArgumentTypeNotMatchedError( + consentHistoryField.Name, + code.SimpleType("ConsentHistoryItem"), + code.ArrayType{ + ContainedType: code.SimpleType("ConsentHistoryItem"), + }, + ), }, { Name: "insufficient function parameters", @@ -1829,7 +1995,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidUpdateFieldsError, + ExpectedError: spec.ErrInvalidUpdateFields, }, { Name: "update model with invalid parameter", @@ -1844,7 +2010,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidUpdateFieldsError, + ExpectedError: spec.ErrInvalidUpdateFields, }, { Name: "no context parameter", @@ -1859,7 +2025,7 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.ContextParamRequiredError, + ExpectedError: spec.ErrContextParamRequired, }, { Name: "struct field not found in update fields", @@ -1967,7 +2133,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.QueryRequiredError, + ExpectedError: spec.ErrQueryRequired, }, { Name: "misplaced operator token (leftmost)", @@ -2025,7 +2191,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.ContextParamRequiredError, + ExpectedError: spec.ErrContextParamRequired, }, { Name: "mismatched number of parameters", @@ -2041,7 +2207,7 @@ func TestParseInterfaceMethod_Delete_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidParamError, + ExpectedError: spec.ErrInvalidParam, }, { Name: "struct field not found", @@ -2147,7 +2313,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.QueryRequiredError, + ExpectedError: spec.ErrQueryRequired, }, { Name: "invalid query", @@ -2172,7 +2338,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.ContextParamRequiredError, + ExpectedError: spec.ErrContextParamRequired, }, { Name: "mismatched number of parameter", @@ -2188,7 +2354,7 @@ func TestParseInterfaceMethod_Count_Invalid(t *testing.T) { code.TypeError, }, }, - ExpectedError: spec.InvalidParamError, + ExpectedError: spec.ErrInvalidParam, }, { Name: "mismatched method parameter type", diff --git a/internal/spec/query.go b/internal/spec/query.go index 83ad6ed..d187bcc 100644 --- a/internal/spec/query.go +++ b/internal/spec/query.go @@ -46,7 +46,8 @@ const ( ComparatorFalse Comparator = "EQUAL_FALSE" ) -// ArgumentTypeFromFieldType returns a type of required argument from the given struct field type +// ArgumentTypeFromFieldType returns a type of required argument from the given +// struct field type. func (c Comparator) ArgumentTypeFromFieldType(t code.Type) code.Type { switch c { case ComparatorIn, ComparatorNotIn: @@ -56,7 +57,8 @@ func (c Comparator) ArgumentTypeFromFieldType(t code.Type) code.Type { } } -// NumberOfArguments returns the number of arguments required to perform the comparison +// NumberOfArguments returns the number of arguments required to perform the +// comparison. func (c Comparator) NumberOfArguments() int { switch c { case ComparatorBetween: @@ -82,7 +84,7 @@ type queryParser struct { func (p queryParser) parseQuery(rawTokens []string, paramIndex int) (QuerySpec, error) { if len(rawTokens) == 0 { - return QuerySpec{}, QueryRequiredError + return QuerySpec{}, ErrQueryRequired } tokens := rawTokens diff --git a/internal/spec/update.go b/internal/spec/update.go index 245807a..4c7cfea 100644 --- a/internal/spec/update.go +++ b/internal/spec/update.go @@ -47,14 +47,16 @@ func (u UpdateFields) NumberOfArguments() int { return len(u) } -// UpdateField stores mapping between field name in the model and the parameter index +// UpdateField stores mapping between field name in the model and the parameter +// index. type UpdateField struct { FieldReference FieldReference ParamIndex int Operator UpdateOperator } -// UpdateOperator is a custom type that declares update operator to be used in an update operation +// UpdateOperator is a custom type that declares update operator to be used in +// an update operation type UpdateOperator string // UpdateOperator constants @@ -117,14 +119,14 @@ func (p interfaceMethodParser) parseUpdate(tokens []string) (Update, error) { if len(tokens) == 0 { requiredType := code.PointerType{ContainedType: p.StructModel.ReferencedType()} if len(p.Method.Params) <= 1 || p.Method.Params[1].Type != requiredType { - return nil, InvalidUpdateFieldsError + return nil, ErrInvalidUpdateFields } return UpdateModel{}, nil } updateFieldTokens, ok := splitByAnd(tokens) if !ok { - return nil, InvalidUpdateFieldsError + return nil, ErrInvalidUpdateFields } var updateFields UpdateFields @@ -142,7 +144,7 @@ func (p interfaceMethodParser) parseUpdate(tokens []string) (Update, error) { for _, field := range updateFields { if len(p.Method.Params) < field.ParamIndex+field.Operator.NumberOfArguments() { - return nil, InvalidUpdateFieldsError + return nil, ErrInvalidUpdateFields } requiredType := field.Operator.ArgumentType(field.FieldReference.ReferencedField().Type) @@ -158,7 +160,9 @@ func (p interfaceMethodParser) parseUpdate(tokens []string) (Update, error) { return updateFields, nil } -func (p interfaceMethodParser) parseUpdateField(t []string, paramIndex int) (UpdateField, error) { +func (p interfaceMethodParser) parseUpdateField(t []string, + paramIndex int) (UpdateField, error) { + if len(t) > 1 && t[len(t)-1] == "Push" { return p.createUpdateField(t[:len(t)-1], UpdateOperatorPush, paramIndex) } @@ -168,7 +172,9 @@ func (p interfaceMethodParser) parseUpdateField(t []string, paramIndex int) (Upd return p.createUpdateField(t, UpdateOperatorSet, paramIndex) } -func (p interfaceMethodParser) createUpdateField(t []string, operator UpdateOperator, paramIndex int) (UpdateField, error) { +func (p interfaceMethodParser) createUpdateField(t []string, + operator UpdateOperator, paramIndex int) (UpdateField, error) { + fieldReference, ok := p.fieldResolver.ResolveStructField(p.StructModel, t) if !ok { return UpdateField{}, NewStructFieldNotFoundError(t) diff --git a/internal/testutils/multilines.go b/internal/testutils/multilines.go index d435a2b..35c5c7b 100644 --- a/internal/testutils/multilines.go +++ b/internal/testutils/multilines.go @@ -5,7 +5,8 @@ import ( "strings" ) -// ExpectMultiLineString compares two multi-line strings and report the difference +// ExpectMultiLineString compares two multi-line strings and report the +// difference. func ExpectMultiLineString(expected, actual string) error { expectedLines := strings.Split(expected, "\n") actualLines := strings.Split(actual, "\n") @@ -17,14 +18,14 @@ func ExpectMultiLineString(expected, actual string) error { for i := 0; i < numberOfComparableLines; i++ { if expectedLines[i] != actualLines[i] { - return fmt.Errorf("On line %d\nExpected: %v\nReceived: %v", i+1, expectedLines[i], actualLines[i]) + return fmt.Errorf("at line %d\nexpected: %v\nreceived: %v", i+1, expectedLines[i], actualLines[i]) } } if len(expectedLines) < len(actualLines) { - return fmt.Errorf("Unexpected lines:\n%s", strings.Join(actualLines[len(expectedLines):], "\n")) + return fmt.Errorf("unexpected lines:\n%s", strings.Join(actualLines[len(expectedLines):], "\n")) } else if len(expectedLines) > len(actualLines) { - return fmt.Errorf("Missing lines:\n%s", strings.Join(expectedLines[len(actualLines):], "\n")) + return fmt.Errorf("missing lines:\n%s", strings.Join(expectedLines[len(actualLines):], "\n")) } return nil diff --git a/internal/testutils/multilines_test.go b/internal/testutils/multilines_test.go index 5a6a26c..e33ef55 100644 --- a/internal/testutils/multilines_test.go +++ b/internal/testutils/multilines_test.go @@ -28,9 +28,9 @@ How are you?` err := testutils.ExpectMultiLineString(expectedText, actualText) - expectedError := "On line 2\nExpected: this is an expected text\nReceived: this is a real text" + expectedError := "at line 2\nexpected: this is an expected text\nreceived: this is a real text" if err == nil || err.Error() != expectedError { - t.Errorf("Expected = %s\nReceived = %s", expectedError, err.Error()) + t.Errorf("expected = %s\nreceived = %s", expectedError, err.Error()) } }) @@ -46,9 +46,9 @@ how are you?` err := testutils.ExpectMultiLineString(expectedText, actualText) - expectedError := "Missing lines:\nI'm fine...\nThank you..." + expectedError := "missing lines:\nI'm fine...\nThank you..." if err == nil || err.Error() != expectedError { - t.Errorf("Expected = %s\nReceived = %s", expectedError, err.Error()) + t.Errorf("expected = %s\nreceived = %s", expectedError, err.Error()) } }) @@ -64,9 +64,9 @@ Thank you...` err := testutils.ExpectMultiLineString(expectedText, actualText) - expectedError := "Unexpected lines:\nI'm fine...\nThank you..." + expectedError := "unexpected lines:\nI'm fine...\nThank you..." if err == nil || err.Error() != expectedError { - t.Errorf("Expected = %s\nReceived = %s", expectedError, err.Error()) + t.Errorf("expected = %s\nreceived = %s", expectedError, err.Error()) } }) } diff --git a/test/generator_test_expected.txt b/test/generator_test_expected.txt new file mode 100644 index 0000000..672f3e1 --- /dev/null +++ b/test/generator_test_expected.txt @@ -0,0 +1,127 @@ +// Code generated by repogen. DO NOT EDIT. +package user + +import ( + "context" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func NewUserRepository(collection *mongo.Collection) UserRepository { + return &UserRepositoryMongo{ + collection: collection, + } +} + +type UserRepositoryMongo struct { + collection *mongo.Collection +} + +func (r *UserRepositoryMongo) FindByID(arg0 context.Context, arg1 primitive.ObjectID) (*UserModel, error) { + var entity UserModel + if err := r.collection.FindOne(arg0, bson.M{ + "_id": arg1, + }, options.FindOne().SetSort(bson.M{})).Decode(&entity); err != nil { + return nil, err + } + return &entity, nil +} + +func (r *UserRepositoryMongo) FindByGenderNotAndAgeLessThan(arg0 context.Context, arg1 Gender, arg2 int) (*UserModel, error) { + cursor, err := r.collection.Find(arg0, bson.M{ + "$and": []bson.M{ + {"gender": bson.M{"$ne": arg1}}, + {"age": bson.M{"$lt": arg2}}, + }, + }, options.Find().SetSort(bson.M{})) + if err != nil { + return nil, err + } + var entities []*UserModel + if err := cursor.All(arg0, &entities); err != nil { + return nil, err + } + return entities, nil +} + +func (r *UserRepositoryMongo) FindByAgeLessThanEqualOrderByAge(arg0 context.Context, arg1 int) ([]*UserModel, error) { + cursor, err := r.collection.Find(arg0, bson.M{ + "age": bson.M{"$lte": arg1}, + }, options.Find().SetSort(bson.M{ + "age": 1, + })) + if err != nil { + return nil, err + } + var entities []*UserModel + if err := cursor.All(arg0, &entities); err != nil { + return nil, err + } + return entities, nil +} + +func (r *UserRepositoryMongo) FindByAgeGreaterThanOrderByAgeAsc(arg0 context.Context, arg1 int) ([]*UserModel, error) { + cursor, err := r.collection.Find(arg0, bson.M{ + "age": bson.M{"$gt": arg1}, + }, options.Find().SetSort(bson.M{ + "age": 1, + })) + if err != nil { + return nil, err + } + var entities []*UserModel + if err := cursor.All(arg0, &entities); err != nil { + return nil, err + } + return entities, nil +} + +func (r *UserRepositoryMongo) FindByAgeGreaterThanEqualOrderByAgeDesc(arg0 context.Context, arg1 int) ([]*UserModel, error) { + cursor, err := r.collection.Find(arg0, bson.M{ + "age": bson.M{"$gte": arg1}, + }, options.Find().SetSort(bson.M{ + "age": -1, + })) + if err != nil { + return nil, err + } + var entities []*UserModel + if err := cursor.All(arg0, &entities); err != nil { + return nil, err + } + return entities, nil +} + +func (r *UserRepositoryMongo) FindByAgeBetween(arg0 context.Context, arg1 int, arg2 int) ([]*UserModel, error) { + cursor, err := r.collection.Find(arg0, bson.M{ + "age": bson.M{"$gte": arg1, "$lte": arg2}, + }, options.Find().SetSort(bson.M{})) + if err != nil { + return nil, err + } + var entities []*UserModel + if err := cursor.All(arg0, &entities); err != nil { + return nil, err + } + return entities, nil +} + +func (r *UserRepositoryMongo) FindByGenderOrAge(arg0 context.Context, arg1 Gender, arg2 int) ([]*UserModel, error) { + cursor, err := r.collection.Find(arg0, bson.M{ + "$or": []bson.M{ + {"gender": arg1}, + {"age": arg2}, + }, + }, options.Find().SetSort(bson.M{})) + if err != nil { + return nil, err + } + var entities []*UserModel + if err := cursor.All(arg0, &entities); err != nil { + return nil, err + } + return entities, nil +}