1use dev_report::{CheckResult, Producer, Report, Severity};
8
9use crate::{MutateRun, MutateThreshold};
10
11pub struct MutateProducer {
31 run: MutateRun,
32 threshold: MutateThreshold,
33}
34
35impl MutateProducer {
36 pub fn new(run: MutateRun, threshold: MutateThreshold) -> Self {
38 Self { run, threshold }
39 }
40}
41
42impl Producer for MutateProducer {
43 fn produce(&self) -> Report {
44 let subject = self.run.subject().to_string();
45 let version = self.run.subject_version().to_string();
46 let mut report = Report::new(&subject, &version).with_producer("dev-mutate");
47 match self.run.execute() {
48 Ok(result) => {
49 report.push(result.into_check_result(self.threshold));
50 }
51 Err(e) => {
52 let check = CheckResult::fail(format!("mutate::{subject}"), Severity::Critical)
53 .with_detail(e.to_string())
54 .with_tag("mutate")
55 .with_tag("subprocess");
56 report.push(check);
57 }
58 }
59 report.finish();
60 report
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 #[ignore = "spawns inner `cargo mutants` which deadlocks on the workspace target-dir lock when run from `cargo test`; run with CARGO_TARGET_DIR outside the workspace via `cargo test -- --ignored`"]
70 fn produce_returns_report_regardless_of_subprocess() {
71 let producer = MutateProducer::new(
73 MutateRun::new("self", "0.0.0"),
74 MutateThreshold::min_kill_pct(70.0),
75 );
76 let report = producer.produce();
77 assert_eq!(report.subject, "self");
78 assert!(!report.checks.is_empty());
79 }
80}