Všechny kontroly byly úspěšné
check / check (push) Successful in 1m8s
Remove the unexported applyMigrations() and the runMigrations() method. ApplyMigrations() is now the single implementation, accepting context and an optional logger. connect() calls it directly. All callers updated to pass context.Background() and nil logger.
156 řádky
3.4 KiB
Go
156 řádky
3.4 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
|
|
_ "modernc.org/sqlite" // SQLite driver registration
|
|
)
|
|
|
|
func TestParseMigrationVersion(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
filename string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "version only",
|
|
filename: "001.sql",
|
|
want: "001",
|
|
},
|
|
{
|
|
name: "version with description",
|
|
filename: "001_initial_schema.sql",
|
|
want: "001",
|
|
},
|
|
{
|
|
name: "multi-digit version",
|
|
filename: "042_add_indexes.sql",
|
|
want: "042",
|
|
},
|
|
{
|
|
name: "long version number",
|
|
filename: "00001_long_prefix.sql",
|
|
want: "00001",
|
|
},
|
|
{
|
|
name: "description with multiple underscores",
|
|
filename: "003_add_user_auth_tables.sql",
|
|
want: "003",
|
|
},
|
|
{
|
|
name: "empty filename",
|
|
filename: ".sql",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "leading underscore",
|
|
filename: "_description.sql",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "non-numeric version",
|
|
filename: "abc_migration.sql",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "mixed alphanumeric version",
|
|
filename: "001a_migration.sql",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := ParseMigrationVersion(tt.filename)
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Errorf("ParseMigrationVersion(%q) expected error, got %q", tt.filename, got)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Errorf("ParseMigrationVersion(%q) unexpected error: %v", tt.filename, err)
|
|
|
|
return
|
|
}
|
|
|
|
if got != tt.want {
|
|
t.Errorf("ParseMigrationVersion(%q) = %q, want %q", tt.filename, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestApplyMigrations(t *testing.T) {
|
|
db, err := sql.Open("sqlite", ":memory:")
|
|
if err != nil {
|
|
t.Fatalf("failed to open in-memory database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Apply migrations should succeed.
|
|
if err := ApplyMigrations(context.Background(), db, nil); err != nil {
|
|
t.Fatalf("ApplyMigrations failed: %v", err)
|
|
}
|
|
|
|
// Verify the schema_migrations table recorded the version.
|
|
var version string
|
|
|
|
err = db.QueryRowContext(context.Background(),
|
|
"SELECT version FROM schema_migrations LIMIT 1",
|
|
).Scan(&version)
|
|
if err != nil {
|
|
t.Fatalf("failed to query schema_migrations: %v", err)
|
|
}
|
|
|
|
if version != "001" {
|
|
t.Errorf("expected version %q, got %q", "001", version)
|
|
}
|
|
|
|
// Verify a table from the migration exists (source_content).
|
|
var tableName string
|
|
|
|
err = db.QueryRowContext(context.Background(),
|
|
"SELECT name FROM sqlite_master WHERE type='table' AND name='source_content'",
|
|
).Scan(&tableName)
|
|
if err != nil {
|
|
t.Fatalf("expected source_content table to exist: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestApplyMigrationsIdempotent(t *testing.T) {
|
|
db, err := sql.Open("sqlite", ":memory:")
|
|
if err != nil {
|
|
t.Fatalf("failed to open in-memory database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Apply twice should succeed (idempotent).
|
|
if err := ApplyMigrations(context.Background(), db, nil); err != nil {
|
|
t.Fatalf("first ApplyMigrations failed: %v", err)
|
|
}
|
|
|
|
if err := ApplyMigrations(context.Background(), db, nil); err != nil {
|
|
t.Fatalf("second ApplyMigrations failed: %v", err)
|
|
}
|
|
|
|
// Should still have exactly one migration recorded.
|
|
var count int
|
|
|
|
err = db.QueryRowContext(context.Background(),
|
|
"SELECT COUNT(*) FROM schema_migrations",
|
|
).Scan(&count)
|
|
if err != nil {
|
|
t.Fatalf("failed to count schema_migrations: %v", err)
|
|
}
|
|
|
|
if count != 1 {
|
|
t.Errorf("expected 1 migration record, got %d", count)
|
|
}
|
|
}
|