//! Tests! use std::sync::{Arc, Mutex}; use log::{debug, error, info, trace, warn}; /// Custom logger built to verify our exact test case. struct LogVerify { info: bool, warn: bool, error: bool, } impl LogVerify { fn new() -> Self { LogVerify { info: false, warn: false, error: false, } } fn log(&mut self, record: &log::Record) { let formatted_message = format!("{}", record.args()); match &*formatted_message { "[INFO] Test information message" => { assert!(!self.info, "expected only one info message"); self.info = true; } "[WARN] Test warning message" => { assert!(!self.warn, "expected only one warn message"); self.warn = true; } "[ERROR] Test error message" => { assert!(!self.error, "expected only one error message"); self.error = true; } other => panic!("unexpected message: '{}'", other), } } } /// Wrapper for our verification which acts as the actual logger. #[derive(Clone)] struct LogVerifyWrapper(Arc>); impl LogVerifyWrapper { fn new() -> Self { LogVerifyWrapper(Arc::new(Mutex::new(LogVerify::new()))) } fn cloned_boxed_logger(&self) -> Box { Box::new(self.clone()) } } impl log::Log for LogVerifyWrapper { fn enabled(&self, _: &log::Metadata) -> bool { true } fn log(&self, record: &log::Record) { self.0.lock().unwrap().log(record); } fn flush(&self) {} } #[test] fn test_global_logger() { let verify = LogVerifyWrapper::new(); // Create a basic logger configuration fern::Dispatch::new() .format(|out, msg, record| out.finish(format_args!("[{}] {}", record.level(), msg))) // Only log messages Info and above .level(log::LevelFilter::Info) // Output to our verification logger for verification .chain(verify.cloned_boxed_logger()) .apply() .expect("Failed to initialize logger: global logger already set!"); trace!("SHOULD NOT DISPLAY"); debug!("SHOULD NOT DISPLAY"); info!("Test information message"); warn!("Test warning message"); error!("Test error message"); // ensure all buffers are flushed. log::logger().flush(); let verify_acquired = verify.0.lock().unwrap(); assert!(verify_acquired.info, "expected info message to be received"); assert!(verify_acquired.warn, "expected warn message to be received"); assert!( verify_acquired.error, "expected error message to be received" ); }