go-migrate/sqlx_test.go
2023-01-18 14:15:48 -03:00

175 lines
4.7 KiB
Go

package migrate_test
import (
"database/sql"
"fmt"
"testing"
"gitea.nulo.in/Nulo/go-migrate"
_ "github.com/mattn/go-sqlite3"
)
func sqliteInMem(t *testing.T) *sql.DB {
db, err := sql.Open("sqlite3", fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name()))
if err != nil {
t.Fatalf("Open() err = %v; want nil", err)
}
t.Cleanup(func() {
err = db.Close()
if err != nil {
t.Errorf("Close() err = %v; want nil", err)
}
})
return db
}
// TODO: Add more exhaustive testing. Perhaps try different dialects? Good enough for now tho.
func TestSqlx(t *testing.T) {
t.Run("simple", func(t *testing.T) {
db := sqliteInMem(t)
migrator := migrate.Sqlx{
Printf: func(format string, args ...interface{}) (int, error) {
t.Logf(format, args...)
return 0, nil
},
Migrations: []migrate.SqlxMigration{
migrate.SqlxQueryMigration("001_create_courses", createCoursesSql, ""),
},
}
err := migrator.Migrate(db, "sqlite3")
if err != nil {
t.Fatalf("Migrate() err = %v; want nil", err)
}
_, err = db.Exec("INSERT INTO courses (name) VALUES ($1) ", "cor_test")
if err != nil {
t.Fatalf("db.Exec() err = %v; want nil", err)
}
})
t.Run("existing migrations", func(t *testing.T) {
db := sqliteInMem(t)
migrator := migrate.Sqlx{
Printf: func(format string, args ...interface{}) (int, error) {
t.Logf(format, args...)
return 0, nil
},
Migrations: []migrate.SqlxMigration{
migrate.SqlxQueryMigration("001_create_courses", createCoursesSql, ""),
},
}
err := migrator.Migrate(db, "sqlite3")
if err != nil {
t.Fatalf("Migrate() err = %v; want nil", err)
}
_, err = db.Exec("INSERT INTO courses (name) VALUES ($1) ", "cor_test")
if err != nil {
t.Fatalf("db.Exec() err = %v; want nil", err)
}
// the real test
migrator = migrate.Sqlx{
Printf: func(format string, args ...interface{}) (int, error) {
t.Logf(format, args...)
return 0, nil
},
Migrations: []migrate.SqlxMigration{
migrate.SqlxQueryMigration("001_create_courses", createCoursesSql, ""),
migrate.SqlxQueryMigration("002_create_users", createUsersSql, ""),
},
}
err = migrator.Migrate(db, "sqlite3")
if err != nil {
t.Fatalf("Migrate() err = %v; want nil", err)
}
_, err = db.Exec("INSERT INTO users (email) VALUES ($1) ", "abc@test.com")
if err != nil {
t.Fatalf("db.Exec() err = %v; want nil", err)
}
})
t.Run("file", func(t *testing.T) {
db := sqliteInMem(t)
migrator := migrate.Sqlx{
Printf: func(format string, args ...interface{}) (int, error) {
t.Logf(format, args...)
return 0, nil
},
Migrations: []migrate.SqlxMigration{
migrate.SqlxFileMigration("001_create_widgets", "testdata/widgets.sql", ""),
},
}
err := migrator.Migrate(db, "sqlite3")
if err != nil {
t.Fatalf("Migrate() err = %v; want nil", err)
}
_, err = db.Exec("INSERT INTO widgets (color, price) VALUES ($1, $2)", "red", 1200)
if err != nil {
t.Fatalf("db.Exec() err = %v; want nil", err)
}
})
t.Run("rollback", func(t *testing.T) {
db := sqliteInMem(t)
migrator := migrate.Sqlx{
Printf: func(format string, args ...interface{}) (int, error) {
t.Logf(format, args...)
return 0, nil
},
Migrations: []migrate.SqlxMigration{
migrate.SqlxQueryMigration("001_create_courses", createCoursesSql, dropCoursesSql),
},
}
err := migrator.Migrate(db, "sqlite3")
if err != nil {
t.Fatalf("Migrate() err = %v; want nil", err)
}
_, err = db.Exec("INSERT INTO courses (name) VALUES ($1) ", "cor_test")
if err != nil {
t.Fatalf("db.Exec() err = %v; want nil", err)
}
err = migrator.Rollback(db, "sqlite3")
if err != nil {
t.Fatalf("Rollback() err = %v; want nil", err)
}
var count int
err = db.QueryRow("SELECT COUNT(id) FROM courses;").Scan(&count)
if err == nil {
// Want an error here
t.Fatalf("db.QueryRow() err = nil; want table missing error")
}
// Don't want to test inner workings of lib, so let's just migrate again and verify we have a table now
err = migrator.Migrate(db, "sqlite3")
if err != nil {
t.Fatalf("Migrate() err = %v; want nil", err)
}
_, err = db.Exec("INSERT INTO courses (name) VALUES ($1) ", "cor_test")
if err != nil {
t.Fatalf("db.Exec() err = %v; want nil", err)
}
err = db.QueryRow("SELECT COUNT(*) FROM courses;").Scan(&count)
if err != nil {
// Want an error here
t.Fatalf("db.QueryRow() err = %v; want nil", err)
}
if count != 1 {
t.Fatalf("count = %d; want %d", count, 1)
}
})
}
var (
createCoursesSql = `
CREATE TABLE courses (
id serial PRIMARY KEY,
name text
);`
dropCoursesSql = `DROP TABLE courses;`
createUsersSql = `
CREATE TABLE users (
id serial PRIMARY KEY,
email text UNIQUE NOT NULL
);`
dropUsersSql = `DROP TABLE users;`
)