summaryrefslogtreecommitdiff
path: root/src/bindings.rs
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2020-12-03 17:32:37 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2020-12-18 17:50:18 +0000
commitc0462f2d49a42da8309087441926b5112605c3a0 (patch)
tree7dd32458d05a912e426eb663eda823be593f3ecf /src/bindings.rs
parentb4e8a3cf8164b0bffbc97858ce4dede880f1baa9 (diff)
downloadsubplot-c0462f2d49a42da8309087441926b5112605c3a0.tar.gz
bindings: Support parameter type map
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src/bindings.rs')
-rw-r--r--src/bindings.rs115
1 files changed, 101 insertions, 14 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
index 1223910..9b9a119 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -26,6 +26,7 @@ pub struct Binding {
regex: Regex,
function: String,
cleanup: Option<String>,
+ types: HashMap<String, String>,
}
impl Binding {
@@ -36,6 +37,7 @@ impl Binding {
function: &str,
cleanup: Option<&str>,
case_sensitive: bool,
+ types: HashMap<String, String>,
) -> Result<Binding> {
let regex = RegexBuilder::new(&format!("^{}$", pattern))
.case_insensitive(!case_sensitive)
@@ -46,6 +48,7 @@ impl Binding {
regex,
function: function.to_string(),
cleanup: cleanup.map(String::from),
+ types,
})
}
@@ -90,7 +93,7 @@ impl Binding {
let caps = self.regex.captures(step_text)?;
// If there is only one capture, it's the whole string.
- let mut m = MatchedStep::new(self.kind(), &self.function, self.cleanup());
+ let mut m = MatchedStep::new(self.kind(), &self.function, self.cleanup(), &self.types);
if caps.len() == 1 {
m.append_part(PartialStep::uncaptured(step_text));
return Some(m);
@@ -152,10 +155,19 @@ mod test_binding {
use crate::PartialStep;
use crate::ScenarioStep;
use crate::StepKind;
+ use std::collections::HashMap;
#[test]
fn creates_new_without_cleanup() {
- let b = Binding::new(StepKind::Given, "I am Tomjon", "set_name", None, false).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ "set_name",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .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"));
@@ -172,6 +184,7 @@ mod test_binding {
"set_name",
Some("unset_name"),
false,
+ HashMap::new(),
)
.unwrap();
assert_eq!(b.kind(), StepKind::Given);
@@ -190,6 +203,7 @@ mod test_binding {
"set_name",
Some("unset"),
false,
+ HashMap::new(),
)
.unwrap();
let b = Binding::new(
@@ -198,6 +212,7 @@ mod test_binding {
"set_name",
Some("unset"),
false,
+ HashMap::new(),
)
.unwrap();
assert_eq!(a, b);
@@ -205,13 +220,22 @@ mod test_binding {
#[test]
fn not_equal() {
- let a = Binding::new(StepKind::Given, "I am Tomjon", "set_name", None, false).unwrap();
+ let a = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ "set_name",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .unwrap();
let b = Binding::new(
StepKind::Given,
"I am Tomjon of Lancre",
"set_name",
None,
false,
+ HashMap::new(),
)
.unwrap();
assert_ne!(a, b);
@@ -220,21 +244,29 @@ mod test_binding {
#[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, false).unwrap();
+ let b = Binding::new(StepKind::When, "yo", "do_yo", None, false, HashMap::new()).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, false).unwrap();
+ let b = Binding::new(StepKind::Given, "bar", "yo", None, false, HashMap::new()).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, false).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ "foo",
+ "do_foo",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .unwrap();
let m = b.match_with_step(&step).unwrap();
assert_eq!(m.kind(), StepKind::Given);
let mut parts = m.parts();
@@ -252,6 +284,7 @@ mod test_binding {
"set_name",
None,
false,
+ HashMap::new(),
)
.unwrap();
let m = b.match_with_step(&step).unwrap();
@@ -266,9 +299,25 @@ mod test_binding {
#[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();
+ let b = Binding::new(
+ StepKind::Given,
+ r"i am tomjon",
+ "set_name",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .unwrap();
assert!(b.match_with_step(&step).is_some());
- let b = Binding::new(StepKind::Given, r"i am tomjon", "set_name", None, true).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ r"i am tomjon",
+ "set_name",
+ None,
+ true,
+ HashMap::new(),
+ )
+ .unwrap();
assert!(b.match_with_step(&step).is_none());
}
}
@@ -295,6 +344,8 @@ struct ParsedBinding {
regex: Option<bool>,
#[serde(default)]
case_sensitive: bool,
+ #[serde(default)]
+ types: HashMap<String, String>,
}
#[derive(Debug, Deserialize)]
@@ -417,6 +468,7 @@ fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding> {
&parsed.function,
parsed.cleanup.as_deref(),
parsed.case_sensitive,
+ parsed.types.clone(),
)?)
}
@@ -429,6 +481,8 @@ mod test_bindings {
use crate::StepKind;
use crate::SubplotError;
+ use std::collections::HashMap;
+
#[test]
fn has_no_bindings_initially() {
let bindings = Bindings::new();
@@ -443,6 +497,7 @@ mod test_bindings {
"set_name",
None,
false,
+ HashMap::new(),
)
.unwrap();
let mut bindings = Bindings::new();
@@ -462,6 +517,10 @@ mod test_bindings {
- given: you are alice
function: other_name
case_sensitive: true
+- then: the total is {total}
+ function: check_total
+ types:
+ total: number
";
let mut bindings = Bindings::new();
bindings.add_from_yaml(&yaml).unwrap();
@@ -471,7 +530,8 @@ mod test_bindings {
assert!(bindings.has(StepKind::Then, "there is applause"));
assert!(bindings.has(StepKind::Given, "you are alice"));
assert!(!bindings.has(StepKind::Given, "you are Alice"));
- assert_eq!(bindings.len(), 4);
+ assert!(bindings.has(StepKind::Then, "the total is (?P<total>\\S+)"));
+ assert_eq!(bindings.len(), 5);
}
#[test]
@@ -491,7 +551,15 @@ 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, false).unwrap();
+ let binding = Binding::new(
+ StepKind::When,
+ r"I am Tomjon",
+ "set_foo",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
assert!(matches!(
@@ -509,6 +577,7 @@ mod test_bindings {
"set_foo",
None,
false,
+ HashMap::new(),
)
.unwrap();
let mut bindings = Bindings::new();
@@ -523,8 +592,17 @@ 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, false).unwrap());
+ bindings.add(
+ Binding::new(
+ StepKind::Given,
+ r"I am Tomjon",
+ "set_foo",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .unwrap(),
+ );
bindings.add(
Binding::new(
StepKind::Given,
@@ -532,6 +610,7 @@ mod test_bindings {
"set_foo",
None,
false,
+ HashMap::new(),
)
.unwrap(),
);
@@ -544,8 +623,15 @@ 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, false).unwrap();
+ let binding = Binding::new(
+ StepKind::Given,
+ r"I am Tomjon",
+ "set_name",
+ None,
+ false,
+ HashMap::new(),
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
let m = bindings.find(&step).unwrap();
@@ -568,6 +654,7 @@ mod test_bindings {
"set_name",
None,
false,
+ HashMap::new(),
)
.unwrap();
let mut bindings = Bindings::new();