pase/store/sqlite/store_test.go
2026-05-06 00:16:39 +00:00

71 lines
2.4 KiB
Go

package sqlite_test
import (
"context"
"database/sql"
"testing"
"git.juancwu.dev/juancwu/pase/store/sqlite"
"git.juancwu.dev/juancwu/pase/store/storetest"
// modernc.org/sqlite registers the "sqlite" driver. Pure Go, no CGO.
// Imported only by tests; the sqlite package itself stays driver-agnostic.
_ "modernc.org/sqlite"
)
// newSQLiteStore opens a fresh in-memory SQLite, applies migrations, and
// returns a Store ready to be exercised by the storetest suite. Each call
// produces an isolated database — no cross-test pollution.
//
// DSN notes:
// - file::memory: form is required so the driver parses query params.
// Plain ":memory:?..." would silently ignore them.
// - _pragma=foreign_keys(1) enables ON DELETE CASCADE on this connection.
// - _time_format=sqlite makes the driver write time.Time as
// "2006-01-02 15:04:05.999999999-07:00", which Go's stdlib can read back
// via sql.NullTime.Scan.
func newSQLiteStore(t *testing.T) storetest.SuiteStore {
t.Helper()
db, err := sql.Open("sqlite", "file::memory:?_pragma=foreign_keys(1)&_time_format=sqlite")
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
t.Cleanup(func() { _ = db.Close() })
// In-memory databases are per-connection by default. Pin the pool to a
// single connection so subsequent calls hit the same database.
db.SetMaxOpenConns(1)
if err := sqlite.Migrate(context.Background(), db); err != nil {
t.Fatalf("migrate: %v", err)
}
return sqlite.NewStore(db)
}
// TestSQLiteStore runs the full Store contract suite against the SQLite
// implementation. Add new dialect-specific tests below; they should be
// rare — anything testable as a contract belongs in storetest.
func TestSQLiteStore(t *testing.T) {
storetest.RunSuite(t, newSQLiteStore)
}
// TestMigrate_idempotent stays here because migrations are dialect-specific
// (per-package embed.FS) and not part of the Store interface contract.
func TestMigrate_idempotent(t *testing.T) {
db, err := sql.Open("sqlite", "file::memory:?_pragma=foreign_keys(1)&_time_format=sqlite")
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
t.Cleanup(func() { _ = db.Close() })
db.SetMaxOpenConns(1)
ctx := context.Background()
if err := sqlite.Migrate(ctx, db); err != nil {
t.Fatalf("first Migrate: %v", err)
}
if err := sqlite.Migrate(ctx, db); err != nil {
t.Fatalf("second Migrate should succeed, got: %v", err)
}
}