新增: 迁移全量测试(覆盖 V1-V37 + 关键表/列/schema_version)

This commit is contained in:
lxy
2026-08-01 12:13:56 +08:00
parent d7e2845881
commit 143b859727
+91
View File
@@ -1820,4 +1820,95 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(v, 27); assert_eq!(v, 27);
} }
// ============================================================
// 全量迁移测试 — 新库从零跑完整 V1-V37 路径
// ------------------------------------------------------------
// 目的:某 migrate_vN 的 SQL 手滑写错(列名/类型/缺索引/缺表)只能等运行时暴露,
// 此测试一次性覆盖全部迁移路径。任何一条迁移 SQL 写错、列名拼错、缺建表
// 都会被这里捕获,不必等到应用启动真机才报错。
// ============================================================
/// 辅助:断言表存在且 PRAGMA table_info 返回的列数 > 0(即表非空、有列定义)。
fn assert_table_has_columns(conn: &Connection, table: &str) {
let count: i64 = conn
.query_row(
&format!("SELECT COUNT(*) FROM pragma_table_info('{}')", table),
[],
|r| r.get(0),
)
.unwrap_or_else(|e| panic!("{} 列信息失败: {}", table, e));
assert!(
count > 0,
"表 {} 应存在且至少 1 列(实际 {} 列)—— 可能 migrate_vN 建表 SQL 写错或被遗漏",
table,
count
);
}
/// 全量迁移:新库从零跑完 V1-V37,验证关键表齐全 + 列数 > 0 + 关键列存在。
///
/// 覆盖至少:task / ai_conversations / ai_messages / ai_tool_executions /
/// conversation_checkpoints / ai_providers / projects / ideas。
/// 抽查关键列:ai_providers.enabled/weight、conversation_checkpoints.snapshot、
/// tasks.idea_id(这些列由不同 vN 加,任一漏加此处失败)。
#[tokio::test]
async fn test_full_migration_on_fresh_db() {
// 用 Database::open_in_memory 打开新库,内部自动跑 migrations::run() 全量迁移
let db = crate::db::Database::open_in_memory()
.await
.expect("新库应能跑完全量迁移");
let conn = db.conn();
let conn = conn.lock().await;
// 1. 关键表存在且列数 > 0
for table in [
"tasks",
"ai_conversations",
"ai_messages",
"ai_tool_executions",
"conversation_checkpoints",
"ai_providers",
"projects",
"ideas",
] {
assert_table_has_columns(&conn, table);
}
// 2. 抽查关键列存在(跨多个 vN 加的列,任一漏加此处失败)
// ai_providers.enabled / weight(V19 ALTER)
assert!(
column_exists(&conn, "ai_providers", "enabled"),
"ai_providers.enabled 列缺失(V19 加)"
);
assert!(
column_exists(&conn, "ai_providers", "weight"),
"ai_providers.weight 列缺失(V19 加)"
);
// conversation_checkpoints.snapshot(V37 建表)
assert!(
column_exists(&conn, "conversation_checkpoints", "snapshot"),
"conversation_checkpoints.snapshot 列缺失(V37 建表)"
);
// tasks.idea_id(V1 建表已带,V20 老库兜底——新库应有)
assert!(
column_exists(&conn, "tasks", "idea_id"),
"tasks.idea_id 列缺失(V1 建表已带)"
);
// 3. schema_version 应推进到 37(全量迁移成功落版本号)
let max_version: i64 = conn
.query_row(
"SELECT COALESCE(MAX(version), 0) FROM schema_version",
[],
|r| r.get(0),
)
.expect("查 schema_version 应成功");
assert_eq!(
max_version, 37,
"全量迁移后 schema_version 应为 37(实际 {}),说明某条 migrate_vN 链路断在中间",
max_version
);
}
} }