Skip to content

Commit ce6cf5b

Browse files
authored
ad generics api tests and gorm_test (#56)
Add tests into generics_test.go and gorm_test.go
1 parent 55dbdc3 commit ce6cf5b

File tree

2 files changed

+278
-11
lines changed

2 files changed

+278
-11
lines changed

tests/generics_test.go

Lines changed: 154 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,25 @@ func TestGenericsCreateInBatches(t *testing.T) {
134134
}
135135

136136
found, err := gorm.G[User](DB).Raw("SELECT * FROM \"users\" WHERE \"name\" LIKE ?", "GenericsCreateInBatches%").Find(ctx)
137+
if err != nil {
138+
t.Fatalf("Raw Find failed: %v", err)
139+
}
137140
if len(found) != len(batch) {
138141
t.Errorf("expected %d from Raw Find, got %d", len(batch), len(found))
139142
}
140143

141144
found, err = gorm.G[User](DB).Where("\"name\" like ?", "GenericsCreateInBatches%").Limit(2).Find(ctx)
145+
if err != nil {
146+
t.Fatalf("Raw Find failed: %v", err)
147+
}
142148
if len(found) != 2 {
143149
t.Errorf("expected %d from Raw Find, got %d", 2, len(found))
144150
}
145151

146152
found, err = gorm.G[User](DB).Where("\"name\" like ?", "GenericsCreateInBatches%").Offset(2).Limit(2).Find(ctx)
153+
if err != nil {
154+
t.Fatalf("Raw Find failed: %v", err)
155+
}
147156
if len(found) != 1 {
148157
t.Errorf("expected %d from Raw Find, got %d", 1, len(found))
149158
}
@@ -168,7 +177,9 @@ func TestGenericsExecAndUpdate(t *testing.T) {
168177

169178
name += "Update"
170179
rows, err := gorm.G[User](DB).Where("\"id\" = ?", u.ID).Update(ctx, "name", name)
171-
if rows != 1 {
180+
if err != nil {
181+
t.Fatalf("Update failed: %v", err)
182+
} else if rows != 1 {
172183
t.Fatalf("failed to get affected rows, got %d, should be %d", rows, 1)
173184
}
174185

@@ -180,7 +191,9 @@ func TestGenericsExecAndUpdate(t *testing.T) {
180191
}
181192

182193
rows, err = gorm.G[User](DB).Where("\"id\" = ?", u.ID).Updates(ctx, User{Name: "GenericsExecUpdates", Age: 18})
183-
if rows != 1 {
194+
if err != nil {
195+
t.Fatalf("Updates failed: %v", err)
196+
} else if rows != 1 {
184197
t.Fatalf("failed to get affected rows, got %d, should be %d", rows, 1)
185198
}
186199

@@ -251,6 +264,37 @@ func TestGenericsDelete(t *testing.T) {
251264
if err != gorm.ErrRecordNotFound {
252265
t.Fatalf("User after delete failed: %v", err)
253266
}
267+
268+
u2 := User{Name: "GenericsDeleteCond"}
269+
if err := gorm.G[User](DB).Create(ctx, &u2); err != nil {
270+
t.Fatalf("Create failed: %v", err)
271+
}
272+
rows, err = gorm.G[User](DB).Where("\"name\" = ?", "GenericsDeleteCond").Delete(ctx)
273+
if err != nil {
274+
t.Fatalf("Conditional delete failed: %v", err)
275+
}
276+
if rows != 1 {
277+
t.Fatalf("Conditional delete failed, err=%v, rows=%d", err, rows)
278+
}
279+
_, err = gorm.G[User](DB).Where("\"id\" = ?", u2.ID).First(ctx)
280+
if err != gorm.ErrRecordNotFound {
281+
t.Errorf("Expected deleted record to be gone, got: %v", err)
282+
}
283+
284+
users := []User{
285+
{Name: "GenericsBatchDel1"},
286+
{Name: "GenericsBatchDel2"},
287+
}
288+
if err := gorm.G[User](DB).CreateInBatches(ctx, &users, 2); err != nil {
289+
t.Fatalf("Batch create for delete failed: %v", err)
290+
}
291+
rows, err = gorm.G[User](DB).Where("\"name\" LIKE ?", "GenericsBatchDel%").Delete(ctx)
292+
if err != nil {
293+
t.Fatalf("Batch delete failed: %v", err)
294+
}
295+
if rows != 2 {
296+
t.Errorf("batch delete expected 2 rows, got %d", rows)
297+
}
254298
}
255299

256300
func TestGenericsFindInBatches(t *testing.T) {
@@ -301,20 +345,23 @@ func TestGenericsScopes(t *testing.T) {
301345
results, err := gorm.G[User](DB).Scopes(filterName1).Find(ctx)
302346
if err != nil {
303347
t.Fatalf("Scopes failed: %v", err)
304-
}
305-
if len(results) != 1 || results[0].Name != "GenericsScopes1" {
348+
} else if len(results) != 1 || results[0].Name != "GenericsScopes1" {
306349
t.Fatalf("Scopes expected 1, got %d", len(results))
307350
}
308351

309352
notResult, err := gorm.G[User](DB).Where("\"name\" like ?", "GenericsScopes%").Not("\"name\" = ?", "GenericsScopes1").Order("\"name\"").Find(ctx)
310-
if len(notResult) != 2 {
353+
if err != nil {
354+
t.Fatalf("Not failed: %v", err)
355+
} else if len(notResult) != 2 {
311356
t.Fatalf("expected 2 results, got %d", len(notResult))
312357
} else if notResult[0].Name != "GenericsScopes2" || notResult[1].Name != "GenericsScopes3" {
313358
t.Fatalf("expected names 'GenericsScopes2' and 'GenericsScopes3', got %s and %s", notResult[0].Name, notResult[1].Name)
314359
}
315360

316361
orResult, err := gorm.G[User](DB).Or("\"name\" = ?", "GenericsScopes1").Or("\"name\" = ?", "GenericsScopes2").Order("\"name\"").Find(ctx)
317-
if len(orResult) != 2 {
362+
if err != nil {
363+
t.Fatalf("Or failed: %v", err)
364+
} else if len(orResult) != 2 {
318365
t.Fatalf("expected 2 results, got %d", len(notResult))
319366
} else if orResult[0].Name != "GenericsScopes1" || orResult[1].Name != "GenericsScopes2" {
320367
t.Fatalf("expected names 'GenericsScopes2' and 'GenericsScopes3', got %s and %s", orResult[0].Name, orResult[1].Name)
@@ -554,6 +601,9 @@ func TestGenericsPreloads(t *testing.T) {
554601
return nil
555602
}).Where("\"name\" in ?", names).Find(ctx)
556603

604+
if err != nil {
605+
t.Fatalf("Preload failed: %v", err)
606+
}
557607
for _, result := range results {
558608
if result.Name == u.Name {
559609
if len(result.Pets) != len(u.Pets) {
@@ -577,6 +627,9 @@ func TestGenericsPreloads(t *testing.T) {
577627
return nil
578628
}).Where("\"name\" in ?", names).Find(ctx)
579629

630+
if err != nil {
631+
t.Fatalf("Preload failed: %v", err)
632+
}
580633
for _, result := range results {
581634
if result.Name == u.Name {
582635
if len(result.Pets) != len(u.Pets) {
@@ -608,6 +661,9 @@ func TestGenericsPreloads(t *testing.T) {
608661
return nil
609662
}).Where("\"name\" in ?", names).Find(ctx)
610663

664+
if err != nil {
665+
t.Fatalf("Preload failed: %v", err)
666+
}
611667
for _, result := range results {
612668
if result.Name == u.Name {
613669
if len(result.Pets) != len(u.Pets) {
@@ -868,6 +924,9 @@ func TestGenericsWithTransaction(t *testing.T) {
868924

869925
users := []User{{Name: "TestGenericsTransaction", Age: 18}, {Name: "TestGenericsTransaction2", Age: 18}}
870926
err := gorm.G[User](tx).CreateInBatches(ctx, &users, 2)
927+
if err != nil {
928+
t.Fatalf("CreateInBatches failed: %v", err)
929+
}
871930

872931
count, err := gorm.G[User](tx).Where("\"name\" like ?", "TestGenericsTransaction%").Count(ctx, "*")
873932
if err != nil {
@@ -897,7 +956,95 @@ func TestGenericsToSQL(t *testing.T) {
897956
return tx
898957
})
899958

900-
if !regexp.MustCompile("SELECT \\* FROM .users..* 10").MatchString(sql) {
959+
if !regexp.MustCompile(`SELECT \* FROM .users..* 10`).MatchString(sql) {
901960
t.Errorf("ToSQL: got wrong sql with Generics API %v", sql)
902961
}
903962
}
963+
964+
func TestGenericsCountOmitSelect(t *testing.T) {
965+
ctx := context.Background()
966+
users := []User{{Name: "GenericsCount1", Age: 5}, {Name: "GenericsCount2", Age: 7}}
967+
err := gorm.G[User](DB).CreateInBatches(ctx, &users, 2)
968+
if err != nil {
969+
t.Fatalf("CreateInBatches failed: %v", err)
970+
}
971+
count, err := gorm.G[User](DB).Omit("age").Where("\"name\" LIKE ?", "GenericsCount%").Count(ctx, "*")
972+
if err != nil {
973+
t.Fatalf("Count failed: %v", err)
974+
}
975+
if count != 2 {
976+
t.Errorf("Count with Omit: expected 2, got %d", count)
977+
}
978+
}
979+
980+
func TestGenericsSelectAndOmitFind(t *testing.T) {
981+
ctx := context.Background()
982+
u := User{Name: "GenericsSelectOmit", Age: 30}
983+
err := gorm.G[User](DB).Create(ctx, &u)
984+
if err != nil {
985+
t.Fatalf("Create failed: %v", err)
986+
}
987+
result, err := gorm.G[User](DB).Select("id").Omit("age").Where("\"name\" = ?", u.Name).First(ctx)
988+
if err != nil {
989+
t.Fatalf("Select and Omit Find failed: %v", err)
990+
}
991+
if result.ID != u.ID || result.Name != "" || result.Age != 0 {
992+
t.Errorf("SelectAndOmitFind expects partial zero values, got: %+v", result)
993+
}
994+
}
995+
996+
func TestGenericsSelectWithPreloadAssociations(t *testing.T) {
997+
ctx := context.Background()
998+
user := User{Name: "SelectPreloadCombo", Age: 40, Company: Company{Name: "ComboCompany"}}
999+
for i := 1; i <= 2; i++ {
1000+
user.Pets = append(user.Pets, &Pet{Name: fmt.Sprintf("Pet-%d", i)})
1001+
}
1002+
if err := gorm.G[User](DB).Create(ctx, &user); err != nil {
1003+
t.Fatalf("Create failed: %v", err)
1004+
}
1005+
result, err := gorm.G[User](DB).Select("id", "name", "company_id").Preload("Company", nil).Preload("Pets", nil).Where("\"name\" = ?", user.Name).First(ctx)
1006+
if err != nil {
1007+
t.Fatalf("Select+Preload First failed: %v", err)
1008+
}
1009+
if result.ID == 0 || result.Name == "" {
1010+
t.Errorf("Expected user id/name; got: %+v", result)
1011+
}
1012+
if result.Age != 0 {
1013+
t.Errorf("Expected omitted Age=0, got %d", result.Age)
1014+
}
1015+
if result.Company.Name != user.Company.Name {
1016+
t.Errorf("Expected company %+v, got %+v", user.Company, result.Company)
1017+
}
1018+
if len(result.Pets) != len(user.Pets) {
1019+
t.Errorf("Expected %d pets, got %d", len(user.Pets), len(result.Pets))
1020+
}
1021+
}
1022+
1023+
func TestGenericsTransactionRollbackOnPreloadError(t *testing.T) {
1024+
ctx := context.Background()
1025+
tx := DB.Begin()
1026+
if tx.Error != nil {
1027+
t.Fatalf("Failed to begin transaction: %v", tx.Error)
1028+
}
1029+
user := User{Name: "TxRollbackPreload", Age: 25, Company: Company{Name: "TxCompany"}}
1030+
if err := gorm.G[User](tx).Create(ctx, &user); err != nil {
1031+
_ = tx.Rollback()
1032+
t.Fatalf("Failed to create user in tx: %v", err)
1033+
}
1034+
var gotErr error
1035+
_, gotErr = gorm.G[User](tx).
1036+
Preload("Company", func(db gorm.PreloadBuilder) error { return fmt.Errorf("bad preload") }).
1037+
Where("\"name\" = ?", user.Name).
1038+
First(ctx)
1039+
errRollback := tx.Rollback().Error
1040+
if gotErr == nil {
1041+
t.Errorf("Expected preload error, got nil")
1042+
}
1043+
if errRollback != nil {
1044+
t.Fatalf("Failed to rollback on Preload error: %v", errRollback)
1045+
}
1046+
_, err := gorm.G[User](DB).Where("\"name\" = ?", user.Name).First(ctx)
1047+
if err == nil {
1048+
t.Errorf("Expected no user after rollback, but found one")
1049+
}
1050+
}

tests/gorm_test.go

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,20 @@ import (
4646
)
4747

4848
func TestOpen(t *testing.T) {
49-
dsn := "gorm:gorm@tcp(localhost:9910)/gorm?loc=Asia%2FHongKong" // invalid loc
50-
_, err := gorm.Open(oracle.Open(dsn), &gorm.Config{})
51-
if err == nil {
52-
t.Fatalf("should returns error but got nil")
49+
dsns := []string{
50+
"gorm@localhost:9910/invalid",
51+
"gorm:gorm@localhost:9910",
52+
"invalid_dsn_string",
53+
"gorm:gorm@tcp(localhost:9910)/gorm?loc=Asia%2FHongKong",
54+
"gorm@localhost:2300/invalid_service",
55+
"gorm@localhost:invalid_port/cdb1_pdb1",
56+
"gorm@invalid_host:1111/cdb1_pdb1",
57+
}
58+
for _, dsn := range dsns {
59+
_, err := gorm.Open(oracle.Open(dsn), &gorm.Config{})
60+
if err == nil {
61+
t.Errorf("should return error for dsn=%q but got nil", dsn)
62+
}
5363
}
5464
}
5565

@@ -130,3 +140,113 @@ func TestReturningWithNullToZeroValues(t *testing.T) {
130140
t.Fatalf("rows affected expects: %v, got %v", 1, results.RowsAffected)
131141
}
132142
}
143+
144+
func TestReturningWithNullAndAdditionalFields(t *testing.T) {
145+
type userWithFields struct {
146+
gorm.Model
147+
Name string `gorm:"default:noname"`
148+
Age int
149+
Comment string
150+
}
151+
152+
DB.Migrator().DropTable(&userWithFields{})
153+
DB.Migrator().AutoMigrate(&userWithFields{})
154+
155+
// Insert a user and verify defaults
156+
u := userWithFields{}
157+
if results := DB.Create(&u); results.Error != nil {
158+
t.Fatalf("errors happened on create: %v", results.Error)
159+
} else if results.RowsAffected != 1 {
160+
t.Fatalf("rows affected expects: %v, got %v", 1, results.RowsAffected)
161+
} else if u.ID == 0 || u.Name != "noname" || u.Age != 0 || u.Comment != "" {
162+
t.Fatalf("create expects ID!=0, Name='noname', Age=0, Comment='', got %+v", u)
163+
}
164+
165+
// Update all fields and verify
166+
u.Name = "TestName"
167+
u.Age = 42
168+
u.Comment = "Hello"
169+
if results := DB.Save(&u); results.Error != nil {
170+
t.Fatalf("errors happened on update: %v", results.Error)
171+
} else if results.RowsAffected != 1 {
172+
t.Fatalf("rows affected expects: %v, got %v", 1, results.RowsAffected)
173+
} else if u.Name != "TestName" || u.Age != 42 || u.Comment != "Hello" {
174+
t.Fatalf("update expects Name='TestName', Age=42, Comment='Hello', got %+v", u)
175+
}
176+
177+
// Fetch and verify
178+
got := userWithFields{}
179+
results := DB.First(&got, "\"id\" = ?", u.ID)
180+
if results.Error != nil {
181+
t.Fatalf("errors happened on first: %v", results.Error)
182+
} else if results.RowsAffected != 1 {
183+
t.Fatalf("rows affected expects: %v, got %v", 1, results.RowsAffected)
184+
} else if got.ID != u.ID || got.Name != "TestName" || got.Age != 42 || got.Comment != "Hello" {
185+
t.Fatalf("first expects %+v, got %+v", u, got)
186+
}
187+
188+
// Batch create and check
189+
u1 := userWithFields{}
190+
u2 := userWithFields{Name: "foo"}
191+
u3 := userWithFields{Name: "bar", Age: 99, Comment: "bar-comment"}
192+
db := DB.Session(&gorm.Session{CreateBatchSize: 10})
193+
if results := db.Create([]*userWithFields{&u1, &u2, &u3}); results.Error != nil {
194+
t.Fatalf("errors happened on create: %v", results.Error)
195+
} else if results.RowsAffected != 3 {
196+
t.Fatalf("rows affected expects: %v, got %v", 3, results.RowsAffected)
197+
} else if u1.ID == 0 || u2.ID == 0 || u3.ID == 0 {
198+
t.Fatalf("ID expects : not equal 0, got %v,%v,%v", u1.ID, u2.ID, u3.ID)
199+
} else if u1.Name != "noname" || u2.Name != "foo" || u3.Name != "bar" {
200+
t.Fatalf("names expect: noname, foo, bar, got: %q,%q,%q", u1.Name, u2.Name, u3.Name)
201+
} else if u1.Age != 0 || u2.Age != 0 || u3.Age != 99 {
202+
t.Fatalf("ages expect: 0,0,99, got: %v,%v,%v", u1.Age, u2.Age, u3.Age)
203+
} else if u1.Comment != "" || u2.Comment != "" || u3.Comment != "bar-comment" {
204+
t.Fatalf("comments expect: '', '', 'bar-comment', got: %q,%q,%q", u1.Comment, u2.Comment, u3.Comment)
205+
}
206+
207+
// Batch update and check
208+
u1.Name = "A"
209+
u2.Name = "B"
210+
u3.Comment = "updated"
211+
if results := DB.Save([]*userWithFields{&u1, &u2, &u3}); results.Error != nil {
212+
t.Fatalf("errors happened on update: %v", results.Error)
213+
} else if results.RowsAffected != 3 {
214+
t.Fatalf("rows affected expects: %v, got %v", 3, results.RowsAffected)
215+
} else if u1.Name != "A" || u2.Name != "B" || u3.Name != "bar" {
216+
t.Fatalf("names expect: A, B, bar, got: %q,%q,%q", u1.Name, u2.Name, u3.Name)
217+
} else if u1.Age != 0 || u2.Age != 0 || u3.Age != 99 {
218+
t.Fatalf("ages expect: 0,0,99, got: %v,%v,%v", u1.Age, u2.Age, u3.Age)
219+
} else if u1.Comment != "" || u2.Comment != "" || u3.Comment != "updated" {
220+
t.Fatalf("comments expect: '', '', 'updated', got: %q,%q,%q", u1.Comment, u2.Comment, u3.Comment)
221+
}
222+
223+
// Batch fetch and verify
224+
updated := []userWithFields{}
225+
results = DB.Where("\"id\" in (?, ?, ?)", u1.ID, u2.ID, u3.ID).Order("\"id\" asc").Find(&updated)
226+
if results.Error != nil {
227+
t.Fatalf("errors happened on batch find: %v", results.Error)
228+
} else if results.RowsAffected != 3 {
229+
t.Fatalf("rows affected expects: %v, got %v", 3, results.RowsAffected)
230+
} else if len(updated) != 3 {
231+
t.Fatalf("batch find expects: %v records, got %v", 3, len(updated))
232+
} else if updated[0].ID != u1.ID || updated[1].ID != u2.ID || updated[2].ID != u3.ID {
233+
t.Fatalf("batch find expects IDs: %v,%v,%v, got: %v,%v,%v", u1.ID, u2.ID, u3.ID, updated[0].ID, updated[1].ID, updated[2].ID)
234+
} else if updated[0].Name != "A" || updated[1].Name != "B" || updated[2].Name != "bar" {
235+
t.Fatalf("batch find expects Names: A,B,bar, got: %q,%q,%q", updated[0].Name, updated[1].Name, updated[2].Name)
236+
} else if updated[0].Age != 0 || updated[1].Age != 0 || updated[2].Age != 99 {
237+
t.Fatalf("batch find expects Ages: 0,0,99, got: %v,%v,%v", updated[0].Age, updated[1].Age, updated[2].Age)
238+
} else if updated[0].Comment != "" || updated[1].Comment != "" || updated[2].Comment != "updated" {
239+
t.Fatalf("batch find expects Comments: '', '', 'updated', got: %q,%q,%q", updated[0].Comment, updated[1].Comment, updated[2].Comment)
240+
}
241+
242+
// Delete and verify one user
243+
if err := DB.Delete(&userWithFields{}, u2.ID).Error; err != nil {
244+
t.Fatalf("Delete failed: %v", err)
245+
}
246+
var deleted userWithFields
247+
if err := DB.First(&deleted, u2.ID).Error; err == nil {
248+
t.Fatalf("Deleted user with ID=%d found", u2.ID)
249+
}
250+
251+
DB.Migrator().DropTable(&userWithFields{})
252+
}

0 commit comments

Comments
 (0)