Skip to content

feat(cases): add a boolean flag to return Error in case the binary was not resolved #386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion crates/trycmd/src/cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub struct TestCases {
bins: std::cell::RefCell<crate::BinRegistry>,
substitutions: std::cell::RefCell<snapbox::Redactions>,
has_run: std::cell::Cell<bool>,
fail_unknown_bins: std::cell::Cell<bool>,
}

impl TestCases {
Expand Down Expand Up @@ -169,6 +170,17 @@ impl TestCases {
Ok(self)
}

/// 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 fail_unknown_bins(&self, fail: bool) -> &Self {
self.fail_unknown_bins.set(fail);
self
}

/// Run tests
///
/// This will happen on `drop` if not done explicitly
Expand All @@ -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_unknown_bins(self.fail_unknown_bins.get());
runner.run(&mode, &self.bins.borrow(), &self.substitutions.borrow());
}
}
Expand Down
32 changes: 28 additions & 4 deletions crates/trycmd/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,24 @@ use snapbox::IntoData;
#[derive(Debug)]
pub(crate) struct Runner {
cases: Vec<Case>,
fail_unknown_bins: bool,
}

impl Runner {
pub(crate) fn new() -> Self {
Self {
cases: Default::default(),
fail_unknown_bins: false,
}
}

/// 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
}

pub(crate) fn case(&mut self, case: Case) {
self.cases.push(case);
}
Expand All @@ -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_unknown_bins);

let stderr = stderr();
let mut stderr = stderr.lock();
Expand Down Expand Up @@ -159,6 +168,7 @@ impl Case {
mode: &Mode,
bins: &crate::BinRegistry,
substitutions: &snapbox::Redactions,
fail_unknown_bins: bool,
) -> Vec<Result<Output, Output>> {
if self.expected == Some(crate::schema::CommandStatus::Skipped) {
let output = Output::sequence(self.path.clone());
Expand Down Expand Up @@ -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_unknown_bins,
);
if fs_context.is_mutable() && step_status.is_err() && *mode == Mode::Fail {
prior_step_failed = true;
}
Expand Down Expand Up @@ -324,6 +340,7 @@ impl Case {
cwd: Option<&std::path::Path>,
bins: &crate::BinRegistry,
substitutions: &snapbox::Redactions,
fail_unknown_bins: bool,
) -> Result<Output, Output> {
let output = if let Some(id) = step.id.clone() {
Output::step(self.path.clone(), id)
Expand Down Expand Up @@ -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_unknown_bins {
return Err(output.error(format!("bin={name:?} not found").into()));
}
return Ok(output);
}
Some(crate::schema::Bin::Error(_)) => {}
Expand All @@ -367,6 +388,9 @@ impl Case {
Some(crate::schema::Bin::Ignore) => {
// Unhandled by resolve
assert_eq!(output.spawn.status, SpawnStatus::Skipped);
if fail_unknown_bins {
return Err(output.error("bin not found".into()));
}
return Ok(output);
}
}
Expand Down