package main import ( "context" "database/sql" "errors" "io" "os" "path/filepath" "runtime" "testing" ) func TestRunUp(t *testing.T) { databaseSource := filepath.Join(t.TempDir(), "migrate.db") if err := run(context.Background(), []string{ "-database", databaseSource, "-dir", migrationDirectory(t), "up", }, io.Discard); err != nil { t.Fatalf("run up migration command: %v", err) } database, err := sql.Open("sqlite3", databaseSource) if err != nil { t.Fatalf("open migrated database: %v", err) } t.Cleanup(func() { if err := database.Close(); err != nil { t.Errorf("close migrated database: %v", err) } }) var count int if err := database.QueryRow(`SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'tasks'`).Scan(&count); err != nil { t.Fatalf("look up tasks table: %v", err) } if count != 1 { t.Fatalf("tasks table count = %d, want 1", count) } } func TestRunRequiresDatabase(t *testing.T) { if err := run(context.Background(), []string{"up"}, io.Discard); err == nil { t.Fatal("run without database source succeeded") } } func TestRunRejectsUndeclaredCommand(t *testing.T) { databaseSource := filepath.Join(t.TempDir(), "migrate.db") err := run(context.Background(), []string{"-database", databaseSource, "reset"}, io.Discard) if err == nil { t.Fatal("run with undeclared command succeeded") } if _, err := os.Stat(databaseSource); !errors.Is(err, os.ErrNotExist) { t.Fatalf("undeclared command opened database source: stat error = %v, want not exist", err) } } func migrationDirectory(t *testing.T) string { t.Helper() _, file, _, ok := runtime.Caller(0) if !ok { t.Fatal("locate migration command test source") } return filepath.Join(filepath.Dir(file), "..", "..", "migrations") }