Key improvements: - Extract switch_provider_internal() returning AppError for better testability - Fix backup mtime inheritance: use read+write instead of fs::copy to ensure latest backup survives cleanup - Add 15+ integration tests covering provider commands, atomic writes, and rollback scenarios - Expose write_codex_live_atomic, AppState, and test hooks in public API - Extract tests/support.rs with isolated HOME and mutex utilities Test coverage: - Provider switching with live config backfill and MCP sync - Codex atomic write success and failure rollback - Backup retention policy with proper mtime ordering - Negative cases: missing auth field, invalid provider ID
48 lines
1.6 KiB
Rust
48 lines
1.6 KiB
Rust
use std::path::{Path, PathBuf};
|
|
use std::sync::{Mutex, OnceLock};
|
|
|
|
use cc_switch_lib::{update_settings, AppSettings};
|
|
|
|
/// 为测试设置隔离的 HOME 目录,避免污染真实用户数据。
|
|
pub fn ensure_test_home() -> &'static Path {
|
|
static HOME: OnceLock<PathBuf> = OnceLock::new();
|
|
HOME.get_or_init(|| {
|
|
let base = std::env::temp_dir().join("cc-switch-test-home");
|
|
if base.exists() {
|
|
let _ = std::fs::remove_dir_all(&base);
|
|
}
|
|
std::fs::create_dir_all(&base).expect("create test home");
|
|
std::env::set_var("HOME", &base);
|
|
#[cfg(windows)]
|
|
std::env::set_var("USERPROFILE", &base);
|
|
base
|
|
})
|
|
.as_path()
|
|
}
|
|
|
|
/// 清理测试目录中生成的配置文件与缓存。
|
|
pub fn reset_test_fs() {
|
|
let home = ensure_test_home();
|
|
for sub in [".claude", ".codex", ".cc-switch"] {
|
|
let path = home.join(sub);
|
|
if path.exists() {
|
|
if let Err(err) = std::fs::remove_dir_all(&path) {
|
|
eprintln!("failed to clean {}: {}", path.display(), err);
|
|
}
|
|
}
|
|
}
|
|
let claude_json = home.join(".claude.json");
|
|
if claude_json.exists() {
|
|
let _ = std::fs::remove_file(&claude_json);
|
|
}
|
|
|
|
// 重置内存中的设置缓存,确保测试环境不受上一次调用影响
|
|
let _ = update_settings(AppSettings::default());
|
|
}
|
|
|
|
/// 全局互斥锁,避免多测试并发写入相同的 HOME 目录。
|
|
pub fn test_mutex() -> &'static Mutex<()> {
|
|
static MUTEX: OnceLock<Mutex<()>> = OnceLock::new();
|
|
MUTEX.get_or_init(|| Mutex::new(()))
|
|
}
|