diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-12-03 17:32:37 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-12-18 17:50:18 +0000 |
commit | c0462f2d49a42da8309087441926b5112605c3a0 (patch) | |
tree | 7dd32458d05a912e426eb663eda823be593f3ecf /src/bindings.rs | |
parent | b4e8a3cf8164b0bffbc97858ce4dede880f1baa9 (diff) | |
download | subplot-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.rs | 115 |
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(); |