#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]
#![warn(rust_2018_idioms)]
pub use dev_report as report;
#[cfg(feature = "fixtures")]
#[cfg_attr(docsrs, doc(cfg(feature = "fixtures")))]
pub use dev_fixtures as fixtures;
#[cfg(feature = "bench")]
#[cfg_attr(docsrs, doc(cfg(feature = "bench")))]
pub use dev_bench as bench;
#[cfg(feature = "async")]
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
pub use dev_async as r#async;
#[cfg(feature = "stress")]
#[cfg_attr(docsrs, doc(cfg(feature = "stress")))]
pub use dev_stress as stress;
#[cfg(feature = "chaos")]
#[cfg_attr(docsrs, doc(cfg(feature = "chaos")))]
pub use dev_chaos as chaos;
#[macro_export]
macro_rules! full_run {
($subject:expr, $version:expr; $($producer:expr),* $(,)?) => {{
let mut multi = $crate::report::MultiReport::new($subject, $version);
$(
multi.push(<_ as $crate::report::Producer>::produce(&$producer));
)*
multi.finish();
multi
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn report_module_is_always_available() {
let r = report::Report::new("self", "0.1.0");
assert_eq!(r.subject, "self");
}
#[cfg(feature = "fixtures")]
#[test]
fn fixtures_module_is_available_with_feature() {
let _ = fixtures::TempProject::new();
}
#[cfg(feature = "bench")]
#[test]
fn bench_module_is_available_with_feature() {
let _ = bench::Benchmark::new("x");
}
#[test]
fn full_run_combines_zero_producers() {
let multi = full_run!("crate", "0.1.0";);
assert_eq!(multi.reports.len(), 0);
assert_eq!(multi.overall_verdict(), report::Verdict::Skip);
}
#[test]
fn full_run_combines_two_producers() {
struct OkProducer(&'static str);
impl report::Producer for OkProducer {
fn produce(&self) -> report::Report {
let mut r = report::Report::new("c", "0.1.0").with_producer(self.0);
r.push(report::CheckResult::pass("x"));
r.finish();
r
}
}
let multi = full_run!("c", "0.1.0"; OkProducer("a"), OkProducer("b"));
assert_eq!(multi.reports.len(), 2);
assert_eq!(multi.overall_verdict(), report::Verdict::Pass);
}
#[test]
fn full_run_propagates_failures() {
struct OkProducer;
impl report::Producer for OkProducer {
fn produce(&self) -> report::Report {
let mut r = report::Report::new("c", "0.1.0").with_producer("ok");
r.push(report::CheckResult::pass("x"));
r.finish();
r
}
}
struct FailProducer;
impl report::Producer for FailProducer {
fn produce(&self) -> report::Report {
let mut r = report::Report::new("c", "0.1.0").with_producer("fail");
r.push(report::CheckResult::fail("y", report::Severity::Error));
r.finish();
r
}
}
let multi = full_run!("c", "0.1.0"; OkProducer, FailProducer);
assert_eq!(multi.overall_verdict(), report::Verdict::Fail);
}
#[cfg(all(feature = "fixtures", feature = "bench"))]
#[test]
fn full_run_with_real_producers() {
let fixture_producer =
fixtures::FixtureProducer::new("temp_project_lifecycle", "0.1.0", || {
let _p = fixtures::TempProject::new()
.with_file("README.md", "hi")
.build()?;
Ok(())
});
let bench_producer = bench::BenchProducer::new(
|| {
let mut b = bench::Benchmark::new("hot");
for _ in 0..5 {
b.iter(|| std::hint::black_box(1 + 1));
}
b.finish()
},
"0.1.0",
None,
bench::Threshold::regression_pct(20.0),
);
let multi = full_run!("crate", "0.1.0"; fixture_producer, bench_producer);
assert_eq!(multi.reports.len(), 2);
}
}