63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
use sqlx::migrate::Migrator;
|
|
use sqlx::sqlite::SqlitePoolOptions;
|
|
use sqlx::SqlitePool;
|
|
|
|
static MIGRATOR: Migrator = sqlx::migrate!("./migrations");
|
|
|
|
async fn mem_pool() -> SqlitePool {
|
|
// NOTE: max_connections(1) is required because each :memory: connection
|
|
// creates a separate database
|
|
SqlitePoolOptions::new()
|
|
.max_connections(1)
|
|
.connect("sqlite::memory:")
|
|
.await
|
|
.expect("cannot open in-memory db")
|
|
}
|
|
|
|
async fn user_tables(pool: &SqlitePool) -> Vec<String> {
|
|
sqlx::query_scalar::<_, String>(
|
|
"SELECT name FROM sqlite_master
|
|
WHERE type = 'table'
|
|
AND name NOT LIKE '_sqlx%'
|
|
AND name NOT LIKE 'sqlite_%'
|
|
ORDER BY name",
|
|
)
|
|
.fetch_all(pool)
|
|
.await
|
|
.expect("cannot query sqlite_master")
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn migrations_up() {
|
|
let pool = mem_pool().await;
|
|
MIGRATOR.run(&pool).await.expect("migrations failed");
|
|
|
|
let tables = user_tables(&pool).await;
|
|
assert!(tables.contains(&"todos".to_string()));
|
|
assert!(tables.contains(&"todo_tags".to_string()));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn migrations_down() {
|
|
let pool = mem_pool().await;
|
|
MIGRATOR.run(&pool).await.expect("run failed");
|
|
MIGRATOR.undo(&pool, 0).await.expect("undo failed");
|
|
|
|
let tables = user_tables(&pool).await;
|
|
assert!(tables.is_empty(), "tables should be gone after revert: {tables:?}");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn migrations_round_trip() {
|
|
let pool = mem_pool().await;
|
|
|
|
MIGRATOR.run(&pool).await.expect("first run failed");
|
|
let tables_before = user_tables(&pool).await;
|
|
|
|
MIGRATOR.undo(&pool, 0).await.expect("undo failed");
|
|
MIGRATOR.run(&pool).await.expect("second run failed");
|
|
let tables_after = user_tables(&pool).await;
|
|
|
|
assert_eq!(tables_before, tables_after);
|
|
}
|