From 50987d222b56697a33ecf23d0f19cb4190dca6bc Mon Sep 17 00:00:00 2001 From: UnaffiliatedCode Date: Tue, 3 Jun 2025 12:23:27 -0400 Subject: [PATCH 1/3] fix: migrated template to new file for referencing in unit tests for verification --- internal/template/method_original_test.go | 133 ++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 internal/template/method_original_test.go diff --git a/internal/template/method_original_test.go b/internal/template/method_original_test.go new file mode 100644 index 00000000..92c93d60 --- /dev/null +++ b/internal/template/method_original_test.go @@ -0,0 +1,133 @@ +package template_test + +// CRUDMethodTest CRUD method test +const CRUDMethodTest = ` +func init() { + InitializeDB() + err := _gen_test_db.AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil{ + fmt.Printf("Error: AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) fail: %s", err) + } +} + +func Test_{{.QueryStructName}}Query(t *testing.T) { + {{.QueryStructName}} := new{{.ModelStructName}}(_gen_test_db) + {{.QueryStructName}} = *{{.QueryStructName}}.As({{.QueryStructName}}.TableName()) + _do := {{.QueryStructName}}.WithContext(context.Background()).Debug() + + primaryKey := field.NewString({{.QueryStructName}}.TableName(), clause.PrimaryKey) + _, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete() + if err != nil { + t.Error("clean table <{{.TableName}}> fail:", err) + return + } + + _, ok := {{.QueryStructName}}.GetFieldByName("") + if ok { + t.Error("GetFieldByName(\"\") from {{.QueryStructName}} success") + } + + err = _do.Create(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + } + + err = _do.Save(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + } + + err = _do.CreateInBatches([]*{{.StructInfo.Package}}.{{.ModelStructName}}{ {}, {} }, 10) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + } + + _, err = _do.Select({{.QueryStructName}}.ALL).Take() + if err != nil { + t.Error("Take() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.First() + if err != nil { + t.Error("First() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Last() + if err != nil { + t.Error("First() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatch() on table <{{.TableName}}> fail:", err) + } + + err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*{{.StructInfo.Package}}.{{.ModelStructName}}{}, 10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatches() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Select({{.QueryStructName}}.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() + if err != nil { + t.Error("Find() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Distinct(primaryKey).Take() + if err != nil { + t.Error("select Distinct() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Select({{.QueryStructName}}.ALL).Omit(primaryKey).Take() + if err != nil { + t.Error("Omit() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Group(primaryKey).Find() + if err != nil { + t.Error("Group() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() + if err != nil { + t.Error("Scopes() on table <{{.TableName}}> fail:", err) + } + + _, _, err = _do.FindByPage(0, 1) + if err != nil { + t.Error("FindByPage() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.ScanByPage(&{{.StructInfo.Package}}.{{.ModelStructName}}{}, 0, 1) + if err != nil { + t.Error("ScanByPage() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() + if err != nil { + t.Error("FirstOrInit() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() + if err != nil { + t.Error("FirstOrCreate() on table <{{.TableName}}> fail:", err) + } + + var _a _another + var _aPK = field.NewString(_a.TableName(), "id") + + err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("Join() on table <{{.TableName}}> fail:", err) + } + + err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("LeftJoin() on table <{{.TableName}}> fail:", err) + } + + _, err = _do.Not().Or().Clauses().Take() + if err != nil { + t.Error("Not/Or/Clauses on table <{{.TableName}}> fail:", err) + } +} +` From f10ab4d5d4bc763b7ee8d51fefebdaad254b3cfa Mon Sep 17 00:00:00 2001 From: UnaffiliatedCode Date: Tue, 3 Jun 2025 12:24:46 -0400 Subject: [PATCH 2/3] fix: Applied expectation change in format for splitting run operations --- internal/template/method_original_test.go | 262 +++++++++++++--------- 1 file changed, 154 insertions(+), 108 deletions(-) diff --git a/internal/template/method_original_test.go b/internal/template/method_original_test.go index 92c93d60..ee6c3a15 100644 --- a/internal/template/method_original_test.go +++ b/internal/template/method_original_test.go @@ -5,7 +5,7 @@ const CRUDMethodTest = ` func init() { InitializeDB() err := _gen_test_db.AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) - if err != nil{ + if err != nil { fmt.Printf("Error: AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) fail: %s", err) } } @@ -22,112 +22,158 @@ func Test_{{.QueryStructName}}Query(t *testing.T) { return } - _, ok := {{.QueryStructName}}.GetFieldByName("") - if ok { - t.Error("GetFieldByName(\"\") from {{.QueryStructName}} success") - } - - err = _do.Create(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) - if err != nil { - t.Error("create item in table <{{.TableName}}> fail:", err) - } - - err = _do.Save(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) - if err != nil { - t.Error("create item in table <{{.TableName}}> fail:", err) - } - - err = _do.CreateInBatches([]*{{.StructInfo.Package}}.{{.ModelStructName}}{ {}, {} }, 10) - if err != nil { - t.Error("create item in table <{{.TableName}}> fail:", err) - } - - _, err = _do.Select({{.QueryStructName}}.ALL).Take() - if err != nil { - t.Error("Take() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.First() - if err != nil { - t.Error("First() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Last() - if err != nil { - t.Error("First() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) - if err != nil { - t.Error("FindInBatch() on table <{{.TableName}}> fail:", err) - } - - err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*{{.StructInfo.Package}}.{{.ModelStructName}}{}, 10, func(tx gen.Dao, batch int) error { return nil }) - if err != nil { - t.Error("FindInBatches() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Select({{.QueryStructName}}.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() - if err != nil { - t.Error("Find() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Distinct(primaryKey).Take() - if err != nil { - t.Error("select Distinct() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Select({{.QueryStructName}}.ALL).Omit(primaryKey).Take() - if err != nil { - t.Error("Omit() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Group(primaryKey).Find() - if err != nil { - t.Error("Group() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() - if err != nil { - t.Error("Scopes() on table <{{.TableName}}> fail:", err) - } - - _, _, err = _do.FindByPage(0, 1) - if err != nil { - t.Error("FindByPage() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.ScanByPage(&{{.StructInfo.Package}}.{{.ModelStructName}}{}, 0, 1) - if err != nil { - t.Error("ScanByPage() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() - if err != nil { - t.Error("FirstOrInit() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() - if err != nil { - t.Error("FirstOrCreate() on table <{{.TableName}}> fail:", err) - } - - var _a _another - var _aPK = field.NewString(_a.TableName(), "id") - - err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) - if err != nil { - t.Error("Join() on table <{{.TableName}}> fail:", err) - } - - err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) - if err != nil { - t.Error("LeftJoin() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Not().Or().Clauses().Take() - if err != nil { - t.Error("Not/Or/Clauses on table <{{.TableName}}> fail:", err) - } + t.Run("FieldByName", func(t *testing.T) { + _, ok := {{.QueryStructName}}.GetFieldByName("") + if ok { + t.Error("GetFieldByName(\"\") from {{.QueryStructName}} success") + } + }) + + t.Run("Create", func(t *testing.T) { + err := _do.Create(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Save", func(t *testing.T) { + err := _do.Save(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + } + }) + + t.Run("CreateInBatches", func(t *testing.T) { + err := _do.CreateInBatches([]*{{.StructInfo.Package}}.{{.ModelStructName}}{ {}, {} }, 10) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Take", func(t *testing.T) { + _, err := _do.Select({{.QueryStructName}}.ALL).Take() + if err != nil { + t.Error("Take() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("First", func(t *testing.T) { + _, err := _do.First() + if err != nil { + t.Error("First() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Last", func(t *testing.T) { + _, err := _do.Last() + if err != nil { + t.Error("First() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("FindInBatch", func(t *testing.T) { + _, err := _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatch() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("FindInBatches", func(t *testing.T) { + err := _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*{{.StructInfo.Package}}.{{.ModelStructName}}{}, 10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatches() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Find", func(t *testing.T) { + _, err := _do.Select({{.QueryStructName}}.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() + if err != nil { + t.Error("Find() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Distinct", func(t *testing.T) { + _, err := _do.Distinct(primaryKey).Take() + if err != nil { + t.Error("select Distinct() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Omit", func(t *testing.T) { + _, err := _do.Select({{.QueryStructName}}.ALL).Omit(primaryKey).Take() + if err != nil { + t.Error("Omit() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Group", func(t *testing.T) { + _, err := _do.Group(primaryKey).Find() + if err != nil { + t.Error("Group() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Scopes", func(t *testing.T) { + _, err := _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() + if err != nil { + t.Error("Scopes() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("FindByPage", func(t *testing.T) { + _, _, err := _do.FindByPage(0, 1) + if err != nil { + t.Error("FindByPage() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("ScanByPage", func(t *testing.T) { + _, err := _do.ScanByPage(&{{.StructInfo.Package}}.{{.ModelStructName}}{}, 0, 1) + if err != nil { + t.Error("ScanByPage() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("FirstOrInit", func(t *testing.T) { + _, err := _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() + if err != nil { + t.Error("FirstOrInit() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("FirstOrCreate", func(t *testing.T) { + _, err := _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() + if err != nil { + t.Error("FirstOrCreate() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("Join", func(t *testing.T) { + var _a _another + var _aPK = field.NewString(_a.TableName(), "id") + + t.Run("Basic Join", func(t *testing.T) { + err := _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("Join() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("LeftJoin", func(t *testing.T) { + err := _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("LeftJoin() on table <{{.TableName}}> fail:", err) + } + }) + + t.Run("NotOrClauses", func(t *testing.T) { + _, err := _do.Not().Or().Clauses().Take() + if err != nil { + t.Error("Not/Or/Clauses on table <{{.TableName}}> fail:", err) + } + }) + + + }) } ` From 9cb2f62a78e9757a316d56a699b453c17f6af23c Mon Sep 17 00:00:00 2001 From: UnaffiliatedCode Date: Tue, 3 Jun 2025 12:29:16 -0400 Subject: [PATCH 3/3] feat: added child-test runs within generated unit tests. This increases clarity when reviewing failures. Generated content now identifies which operations fail/succeed; allowing toolsets to parse the output gracefully. --- generator.go | 2 +- go.mod | 4 + go.sum | 5 + internal/template/method.go | 276 ++++++++++++++++++------------- internal/template/method_test.go | 21 +++ 5 files changed, 194 insertions(+), 114 deletions(-) create mode 100644 internal/template/method_test.go diff --git a/generator.go b/generator.go index b90bbc79..6b23ffec 100644 --- a/generator.go +++ b/generator.go @@ -457,7 +457,7 @@ func (g *Generator) generateQueryUnitTestFile(data *genInfo) (err error) { return err } - err = render(tmpl.CRUDMethodTest, &buf, data.QueryStructMeta) + err = render(tmpl.GenerateCRUDMethodTest(), &buf, data.QueryStructMeta) if err != nil { return err } diff --git a/go.mod b/go.mod index 4d7d18ea..9b3a1064 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gorm.io/gen go 1.18 require ( + github.com/stretchr/testify v1.7.0 golang.org/x/tools v0.17.0 gorm.io/datatypes v1.2.4 gorm.io/gorm v1.25.12 @@ -12,11 +13,14 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect gorm.io/driver/mysql v1.5.7 // indirect ) diff --git a/go.sum b/go.sum index c64ecacc..07a5725d 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,7 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -21,8 +22,10 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -62,7 +65,9 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4= gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI= diff --git a/internal/template/method.go b/internal/template/method.go index 5263166e..518f703e 100644 --- a/internal/template/method.go +++ b/internal/template/method.go @@ -1,5 +1,10 @@ package template +import ( + "fmt" + "strings" +) + // DIYMethod DIY method const DIYMethod = ` @@ -261,12 +266,78 @@ func ({{.S}} *{{.QueryStructName}}Do) withDO(do gen.Dao) (*{{.QueryStructName}}D ` -// CRUDMethodTest CRUD method test -const CRUDMethodTest = ` +func GenerateCRUDMethodTest() string { + sections := []string{ + "FieldByName", templateTestOperationFieldByName, + "Create", templateTestOperationCreate, + "Save", templateTestOperationSave, + "CreateInBatches", templateTestOperationCreateInBatches, + "Take", templateTestOperationTake, + "First", templatetestOperationFirst, + "Last", templateTestOperationLast, + "FindInBatch", templateTestOperationFindInBatch, + "FindInBatches", templateTestOperationFindInBatches, + "Find", templateTestOperationFind, + "Distinct", templateTestOperationDistinct, + "Omit", templateTestOperationOmit, + "Group", templateTestOperationGroup, + "Scopes", templateTestOperationScopes, + "FindByPage", templateTestOperationFindByPage, + "ScanByPage", templateTestOperationScanByPage, + "FirstOrInit", templateTestOperationFirstOrInit, + "FirstOrCreate", templateTestOperationFirstOrCreate, + } + joinSections := []string{ + "Basic Join", templateTestOperationJoin, + "LeftJoin", templateTestOperationLeftJoin, + "NotOrClauses", templateTestOperationNotOrClauses, + } + joinBody := joinTestSections(joinSections, "\t") + joinBody = fmt.Sprintf("%s\n%s", templateTestOperationJoinHeader, joinBody) + sections = append(sections, "Join", joinBody) + body := joinTestSections(sections, "") + return fmt.Sprintf("%s\n%s%s", + templateTestOperationHeader, + body, + templateTestOperationFooter, + ) +} + +func joinTestSections(kv []string, linePrefix string) string { + result := "" + for x := 0; x < len(kv); x = x + 2 { + name := kv[x] + section := kv[x+1] + if section != "" { + result += fmt.Sprintf(templateTestRunnerFormat, name, section) + } + } + if linePrefix != "" { + delimiter := "\n" + lines := strings.Split(result, delimiter) + result = "" + for _, line := range lines { + if strings.TrimSpace(line) == "" { + result += line + delimiter + } else { + result += linePrefix + line + delimiter + } + } + } + return result +} + +const ( + templateTestRunnerFormat = ` + t.Run("%s", func(t *testing.T) { + %s + }) +` + templateTestOperationHeader = ` func init() { InitializeDB() err := _gen_test_db.AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) - if err != nil{ + if err != nil { fmt.Printf("Error: AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) fail: %s", err) } } @@ -281,117 +352,96 @@ func Test_{{.QueryStructName}}Query(t *testing.T) { if err != nil { t.Error("clean table <{{.TableName}}> fail:", err) return - } - - _, ok := {{.QueryStructName}}.GetFieldByName("") - if ok { - t.Error("GetFieldByName(\"\") from {{.QueryStructName}} success") - } - - err = _do.Create(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) - if err != nil { - t.Error("create item in table <{{.TableName}}> fail:", err) - } - - err = _do.Save(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) - if err != nil { - t.Error("create item in table <{{.TableName}}> fail:", err) - } - - err = _do.CreateInBatches([]*{{.StructInfo.Package}}.{{.ModelStructName}}{ {}, {} }, 10) - if err != nil { - t.Error("create item in table <{{.TableName}}> fail:", err) - } - - _, err = _do.Select({{.QueryStructName}}.ALL).Take() - if err != nil { - t.Error("Take() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.First() - if err != nil { - t.Error("First() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Last() - if err != nil { - t.Error("First() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) - if err != nil { - t.Error("FindInBatch() on table <{{.TableName}}> fail:", err) - } - - err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*{{.StructInfo.Package}}.{{.ModelStructName}}{}, 10, func(tx gen.Dao, batch int) error { return nil }) - if err != nil { - t.Error("FindInBatches() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Select({{.QueryStructName}}.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() - if err != nil { - t.Error("Find() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Distinct(primaryKey).Take() - if err != nil { - t.Error("select Distinct() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Select({{.QueryStructName}}.ALL).Omit(primaryKey).Take() - if err != nil { - t.Error("Omit() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Group(primaryKey).Find() - if err != nil { - t.Error("Group() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() - if err != nil { - t.Error("Scopes() on table <{{.TableName}}> fail:", err) - } - - _, _, err = _do.FindByPage(0, 1) - if err != nil { - t.Error("FindByPage() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.ScanByPage(&{{.StructInfo.Package}}.{{.ModelStructName}}{}, 0, 1) - if err != nil { - t.Error("ScanByPage() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() - if err != nil { - t.Error("FirstOrInit() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() - if err != nil { - t.Error("FirstOrCreate() on table <{{.TableName}}> fail:", err) - } - - var _a _another - var _aPK = field.NewString(_a.TableName(), "id") - - err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) - if err != nil { - t.Error("Join() on table <{{.TableName}}> fail:", err) - } - - err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) - if err != nil { - t.Error("LeftJoin() on table <{{.TableName}}> fail:", err) - } - - _, err = _do.Not().Or().Clauses().Take() - if err != nil { - t.Error("Not/Or/Clauses on table <{{.TableName}}> fail:", err) - } -} + }` + templateTestOperationFooter = `} ` + templateTestOperationFieldByName = `_, ok := {{.QueryStructName}}.GetFieldByName("") + if ok { + t.Error("GetFieldByName(\"\") from {{.QueryStructName}} success") + }` + templateTestOperationCreate = `err := _do.Create(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + }` + templateTestOperationSave = `err := _do.Save(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + }` + templateTestOperationCreateInBatches = `err := _do.CreateInBatches([]*{{.StructInfo.Package}}.{{.ModelStructName}}{ {}, {} }, 10) + if err != nil { + t.Error("create item in table <{{.TableName}}> fail:", err) + }` + templateTestOperationTake = `_, err := _do.Select({{.QueryStructName}}.ALL).Take() + if err != nil { + t.Error("Take() on table <{{.TableName}}> fail:", err) + }` + templatetestOperationFirst = `_, err := _do.First() + if err != nil { + t.Error("First() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationLast = `_, err := _do.Last() + if err != nil { + t.Error("First() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationFindInBatch = `_, err := _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatch() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationFindInBatches = `err := _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*{{.StructInfo.Package}}.{{.ModelStructName}}{}, 10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatches() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationFind = `_, err := _do.Select({{.QueryStructName}}.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() + if err != nil { + t.Error("Find() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationDistinct = `_, err := _do.Distinct(primaryKey).Take() + if err != nil { + t.Error("select Distinct() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationOmit = `_, err := _do.Select({{.QueryStructName}}.ALL).Omit(primaryKey).Take() + if err != nil { + t.Error("Omit() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationGroup = `_, err := _do.Group(primaryKey).Find() + if err != nil { + t.Error("Group() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationScopes = `_, err := _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() + if err != nil { + t.Error("Scopes() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationFindByPage = `_, _, err := _do.FindByPage(0, 1) + if err != nil { + t.Error("FindByPage() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationScanByPage = `_, err := _do.ScanByPage(&{{.StructInfo.Package}}.{{.ModelStructName}}{}, 0, 1) + if err != nil { + t.Error("ScanByPage() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationFirstOrInit = `_, err := _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() + if err != nil { + t.Error("FirstOrInit() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationFirstOrCreate = `_, err := _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() + if err != nil { + t.Error("FirstOrCreate() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationJoinHeader = `var _a _another + var _aPK = field.NewString(_a.TableName(), "id")` + templateTestOperationJoin = `err := _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("Join() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationLeftJoin = `err := _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("LeftJoin() on table <{{.TableName}}> fail:", err) + }` + templateTestOperationNotOrClauses = `_, err := _do.Not().Or().Clauses().Take() + if err != nil { + t.Error("Not/Or/Clauses on table <{{.TableName}}> fail:", err) + }` +) // DIYMethodTestBasic DIY method test basic const DIYMethodTestBasic = ` diff --git a/internal/template/method_test.go b/internal/template/method_test.go new file mode 100644 index 00000000..e19f95eb --- /dev/null +++ b/internal/template/method_test.go @@ -0,0 +1,21 @@ +package template_test + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "gorm.io/gen/internal/template" +) + +func TestCanGenerateCRUDMethodTest(t *testing.T) { + actual := template.GenerateCRUDMethodTest() + delimiter := "\n" + actualSplit := strings.Split(actual, delimiter) + expectedSplit := strings.Split(CRUDMethodTest, delimiter) + assert.EqualValues(t, len(expectedSplit), len(actualSplit), "length of generated code does not match expected length") + for i, actualLine := range actualSplit { + assert.Equal(t, expectedSplit[i], actualLine, "line %d does not match expected line\nACT:[%s]\nEXP:[%s]", i+1, actualLine, expectedSplit[i]) + } + assert.Equal(t, CRUDMethodTest, actual) +}