+55
-181
query_test.go
+55
-181
query_test.go
···
1
1
package norm
2
2
3
3
import (
4
-
"database/sql"
5
4
"testing"
6
5
"time"
7
6
···
91
90
}
92
91
93
92
func TestComplexExpressions(t *testing.T) {
94
-
// Test chained logical operations
95
93
age := Eq("age", 25)
96
94
status := Eq("status", "active")
97
95
score := Gt("score", 100)
···
119
117
}
120
118
121
119
func TestSelectAPI(t *testing.T) {
122
-
// Test fluent API chaining
123
120
s := Select("*").
124
121
From("users").
125
122
Where(Eq("id", 1)).
···
163
160
func TestSelectBuild_Success(t *testing.T) {
164
161
tests := []struct {
165
162
name string
166
-
builder func() select_
163
+
stmt select_
167
164
expectedSql string
168
165
expectedArgs []any
169
166
}{
170
167
{
171
-
name: "Simple select",
172
-
builder: func() select_ {
173
-
return Select("name", "age").From("users")
174
-
},
168
+
name: "Simple select",
169
+
stmt: Select("name", "age").From("users"),
175
170
expectedSql: "SELECT name, age FROM users",
176
171
expectedArgs: nil,
177
172
},
178
173
{
179
174
name: "Select with where",
180
-
builder: func() select_ {
181
-
return Select("*").
182
-
From("users").
183
-
Where(Eq("active", true))
184
-
},
175
+
stmt: Select("*").
176
+
From("users").
177
+
Where(Eq("active", true)),
185
178
expectedSql: "SELECT * FROM users WHERE (active) = (?)",
186
179
expectedArgs: []any{true},
187
180
},
188
181
{
189
182
name: "Select with order by",
190
-
builder: func() select_ {
191
-
return Select("name").
192
-
From("users").
193
-
OrderBy("name", Ascending)
194
-
},
183
+
stmt: Select("name").
184
+
From("users").
185
+
OrderBy("name", Ascending),
195
186
expectedSql: "SELECT name FROM users ORDER BY name asc",
196
187
expectedArgs: nil,
197
188
},
198
189
{
199
190
name: "Select with multiple order by",
200
-
builder: func() select_ {
201
-
return Select("name", "age").
202
-
From("users").
203
-
OrderBy("name", Ascending).
204
-
OrderBy("age", Descending)
205
-
},
191
+
stmt: Select("name", "age").
192
+
From("users").
193
+
OrderBy("name", Ascending).
194
+
OrderBy("age", Descending),
206
195
expectedSql: "SELECT name, age FROM users ORDER BY name asc, age desc",
207
196
expectedArgs: nil,
208
197
},
209
198
{
210
199
name: "Select with group by",
211
-
builder: func() select_ {
212
-
return Select("department", "COUNT(*)").
213
-
From("users").
214
-
GroupBy("department")
215
-
},
200
+
stmt: Select("department", "COUNT(*)").
201
+
From("users").
202
+
GroupBy("department"),
216
203
expectedSql: "SELECT department, COUNT(*) FROM users GROUP BY department",
217
204
expectedArgs: nil,
218
205
},
219
206
{
220
207
name: "Select with limit",
221
-
builder: func() select_ {
222
-
return Select("*").
223
-
From("users").
224
-
Limit(5)
225
-
},
208
+
stmt: Select("*").
209
+
From("users").
210
+
Limit(5),
226
211
expectedSql: "SELECT * FROM users LIMIT 5",
227
212
expectedArgs: nil,
228
213
},
229
214
{
230
215
name: "Complex select",
231
-
builder: func() select_ {
232
-
return Select("name", "age", "department").
233
-
From("users").
234
-
Where(Eq("active", true).And(Gt("age", 18))).
235
-
GroupBy("department").
236
-
OrderBy("name", Ascending).
237
-
Limit(10)
238
-
},
216
+
stmt: Select("name", "age", "department").
217
+
From("users").
218
+
Where(Eq("active", true).And(Gt("age", 18))).
219
+
GroupBy("department").
220
+
OrderBy("name", Ascending).
221
+
Limit(10),
239
222
expectedSql: "SELECT name, age, department FROM users WHERE ((active) = (?)) and ((age) > (?)) GROUP BY department ORDER BY name asc LIMIT 10",
240
223
expectedArgs: []any{true, 18},
241
224
},
···
243
226
244
227
for _, test := range tests {
245
228
t.Run(test.name, func(t *testing.T) {
246
-
s := test.builder()
247
-
sql, args, err := s.Build()
229
+
sql, args, err := test.stmt.Build()
248
230
249
231
if err != nil {
250
232
t.Errorf("Expected no error, got %v", err)
···
270
252
func TestSelectBuild_Errors(t *testing.T) {
271
253
tests := []struct {
272
254
name string
273
-
builder func() select_
255
+
stmt select_
274
256
expectedError string
275
257
}{
276
258
{
277
-
name: "No columns",
278
-
builder: func() select_ {
279
-
return Select()
280
-
},
259
+
name: "No columns",
260
+
stmt: Select(),
281
261
expectedError: "result columns empty",
282
262
},
283
263
{
284
-
name: "No from clause",
285
-
builder: func() select_ {
286
-
return Select("name")
287
-
},
264
+
name: "No from clause",
265
+
stmt: Select("name"),
288
266
expectedError: "FROM clause is required",
289
267
},
290
268
{
291
269
name: "Invalid limit",
292
-
builder: func() select_ {
293
-
return Select("name").
294
-
From("users").
295
-
Limit(0)
296
-
},
270
+
stmt: Select("name").
271
+
From("users").
272
+
Limit(0),
297
273
expectedError: "LIMIT must be positive, got 0",
298
274
},
299
275
{
300
276
name: "Negative limit",
301
-
builder: func() select_ {
302
-
return Select("name").
303
-
From("users").
304
-
Limit(-5)
305
-
},
277
+
stmt: Select("name").
278
+
From("users").
279
+
Limit(-5),
306
280
expectedError: "LIMIT must be positive, got -5",
307
281
},
308
282
}
309
283
310
284
for _, test := range tests {
311
285
t.Run(test.name, func(t *testing.T) {
312
-
s := test.builder()
313
-
sql, args, err := s.Build()
286
+
sql, args, err := test.stmt.Build()
314
287
315
288
if err == nil {
316
289
t.Error("Expected error, got nil")
···
384
357
}
385
358
}
386
359
387
-
// setupTestDB creates an in-memory SQLite database with test data
388
-
func setupTestDB(t *testing.T) *sql.DB {
389
-
db, err := sql.Open("sqlite3", ":memory:")
390
-
if err != nil {
391
-
t.Fatalf("Failed to open database: %v", err)
392
-
}
393
-
394
-
// Create users table
395
-
_, err = db.Exec(`
396
-
CREATE TABLE users (
397
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
398
-
name TEXT NOT NULL,
399
-
age INTEGER NOT NULL,
400
-
email TEXT UNIQUE NOT NULL,
401
-
department TEXT,
402
-
active BOOLEAN DEFAULT TRUE,
403
-
salary REAL,
404
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
405
-
)
406
-
`)
407
-
if err != nil {
408
-
t.Fatalf("Failed to create users table: %v", err)
409
-
}
410
-
411
-
// Create departments table
412
-
_, err = db.Exec(`
413
-
CREATE TABLE departments (
414
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
415
-
name TEXT NOT NULL,
416
-
budget REAL
417
-
)
418
-
`)
419
-
if err != nil {
420
-
t.Fatalf("Failed to create departments table: %v", err)
421
-
}
422
-
423
-
// Insert test data
424
-
users := []struct {
425
-
name, email, department string
426
-
age int
427
-
active bool
428
-
salary float64
429
-
}{
430
-
{"John Doe", "john@example.com", "Engineering", 30, true, 75000.0},
431
-
{"Jane Smith", "jane@example.com", "Marketing", 25, true, 65000.0},
432
-
{"Bob Johnson", "bob@example.com", "Engineering", 35, false, 80000.0},
433
-
{"Alice Brown", "alice@example.com", "Sales", 28, true, 70000.0},
434
-
{"Charlie Wilson", "charlie@example.com", "Engineering", 32, true, 85000.0},
435
-
{"Diana Prince", "diana@example.com", "Marketing", 29, false, 68000.0},
436
-
}
437
-
438
-
for _, user := range users {
439
-
_, err = db.Exec(`
440
-
INSERT INTO users (name, email, department, age, active, salary)
441
-
VALUES (?, ?, ?, ?, ?, ?)
442
-
`, user.name, user.email, user.department, user.age, user.active, user.salary)
443
-
if err != nil {
444
-
t.Fatalf("Failed to insert user %s: %v", user.name, err)
445
-
}
446
-
}
447
-
448
-
// Insert departments
449
-
departments := []struct {
450
-
name string
451
-
budget float64
452
-
}{
453
-
{"Engineering", 500000.0},
454
-
{"Marketing", 300000.0},
455
-
{"Sales", 400000.0},
456
-
}
457
-
458
-
for _, dept := range departments {
459
-
_, err = db.Exec(`
460
-
INSERT INTO departments (name, budget)
461
-
VALUES (?, ?)
462
-
`, dept.name, dept.budget)
463
-
if err != nil {
464
-
t.Fatalf("Failed to insert department %s: %v", dept.name, err)
465
-
}
466
-
}
467
-
468
-
return db
469
-
}
470
-
471
360
func TestSelectIntegration_BasicQueries(t *testing.T) {
472
361
db := setupTestDB(t)
473
362
defer db.Close()
474
363
475
364
tests := []struct {
476
365
name string
477
-
builder func() select_
366
+
stmt select_
478
367
expectedRows int
479
368
}{
480
369
{
481
-
name: "Select all users",
482
-
builder: func() select_ {
483
-
return Select("*").From("users")
484
-
},
370
+
name: "Select all users",
371
+
stmt: Select("*").From("users"),
485
372
expectedRows: 6,
486
373
},
487
374
{
488
375
name: "Select active users only",
489
-
builder: func() select_ {
490
-
return Select("name", "email").
491
-
From("users").
492
-
Where(Eq("active", true))
493
-
},
376
+
stmt: Select("name", "email").
377
+
From("users").
378
+
Where(Eq("active", true)),
494
379
expectedRows: 4,
495
380
},
496
381
{
497
382
name: "Select users in Engineering",
498
-
builder: func() select_ {
499
-
return Select("name", "age").
500
-
From("users").
501
-
Where(Eq("department", "Engineering"))
502
-
},
383
+
stmt: Select("name", "age").
384
+
From("users").
385
+
Where(Eq("department", "Engineering")),
503
386
expectedRows: 3,
504
387
},
505
388
{
506
389
name: "Select users with age > 30",
507
-
builder: func() select_ {
508
-
return Select("name", "age").
509
-
From("users").
510
-
Where(Gt("age", 30))
511
-
},
390
+
stmt: Select("name", "age").
391
+
From("users").
392
+
Where(Gt("age", 30)),
512
393
expectedRows: 2,
513
394
},
514
395
{
515
396
name: "Select users with salary between 70000 and 80000",
516
-
builder: func() select_ {
517
-
return Select("name", "salary").
518
-
From("users").
519
-
Where(Gte("salary", 70000.0).And(Lte("salary", 80000.0)))
520
-
},
397
+
stmt: Select("name", "salary").
398
+
From("users").
399
+
Where(Gte("salary", 70000.0).And(Lte("salary", 80000.0))),
521
400
expectedRows: 3,
522
401
},
523
402
}
524
403
525
404
for _, test := range tests {
526
405
t.Run(test.name, func(t *testing.T) {
527
-
s := test.builder()
528
-
sql, args, err := s.Build()
406
+
sql, args, err := test.stmt.Build()
529
407
if err != nil {
530
408
t.Fatalf("Failed to build query: %v", err)
531
409
}
···
637
515
t.Fatalf("Expected 6 results, got %d", len(results))
638
516
}
639
517
640
-
// First result should be from Engineering (alphabetically first) with highest age
641
518
if results[0].department != "Engineering" {
642
519
t.Errorf("Expected first result to be from Engineering, got %s", results[0].department)
643
520
}
···
684
561
t.Errorf("Expected 3 departments, got %d", len(results))
685
562
}
686
563
687
-
// Engineering should have the most users (3)
688
564
if results[0].department != "Engineering" || results[0].count != 3 {
689
565
t.Errorf("Expected Engineering with 3 users first, got %s with %d users", results[0].department, results[0].count)
690
566
}
···
729
605
t.Errorf("Expected 2 results, got %d", len(results))
730
606
}
731
607
732
-
// Should get Charlie Wilson (85000) and John Doe (75000)
733
608
if results[0].salary != 85000.0 {
734
609
t.Errorf("Expected highest salary to be 85000, got %f", results[0].salary)
735
610
}
···
859
734
db := setupTestDB(t)
860
735
defer db.Close()
861
736
862
-
// Add more test data for performance testing
863
737
start := time.Now()
864
-
for i := 0; i < 1000; i++ {
738
+
for i := range 1000 {
865
739
_, err := db.Exec(`
866
740
INSERT INTO users (name, email, department, age, active, salary)
867
741
VALUES (?, ?, ?, ?, ?, ?)
+4
-2
scanner.go
+4
-2
scanner.go
···
33
33
34
34
func (s *Scanner[T]) Scan() iter.Seq[T] {
35
35
return func(yield func(T) bool) {
36
-
defer s.rows.Close()
37
-
38
36
for s.rows.Next() {
39
37
var data T
40
38
elem := reflect.ValueOf(&data).Elem()
···
58
56
}
59
57
}
60
58
}
59
+
60
+
func (s *Scanner[T]) Close() error {
61
+
return s.rows.Close()
62
+
}
+333
scanner_test.go
+333
scanner_test.go
···
1
+
package norm
2
+
3
+
import (
4
+
"database/sql"
5
+
"testing"
6
+
"time"
7
+
8
+
_ "github.com/mattn/go-sqlite3"
9
+
)
10
+
11
+
type User struct {
12
+
ID int
13
+
Name string
14
+
Age int
15
+
Email string
16
+
Department sql.NullString
17
+
Active bool
18
+
Salary sql.NullFloat64
19
+
CreatedAt time.Time
20
+
}
21
+
22
+
type UserBasic struct {
23
+
ID int
24
+
Name string
25
+
Email string
26
+
}
27
+
28
+
type Department struct {
29
+
ID int
30
+
Name string
31
+
Budget float64
32
+
}
33
+
34
+
type SimpleStruct struct {
35
+
Value int
36
+
}
37
+
38
+
func TestScannerWithDepartments(t *testing.T) {
39
+
db := setupTestDB(t)
40
+
defer db.Close()
41
+
42
+
rows, err := db.Query("SELECT id, name, budget FROM departments ORDER BY id")
43
+
if err != nil {
44
+
t.Fatalf("Failed to query departments: %v", err)
45
+
}
46
+
47
+
scanner := NewScanner[Department](rows)
48
+
defer scanner.Close()
49
+
var departments []Department
50
+
51
+
for dept := range scanner.Scan() {
52
+
departments = append(departments, dept)
53
+
}
54
+
55
+
if len(departments) != 3 {
56
+
t.Errorf("Expected 3 departments, got %d", len(departments))
57
+
}
58
+
59
+
d1 := departments[0]
60
+
if d1.ID != 1 || d1.Name != "Engineering" || d1.Budget != 500000.0 {
61
+
t.Errorf("Engineering department data incorrect: %+v", d1)
62
+
}
63
+
64
+
d2 := departments[1]
65
+
if d2.ID != 2 || d2.Name != "Marketing" || d2.Budget != 300000.0 {
66
+
t.Errorf("Marketing department data incorrect: %+v", d2)
67
+
}
68
+
}
69
+
70
+
func TestScannerBasicFunctionality(t *testing.T) {
71
+
db := setupTestDB(t)
72
+
defer db.Close()
73
+
74
+
rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id")
75
+
if err != nil {
76
+
t.Fatalf("Failed to query users: %v", err)
77
+
}
78
+
79
+
scanner := NewScanner[UserBasic](rows)
80
+
defer scanner.Close()
81
+
var users []UserBasic
82
+
83
+
for user := range scanner.Scan() {
84
+
users = append(users, user)
85
+
}
86
+
87
+
if len(users) != 6 {
88
+
t.Errorf("Expected 6 users, got %d", len(users))
89
+
}
90
+
91
+
if users[0].ID != 1 || users[0].Name != "John Doe" || users[0].Email != "john@example.com" {
92
+
t.Errorf("Expected first user to be John Doe, got %+v", users[0])
93
+
}
94
+
95
+
if users[5].Name != "Diana Prince" || users[5].Email != "diana@example.com" {
96
+
t.Errorf("Expected last user to be Diana Prince, got %+v", users[5])
97
+
}
98
+
}
99
+
100
+
func TestScannerWithAllFields(t *testing.T) {
101
+
db := setupTestDB(t)
102
+
defer db.Close()
103
+
104
+
rows, err := db.Query("SELECT id, name, age, email, department, active, salary, created_at FROM users ORDER BY id")
105
+
if err != nil {
106
+
t.Fatalf("Failed to query users: %v", err)
107
+
}
108
+
109
+
scanner := NewScanner[User](rows)
110
+
defer scanner.Close()
111
+
var users []User
112
+
113
+
for user := range scanner.Scan() {
114
+
users = append(users, user)
115
+
}
116
+
117
+
if len(users) != 6 {
118
+
t.Errorf("Expected 6 users, got %d", len(users))
119
+
}
120
+
121
+
u1 := users[0]
122
+
if u1.ID != 1 || u1.Name != "John Doe" || u1.Age != 30 || u1.Email != "john@example.com" || !u1.Active {
123
+
t.Errorf("User 1 basic data incorrect: %+v", u1)
124
+
}
125
+
if !u1.Department.Valid || u1.Department.String != "Engineering" {
126
+
t.Errorf("User 1 department incorrect: %v", u1.Department)
127
+
}
128
+
if !u1.Salary.Valid || u1.Salary.Float64 != 75000.0 {
129
+
t.Errorf("User 1 salary incorrect: %v", u1.Salary)
130
+
}
131
+
132
+
u3 := users[2]
133
+
if u3.Name != "Bob Johnson" || u3.Active {
134
+
t.Errorf("User 3 should be inactive Bob Johnson: %+v", u3)
135
+
}
136
+
137
+
if u1.CreatedAt.IsZero() {
138
+
t.Error("User 1 created_at should not be zero")
139
+
}
140
+
}
141
+
142
+
func TestScannerWithErrorHandler(t *testing.T) {
143
+
db := setupTestDB(t)
144
+
defer db.Close()
145
+
146
+
rows, err := db.Query("SELECT id, name, email FROM users LIMIT 1")
147
+
if err != nil {
148
+
t.Fatalf("Failed to query users: %v", err)
149
+
}
150
+
151
+
var capturedError error
152
+
scanner := NewScanner(rows, OnScannerError[SimpleStruct](func(err error) {
153
+
capturedError = err
154
+
}))
155
+
defer scanner.Close()
156
+
157
+
var results []SimpleStruct
158
+
for result := range scanner.Scan() {
159
+
results = append(results, result)
160
+
}
161
+
162
+
if capturedError == nil {
163
+
t.Error("Expected an error to be captured, but none was")
164
+
}
165
+
166
+
if len(results) != 0 {
167
+
t.Errorf("Expected 0 results due to scan error, got %d", len(results))
168
+
}
169
+
}
170
+
171
+
func TestScannerEarlyTermination(t *testing.T) {
172
+
db := setupTestDB(t)
173
+
defer db.Close()
174
+
175
+
rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id")
176
+
if err != nil {
177
+
t.Fatalf("Failed to query users: %v", err)
178
+
}
179
+
180
+
scanner := NewScanner[UserBasic](rows)
181
+
defer scanner.Close()
182
+
var users []UserBasic
183
+
count := 0
184
+
185
+
for user := range scanner.Scan() {
186
+
users = append(users, user)
187
+
count++
188
+
if count == 1 {
189
+
break
190
+
}
191
+
}
192
+
193
+
if len(users) != 1 {
194
+
t.Errorf("Expected 1 user due to early termination, got %d", len(users))
195
+
}
196
+
197
+
if users[0].ID != 1 || users[0].Name != "John Doe" {
198
+
t.Errorf("Expected first user to be John Doe, got %+v", users[0])
199
+
}
200
+
}
201
+
202
+
func TestScannerEmptyResults(t *testing.T) {
203
+
db := setupTestDB(t)
204
+
defer db.Close()
205
+
206
+
rows, err := db.Query("SELECT id, name, email FROM users WHERE id = 999")
207
+
if err != nil {
208
+
t.Fatalf("Failed to query users: %v", err)
209
+
}
210
+
211
+
scanner := NewScanner[UserBasic](rows)
212
+
defer scanner.Close()
213
+
var users []UserBasic
214
+
215
+
for user := range scanner.Scan() {
216
+
users = append(users, user)
217
+
}
218
+
219
+
if len(users) != 0 {
220
+
t.Errorf("Expected 0 users from empty query, got %d", len(users))
221
+
}
222
+
}
223
+
224
+
func TestScannerMultipleIterations(t *testing.T) {
225
+
db := setupTestDB(t)
226
+
defer db.Close()
227
+
228
+
rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id LIMIT 1")
229
+
if err != nil {
230
+
t.Fatalf("Failed to query users: %v", err)
231
+
}
232
+
233
+
scanner := NewScanner[UserBasic](rows)
234
+
defer scanner.Close()
235
+
seq := scanner.Scan()
236
+
237
+
var users1 []UserBasic
238
+
for user := range seq {
239
+
users1 = append(users1, user)
240
+
}
241
+
242
+
var users2 []UserBasic
243
+
for user := range seq {
244
+
users2 = append(users2, user)
245
+
}
246
+
247
+
if len(users1) != 1 {
248
+
t.Errorf("Expected 1 user from first iteration, got %d", len(users1))
249
+
}
250
+
251
+
if len(users2) != 0 {
252
+
t.Errorf("Expected 0 users from second iteration, got %d", len(users2))
253
+
}
254
+
}
255
+
256
+
func TestScannerWithNilErrorHandler(t *testing.T) {
257
+
db := setupTestDB(t)
258
+
defer db.Close()
259
+
260
+
rows, err := db.Query("SELECT id, name, email FROM users LIMIT 1")
261
+
if err != nil {
262
+
t.Fatalf("Failed to query users: %v", err)
263
+
}
264
+
265
+
scanner := NewScanner[UserBasic](rows)
266
+
defer scanner.Close()
267
+
var users []UserBasic
268
+
269
+
for user := range scanner.Scan() {
270
+
users = append(users, user)
271
+
}
272
+
273
+
if len(users) != 1 {
274
+
t.Errorf("Expected 1 user, got %d", len(users))
275
+
}
276
+
}
277
+
278
+
func TestScannerResourceCleanup(t *testing.T) {
279
+
db := setupTestDB(t)
280
+
defer db.Close()
281
+
282
+
rows, err := db.Query("SELECT id, name, email FROM users")
283
+
if err != nil {
284
+
t.Fatalf("Failed to query users: %v", err)
285
+
}
286
+
287
+
scanner := NewScanner[UserBasic](rows)
288
+
289
+
for user := range scanner.Scan() {
290
+
_ = user
291
+
break
292
+
}
293
+
294
+
scanner.Close()
295
+
if err := rows.Err(); err != nil {
296
+
t.Errorf("Expected no error, got %s", err)
297
+
}
298
+
}
299
+
300
+
func TestScannerFilterByDepartment(t *testing.T) {
301
+
db := setupTestDB(t)
302
+
defer db.Close()
303
+
304
+
rows, err := db.Query("SELECT id, name, age, email, department, active, salary, created_at FROM users WHERE department = 'Engineering' ORDER BY id")
305
+
if err != nil {
306
+
t.Fatalf("Failed to query users: %v", err)
307
+
}
308
+
309
+
scanner := NewScanner[User](rows)
310
+
defer scanner.Close()
311
+
var users []User
312
+
313
+
for user := range scanner.Scan() {
314
+
users = append(users, user)
315
+
}
316
+
317
+
if len(users) != 3 {
318
+
t.Errorf("Expected 3 Engineering users, got %d", len(users))
319
+
}
320
+
321
+
for i, user := range users {
322
+
if !user.Department.Valid || user.Department.String != "Engineering" {
323
+
t.Errorf("User %d should be from Engineering: %+v", i, user)
324
+
}
325
+
}
326
+
327
+
expectedNames := []string{"John Doe", "Bob Johnson", "Charlie Wilson"}
328
+
for i, user := range users {
329
+
if user.Name != expectedNames[i] {
330
+
t.Errorf("Expected user %d to be %s, got %s", i, expectedNames[i], user.Name)
331
+
}
332
+
}
333
+
}
+92
test_util.go
+92
test_util.go
···
1
+
package norm
2
+
3
+
import (
4
+
"database/sql"
5
+
"testing"
6
+
7
+
_ "github.com/mattn/go-sqlite3"
8
+
)
9
+
10
+
// setupTestDB creates an in-memory SQLite database with test data
11
+
func setupTestDB(t *testing.T) *sql.DB {
12
+
db, err := sql.Open("sqlite3", ":memory:")
13
+
if err != nil {
14
+
t.Fatalf("Failed to open database: %v", err)
15
+
}
16
+
17
+
// Create users table
18
+
_, err = db.Exec(`
19
+
CREATE TABLE users (
20
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+
name TEXT NOT NULL,
22
+
age INTEGER NOT NULL,
23
+
email TEXT UNIQUE NOT NULL,
24
+
department TEXT,
25
+
active BOOLEAN DEFAULT TRUE,
26
+
salary REAL,
27
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
28
+
)
29
+
`)
30
+
if err != nil {
31
+
t.Fatalf("Failed to create users table: %v", err)
32
+
}
33
+
34
+
// Create departments table
35
+
_, err = db.Exec(`
36
+
CREATE TABLE departments (
37
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
38
+
name TEXT NOT NULL,
39
+
budget REAL
40
+
)
41
+
`)
42
+
if err != nil {
43
+
t.Fatalf("Failed to create departments table: %v", err)
44
+
}
45
+
46
+
// Insert test data
47
+
users := []struct {
48
+
name, email, department string
49
+
age int
50
+
active bool
51
+
salary float64
52
+
}{
53
+
{"John Doe", "john@example.com", "Engineering", 30, true, 75000.0},
54
+
{"Jane Smith", "jane@example.com", "Marketing", 25, true, 65000.0},
55
+
{"Bob Johnson", "bob@example.com", "Engineering", 35, false, 80000.0},
56
+
{"Alice Brown", "alice@example.com", "Sales", 28, true, 70000.0},
57
+
{"Charlie Wilson", "charlie@example.com", "Engineering", 32, true, 85000.0},
58
+
{"Diana Prince", "diana@example.com", "Marketing", 29, false, 68000.0},
59
+
}
60
+
61
+
for _, user := range users {
62
+
_, err = db.Exec(`
63
+
INSERT INTO users (name, email, department, age, active, salary)
64
+
VALUES (?, ?, ?, ?, ?, ?)
65
+
`, user.name, user.email, user.department, user.age, user.active, user.salary)
66
+
if err != nil {
67
+
t.Fatalf("Failed to insert user %s: %v", user.name, err)
68
+
}
69
+
}
70
+
71
+
// Insert departments
72
+
departments := []struct {
73
+
name string
74
+
budget float64
75
+
}{
76
+
{"Engineering", 500000.0},
77
+
{"Marketing", 300000.0},
78
+
{"Sales", 400000.0},
79
+
}
80
+
81
+
for _, dept := range departments {
82
+
_, err = db.Exec(`
83
+
INSERT INTO departments (name, budget)
84
+
VALUES (?, ?)
85
+
`, dept.name, dept.budget)
86
+
if err != nil {
87
+
t.Fatalf("Failed to insert department %s: %v", dept.name, err)
88
+
}
89
+
}
90
+
91
+
return db
92
+
}