1 // Copyright (c) 2018 The predicates-rs Project Developers.
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 use std::fmt;
10
11 use crate::reflection;
12 use crate::utils;
13 use crate::Predicate;
14
15 /// Predicate that checks for empty strings.
16 ///
17 /// This is created by `predicates::str::is_empty`.
18 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
19 pub struct IsEmptyPredicate {}
20
21 impl Predicate<str> for IsEmptyPredicate {
eval(&self, variable: &str) -> bool22 fn eval(&self, variable: &str) -> bool {
23 variable.is_empty()
24 }
25
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>26 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
27 utils::default_find_case(self, expected, variable)
28 .map(|case| case.add_product(reflection::Product::new("var", variable.to_owned())))
29 }
30 }
31
32 impl reflection::PredicateReflection for IsEmptyPredicate {}
33
34 impl fmt::Display for IsEmptyPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 let palette = crate::Palette::new(f.alternate());
37 write!(
38 f,
39 "{}.{}()",
40 palette.var("var"),
41 palette.description("is_empty"),
42 )
43 }
44 }
45
46 /// Creates a new `Predicate` that ensures a str is empty
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use predicates::prelude::*;
52 ///
53 /// let predicate_fn = predicate::str::is_empty();
54 /// assert_eq!(true, predicate_fn.eval(""));
55 /// assert_eq!(false, predicate_fn.eval("Food World"));
56 /// ```
is_empty() -> IsEmptyPredicate57 pub fn is_empty() -> IsEmptyPredicate {
58 IsEmptyPredicate {}
59 }
60
61 /// Predicate checks start of str
62 ///
63 /// This is created by `predicates::str::starts_with`.
64 #[derive(Debug, Clone, PartialEq, Eq)]
65 pub struct StartsWithPredicate {
66 pattern: String,
67 }
68
69 impl Predicate<str> for StartsWithPredicate {
eval(&self, variable: &str) -> bool70 fn eval(&self, variable: &str) -> bool {
71 variable.starts_with(&self.pattern)
72 }
73
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>74 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
75 utils::default_find_case(self, expected, variable)
76 .map(|case| case.add_product(reflection::Product::new("var", variable.to_owned())))
77 }
78 }
79
80 impl reflection::PredicateReflection for StartsWithPredicate {}
81
82 impl fmt::Display for StartsWithPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 let palette = crate::Palette::new(f.alternate());
85 write!(
86 f,
87 "{}.{}({:?})",
88 palette.var("var"),
89 palette.description("starts_with"),
90 self.pattern
91 )
92 }
93 }
94
95 /// Creates a new `Predicate` that ensures a str starts with `pattern`
96 ///
97 /// # Examples
98 ///
99 /// ```
100 /// use predicates::prelude::*;
101 ///
102 /// let predicate_fn = predicate::str::starts_with("Hello");
103 /// assert_eq!(true, predicate_fn.eval("Hello World"));
104 /// assert_eq!(false, predicate_fn.eval("Goodbye World"));
105 /// ```
starts_with<P>(pattern: P) -> StartsWithPredicate where P: Into<String>,106 pub fn starts_with<P>(pattern: P) -> StartsWithPredicate
107 where
108 P: Into<String>,
109 {
110 StartsWithPredicate {
111 pattern: pattern.into(),
112 }
113 }
114
115 /// Predicate checks end of str
116 ///
117 /// This is created by `predicates::str::ends_with`.
118 #[derive(Debug, Clone, PartialEq, Eq)]
119 pub struct EndsWithPredicate {
120 pattern: String,
121 }
122
123 impl Predicate<str> for EndsWithPredicate {
eval(&self, variable: &str) -> bool124 fn eval(&self, variable: &str) -> bool {
125 variable.ends_with(&self.pattern)
126 }
127
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>128 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
129 utils::default_find_case(self, expected, variable)
130 .map(|case| case.add_product(reflection::Product::new("var", variable.to_owned())))
131 }
132 }
133
134 impl reflection::PredicateReflection for EndsWithPredicate {}
135
136 impl fmt::Display for EndsWithPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 let palette = crate::Palette::new(f.alternate());
139 write!(
140 f,
141 "{}.{}({:?})",
142 palette.var("var"),
143 palette.description("ends_with"),
144 self.pattern
145 )
146 }
147 }
148
149 /// Creates a new `Predicate` that ensures a str ends with `pattern`
150 ///
151 /// # Examples
152 ///
153 /// ```
154 /// use predicates::prelude::*;
155 ///
156 /// let predicate_fn = predicate::str::ends_with("World");
157 /// assert_eq!(true, predicate_fn.eval("Hello World"));
158 /// assert_eq!(false, predicate_fn.eval("Hello Moon"));
159 /// ```
ends_with<P>(pattern: P) -> EndsWithPredicate where P: Into<String>,160 pub fn ends_with<P>(pattern: P) -> EndsWithPredicate
161 where
162 P: Into<String>,
163 {
164 EndsWithPredicate {
165 pattern: pattern.into(),
166 }
167 }
168
169 /// Predicate that checks for patterns.
170 ///
171 /// This is created by `predicates::str:contains`.
172 #[derive(Debug, Clone, PartialEq, Eq)]
173 pub struct ContainsPredicate {
174 pattern: String,
175 }
176
177 impl ContainsPredicate {
178 /// Require a specific count of matches.
179 ///
180 /// # Examples
181 ///
182 /// ```
183 /// use predicates::prelude::*;
184 ///
185 /// let predicate_fn = predicate::str::contains("Two").count(2);
186 /// assert_eq!(true, predicate_fn.eval("One Two Three Two One"));
187 /// assert_eq!(false, predicate_fn.eval("One Two Three"));
188 /// ```
count(self, count: usize) -> MatchesPredicate189 pub fn count(self, count: usize) -> MatchesPredicate {
190 MatchesPredicate {
191 pattern: self.pattern,
192 count,
193 }
194 }
195 }
196
197 impl Predicate<str> for ContainsPredicate {
eval(&self, variable: &str) -> bool198 fn eval(&self, variable: &str) -> bool {
199 variable.contains(&self.pattern)
200 }
201
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>202 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
203 utils::default_find_case(self, expected, variable)
204 .map(|case| case.add_product(reflection::Product::new("var", variable.to_owned())))
205 }
206 }
207
208 impl reflection::PredicateReflection for ContainsPredicate {}
209
210 impl fmt::Display for ContainsPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212 let palette = crate::Palette::new(f.alternate());
213 write!(
214 f,
215 "{}.{}({})",
216 palette.var("var"),
217 palette.description("contains"),
218 palette.expected(&self.pattern),
219 )
220 }
221 }
222
223 /// Predicate that checks for repeated patterns.
224 ///
225 /// This is created by `predicates::str::contains(...).count`.
226 #[derive(Debug, Clone, PartialEq, Eq)]
227 pub struct MatchesPredicate {
228 pattern: String,
229 count: usize,
230 }
231
232 impl Predicate<str> for MatchesPredicate {
eval(&self, variable: &str) -> bool233 fn eval(&self, variable: &str) -> bool {
234 variable.matches(&self.pattern).count() == self.count
235 }
236
find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>>237 fn find_case<'a>(&'a self, expected: bool, variable: &str) -> Option<reflection::Case<'a>> {
238 let actual_count = variable.matches(&self.pattern).count();
239 let result = self.count == actual_count;
240 if result == expected {
241 Some(
242 reflection::Case::new(Some(self), result)
243 .add_product(reflection::Product::new("var", variable.to_owned()))
244 .add_product(reflection::Product::new("actual count", actual_count)),
245 )
246 } else {
247 None
248 }
249 }
250 }
251
252 impl reflection::PredicateReflection for MatchesPredicate {
parameters<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Parameter<'a>> + 'a>253 fn parameters<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Parameter<'a>> + 'a> {
254 let params = vec![reflection::Parameter::new("count", &self.count)];
255 Box::new(params.into_iter())
256 }
257 }
258
259 impl fmt::Display for MatchesPredicate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 let palette = crate::Palette::new(f.alternate());
262 write!(
263 f,
264 "{}.{}({})",
265 palette.var("var"),
266 palette.description("contains"),
267 palette.expected(&self.pattern),
268 )
269 }
270 }
271
272 /// Creates a new `Predicate` that ensures a str contains `pattern`
273 ///
274 /// # Examples
275 ///
276 /// ```
277 /// use predicates::prelude::*;
278 ///
279 /// let predicate_fn = predicate::str::contains("Two");
280 /// assert_eq!(true, predicate_fn.eval("One Two Three"));
281 /// assert_eq!(false, predicate_fn.eval("Four Five Six"));
282 /// ```
contains<P>(pattern: P) -> ContainsPredicate where P: Into<String>,283 pub fn contains<P>(pattern: P) -> ContainsPredicate
284 where
285 P: Into<String>,
286 {
287 ContainsPredicate {
288 pattern: pattern.into(),
289 }
290 }
291