summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2023-12-27 17:37:27 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2023-12-27 17:38:43 +0000
commit439bbfe88e971bfa5f07a1faec8ff4a48bbeeb86 (patch)
tree52b0fc07d789e5d49bc52eef07c066b021834d9a
parentd7d4a575e0d09e05928eba1180b49211149d49af (diff)
downloadsubplot-439bbfe88e971bfa5f07a1faec8ff4a48bbeeb86.tar.gz
bindings: Remember filename when loading bindings
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--src/bindings.rs148
-rw-r--r--tests/bindings-ubm.rs9
2 files changed, 130 insertions, 27 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
index b937edb..c342432 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -167,6 +167,7 @@ pub struct Binding {
impls: HashMap<String, Arc<BindingImpl>>,
types: HashMap<String, CaptureType>,
doc: Option<String>,
+ filename: Arc<Path>,
}
impl Binding {
@@ -177,6 +178,7 @@ impl Binding {
case_sensitive: bool,
mut types: HashMap<String, CaptureType>,
doc: Option<String>,
+ filename: Arc<Path>,
) -> Result<Binding, SubplotError> {
let regex = RegexBuilder::new(&format!("^{pattern}$"))
.case_insensitive(!case_sensitive)
@@ -196,6 +198,7 @@ impl Binding {
impls: HashMap::new(),
types,
doc,
+ filename,
})
}
@@ -307,6 +310,10 @@ impl Binding {
Some(m)
}
+
+ fn filename(&self) -> &Path {
+ &self.filename
+ }
}
impl PartialEq for Binding {
@@ -325,10 +332,25 @@ mod test_binding {
use crate::ScenarioStep;
use crate::StepKind;
use std::collections::HashMap;
+ use std::path::Path;
+ use std::path::PathBuf;
+ use std::sync::Arc;
+
+ fn path() -> Arc<Path> {
+ PathBuf::new().into()
+ }
#[test]
fn creates_new() {
- let b = Binding::new(StepKind::Given, "I am Tomjon", false, HashMap::new(), None).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .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"));
@@ -337,20 +359,45 @@ mod test_binding {
#[test]
fn equal() {
- let a = Binding::new(StepKind::Given, "I am Tomjon", false, HashMap::new(), None).unwrap();
- let b = Binding::new(StepKind::Given, "I am Tomjon", false, HashMap::new(), None).unwrap();
+ let a = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
assert_eq!(a, b);
}
#[test]
fn not_equal() {
- let a = Binding::new(StepKind::Given, "I am Tomjon", false, HashMap::new(), None).unwrap();
+ let a = Binding::new(
+ StepKind::Given,
+ "I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
let b = Binding::new(
StepKind::Given,
"I am Tomjon of Lancre",
false,
HashMap::new(),
None,
+ path(),
)
.unwrap();
assert_ne!(a, b);
@@ -359,21 +406,21 @@ mod test_binding {
#[test]
fn does_not_match_with_wrong_kind() {
let step = ScenarioStep::new(StepKind::Given, "given", "yo", Location::Unknown);
- let b = Binding::new(StepKind::When, "yo", false, HashMap::new(), None).unwrap();
+ let b = Binding::new(StepKind::When, "yo", false, HashMap::new(), None, path()).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", Location::Unknown);
- let b = Binding::new(StepKind::Given, "bar", false, HashMap::new(), None).unwrap();
+ let b = Binding::new(StepKind::Given, "bar", false, HashMap::new(), None, path()).unwrap();
assert!(b.match_with_step("", &step).is_none());
}
#[test]
fn match_with_fixed_pattern() {
let step = ScenarioStep::new(StepKind::Given, "given", "foo", Location::Unknown);
- let b = Binding::new(StepKind::Given, "foo", false, HashMap::new(), None).unwrap();
+ let b = Binding::new(StepKind::Given, "foo", false, HashMap::new(), None, path()).unwrap();
let m = b.match_with_step("", &step).unwrap();
assert_eq!(m.kind(), StepKind::Given);
let mut parts = m.parts();
@@ -396,6 +443,7 @@ mod test_binding {
false,
HashMap::new(),
None,
+ path(),
)
.unwrap();
let m = b.match_with_step("", &step).unwrap();
@@ -413,9 +461,25 @@ mod test_binding {
#[test]
fn case_sensitive_mismatch() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon", Location::Unknown);
- let b = Binding::new(StepKind::Given, r"i am tomjon", false, HashMap::new(), None).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ r"i am tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
assert!(b.match_with_step("", &step).is_some());
- let b = Binding::new(StepKind::Given, r"i am tomjon", true, HashMap::new(), None).unwrap();
+ let b = Binding::new(
+ StepKind::Given,
+ r"i am tomjon",
+ true,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
assert!(b.match_with_step("", &step).is_none());
}
}
@@ -493,11 +557,11 @@ impl Bindings {
}
/// Add bindings from a YAML string
- pub fn add_from_yaml(&mut self, yaml: &str) -> Result<(), SubplotError> {
+ pub fn add_from_yaml(&mut self, yaml: &str, filename: Arc<Path>) -> Result<(), SubplotError> {
let bindings: Vec<ParsedBindingWrapper> =
serde_yaml::from_str(yaml).map_err(SubplotError::Metadata)?;
for wrapper in bindings {
- self.add(from_hashmap(&wrapper.binding)?);
+ self.add(from_hashmap(&wrapper.binding, Arc::clone(&filename))?);
}
Ok(())
}
@@ -539,12 +603,12 @@ impl Bindings {
where
P: AsRef<Path> + Debug,
{
- let yaml = resource::read_as_string(filename.as_ref(), template)
- .map_err(|e| SubplotError::BindingsFileNotFound(filename.as_ref().into(), e))?;
+ let filename = filename.as_ref();
+ let yaml = resource::read_as_string(filename, template)
+ .map_err(|e| SubplotError::BindingsFileNotFound(filename.into(), e))?;
trace!("Loaded file content");
- self.add_from_yaml(&yaml).map_err(|e| {
- SubplotError::BindingFileParseError(filename.as_ref().to_owned(), Box::new(e))
- })?;
+ self.add_from_yaml(&yaml, filename.to_owned().into())
+ .map_err(|e| SubplotError::BindingFileParseError(filename.to_owned(), Box::new(e)))?;
Ok(())
}
@@ -558,7 +622,7 @@ impl Bindings {
}
}
-fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding, SubplotError> {
+fn from_hashmap(parsed: &ParsedBinding, filename: Arc<Path>) -> Result<Binding, SubplotError> {
let given: i32 = parsed.given.is_some().into();
let when: i32 = parsed.when.is_some().into();
let then: i32 = parsed.then.is_some().into();
@@ -601,6 +665,7 @@ fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding, SubplotError> {
parsed.case_sensitive,
types,
parsed.doc.clone(),
+ filename,
)?;
trace!("Binding parsed OK");
for (template, pimpl) in &parsed.impls {
@@ -622,6 +687,13 @@ mod test_bindings {
use crate::SubplotError;
use std::collections::HashMap;
+ use std::path::Path;
+ use std::path::PathBuf;
+ use std::sync::Arc;
+
+ fn path() -> Arc<Path> {
+ PathBuf::new().into()
+ }
#[test]
fn has_no_bindings_initially() {
@@ -637,6 +709,7 @@ mod test_bindings {
false,
HashMap::new(),
None,
+ path(),
)
.unwrap();
let mut bindings = Bindings::new();
@@ -672,7 +745,7 @@ mod test_bindings {
total: word
";
let mut bindings = Bindings::new();
- bindings.add_from_yaml(yaml).unwrap();
+ bindings.add_from_yaml(yaml, path()).unwrap();
println!("test: {bindings:?}");
assert!(bindings.has(StepKind::Given, "I am Tomjon"));
assert!(bindings.has(StepKind::When, "I declare myself king"));
@@ -692,7 +765,7 @@ mod test_bindings {
python:
FUNCTION: set_name
";
- match Bindings::new().add_from_yaml(yaml) {
+ match Bindings::new().add_from_yaml(yaml, path()) {
Ok(_) => unreachable!(),
Err(SubplotError::BindingHasManyKeywords(_)) => (),
Err(e) => panic!("Incorrect error: {}", e),
@@ -709,7 +782,7 @@ mod test_bindings {
types:
age: number
";
- match Bindings::new().add_from_yaml(yaml) {
+ match Bindings::new().add_from_yaml(yaml, path()) {
Ok(_) => unreachable!(),
Err(SubplotError::SimplePatternKindMismatch(_)) => (),
Err(e) => panic!("Incorrect error: {}", e),
@@ -719,8 +792,15 @@ mod test_bindings {
#[test]
fn does_not_find_match_for_unmatching_kind() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon", Location::Unknown);
- let binding =
- Binding::new(StepKind::When, r"I am Tomjon", false, HashMap::new(), None).unwrap();
+ let binding = Binding::new(
+ StepKind::When,
+ r"I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
assert!(matches!(
@@ -738,6 +818,7 @@ mod test_bindings {
false,
HashMap::new(),
None,
+ path(),
)
.unwrap();
let mut bindings = Bindings::new();
@@ -753,7 +834,15 @@ mod test_bindings {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon", Location::Unknown);
let mut bindings = Bindings::default();
bindings.add(
- Binding::new(StepKind::Given, r"I am Tomjon", false, HashMap::new(), None).unwrap(),
+ Binding::new(
+ StepKind::Given,
+ r"I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap(),
);
bindings.add(
Binding::new(
@@ -763,6 +852,7 @@ mod test_bindings {
false,
HashMap::new(),
None,
+ path(),
)
.unwrap(),
);
@@ -775,8 +865,15 @@ mod test_bindings {
#[test]
fn finds_match_for_fixed_string_pattern() {
let step = ScenarioStep::new(StepKind::Given, "given", "I am Tomjon", Location::Unknown);
- let binding =
- Binding::new(StepKind::Given, r"I am Tomjon", false, HashMap::new(), None).unwrap();
+ let binding = Binding::new(
+ StepKind::Given,
+ r"I am Tomjon",
+ false,
+ HashMap::new(),
+ None,
+ path(),
+ )
+ .unwrap();
let mut bindings = Bindings::new();
bindings.add(binding);
let m = bindings.find("", &step).unwrap();
@@ -799,6 +896,7 @@ mod test_bindings {
false,
HashMap::new(),
None,
+ path(),
)
.unwrap();
let mut bindings = Bindings::new();
diff --git a/tests/bindings-ubm.rs b/tests/bindings-ubm.rs
index 4c4aaa0..e4232d1 100644
--- a/tests/bindings-ubm.rs
+++ b/tests/bindings-ubm.rs
@@ -4,12 +4,17 @@
// there are a large number of them.
use regex::RegexBuilder;
-use std::collections::HashMap;
+use std::path::{Path, PathBuf};
use std::time::SystemTime;
+use std::{collections::HashMap, sync::Arc};
use subplot::{html::Location, Binding, Bindings, ScenarioStep, StepKind};
const N: i32 = 1000;
+fn path() -> Arc<Path> {
+ PathBuf::new().into()
+}
+
#[test]
fn bindings_microbenchmark() {
let time = SystemTime::now();
@@ -34,7 +39,7 @@ fn bindings_microbenchmark() {
let mut toadd = vec![];
for t in texts.iter() {
- toadd.push(Binding::new(StepKind::Given, t, false, HashMap::new(), None).unwrap());
+ toadd.push(Binding::new(StepKind::Given, t, false, HashMap::new(), None, path()).unwrap());
}
let created = time.elapsed().unwrap();