test: add migration tests

This commit is contained in:
2026-02-28 12:27:58 +01:00
parent 428d3b41cf
commit 7ef93a30f5

62
tests/migrations.rs Normal file
View File

@@ -0,0 +1,62 @@
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);
}