#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![warn(clippy::print_stdout)]
pub use libtest2_harness::Harness;
pub use libtest2_harness::RunError;
pub use libtest2_harness::RunResult;
pub use libtest2_harness::TestContext;
pub use libtest2_harness::TestKind;
pub use libtest2_harness::ERROR_EXIT_CODE;
use libtest2_harness::Case;
use libtest2_harness::Source;
pub struct Trial {
name: String,
#[allow(clippy::type_complexity)]
runner: Box<dyn Fn(&TestContext) -> Result<(), RunError> + Send + Sync>,
}
impl Trial {
pub fn test(
name: impl Into<String>,
runner: impl Fn(&TestContext) -> Result<(), RunError> + Send + Sync + 'static,
) -> Self {
Self {
name: name.into(),
runner: Box::new(runner),
}
}
}
impl Case for Trial {
fn name(&self) -> &str {
&self.name
}
fn kind(&self) -> TestKind {
Default::default()
}
fn source(&self) -> Option<&Source> {
None
}
fn exclusive(&self, _: &TestContext) -> bool {
false
}
fn run(&self, context: &TestContext) -> Result<(), RunError> {
(self.runner)(context)
}
}
#[macro_export]
macro_rules! libtest2_main {
( $( $test:path ),* $(,)*) => {
fn main() {
let harness = $crate::Harness::new();
let harness = match harness.with_env() {
Ok(harness) => harness,
Err(err) => {
eprintln!("{err}");
::std::process::exit(1);
}
};
let harness = match harness.parse() {
Ok(harness) => harness,
Err(err) => {
eprintln!("{err}");
::std::process::exit(1);
}
};
let harness = match harness.discover([
$($crate::Trial::test(::std::stringify!($test), $test)),*
]) {
Ok(harness) => harness,
Err(err) => {
eprintln!("{err}");
::std::process::exit($crate::ERROR_EXIT_CODE)
}
};
match harness.run() {
Ok(true) => ::std::process::exit(0),
Ok(false) => ::std::process::exit($crate::ERROR_EXIT_CODE),
Err(err) => {
eprintln!("{err}");
::std::process::exit($crate::ERROR_EXIT_CODE)
}
}
}
}
}
#[doc = include_str!("../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;