package infra import ( "database/sql" "testing" "testing/fstest" _ "github.com/mattn/go-sqlite3" ) // makeFS builds a simple in-memory FS with the given path→content pairs. func makeFS(files map[string]string) fstest.MapFS { m := make(fstest.MapFS, len(files)) for path, content := range files { m[path] = &fstest.MapFile{Data: []byte(content)} } return m } func TestApplyMigrations(t *testing.T) { t.Run("una migracion se aplica correctamente", func(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatal(err) } defer db.Close() fsys := makeFS(map[string]string{ "migrations/001_init.sql": `CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT);`, }) if err := ApplyMigrations(db, fsys, ""); err != nil { t.Fatalf("unexpected error: %v", err) } // Verify table exists. var count int if err := db.QueryRow(`SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='items'`).Scan(&count); err != nil { t.Fatal(err) } if count != 1 { t.Errorf("table 'items' not created; count=%d", count) } }) t.Run("multiples migraciones en orden", func(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatal(err) } defer db.Close() fsys := makeFS(map[string]string{ "migrations/001_init.sql": `CREATE TABLE IF NOT EXISTS t (id INTEGER PRIMARY KEY);`, "migrations/002_add_column.sql": `ALTER TABLE t ADD COLUMN val TEXT;`, }) if err := ApplyMigrations(db, fsys, ""); err != nil { t.Fatalf("unexpected error: %v", err) } // Insert using the new column. if _, err := db.Exec(`INSERT INTO t (id, val) VALUES (1, 'hello')`); err != nil { t.Fatalf("insert failed (column may be missing): %v", err) } }) t.Run("error real se propaga", func(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatal(err) } defer db.Close() fsys := makeFS(map[string]string{ "migrations/001_bad.sql": `THIS IS NOT VALID SQL;`, }) if err := ApplyMigrations(db, fsys, ""); err == nil { t.Errorf("expected error for invalid SQL, got nil") } }) t.Run("ALTER TABLE ADD COLUMN duplicado se ignora", func(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatal(err) } defer db.Close() setup := `CREATE TABLE IF NOT EXISTS t (id INTEGER PRIMARY KEY, val TEXT);` if _, err := db.Exec(setup); err != nil { t.Fatal(err) } // Run ALTER that would fail with "duplicate column". fsys := makeFS(map[string]string{ "migrations/001_dup.sql": `ALTER TABLE t ADD COLUMN val TEXT;`, }) if err := ApplyMigrations(db, fsys, ""); err != nil { t.Errorf("duplicate column error should be ignored, got: %v", err) } }) }