use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use u2secure::domain::undo::UndoAction;
use u2secure::infrastructure::rollback;
#[test]
fn test_undo_action_execute() {
let executed = Arc::new(AtomicBool::new(false));
let flag = executed.clone();
let action = UndoAction::new(
"测试撤销".into(),
Box::new(move || {
flag.store(true, Ordering::SeqCst);
}),
);
assert!(!executed.load(Ordering::SeqCst));
action.execute();
assert!(executed.load(Ordering::SeqCst));
}
#[test]
fn test_undo_action_description() {
let action = UndoAction::new("描述文本".into(), Box::new(|| {}));
assert_eq!(action.description, "描述文本");
}
#[test]
fn test_rollback_manager_global_workflow() {
rollback::undo_all();
let flag1 = Arc::new(AtomicBool::new(false));
let flag2 = Arc::new(AtomicBool::new(false));
let f1 = flag1.clone();
let f2 = flag2.clone();
rollback::register_undo(UndoAction::new(
"撤销 1".into(),
Box::new(move || {
f1.store(true, Ordering::SeqCst);
}),
));
rollback::register_undo(UndoAction::new(
"撤销 2".into(),
Box::new(move || {
f2.store(true, Ordering::SeqCst);
}),
));
rollback::undo_all();
assert!(flag2.load(Ordering::SeqCst), "undo2 应先执行(LIFO)");
assert!(flag1.load(Ordering::SeqCst), "undo1 应后执行");
let count = Arc::new(AtomicUsize::new(0));
let c = count.clone();
rollback::register_undo(UndoAction::new(
"计数".into(),
Box::new(move || {
c.fetch_add(1, Ordering::SeqCst);
}),
));
rollback::undo_all();
assert_eq!(count.load(Ordering::SeqCst), 1);
rollback::undo_all(); assert_eq!(count.load(Ordering::SeqCst), 1, "不应重复执行撤销");
let reentry_count = Arc::new(AtomicUsize::new(0));
let rc = reentry_count.clone();
rollback::register_undo(UndoAction::new(
"自旋".into(),
Box::new(move || {
rc.fetch_add(1, Ordering::SeqCst);
rollback::undo_all(); }),
));
rollback::undo_all();
assert_eq!(reentry_count.load(Ordering::SeqCst), 1, "重入应被阻止");
let tmp = tempfile::NamedTempFile::new().expect("创建临时文件失败");
let path = tmp.path().to_str().unwrap().to_string();
let backup_path = format!("{path}.bak");
std::fs::write(&path, "原始内容").unwrap();
std::fs::copy(&path, &backup_path).unwrap();
std::fs::write(&path, "修改后内容").unwrap();
rollback::register_file_backup("恢复测试文件".into(), backup_path.clone(), path.clone());
assert_eq!(std::fs::read_to_string(&path).unwrap(), "修改后内容");
rollback::undo_all();
assert_eq!(
std::fs::read_to_string(&path).unwrap(),
"原始内容",
"文件应被恢复为备份内容"
);
assert!(
!std::path::Path::new(&backup_path).exists(),
"备份文件应在恢复后被删除"
);
let tmp2 = tempfile::NamedTempFile::new().expect("创建临时文件失败");
let path2 = tmp2.path().to_str().unwrap().to_string();
std::fs::write(&path2, "待删除").unwrap();
assert!(std::path::Path::new(&path2).exists());
rollback::register_command_undo(
"删除测试文件".into(),
vec!["rm".into(), "-f".into(), path2.clone()],
);
rollback::undo_all();
assert!(!std::path::Path::new(&path2).exists(), "rm 命令应删除文件");
}