From eef07874c5fb4d94e84f59bb50e1d0505b7c9513 Mon Sep 17 00:00:00 2001 From: veeso Date: Tue, 22 Apr 2025 12:28:08 +0200 Subject: [PATCH 1/2] feat(cases): Boolean flag to return Err for bin not found --- crates/trycmd/src/cases.rs | 18 +++++++++++++++++- crates/trycmd/src/runner.rs | 32 ++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/crates/trycmd/src/cases.rs b/crates/trycmd/src/cases.rs index 273309fb..542dc35f 100644 --- a/crates/trycmd/src/cases.rs +++ b/crates/trycmd/src/cases.rs @@ -7,6 +7,7 @@ pub struct TestCases { bins: std::cell::RefCell, substitutions: std::cell::RefCell, has_run: std::cell::Cell, + fail_on_unresolved_bin: std::cell::Cell, } impl TestCases { @@ -169,6 +170,17 @@ impl TestCases { Ok(self) } + /// Set rule to whether to fail on unresolved bin. + /// + /// If this flag is set to `true`, the test will fail if a bin cannot be resolved. + /// By default, this is set to `false`. + /// + /// When set to `false`, the test will not fail if a bin cannot be resolved, but the case will just be ignored. + pub fn set_fail_on_unresolved_bin(&self, fail: bool) -> &Self { + self.fail_on_unresolved_bin.set(fail); + self + } + /// Run tests /// /// This will happen on `drop` if not done explicitly @@ -178,7 +190,11 @@ impl TestCases { let mode = parse_mode(std::env::var_os("TRYCMD").as_deref()); mode.initialize().unwrap(); - let runner = self.runner.borrow_mut().prepare(); + let runner = self + .runner + .borrow_mut() + .prepare() + .fail_on_unresolved_bin(self.fail_on_unresolved_bin.get()); runner.run(&mode, &self.bins.borrow(), &self.substitutions.borrow()); } } diff --git a/crates/trycmd/src/runner.rs b/crates/trycmd/src/runner.rs index b9815f17..d96f99a8 100644 --- a/crates/trycmd/src/runner.rs +++ b/crates/trycmd/src/runner.rs @@ -20,15 +20,24 @@ use snapbox::IntoData; #[derive(Debug)] pub(crate) struct Runner { cases: Vec, + fail_on_unresolved_bin: bool, } impl Runner { pub(crate) fn new() -> Self { Self { cases: Default::default(), + fail_on_unresolved_bin: false, } } + /// Set the rule value for `fail_on_unresolved_bin` + pub(crate) fn fail_on_unresolved_bin(mut self, fail: bool) -> Self { + self.fail_on_unresolved_bin = fail; + + self + } + pub(crate) fn case(&mut self, case: Case) { self.cases.push(case); } @@ -49,7 +58,7 @@ impl Runner { .cases .par_iter() .flat_map(|c| { - let results = c.run(mode, bins, substitutions); + let results = c.run(mode, bins, substitutions, self.fail_on_unresolved_bin); let stderr = stderr(); let mut stderr = stderr.lock(); @@ -159,6 +168,7 @@ impl Case { mode: &Mode, bins: &crate::BinRegistry, substitutions: &snapbox::Redactions, + fail_on_unresolved_bin: bool, ) -> Vec> { if self.expected == Some(crate::schema::CommandStatus::Skipped) { let output = Output::sequence(self.path.clone()); @@ -235,7 +245,13 @@ impl Case { step.expected_status = Some(crate::schema::CommandStatus::Skipped); } - let step_status = self.run_step(step, cwd.as_deref(), bins, &substitutions); + let step_status = self.run_step( + step, + cwd.as_deref(), + bins, + &substitutions, + fail_on_unresolved_bin, + ); if fs_context.is_mutable() && step_status.is_err() && *mode == Mode::Fail { prior_step_failed = true; } @@ -324,6 +340,7 @@ impl Case { cwd: Option<&std::path::Path>, bins: &crate::BinRegistry, substitutions: &snapbox::Redactions, + fail_on_unresolved_bin: bool, ) -> Result { let output = if let Some(id) = step.id.clone() { Output::step(self.path.clone(), id) @@ -355,10 +372,14 @@ impl Case { match &step.bin { Some(crate::schema::Bin::Path(_)) => {} - Some(crate::schema::Bin::Name(_name)) => { + Some(crate::schema::Bin::Name(name)) => { // Unhandled by resolve - snapbox::debug!("bin={:?} not found", _name); + snapbox::debug!("bin={:?} not found", name); assert_eq!(output.spawn.status, SpawnStatus::Skipped); + + if fail_on_unresolved_bin { + return Err(output.error(format!("bin={name:?} not found").into())); + } return Ok(output); } Some(crate::schema::Bin::Error(_)) => {} @@ -367,6 +388,9 @@ impl Case { Some(crate::schema::Bin::Ignore) => { // Unhandled by resolve assert_eq!(output.spawn.status, SpawnStatus::Skipped); + if fail_on_unresolved_bin { + return Err(output.error("bin not found".into())); + } return Ok(output); } } From b5e004c04f376f469e4a9244c99499cbb23c34d2 Mon Sep 17 00:00:00 2001 From: veeso Date: Thu, 24 Apr 2025 11:19:24 +0200 Subject: [PATCH 2/2] style: Renamed fail_on_unresolved_bin to fail_unknown_bins --- crates/trycmd/src/cases.rs | 10 +++++----- crates/trycmd/src/runner.rs | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/crates/trycmd/src/cases.rs b/crates/trycmd/src/cases.rs index 542dc35f..6ed07396 100644 --- a/crates/trycmd/src/cases.rs +++ b/crates/trycmd/src/cases.rs @@ -7,7 +7,7 @@ pub struct TestCases { bins: std::cell::RefCell, substitutions: std::cell::RefCell, has_run: std::cell::Cell, - fail_on_unresolved_bin: std::cell::Cell, + fail_unknown_bins: std::cell::Cell, } impl TestCases { @@ -170,14 +170,14 @@ impl TestCases { Ok(self) } - /// Set rule to whether to fail on unresolved bin. + /// Set whether to fail on unknown binaries. /// /// If this flag is set to `true`, the test will fail if a bin cannot be resolved. /// By default, this is set to `false`. /// /// When set to `false`, the test will not fail if a bin cannot be resolved, but the case will just be ignored. - pub fn set_fail_on_unresolved_bin(&self, fail: bool) -> &Self { - self.fail_on_unresolved_bin.set(fail); + pub fn fail_unknown_bins(&self, fail: bool) -> &Self { + self.fail_unknown_bins.set(fail); self } @@ -194,7 +194,7 @@ impl TestCases { .runner .borrow_mut() .prepare() - .fail_on_unresolved_bin(self.fail_on_unresolved_bin.get()); + .fail_unknown_bins(self.fail_unknown_bins.get()); runner.run(&mode, &self.bins.borrow(), &self.substitutions.borrow()); } } diff --git a/crates/trycmd/src/runner.rs b/crates/trycmd/src/runner.rs index d96f99a8..ca918621 100644 --- a/crates/trycmd/src/runner.rs +++ b/crates/trycmd/src/runner.rs @@ -20,20 +20,20 @@ use snapbox::IntoData; #[derive(Debug)] pub(crate) struct Runner { cases: Vec, - fail_on_unresolved_bin: bool, + fail_unknown_bins: bool, } impl Runner { pub(crate) fn new() -> Self { Self { cases: Default::default(), - fail_on_unresolved_bin: false, + fail_unknown_bins: false, } } - /// Set the rule value for `fail_on_unresolved_bin` - pub(crate) fn fail_on_unresolved_bin(mut self, fail: bool) -> Self { - self.fail_on_unresolved_bin = fail; + /// Set the rule value for `fail_unknown_bins` + pub(crate) fn fail_unknown_bins(mut self, fail: bool) -> Self { + self.fail_unknown_bins = fail; self } @@ -58,7 +58,7 @@ impl Runner { .cases .par_iter() .flat_map(|c| { - let results = c.run(mode, bins, substitutions, self.fail_on_unresolved_bin); + let results = c.run(mode, bins, substitutions, self.fail_unknown_bins); let stderr = stderr(); let mut stderr = stderr.lock(); @@ -168,7 +168,7 @@ impl Case { mode: &Mode, bins: &crate::BinRegistry, substitutions: &snapbox::Redactions, - fail_on_unresolved_bin: bool, + fail_unknown_bins: bool, ) -> Vec> { if self.expected == Some(crate::schema::CommandStatus::Skipped) { let output = Output::sequence(self.path.clone()); @@ -250,7 +250,7 @@ impl Case { cwd.as_deref(), bins, &substitutions, - fail_on_unresolved_bin, + fail_unknown_bins, ); if fs_context.is_mutable() && step_status.is_err() && *mode == Mode::Fail { prior_step_failed = true; @@ -340,7 +340,7 @@ impl Case { cwd: Option<&std::path::Path>, bins: &crate::BinRegistry, substitutions: &snapbox::Redactions, - fail_on_unresolved_bin: bool, + fail_unknown_bins: bool, ) -> Result { let output = if let Some(id) = step.id.clone() { Output::step(self.path.clone(), id) @@ -377,7 +377,7 @@ impl Case { snapbox::debug!("bin={:?} not found", name); assert_eq!(output.spawn.status, SpawnStatus::Skipped); - if fail_on_unresolved_bin { + if fail_unknown_bins { return Err(output.error(format!("bin={name:?} not found").into())); } return Ok(output); @@ -388,7 +388,7 @@ impl Case { Some(crate::schema::Bin::Ignore) => { // Unhandled by resolve assert_eq!(output.spawn.status, SpawnStatus::Skipped); - if fail_on_unresolved_bin { + if fail_unknown_bins { return Err(output.error("bin not found".into())); } return Ok(output);