pub fn lock_env_tests() -> std::sync::MutexGuard<'static, ()> {
crate::diff_tool::TEST_MUTEX
.get_or_init(|| std::sync::Mutex::new(()))
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
pub struct RedirectedConfigDir {
_dir: tempfile::TempDir,
old_xdg: Option<String>,
old_home: Option<String>,
old_userprofile: Option<String>,
}
impl RedirectedConfigDir {
pub fn new() -> Self {
let dir = tempfile::tempdir().unwrap();
let old_xdg = std::env::var("XDG_CONFIG_HOME").ok();
let old_home = std::env::var("HOME").ok();
let old_userprofile = std::env::var("USERPROFILE").ok();
unsafe {
std::env::set_var("XDG_CONFIG_HOME", dir.path());
std::env::set_var("HOME", dir.path());
std::env::set_var("USERPROFILE", dir.path());
}
let seed = crate::settings::AppSettings {
external_diff_tool: Some("vim".to_string()),
check_updates: false,
mouse: false,
theme: crate::theme::ThemeChoice::Light,
diff_context: 7,
};
let config_dir = dir.path().join("duodiff");
std::fs::create_dir_all(&config_dir).unwrap();
std::fs::write(
config_dir.join("config.toml"),
toml::to_string(&seed).unwrap(),
)
.unwrap();
Self {
_dir: dir,
old_xdg,
old_home,
old_userprofile,
}
}
}
impl Default for RedirectedConfigDir {
fn default() -> Self {
Self::new()
}
}
impl Drop for RedirectedConfigDir {
fn drop(&mut self) {
unsafe {
match &self.old_xdg {
Some(v) => std::env::set_var("XDG_CONFIG_HOME", v),
None => std::env::remove_var("XDG_CONFIG_HOME"),
}
match &self.old_home {
Some(v) => std::env::set_var("HOME", v),
None => std::env::remove_var("HOME"),
}
match &self.old_userprofile {
Some(v) => std::env::set_var("USERPROFILE", v),
None => std::env::remove_var("USERPROFILE"),
}
}
}
}
pub struct ConfigEnvGuard {
_redirect: RedirectedConfigDir,
_lock: std::sync::MutexGuard<'static, ()>,
}
impl ConfigEnvGuard {
pub fn new() -> Self {
let lock = lock_env_tests();
let redirect = RedirectedConfigDir::new();
Self {
_redirect: redirect,
_lock: lock,
}
}
}
impl Default for ConfigEnvGuard {
fn default() -> Self {
Self::new()
}
}
pub struct RecordingTerminalHandoff {
log: std::rc::Rc<std::cell::RefCell<Vec<&'static str>>>,
}
impl RecordingTerminalHandoff {
pub fn new(log: std::rc::Rc<std::cell::RefCell<Vec<&'static str>>>) -> Self {
log.borrow_mut().push("suspend");
Self { log }
}
}
impl Drop for RecordingTerminalHandoff {
fn drop(&mut self) {
self.log.borrow_mut().push("resume");
}
}