#![warn(missing_docs)]
#![warn(clippy::std_instead_of_core)]
#![warn(clippy::std_instead_of_alloc)]
#![forbid(unsafe_code)]
#![doc = include_str!("../readme-footer.md")]
pub use facet_testhelpers_macros::test;
use std::sync::LazyLock;
use std::time::Instant;
use tracing_subscriber::filter::Targets;
use tracing_subscriber::fmt::format::Writer;
use tracing_subscriber::fmt::time::FormatTime;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
static START_TIME: LazyLock<Instant> = LazyLock::new(Instant::now);
struct Uptime;
impl FormatTime for Uptime {
fn format_time(&self, w: &mut Writer<'_>) -> core::fmt::Result {
let elapsed = START_TIME.elapsed();
let secs = elapsed.as_secs();
let millis = elapsed.subsec_millis();
write!(w, "{:4}.{:03}s", secs, millis)
}
}
static SUBSCRIBER_INIT: LazyLock<()> = LazyLock::new(|| {
let _ = *START_TIME;
let verbosity = color_backtrace::Verbosity::Medium;
color_backtrace::BacktracePrinter::new()
.verbosity(verbosity)
.add_frame_filter(Box::new(|frames| {
frames.retain(|frame| {
let dominated_by_noise = |name: &str| {
name.starts_with("test::run_test")
|| name.starts_with("test::__rust_begin_short_backtrace")
|| name.starts_with("std::panicking::")
|| name.starts_with("std::panic::")
|| name.starts_with("core::panicking::")
|| name.starts_with("std::thread::Builder::spawn_unchecked_")
|| name.starts_with("std::sys::thread::")
|| name.starts_with("std::sys::backtrace::")
|| name.starts_with("core::ops::function::FnOnce::call_once")
|| name.starts_with("<alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once")
|| name.starts_with("<core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once")
|| name.starts_with("__pthread")
};
match &frame.name {
Some(name) => !dominated_by_noise(name),
None => true,
}
})
}))
.install(Box::new(termcolor::StandardStream::stderr(
termcolor::ColorChoice::AlwaysAnsi,
)));
let filter = std::env::var("FACET_LOG")
.ok()
.and_then(|s| s.parse::<Targets>().ok())
.unwrap_or_else(|| {
eprintln!("Assuming FACET_LOG=debug (feel free to set the $FACET_LOG env var to override tracing filters) (note: $RUST_LOG doesn't do anything)");
Targets::new().with_default(tracing::Level::DEBUG)
});
fn is_set_to_1(key: &str) -> bool {
match std::env::var(key) {
Ok(val) => val == "1",
Err(_) => false,
}
}
let is_verbose = is_set_to_1("FACET_LOG_VERBOSE");
if !is_verbose {
eprintln!(
"You can set FACET_LOG_VERBOSE=1 to see targets, files and line numbers for each tracing message"
);
}
tracing_subscriber::registry()
.with(
tracing_subscriber::fmt::layer()
.with_ansi(true)
.with_timer(Uptime)
.with_target(false)
.with_level(true)
.with_file(is_verbose)
.with_line_number(is_verbose)
.compact(),
)
.with(filter)
.try_init()
.ok();
});
pub fn setup() {
let is_nextest = std::env::var("NEXTEST").as_deref() == Ok("1");
if !is_nextest {
static NEXTEST_WARNING: LazyLock<()> = LazyLock::new(|| {
eprintln!(
"💡 Tip: Consider using `cargo nextest run` for better test output and performance."
);
eprintln!(" Install with: cargo install cargo-nextest");
eprintln!(" More info: https://nexte.st");
eprintln!();
});
#[allow(clippy::let_unit_value)]
let _ = *NEXTEST_WARNING;
}
#[allow(clippy::let_unit_value)]
let _ = *SUBSCRIBER_INIT;
}
#[derive(Debug)]
pub struct IPanic;
impl<E> From<E> for IPanic
where
E: core::error::Error + Send + Sync,
{
#[track_caller]
fn from(value: E) -> Self {
panic!("from: {}: {value}", core::panic::Location::caller())
}
}