an ORM-free SQL experience
at main 6.6 kB view raw
1package norm 2 3import ( 4 "database/sql" 5 "testing" 6 "time" 7 8 _ "github.com/mattn/go-sqlite3" 9) 10 11type 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 22type UserBasic struct { 23 ID int 24 Name string 25 Email string 26} 27 28type Department struct { 29 ID int 30 Name string 31 Budget float64 32} 33 34type SimpleStruct struct { 35 Value int 36} 37 38func 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 var departments []Department 48 err = ScanAll(rows, &departments) 49 if err != nil { 50 t.Fatalf("Failed to scan departments: %v", err) 51 } 52 53 if len(departments) != 3 { 54 t.Errorf("Expected 3 departments, got %d", len(departments)) 55 } 56 57 d1 := departments[0] 58 if d1.ID != 1 || d1.Name != "Engineering" || d1.Budget != 500000.0 { 59 t.Errorf("Engineering department data incorrect: %+v", d1) 60 } 61 62 d2 := departments[1] 63 if d2.ID != 2 || d2.Name != "Marketing" || d2.Budget != 300000.0 { 64 t.Errorf("Marketing department data incorrect: %+v", d2) 65 } 66} 67 68func TestScannerBasicFunctionality(t *testing.T) { 69 db := setupTestDB(t) 70 defer db.Close() 71 72 rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id") 73 if err != nil { 74 t.Fatalf("Failed to query users: %v", err) 75 } 76 77 var users []UserBasic 78 err = ScanAll(rows, &users) 79 if err != nil { 80 t.Fatalf("Failed to scan users: %v", err) 81 } 82 83 if len(users) != 6 { 84 t.Errorf("Expected 6 users, got %d", len(users)) 85 } 86 87 if users[0].ID != 1 || users[0].Name != "John Doe" || users[0].Email != "john@example.com" { 88 t.Errorf("Expected first user to be John Doe, got %+v", users[0]) 89 } 90 91 if users[5].Name != "Diana Prince" || users[5].Email != "diana@example.com" { 92 t.Errorf("Expected last user to be Diana Prince, got %+v", users[5]) 93 } 94} 95 96func TestScannerWithAllFields(t *testing.T) { 97 db := setupTestDB(t) 98 defer db.Close() 99 100 rows, err := db.Query("SELECT id, name, age, email, department, active, salary, created_at FROM users ORDER BY id") 101 if err != nil { 102 t.Fatalf("Failed to query users: %v", err) 103 } 104 105 var users []User 106 err = ScanAll(rows, &users) 107 if err != nil { 108 t.Fatalf("Failed to scan users: %v", err) 109 } 110 111 if len(users) != 6 { 112 t.Errorf("Expected 6 users, got %d", len(users)) 113 } 114 115 u1 := users[0] 116 if u1.ID != 1 || u1.Name != "John Doe" || u1.Age != 30 || u1.Email != "john@example.com" || !u1.Active { 117 t.Errorf("User 1 basic data incorrect: %+v", u1) 118 } 119 if !u1.Department.Valid || u1.Department.String != "Engineering" { 120 t.Errorf("User 1 department incorrect: %v", u1.Department) 121 } 122 if !u1.Salary.Valid || u1.Salary.Float64 != 75000.0 { 123 t.Errorf("User 1 salary incorrect: %v", u1.Salary) 124 } 125 126 u3 := users[2] 127 if u3.Name != "Bob Johnson" || u3.Active { 128 t.Errorf("User 3 should be inactive Bob Johnson: %+v", u3) 129 } 130 131 if u1.CreatedAt.IsZero() { 132 t.Error("User 1 created_at should not be zero") 133 } 134} 135 136func TestScannerEarlyTermination(t *testing.T) { 137 db := setupTestDB(t) 138 defer db.Close() 139 140 rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id") 141 if err != nil { 142 t.Fatalf("Failed to query users: %v", err) 143 } 144 145 scanner := NewScanner[UserBasic](rows) 146 defer scanner.Close() 147 var users []UserBasic 148 count := 0 149 150 for user := range scanner.Scan() { 151 users = append(users, user) 152 count++ 153 if count == 1 { 154 break 155 } 156 } 157 158 if len(users) != 1 { 159 t.Errorf("Expected 1 user due to early termination, got %d", len(users)) 160 } 161 162 if users[0].ID != 1 || users[0].Name != "John Doe" { 163 t.Errorf("Expected first user to be John Doe, got %+v", users[0]) 164 } 165} 166 167func TestScannerEmptyResults(t *testing.T) { 168 db := setupTestDB(t) 169 defer db.Close() 170 171 rows, err := db.Query("SELECT id, name, email FROM users WHERE id = 999") 172 if err != nil { 173 t.Fatalf("Failed to query users: %v", err) 174 } 175 176 scanner := NewScanner[UserBasic](rows) 177 defer scanner.Close() 178 var users []UserBasic 179 180 for user := range scanner.Scan() { 181 users = append(users, user) 182 } 183 184 if len(users) != 0 { 185 t.Errorf("Expected 0 users from empty query, got %d", len(users)) 186 } 187} 188 189func TestScannerMultipleIterations(t *testing.T) { 190 db := setupTestDB(t) 191 defer db.Close() 192 193 rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id LIMIT 1") 194 if err != nil { 195 t.Fatalf("Failed to query users: %v", err) 196 } 197 198 scanner := NewScanner[UserBasic](rows) 199 defer scanner.Close() 200 seq := scanner.Scan() 201 202 var users1 []UserBasic 203 for user := range seq { 204 users1 = append(users1, user) 205 } 206 207 var users2 []UserBasic 208 for user := range seq { 209 users2 = append(users2, user) 210 } 211 212 if len(users1) != 1 { 213 t.Errorf("Expected 1 user from first iteration, got %d", len(users1)) 214 } 215 216 if len(users2) != 0 { 217 t.Errorf("Expected 0 users from second iteration, got %d", len(users2)) 218 } 219} 220 221func TestScannerResourceCleanup(t *testing.T) { 222 db := setupTestDB(t) 223 defer db.Close() 224 225 rows, err := db.Query("SELECT id, name, email FROM users") 226 if err != nil { 227 t.Fatalf("Failed to query users: %v", err) 228 } 229 230 scanner := NewScanner[UserBasic](rows) 231 232 for user := range scanner.Scan() { 233 _ = user 234 break 235 } 236 237 scanner.Close() 238 if err := rows.Err(); err != nil { 239 t.Errorf("Expected no error, got %s", err) 240 } 241} 242 243func TestScannerFilterByDepartment(t *testing.T) { 244 db := setupTestDB(t) 245 defer db.Close() 246 247 rows, err := db.Query("SELECT id, name, age, email, department, active, salary, created_at FROM users WHERE department = 'Engineering' ORDER BY id") 248 if err != nil { 249 t.Fatalf("Failed to query users: %v", err) 250 } 251 252 scanner := NewScanner[User](rows) 253 defer scanner.Close() 254 var users []User 255 256 for user := range scanner.Scan() { 257 users = append(users, user) 258 } 259 260 if len(users) != 3 { 261 t.Errorf("Expected 3 Engineering users, got %d", len(users)) 262 } 263 264 for i, user := range users { 265 if !user.Department.Valid || user.Department.String != "Engineering" { 266 t.Errorf("User %d should be from Engineering: %+v", i, user) 267 } 268 } 269 270 expectedNames := []string{"John Doe", "Bob Johnson", "Charlie Wilson"} 271 for i, user := range users { 272 if user.Name != expectedNames[i] { 273 t.Errorf("Expected user %d to be %s, got %s", i, expectedNames[i], user.Name) 274 } 275 } 276} 277 278func TestScanOne(t *testing.T) { 279 db := setupTestDB(t) 280 defer db.Close() 281 282 row := db.QueryRow("SELECT * FROM users WHERE id = 1") 283 284 var u User 285 err := Scan(row, &u) 286 if err != nil { 287 t.Fatalf("Failed to scan user: %v", err) 288 } 289 290 if u.ID != 1 || u.Name != "John Doe" { 291 t.Errorf("user data incorrect: %+v", u) 292 } 293}