googletest/matchers/
matches_regex_matcher.rs1use crate::description::Description;
16use crate::matcher::{Matcher, MatcherBase, MatcherResult};
17use regex::Regex;
18use std::fmt::Debug;
19use std::ops::Deref;
20
21pub fn matches_regex<PatternT: Deref<Target = str>>(
63 pattern: PatternT,
64) -> MatchesRegexMatcher<PatternT> {
65 let adjusted_pattern = format!("^{}$", pattern.deref());
66 let regex = Regex::new(adjusted_pattern.as_str()).unwrap();
67 MatchesRegexMatcher { regex, pattern, _adjusted_pattern: adjusted_pattern }
68}
69
70#[derive(MatcherBase)]
75pub struct MatchesRegexMatcher<PatternT: Deref<Target = str>> {
76 regex: Regex,
77 pattern: PatternT,
78 _adjusted_pattern: String,
79}
80
81impl<PatternT, ActualT> Matcher<ActualT> for MatchesRegexMatcher<PatternT>
82where
83 PatternT: Deref<Target = str>,
84 ActualT: AsRef<str> + Debug + Copy,
85{
86 fn matches(&self, actual: ActualT) -> MatcherResult {
87 self.regex.is_match(actual.as_ref()).into()
88 }
89
90 fn describe(&self, matcher_result: MatcherResult) -> Description {
91 match matcher_result {
92 MatcherResult::Match => {
93 format!("matches the regular expression {:#?}", self.pattern.deref()).into()
94 }
95 MatcherResult::NoMatch => {
96 format!("doesn't match the regular expression {:#?}", self.pattern.deref()).into()
97 }
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::matcher::MatcherResult;
105 use crate::prelude::*;
106 use crate::Result;
107
108 #[test]
109 fn matches_regex_matches_string_reference_with_pattern() -> Result<()> {
110 let matcher = matches_regex("S.*e");
111
112 let result = matcher.matches("Some value");
113
114 verify_that!(result, eq(MatcherResult::Match))
115 }
116
117 #[test]
118 fn matches_regex_does_not_match_string_without_pattern() -> Result<()> {
119 let matcher = matches_regex("Another");
120
121 let result = matcher.matches("Some value");
122
123 verify_that!(result, eq(MatcherResult::NoMatch))
124 }
125
126 #[test]
127 fn matches_regex_does_not_match_string_only_beginning_of_which_matches() -> Result<()> {
128 let matcher = matches_regex("Some");
129
130 let result = matcher.matches("Some value");
131
132 verify_that!(result, eq(MatcherResult::NoMatch))
133 }
134
135 #[test]
136 fn matches_regex_does_not_match_string_only_end_of_which_matches() -> Result<()> {
137 let matcher = matches_regex("value");
138
139 let result = matcher.matches("Some value");
140
141 verify_that!(result, eq(MatcherResult::NoMatch))
142 }
143
144 #[test]
145 fn matches_regex_matches_owned_string_with_pattern() -> Result<()> {
146 let matcher = matches_regex(".*value");
147
148 let result = matcher.matches(&"Some value".to_string());
149
150 verify_that!(result, eq(MatcherResult::Match))
151 }
152
153 #[test]
154 fn matches_regex_matches_string_when_regex_has_beginning_of_string_marker() -> Result<()> {
155 let matcher = matches_regex("^Some value");
156
157 let result = matcher.matches("Some value");
158
159 verify_that!(result, eq(MatcherResult::Match))
160 }
161
162 #[test]
163 fn matches_regex_matches_string_when_regex_has_end_of_string_marker() -> Result<()> {
164 let matcher = matches_regex("Some value$");
165
166 let result = matcher.matches("Some value");
167
168 verify_that!(result, eq(MatcherResult::Match))
169 }
170
171 #[test]
172 fn matches_regex_matches_string_when_regex_has_both_end_markers() -> Result<()> {
173 let matcher = matches_regex("^Some value$");
174
175 let result = matcher.matches("Some value");
176
177 verify_that!(result, eq(MatcherResult::Match))
178 }
179
180 #[test]
181 fn matches_regex_matches_string_reference_with_owned_string() -> Result<()> {
182 let matcher = matches_regex(".*value".to_string());
183
184 let result = matcher.matches("Some value");
185
186 verify_that!(result, eq(MatcherResult::Match))
187 }
188
189 #[test]
190 fn verify_that_works_with_owned_string() -> Result<()> {
191 verify_that!("Some value".to_string(), matches_regex(".*value"))
192 }
193
194 #[test]
195 fn matches_regex_displays_quoted_debug_of_pattern() -> Result<()> {
196 let matcher = matches_regex("\n");
197
198 verify_that!(
199 Matcher::<&str>::describe(&matcher, MatcherResult::Match),
200 displays_as(eq("matches the regular expression \"\\n\""))
201 )
202 }
203}