package sqlite import ( "context" "database/sql" "errors" "path/filepath" "testing" ) func TestOpenClose(t *testing.T) { store := openTestDB(t) if store == nil { t.Fatal("Open() returned nil") } } func TestOpenInvalidDSN(t *testing.T) { _, err := Open(context.Background(), "file:/nonexistent/dir/test.db?_pragma=foreign_keys(0)") if err == nil { t.Fatal("Open() with invalid dsn error = nil, want error") } } func TestWithTxCommit(t *testing.T) { store := openTestDB(t) err := store.WithTx(context.Background(), func(q *Queries) error { _, err := q.Hosts.Create(context.Background(), Host{ HostID: "tx-host", BaseURL: "https://tx.com", HostVersion: "1.0", }) return err }) if err != nil { t.Fatalf("WithTx() error = %v", err) } host, err := store.Hosts().GetByHostID(context.Background(), "tx-host") if err != nil { t.Fatalf("GetByHostID() after tx = %v", err) } if host.HostID != "tx-host" { t.Fatalf("host = %+v, want tx-host", host) } } func TestWithTxRollbackOnError(t *testing.T) { store := openTestDB(t) err := store.WithTx(context.Background(), func(q *Queries) error { q.Hosts.Create(context.Background(), Host{ HostID: "rollback-host", BaseURL: "https://r.com", HostVersion: "1.0", }) return errors.New("rollback") }) if err == nil { t.Fatal("WithTx() error = nil, want rollback error") } _, err = store.Hosts().GetByHostID(context.Background(), "rollback-host") if !errors.Is(err, sql.ErrNoRows) { t.Fatalf("GetByHostID() after rollback error = %v, want sql.ErrNoRows", err) } } func TestTableExists(t *testing.T) { store := openTestDB(t) db := store.SQLDB() found, err := tableExists(context.Background(), db, "hosts") if err != nil { t.Fatalf("tableExists('hosts') error = %v", err) } if !found { t.Fatal("tableExists('hosts') = false, want true") } found, err = tableExists(context.Background(), db, "nonexistent") if err != nil { t.Fatalf("tableExists('nonexistent') error = %v", err) } if found { t.Fatal("tableExists('nonexistent') = true, want false") } } func TestDetectLegacy0001Schema(t *testing.T) { store := openTestDB(t) db := store.SQLDB() tx, err := db.BeginTx(context.Background(), nil) if err != nil { t.Fatalf("BeginTx error = %v", err) } defer tx.Rollback() // After migration all three host/packs/providers tables exist, // so detectLegacy0001Schema reports complete=true. complete, partial, err := detectLegacy0001Schema(context.Background(), tx) if err != nil { t.Fatalf("detectLegacy0001Schema() error = %v", err) } if !complete { t.Fatalf("detectLegacy0001Schema() = (complete=%v, partial=%v), want (true, false)", complete, partial) } if partial { t.Fatal("partial should be false when all 3 tables exist") } } func TestWithForeignKeysEnabled(t *testing.T) { if got := withForeignKeysEnabled("file:test.db"); got != "file:test.db?_pragma=foreign_keys(1)" { t.Fatalf("withForeignKeysEnabled no query = %q", got) } if got := withForeignKeysEnabled("file:test.db?a=1"); got != "file:test.db?a=1&_pragma=foreign_keys(1)" { t.Fatalf("withForeignKeysEnabled with query = %q", got) } } func TestSQLDB(t *testing.T) { store := openTestDB(t) db := store.SQLDB() if db == nil { t.Fatal("SQLDB() returned nil") } if err := db.PingContext(context.Background()); err != nil { t.Fatalf("Ping() error = %v", err) } } func TestMigrationFileNames(t *testing.T) { names, err := migrationFileNames() if err != nil { t.Fatalf("migrationFileNames() error = %v", err) } if len(names) == 0 { t.Fatal("migrationFileNames() returned empty") } for _, name := range names { if filepath.Ext(name) != ".sql" { t.Fatalf("migrationFileNames() entry %q not .sql file", name) } } } func TestReadMigration(t *testing.T) { content, err := readMigration("0001_init.sql") if err != nil { t.Fatalf("readMigration('0001_init.sql') error = %v", err) } if len(content) == 0 { t.Fatal("readMigration() returned empty content") } } func TestReadMigrationNotFound(t *testing.T) { _, err := readMigration("nonexistent.sql") if err == nil { t.Fatal("readMigration('nonexistent.sql') error = nil, want error") } }