71 lines
2.4 KiB
Go
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)
|
|
}
|
|
}
|