use std::path::{Path, PathBuf};
use std::{env, fs};
#[macro_export]
macro_rules! unique_test_name {
() => {{
fn f() {}
fn type_name_of<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
let name = type_name_of(f);
format!(
"{}_l{}_pid{}",
name[..name.len() - 3]
.replace("::{{closure}}", "")
.replace(':', "_"),
line!(),
std::process::id()
)
}};
}
#[allow(unused_imports)]
pub(crate) use unique_test_name;
pub struct ChangeDir {
original_dir: PathBuf,
}
impl ChangeDir {
pub fn new(path: &Path) -> Self {
let original_dir = env::current_dir().unwrap();
env::set_current_dir(path).unwrap();
Self { original_dir }
}
}
impl Drop for ChangeDir {
fn drop(&mut self) {
env::set_current_dir(&self.original_dir).unwrap();
}
}
#[macro_export]
macro_rules! new_tmp_dir {
() => {{
$crate::test_utils::TempDir::with_dir(
std::path::Path::new(".tmp").join($crate::test_utils::unique_test_name!()),
)
}};
}
pub struct TempDir {
dir: PathBuf,
}
impl TempDir {
pub fn with_dir(dir: PathBuf) -> Self {
fs::create_dir_all(&dir).unwrap();
Self { dir }
}
pub fn dir(&self) -> &PathBuf {
&self.dir
}
pub fn join(&self, path: &str) -> PathBuf {
self.dir.join(path)
}
pub fn join_and_create_parent(&self, path: &str) -> PathBuf {
let child = self.dir.join(path);
fs::create_dir_all(child.parent().unwrap()).unwrap();
child
}
pub fn join_and_write_file(&self, path: &str, contents: &str) -> PathBuf {
let child = self.dir.join(path);
fs::create_dir_all(child.parent().unwrap()).unwrap();
fs::write(&child, contents).unwrap();
child
}
}
impl Drop for TempDir {
fn drop(&mut self) {
fs::remove_dir_all(&self.dir).ok();
}
}