This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302package norm
import ( "slices" "testing"
_ "github.com/mattn/go-sqlite3")
func TestUpdateBuild_Success(t *testing.T) { tests := []struct { name string stmt Compiler expectedSql string expectedArgs []any }{ { name: "Simple update", stmt: Update("users").Set("name", "John"), expectedSql: "UPDATE users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Update with WHERE", stmt: Update("users").Set("name", "John").Where(Eq("id", 1)), expectedSql: "UPDATE users SET name = ? WHERE (id) = (?)", expectedArgs: []any{"John", 1}, }, { name: "Abort clause", stmt: Update("users").Or(UpdateAbort).Set("name", "John"), expectedSql: "UPDATE OR ABORT users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Ignore clause", stmt: Update("users").Or(UpdateIgnore).Set("name", "John"), expectedSql: "UPDATE OR IGNORE users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Fail clause", stmt: Update("users").Or(UpdateFail).Set("name", "John"), expectedSql: "UPDATE OR FAIL users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Replace clause", stmt: Update("users").Or(UpdateReplace).Set("name", "John"), expectedSql: "UPDATE OR REPLACE users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Rollback clause", stmt: Update("users").Or(UpdateRollback).Set("name", "John"), expectedSql: "UPDATE OR ROLLBACK users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Default clause", stmt: Update("users").Or(UpdateOr(10)).Set("name", "John"), expectedSql: "UPDATE users SET name = ?", expectedArgs: []any{"John"}, }, { name: "Multiple sets", stmt: Update("users").Set("name", "John").Set("age", 35), expectedSql: "UPDATE users SET name = ?, age = ?", expectedArgs: []any{"John", 35}, }, { name: "Multiple WHERE conditions", stmt: Update("users").Set("salary", 90000.0).Where(Eq("department", "Engineering").And(Eq("active", true))), expectedSql: "UPDATE users SET salary = ? WHERE ((department) = (?)) AND ((active) = (?))", expectedArgs: []any{90000.0, "Engineering", true}, }, { name: "Complex update", stmt: Update("users").Or(UpdateIgnore).Set("name", "Updated").Set("salary", 100000.0).Where(Gt("age", 30).And(Eq("active", true))), expectedSql: "UPDATE OR IGNORE users SET name = ?, salary = ? WHERE ((age) > (?)) AND ((active) = (?))", expectedArgs: []any{"Updated", 100000.0, 30, true}, }, }
for _, test := range tests { t.Run(test.name, func(t *testing.T) { sql, args := test.stmt.MustCompile()
if sql != test.expectedSql { t.Errorf("Expected '%s', got '%s'", test.expectedSql, sql) }
if len(args) != len(test.expectedArgs) { t.Errorf("Expected '%d' args, got '%d' args", len(test.expectedArgs), len(args)) }
for i := range len(args) { if args[i] != test.expectedArgs[i] { t.Errorf("Expected '%v', got '%v' at index %d", test.expectedArgs[i], args[i], i) } } }) }}
func TestUpdateSetMap_Build(t *testing.T) { tests := []struct { name string stmt Compiler expectedConfig []struct { sql string args []any } }{ { name: "Sets with map", stmt: Update("users").Sets(map[string]any{ "name": "John", "age": 25, }).Where(Eq("id", 1)), expectedConfig: []struct { sql string args []any }{ { sql: "UPDATE users SET name = ?, age = ? WHERE (id) = (?)", args: []any{"John", 25, 1}, }, { sql: "UPDATE users SET age = ?, name = ? WHERE (id) = (?)", args: []any{25, "John", 1}, }, }, }, { name: "Mixed individual and map sets", stmt: Update("users").Set("active", false).Sets(map[string]any{ "name": "Updated User", "salary": 95000.0, }), expectedConfig: []struct { sql string args []any }{ { sql: "UPDATE users SET active = ?, name = ?, salary = ?", args: []any{false, "Updated User", 95000.0}, }, { sql: "UPDATE users SET active = ?, salary = ?, name = ?", args: []any{false, 95000.0, "Updated User"}, }, }, }, }
for _, test := range tests { t.Run(test.name, func(t *testing.T) { sql, args := test.stmt.MustCompile()
any := false idx := 0 for i, config := range test.expectedConfig { idx = i equalSql := config.sql == sql equalArgs := slices.Equal(config.args, args) if equalSql && equalArgs { any = true } }
if !any { t.Errorf("Config did not match: %d: %q; got %q, %q", idx, test.expectedConfig[idx], sql, args) }
}) }}
func TestUpdateCompileFail(t *testing.T) { tests := []struct { name string stmt Compiler expectedError string }{ { name: "No SET clauses", stmt: Update("users"), expectedError: "no SET clauses supplied", }, }
for _, test := range tests { t.Run(test.name, func(t *testing.T) { sql, args, err := test.stmt.Compile() if err == nil { t.Error("Expected error, got nil") }
if err.Error() != test.expectedError { t.Errorf("Expected error '%s', got '%s'", test.expectedError, err.Error()) }
if sql != "" { t.Errorf("Expected empty SQL on error, got '%s'", sql) }
if args != nil { t.Errorf("Expected empty args on error, got '%q'", args) } }) }}
func TestUpdateIntegration(t *testing.T) { tests := []struct { name string stmt Execer expectedRows int64 }{ { name: "Update all users salary", stmt: Update("users").Set("salary", 100000.0), expectedRows: 6, }, { name: "Update active users only", stmt: Update("users"). Set("department", "Updated Department"). Where(Eq("active", true)), expectedRows: 4, }, { name: "Update users in Engineering", stmt: Update("users"). Set("salary", 95000.0). Where(Eq("department", "Engineering")), expectedRows: 3, }, { name: "Update users with age > 30", stmt: Update("users"). Set("active", false). Where(Gt("age", 30)), expectedRows: 2, }, { name: "Update users with multiple conditions", stmt: Update("users"). Set("salary", 120000.0). Where(Eq("department", "Engineering").And(Eq("active", true))), expectedRows: 2, }, { name: "Update with OR IGNORE (no conflict expected)", stmt: Update("users"). Or(UpdateIgnore). Set("name", "Updated Name"). Where(Eq("id", 1)), expectedRows: 1, }, { name: "Update multiple fields", stmt: Update("users"). Sets(map[string]any{ "active": true, "salary": 110000.0, }). Where(Eq("department", "Marketing")), expectedRows: 2, }, { name: "Update with no matching rows", stmt: Update("users"). Set("name", "Non-existent"). Where(Eq("id", 999)), expectedRows: 0, }, }
for _, test := range tests { t.Run(test.name, func(t *testing.T) { db := setupTestDB(t) defer db.Close()
res, err := test.stmt.Exec(db) if err != nil { t.Fatalf("Failed to execute query: %v", err) }
count, err := res.RowsAffected() if err != nil { t.Fatalf("Failed to get rows affected: %v", err) }
if count != test.expectedRows { t.Errorf("Expected %d rows, got %d", test.expectedRows, count) } }) }}