35a49174ca
Fase 2 del issue 0015. MigrationCreate (crea archivo .sql template con version auto-calculada), MigrationUp (aplica migraciones pendientes en transacciones individuales), MigrationDown (revierte ultimas N via down_sql de _migrations), MigrationGetStatus (cruza disco con BD, detecta orphaned). Tests de integracion: ciclo completo create->up->status->down->status. 26 tests, todos pasan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package infra
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestMigrationCreate(t *testing.T) {
|
|
t.Run("directorio vacio crea archivo con version 001", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path, err := MigrationCreate(dir, "create_users")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
base := filepath.Base(path)
|
|
if base != "001_create_users.sql" {
|
|
t.Errorf("filename: got %q, want %q", base, "001_create_users.sql")
|
|
}
|
|
|
|
content, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("cannot read created file: %v", err)
|
|
}
|
|
if !strings.Contains(string(content), "-- +up") {
|
|
t.Errorf("file missing -- +up marker")
|
|
}
|
|
if !strings.Contains(string(content), "-- +down") {
|
|
t.Errorf("file missing -- +down marker")
|
|
}
|
|
})
|
|
|
|
t.Run("directorio con migraciones existentes calcula siguiente version", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
// Create existing files
|
|
os.WriteFile(filepath.Join(dir, "001_create_users.sql"), []byte("-- +up\nCREATE TABLE users (id TEXT);\n-- +down\nDROP TABLE users;\n"), 0o644)
|
|
os.WriteFile(filepath.Join(dir, "002_add_email.sql"), []byte("-- +up\nALTER TABLE users ADD COLUMN email TEXT;\n-- +down\n\n"), 0o644)
|
|
|
|
path, err := MigrationCreate(dir, "add_index")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
base := filepath.Base(path)
|
|
if base != "003_add_index.sql" {
|
|
t.Errorf("filename: got %q, want %q", base, "003_add_index.sql")
|
|
}
|
|
})
|
|
|
|
t.Run("nombre invalido retorna error", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
_, err := MigrationCreate(dir, "123invalid")
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid name, got nil")
|
|
}
|
|
})
|
|
|
|
t.Run("directorio inexistente se crea automaticamente", func(t *testing.T) {
|
|
base := t.TempDir()
|
|
dir := filepath.Join(base, "nested", "migrations")
|
|
|
|
path, err := MigrationCreate(dir, "init")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
|
t.Errorf("directory was not created: %s", dir)
|
|
}
|
|
|
|
if filepath.Dir(path) != dir {
|
|
t.Errorf("file not in expected dir: %s", path)
|
|
}
|
|
})
|
|
}
|