summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2020-06-20 14:17:12 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2020-06-20 14:17:12 +0100
commit7572bc1ad516b9686427558e98a069738bace73d (patch)
treea39f704b479f06710f5902fe6857846873fd078c
parenta80f1243f5b65b8b6876e0c2cd81134155d7af65 (diff)
downloadsubplot-7572bc1ad516b9686427558e98a069738bace73d.tar.gz
feat: Case insensitive matching by default
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--src/bindings.rs105
1 files changed, 85 insertions, 20 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
index 617d725..9d80394 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -11,7 +11,7 @@ use std::fs::File;
use std::io::Read;
use std::path::Path;
-use regex::{escape, Regex};
+use regex::{escape, Regex, RegexBuilder};
/// A binding of a scenario step to its implementation.
///
@@ -34,11 +34,15 @@ impl Binding {
pattern: &str,
function: &str,
cleanup: Option<&str>,
+ case_sensitive: bool,
) -> Result<Binding> {
+ let regex = RegexBuilder::new(&format!("^{}$", pattern))
+ .case_insensitive(!case_sensitive)
+ .build()?;
Ok(Binding {
kind,
pattern: pattern.to_owned(),
- regex: Regex::new(&format!("^{}$", pattern))?,
+ regex,
function: function.to_string(),
cleanup: cleanup.map(String::from),
})
@@ -150,7 +154,7 @@ mod test_binding {
#[test]
fn creates_new_without_cleanup() {
- let b = Binding::new(StepKind::Given, "I am Tomjon", "set_name", None).unwrap();
+ let b = Binding::new(StepKind::Given, "I am Tomjon", "set_name", None, false).unwrap();
assert_eq!(b.kind(), StepKind::Given);
assert!(b.regex().is_match("I am Tomjon"));
assert!(!b.regex().is_match("I am Tomjon of Lancre"));
@@ -166,6 +170,7 @@ mod test_binding {
"I am Tomjon",
"set_name",
Some("unset_name"),
+ false,
)
.unwrap();
assert_eq!(b.kind(), StepKind::Given);
@@ -178,36 +183,57 @@ mod test_binding {
#[test]
fn equal() {
- let a = Binding::new(StepKind::Given, "I am Tomjon", "set_name", Some("unset")).unwrap();
- let b = Binding::new(StepKind::Given, "I am Tomjon", "set_name", Some("unset")).unwrap();
+ let a = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ "set_name",
+ Some("unset"),
+ false,
+ )
+ .unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ "set_name",
+ Some("unset"),
+ false,
+ )
+ .unwrap();
assert_eq!(a, b);
}
#[test]
fn not_equal() {
- let a = Binding::new(StepKind::Given, "I am Tomjon", "set_name", None).unwrap();
- let b = Binding::new(StepKind::Given, "I am Tomjon of Lancre", "set_name", None).unwrap();
+ let a = Binding::new(StepKind::Given, "I am Tomjon", "set_name", None, false).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ "I am Tomjon of Lancre",
+ "set_name",
+ None,
+ false,
+ )
+ .unwrap();
assert_ne!(a, b);
}
#[test]
fn does_not_match_with_wrong_kind() {
let step = ScenarioStep::new(StepKind::Given, "given", "yo");
- let b = Binding::new(StepKind::When, "yo", "do_yo", None).unwrap();
+ let b = Binding::new(StepKind::When, "yo", "do_yo", None, false).unwrap();
assert!(b.match_with_step(&step).is_none());
}
#[test]
fn does_not_match_with_wrong_text() {
let step = ScenarioStep::new(StepKind::Given, "given", "foo");
- let b = Binding::new(StepKind::Given, "bar", "yo", None).unwrap();
+ let b = Binding::new(StepKind::Given, "bar", "yo", None, false).unwrap();
assert!(b.match_with_step(&step).is_none());
}
#[test]
fn match_with_fixed_pattern() {
let step = ScenarioStep::new(StepKind::Given, "given", "foo");
- let b = Binding::new(StepKind::Given, "foo", "do_foo", None).unwrap();
+ let b = Binding::new(StepKind::Given, "foo", "do_foo", None, false).unwrap();
let m = b.match_with_step(&step).unwrap();
assert_eq!(m.kind(), StepKind::Given);
let mut parts = m.parts();
@@ -224,6 +250,7 @@ mod test_binding {
r"I am (?P<who>\S+), I am",
"set_name",
None,
+ false,
)
.unwrap();
let m = b.match_with_step(&step).unwrap();
@@ -234,6 +261,15 @@ mod test_binding {
assert_eq!(parts.next().unwrap(), &PartialStep::uncaptured(", I am"));
assert_eq!(parts.next(), None);
}
+
+ #[test]
+ fn case_sensitive_mismatch() {
+ let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon");
+ let b = Binding::new(StepKind::Given, r"i am tomjon", "set_name", None, false).unwrap();
+ assert!(b.match_with_step(&step).is_some());
+ let b = Binding::new(StepKind::Given, r"i am tomjon", "set_name", None, true).unwrap();
+ assert!(b.match_with_step(&step).is_none());
+ }
}
/// Set of all known bindings.
@@ -256,6 +292,8 @@ struct ParsedBinding {
function: String,
cleanup: Option<String>,
regex: Option<bool>,
+ #[serde(default)]
+ case_sensitive: bool,
}
#[derive(Debug, Deserialize)]
@@ -380,6 +418,7 @@ fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding> {
None => None,
Some(ref s) => Some(s),
},
+ parsed.case_sensitive,
)?)
}
@@ -400,8 +439,14 @@ mod test_bindings {
#[test]
fn adds_binding() {
- let binding =
- Binding::new(StepKind::Given, r"I am (?P<name>\S+)", "set_name", None).unwrap();
+ let binding = Binding::new(
+ StepKind::Given,
+ r"I am (?P<name>\S+)",
+ "set_name",
+ None,
+ false,
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding.clone());
assert_eq!(bindings.bindings(), &[binding]);
@@ -416,6 +461,9 @@ mod test_bindings {
Function: declare_king
- tHEn: there is applause
function: check_for_applause
+- given: you are alice
+ function: other_name
+ case_sensitive: true
";
let mut bindings = Bindings::new();
bindings.add_from_yaml(&yaml).unwrap();
@@ -423,7 +471,9 @@ mod test_bindings {
assert!(bindings.has(StepKind::Given, "I am Tomjon"));
assert!(bindings.has(StepKind::When, "I declare myself king"));
assert!(bindings.has(StepKind::Then, "there is applause"));
- assert_eq!(bindings.len(), 3);
+ assert!(bindings.has(StepKind::Given, "you are alice"));
+ assert!(!bindings.has(StepKind::Given, "you are Alice"));
+ assert_eq!(bindings.len(), 4);
}
#[test]
@@ -443,7 +493,7 @@ mod test_bindings {
#[test]
fn does_not_find_match_for_unmatching_kind() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon");
- let binding = Binding::new(StepKind::When, r"I am Tomjon", "set_foo", None).unwrap();
+ let binding = Binding::new(StepKind::When, r"I am Tomjon", "set_foo", None, false).unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
assert!(match bindings.find(&step) {
@@ -455,8 +505,14 @@ mod test_bindings {
#[test]
fn does_not_find_match_for_unmatching_pattern() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon");
- let binding =
- Binding::new(StepKind::Given, r"I am Tomjon of Lancre", "set_foo", None).unwrap();
+ let binding = Binding::new(
+ StepKind::Given,
+ r"I am Tomjon of Lancre",
+ "set_foo",
+ None,
+ false,
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
assert!(match bindings.find(&step) {
@@ -469,13 +525,15 @@ mod test_bindings {
fn two_matching_bindings() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon");
let mut bindings = Bindings::default();
- bindings.add(Binding::new(StepKind::Given, r"I am Tomjon", "set_foo", None).unwrap());
+ bindings
+ .add(Binding::new(StepKind::Given, r"I am Tomjon", "set_foo", None, false).unwrap());
bindings.add(
Binding::new(
StepKind::Given,
&super::regex_from_simple_pattern(r"I am {name}", false).unwrap(),
"set_foo",
None,
+ false,
)
.unwrap(),
);
@@ -488,7 +546,8 @@ mod test_bindings {
#[test]
fn finds_match_for_fixed_string_pattern() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon");
- let binding = Binding::new(StepKind::Given, r"I am Tomjon", "set_name", None).unwrap();
+ let binding =
+ Binding::new(StepKind::Given, r"I am Tomjon", "set_name", None, false).unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
let m = bindings.find(&step).unwrap();
@@ -505,8 +564,14 @@ mod test_bindings {
#[test]
fn finds_match_for_regexp_pattern() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon");
- let binding =
- Binding::new(StepKind::Given, r"I am (?P<name>\S+)", "set_name", None).unwrap();
+ let binding = Binding::new(
+ StepKind::Given,
+ r"I am (?P<name>\S+)",
+ "set_name",
+ None,
+ false,
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
let m = bindings.find(&step).unwrap();