json_test/matchers/
regex.rs

1use 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        // Test valid date format
41        assert!(matcher.matches(&json!("2024-01-01")));
42
43        // Test invalid formats
44        assert!(!matcher.matches(&json!("2024/01/01")));
45        assert!(!matcher.matches(&json!("not-a-date")));
46
47        // Test non-string values
48        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}