an ORM-free SQL experience
at main 4.9 kB view raw
1package norm 2 3import ( 4 _ "github.com/mattn/go-sqlite3" 5 "testing" 6) 7 8func TestSelectCompileSuccess(t *testing.T) { 9 tests := []struct { 10 name string 11 stmt Compiler 12 expectedSql string 13 expectedArgs []any 14 }{ 15 { 16 name: "Simple select", 17 stmt: Select("name", "age").From("users"), 18 expectedSql: "SELECT name, age FROM users", 19 expectedArgs: nil, 20 }, 21 { 22 name: "Select with where", 23 stmt: Select("*"). 24 From("users"). 25 Where(Eq("active", true)), 26 expectedSql: "SELECT * FROM users WHERE (active) = (?)", 27 expectedArgs: []any{true}, 28 }, 29 { 30 name: "Select with order by", 31 stmt: Select("name"). 32 From("users"). 33 OrderBy("name", Ascending), 34 expectedSql: "SELECT name FROM users ORDER BY name asc", 35 expectedArgs: nil, 36 }, 37 { 38 name: "Select with multiple order by", 39 stmt: Select("name", "age"). 40 From("users"). 41 OrderBy("name", Ascending). 42 OrderBy("age", Descending), 43 expectedSql: "SELECT name, age FROM users ORDER BY name asc, age desc", 44 expectedArgs: nil, 45 }, 46 { 47 name: "Select with group by", 48 stmt: Select("department", "COUNT(*)"). 49 From("users"). 50 GroupBy("department"), 51 expectedSql: "SELECT department, COUNT(*) FROM users GROUP BY department", 52 expectedArgs: nil, 53 }, 54 { 55 name: "Select with limit", 56 stmt: Select("*"). 57 From("users"). 58 Limit(5), 59 expectedSql: "SELECT * FROM users LIMIT 5", 60 expectedArgs: nil, 61 }, 62 { 63 name: "Complex select", 64 stmt: Select("name", "age", "department"). 65 From("users"). 66 Where(Eq("active", true).And(Gt("age", 18))). 67 GroupBy("department"). 68 OrderBy("name", Ascending). 69 Limit(10), 70 expectedSql: "SELECT name, age, department FROM users WHERE ((active) = (?)) AND ((age) > (?)) GROUP BY department ORDER BY name asc LIMIT 10", 71 expectedArgs: []any{true, 18}, 72 }, 73 } 74 75 for _, test := range tests { 76 t.Run(test.name, func(t *testing.T) { 77 sql, args := test.stmt.MustCompile() 78 79 if sql != test.expectedSql { 80 t.Errorf("Expected '%s', got '%s'", test.expectedSql, sql) 81 } 82 83 if len(args) != len(test.expectedArgs) { 84 t.Errorf("Expected '%d' args, got '%d' args", len(test.expectedArgs), len(args)) 85 } 86 87 for i := range len(args) { 88 if args[i] != test.expectedArgs[i] { 89 t.Errorf("Expected '%s', got '%s' at index %d", test.expectedArgs[i], args[i], i) 90 } 91 } 92 }) 93 } 94} 95 96func TestSelectCompileFail(t *testing.T) { 97 tests := []struct { 98 name string 99 stmt Compiler 100 expectedError string 101 }{ 102 { 103 name: "No columns", 104 stmt: Select(), 105 expectedError: "result columns empty", 106 }, 107 { 108 name: "No from clause", 109 stmt: Select("name"), 110 expectedError: "FROM clause is required", 111 }, 112 { 113 name: "Invalid limit", 114 stmt: Select("name"). 115 From("users"). 116 Limit(0), 117 expectedError: "LIMIT must be positive, got 0", 118 }, 119 { 120 name: "Negative limit", 121 stmt: Select("name"). 122 From("users"). 123 Limit(-5), 124 expectedError: "LIMIT must be positive, got -5", 125 }, 126 } 127 128 for _, test := range tests { 129 t.Run(test.name, func(t *testing.T) { 130 sql, args, err := test.stmt.Compile() 131 132 if err == nil { 133 t.Error("Expected error, got nil") 134 } 135 136 if err.Error() != test.expectedError { 137 t.Errorf("Expected error '%s', got '%s'", test.expectedError, err.Error()) 138 } 139 140 if sql != "" { 141 t.Errorf("Expected empty SQL on error, got '%s'", sql) 142 } 143 144 if args != nil { 145 t.Errorf("Expected empty args on error, got '%q'", args) 146 } 147 }) 148 } 149} 150 151func TestSelectIntegration(t *testing.T) { 152 db := setupTestDB(t) 153 defer db.Close() 154 155 tests := []struct { 156 name string 157 stmt select_ 158 expectedRows int 159 }{ 160 { 161 name: "Select all users", 162 stmt: Select("*").From("users"), 163 expectedRows: 6, 164 }, 165 { 166 name: "Select active users only", 167 stmt: Select("name", "email"). 168 From("users"). 169 Where(Eq("active", true)), 170 expectedRows: 4, 171 }, 172 { 173 name: "Select users in Engineering", 174 stmt: Select("name", "age"). 175 From("users"). 176 Where(Eq("department", "Engineering")), 177 expectedRows: 3, 178 }, 179 { 180 name: "Select users with age > 30", 181 stmt: Select("name", "age"). 182 From("users"). 183 Where(Gt("age", 30)), 184 expectedRows: 2, 185 }, 186 { 187 name: "Select users with salary between 70000 AND 80000", 188 stmt: Select("name", "salary"). 189 From("users"). 190 Where(Gte("salary", 70000.0).And(Lte("salary", 80000.0))), 191 expectedRows: 3, 192 }, 193 } 194 195 for _, test := range tests { 196 t.Run(test.name, func(t *testing.T) { 197 rows, err := test.stmt.Query(db) 198 if err != nil { 199 t.Fatalf("Failed to build query: %v", err) 200 } 201 202 count := 0 203 for rows.Next() { 204 count++ 205 } 206 207 if count != test.expectedRows { 208 t.Errorf("Expected %d rows, got %d", test.expectedRows, count) 209 } 210 }) 211 } 212}