Skip to content

Commit

Permalink
Bring back the scenario filter cli option
Browse files Browse the repository at this point in the history
Fixes: #67
  • Loading branch information
mullr authored and bbqsrc committed Oct 19, 2020
1 parent 70d91c7 commit 82eaf76
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ thiserror = "1.0.20"
termcolor = "1.1.0"
textwrap = { version = "0.12.1", features = ["terminal_size"] }
pathdiff = "0.2.0"
clap = "2.33"

[[test]]
name = "cucumber_builder"
Expand Down
36 changes: 36 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use clap::{App, Arg};

#[derive(Default)]
pub struct CliOptions {
pub scenario_filter: Option<String>,
pub nocapture: bool,
}

pub fn make_app() -> CliOptions {
let matches = App::new("cucumber")
.version(env!("CARGO_PKG_VERSION"))
.author("Brendan Molloy <[email protected]>")
.about("Run the tests, pet a dog!")
.arg(
Arg::with_name("filter")
.short("e")
.long("expression")
.value_name("regex")
.help("Regex to select scenarios from")
.takes_value(true),
)
.arg(
Arg::with_name("nocapture")
.long("nocapture")
.help("Use this flag to disable suppression of output from tests"),
)
.get_matches();

let nocapture = matches.is_present("nocapture");
let scenario_filter = matches.value_of("filter").map(|v| v.to_string());

CliOptions {
nocapture,
scenario_filter,
}
}
31 changes: 31 additions & 0 deletions src/cucumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// except according to those terms.

use futures::StreamExt;
use regex::Regex;

use crate::steps::Steps;
use crate::{EventHandler, World};
Expand All @@ -17,14 +18,19 @@ pub struct Cucumber<W: World> {
steps: Steps<W>,
features: Vec<gherkin::Feature>,
event_handler: Box<dyn EventHandler>,

/// If `Some`, enforce an upper bound on the amount
/// of time a step is allowed to execute.
/// If `Some`, also avoid indefinite locks during
/// step clean-up handling (i.e. to recover panic info)
step_timeout: Option<Duration>,

/// If true, capture stdout and stderr content
/// during tests.
enable_capture: bool,

/// If given, filters the scenario which are run
scenario_filter: Option<Regex>,
}

impl<W: World> Default for Cucumber<W> {
Expand All @@ -35,6 +41,7 @@ impl<W: World> Default for Cucumber<W> {
event_handler: Box::new(crate::output::BasicOutput::default()),
step_timeout: None,
enable_capture: true,
scenario_filter: None,
}
}
}
Expand All @@ -56,6 +63,7 @@ impl<W: World> Cucumber<W> {
event_handler: Box::new(event_handler),
step_timeout: None,
enable_capture: true,
scenario_filter: None,
}
}

Expand Down Expand Up @@ -112,12 +120,35 @@ impl<W: World> Cucumber<W> {
self
}

pub fn scenario_regex(mut self, regex: &str) -> Self {
let regex = Regex::new(regex).expect("Error compiling scenario regex");
self.scenario_filter = Some(regex);
self
}

/// Call this to incorporate command line options into the configuration.
pub fn cli(self) -> Self {
let opts = crate::cli::make_app();
let mut s = self;

if let Some(re) = opts.scenario_filter {
s = s.scenario_regex(&re);
}

if opts.nocapture {
s = s.enable_capture(false);
}

s
}

pub async fn run(mut self) {
let runner = crate::runner::Runner::new(
self.steps.steps,
std::rc::Rc::new(self.features),
self.step_timeout,
self.enable_capture,
self.scenario_filter,
);
let mut stream = runner.run();

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub use gherkin;
#[macro_use]
mod macros;

mod cli;
mod collection;
mod cucumber;
pub mod event;
Expand Down
12 changes: 11 additions & 1 deletion src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::sync::{Arc, TryLockError};

use async_stream::stream;
use futures::{Future, Stream, StreamExt};
use regex::Regex;

use crate::collection::StepsCollection;
use crate::event::*;
Expand Down Expand Up @@ -48,6 +49,7 @@ pub(crate) struct Runner<W: World> {
features: Rc<Vec<gherkin::Feature>>,
step_timeout: Option<Duration>,
enable_capture: bool,
scenario_filter: Option<Regex>,
}

impl<W: World> Runner<W> {
Expand All @@ -57,12 +59,14 @@ impl<W: World> Runner<W> {
features: Rc<Vec<gherkin::Feature>>,
step_timeout: Option<Duration>,
enable_capture: bool,
scenario_filter: Option<Regex>,
) -> Rc<Runner<W>> {
Rc::new(Runner {
functions,
features,
step_timeout,
enable_capture,
scenario_filter,
})
}

Expand Down Expand Up @@ -195,6 +199,13 @@ impl<W: World> Runner<W> {
yield FeatureEvent::Starting;

for scenario in feature.scenarios.iter() {
// If regex filter fails, skip the scenario
if let Some(ref regex) = self.scenario_filter {
if !regex.is_match(&scenario.name) {
continue;
}
}

let examples = ExampleValues::from_examples(&scenario.examples);
for example_values in examples {
let this = Rc::clone(&self);
Expand Down Expand Up @@ -356,7 +367,6 @@ impl<W: World> Runner<W> {
yield CucumberEvent::Starting;

let features = self.features.iter().cloned().map(Rc::new).collect::<Vec<_>>();

for feature in features.into_iter() {
let this = Rc::clone(&self);
let mut stream = this.run_feature(Rc::clone(&feature));
Expand Down

0 comments on commit 82eaf76

Please sign in to comment.