diff --git a/rust/pact_models/src/generators/mod.rs b/rust/pact_models/src/generators/mod.rs index e42ffd454..24aad3c2f 100644 --- a/rust/pact_models/src/generators/mod.rs +++ b/rust/pact_models/src/generators/mod.rs @@ -1049,12 +1049,17 @@ impl GenerateValue for Generator { let mut parser = regex_syntax::ParserBuilder::new().unicode(false).build(); match parser.parse(regex) { Ok(hir) => { - let gen = rand_regex::Regex::with_hir(hir, 20).unwrap(); - Ok(json!(rand::thread_rng().sample::(gen))) + match rand_regex::Regex::with_hir(hir, 20) { + Ok(gen) => Ok(json!(rand::thread_rng().sample::(gen))), + Err(err) => { + warn!("Failed to generate a value from regular expression - {}", err); + Err(anyhow!("Failed to generate a value from regular expression - {}", err)) + } + } }, Err(err) => { warn!("'{}' is not a valid regular expression - {}", regex, err); - Err(anyhow!("Could not generate a random string from {} - {}", regex, err)) + Err(anyhow!("'{}' is not a valid regular expression - {}", regex, err)) } } }, @@ -1325,6 +1330,7 @@ mod tests { use pretty_assertions::assert_eq; use test_log::test; + use crate::contain; use crate::generators::Generator::{RandomDecimal, RandomInt, Regex}; use super::*; @@ -2060,6 +2066,21 @@ mod tests { assert_that!(generated.unwrap(), matches_regex(r"^\d{1,2}/\d{1,2}$")); } + #[test] + fn regex_generator_test_with_anchors() { + let generator = Generator::Regex(r"^\/api\/families\/[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$".into()); + + let generated = generator.generate_value(&"".to_string(), &hashmap!{}, &NoopVariantMatcher.boxed()); + let err = generated.unwrap_err().to_string(); + expect!(&err).to(contain("'^\\/api\\/families\\/[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$' is not a valid regular expression")); + expect!(&err).to(contain("error: unrecognized escape sequence")); + + let generated = generator.generate_value(&json!(""), &hashmap!{}, &NoopVariantMatcher.boxed()); + let err = generated.unwrap_err().to_string(); + expect!(&err).to(contain("'^\\/api\\/families\\/[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$' is not a valid regular expression")); + expect!(&err).to(contain("error: unrecognized escape sequence")); + } + #[test] fn uuid_generator_test() { let generated = Generator::Uuid(None).generate_value(&"".to_string(), &hashmap!{}, &NoopVariantMatcher.boxed()); diff --git a/rust/pact_models/src/lib.rs b/rust/pact_models/src/lib.rs index 01f011387..e4efabe94 100644 --- a/rust/pact_models/src/lib.rs +++ b/rust/pact_models/src/lib.rs @@ -430,3 +430,29 @@ impl Display for HttpStatus { #[cfg(test)] mod tests; + +#[cfg(test)] +pub struct Contains { + expected: String +} + +#[cfg(test)] +pub fn contain>(expected: S) -> Contains { + Contains { expected: expected.into() } +} + +#[cfg(test)] +impl expectest::core::Matcher for Contains + where + A: Into + Clone +{ + fn failure_message(&self, _join: expectest::core::Join, actual: &A) -> String { + let s: String = actual.clone().into(); + format!("expected '{}' to contain <{:?}>", s, self.expected) + } + + fn matches(&self, actual: &A) -> bool { + let s: String = actual.clone().into(); + s.contains(self.expected.as_str()) + } +}