#[macro_export]
macro_rules! op_tests_mod {
( $($target:expr => $level:ident),* ) => {
#[cfg(test)]
pub(crate) mod tests {
const LOG_NOT_LOG_INITIALIZED : usize = 0;
const LOG_INITIALIZING : usize = 1;
const LOG_INITIALIZED : usize = 2;
use ::std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
static FERN_STATE: AtomicUsize = ATOMIC_USIZE_INIT;
fn init_log() {
if FERN_STATE.compare_and_swap(LOG_NOT_LOG_INITIALIZED, LOG_INITIALIZING, Ordering::SeqCst) == LOG_NOT_LOG_INITIALIZED {
const CARGO_PKG_NAME: &str = env!("CARGO_PKG_NAME");
let _ = $crate::fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}][{}:{}] {}",
$crate::chrono::Local::now().format("[%H:%M:%S%.3f]"),
record.level(),
record.target(),
record.file().unwrap(),
record.line().unwrap(),
message
))
}).level($crate::log::LevelFilter::Warn)
.level_for(CARGO_PKG_NAME, $crate::log::LevelFilter::Debug)
.chain(::std::io::stdout())
$(
.level_for($target,$crate::log::LevelFilter::$level)
)*
.apply()
.unwrap();
FERN_STATE.swap(LOG_INITIALIZED, Ordering::SeqCst);
info!("logging has been initialized for {}", CARGO_PKG_NAME);
}
while FERN_STATE.load(Ordering::SeqCst) != LOG_INITIALIZED {
::std::thread::yield_now();
}
}
pub fn run_test<F: FnOnce() -> ()>(name: &str, test: F) {
init_log();
let before = ::std::time::Instant::now();
test();
let after = ::std::time::Instant::now();
info!(
"{}: test run time: {:?}",
name,
after.duration_since(before)
);
}
#[test]
fn compiles() {
run_test("compiles", || info!("it compiles :)"));
}
}
#[cfg(test)]
pub use tests::run_test;
};
}
#[macro_export]
macro_rules! op_test {
(
$(#[$outer:meta])*
$Name:ident $Fn:block
) => {
#[test]
fn $Name() {
::tests::run_test(stringify!($Name), || $Fn);
}
};
}
#[cfg(test)]
mod tests {
use tests::run_test;
#[test]
fn tests_op_test() {
run_test("tests_op_test", || {
info!("tests_op_test passed !!!");
info!(target: "foo", "foo info");
info!(target: "bar", "*** bar info should not be logged ***");
error!(target: "bar", "bar error");
});
}
#[test]
fn test_op_test_fn() {
run_test("test_op_test_fn", test_bar);
}
fn test_bar() {
info!("bar passed !!!")
}
op_test!(bar {test_bar()});
}