json_test/matchers/
regex.rs1use super::JsonMatcher;
2use regex::Regex;
3use serde_json::Value;
4
5#[derive(Debug)]
6pub struct RegexMatcher {
7 pattern: Regex,
8}
9
10impl RegexMatcher {
11 pub fn new(pattern: &str) -> Result<Self, regex::Error> {
12 Ok(Self {
13 pattern: Regex::new(pattern)?
14 })
15 }
16}
17
18impl JsonMatcher for RegexMatcher {
19 fn matches(&self, value: &Value) -> bool {
20 match value {
21 Value::String(s) => self.pattern.is_match(s),
22 _ => false,
23 }
24 }
25
26 fn description(&self) -> String {
27 format!("matches regex pattern {}", self.pattern.as_str())
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use serde_json::json;
35
36 #[test]
37 fn test_regex_matching() {
38 let matcher = RegexMatcher::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
39
40 assert!(matcher.matches(&json!("2024-01-01")));
42
43 assert!(!matcher.matches(&json!("2024/01/01")));
45 assert!(!matcher.matches(&json!("not-a-date")));
46
47 assert!(!matcher.matches(&json!(42)));
49 assert!(!matcher.matches(&json!(true)));
50 assert!(!matcher.matches(&json!(null)));
51 }
52
53 #[test]
54 fn test_case_sensitive_matching() {
55 let matcher = RegexMatcher::new(r"[a-z]+\d+").unwrap();
56
57 assert!(matcher.matches(&json!("test123")));
58 assert!(!matcher.matches(&json!("TEST123")));
59 }
60
61 #[test]
62 fn test_invalid_regex() {
63 assert!(RegexMatcher::new(r"[invalid").is_err());
64 }
65
66 #[test]
67 fn test_description() {
68 let matcher = RegexMatcher::new(r"\d+").unwrap();
69 assert_eq!(matcher.description(), r#"matches regex pattern \d+"#);
70 }
71}