expect_json/expect/ops/expect_string/
expect_string.rs

1use crate::expect::ops::expect_string::ExpectStringSubOp;
2use crate::expect_core::expect_op;
3use crate::expect_core::Context;
4use crate::expect_core::ExpectOp;
5use crate::expect_core::ExpectOpResult;
6use crate::JsonType;
7
8#[expect_op(internal, name = "string")]
9#[derive(Debug, Clone, Default, PartialEq)]
10pub struct ExpectString {
11    sub_ops: Vec<ExpectStringSubOp>,
12}
13
14impl ExpectString {
15    pub(crate) fn new() -> Self {
16        Self { sub_ops: vec![] }
17    }
18
19    pub fn empty(mut self) -> Self {
20        self.sub_ops.push(ExpectStringSubOp::Empty);
21        self
22    }
23
24    pub fn not_empty(mut self) -> Self {
25        self.sub_ops.push(ExpectStringSubOp::NotEmpty);
26        self
27    }
28
29    pub fn len(mut self, len: usize) -> Self {
30        self.sub_ops.push(ExpectStringSubOp::Len(len));
31        self
32    }
33
34    pub fn min_len(mut self, min_len: usize) -> Self {
35        self.sub_ops.push(ExpectStringSubOp::MinLen(min_len));
36        self
37    }
38
39    pub fn max_len(mut self, max_len: usize) -> Self {
40        self.sub_ops.push(ExpectStringSubOp::MaxLen(max_len));
41        self
42    }
43
44    ///
45    /// Expect a string containing a subset of the string given.
46    ///
47    /// ```rust
48    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
49    /// #
50    /// # use axum::Router;
51    /// # use axum::extract::Json;
52    /// # use axum::routing::get;
53    /// # use axum_test::TestServer;
54    /// # use serde_json::json;
55    /// #
56    /// # let server = TestServer::new(Router::new())?;
57    /// #
58    /// use axum_test::expect_json;
59    ///
60    /// let server = TestServer::new(Router::new())?;
61    ///
62    /// server.get(&"/user")
63    ///     .await
64    ///     .assert_json(&json!({
65    ///         "name": expect_json::string().contains("apples"),
66    ///     }));
67    /// #
68    /// # Ok(()) }
69    /// ```
70    pub fn contains<S>(mut self, expected_sub_string: S) -> Self
71    where
72        S: Into<String>,
73    {
74        self.sub_ops
75            .push(ExpectStringSubOp::Contains(expected_sub_string.into()));
76        self
77    }
78}
79
80impl ExpectOp for ExpectString {
81    fn on_string(&self, context: &mut Context, received: &str) -> ExpectOpResult<()> {
82        for sub_op in &self.sub_ops {
83            sub_op.on_string(self, context, received)?;
84        }
85
86        Ok(())
87    }
88
89    fn debug_supported_types(&self) -> &'static [JsonType] {
90        &[JsonType::String]
91    }
92}
93
94#[cfg(test)]
95mod test_contains {
96    use crate::expect;
97    use crate::expect_json_eq;
98    use pretty_assertions::assert_eq;
99    use serde_json::json;
100
101    #[test]
102    fn it_should_be_equal_for_identical_strings() {
103        let left = json!("1, 2, 3");
104        let right = json!(expect::string().contains("1, 2, 3"));
105
106        let output = expect_json_eq(&left, &right);
107        assert!(output.is_ok());
108    }
109
110    #[test]
111    fn it_should_be_equal_for_partial_matches_in_middle() {
112        let left = json!("0, 1, 2, 3, 4");
113        let right = json!(expect::string().contains("1, 2, 3"));
114
115        let output = expect_json_eq(&left, &right);
116        assert!(output.is_ok());
117    }
118
119    #[test]
120    fn it_should_be_ok_for_empty_contains() {
121        let left = json!("0, 1, 2, 3, 4, 5");
122        let right = json!(expect::string().contains(""));
123
124        let output = expect_json_eq(&left, &right);
125        assert!(output.is_ok());
126    }
127
128    #[test]
129    fn it_should_error_for_totall_different_values() {
130        let left = json!("1, 2, 3");
131        let right = json!(expect::string().contains("a, b, c"));
132
133        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
134        assert_eq!(
135            output,
136            r#"Json string at root does not contain expected value:
137    expected string to contain "a, b, c", but it was not found.
138    received "1, 2, 3""#
139        );
140    }
141}
142
143#[cfg(test)]
144mod test_empty {
145    use crate::expect;
146    use crate::expect_json_eq;
147    use pretty_assertions::assert_eq;
148    use serde_json::json;
149
150    #[test]
151    fn it_should_pass_when_string_is_empty() {
152        let left = json!("");
153        let right = json!(expect::string().empty());
154
155        let output = expect_json_eq(&left, &right);
156        assert!(output.is_ok(), "assertion error: {output:#?}");
157    }
158
159    #[test]
160    fn it_should_fail_when_string_is_not_empty() {
161        let left = json!("🦊");
162        let right = json!(expect::string().empty());
163
164        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
165        assert_eq!(
166            output,
167            r#"Json expect::string() error at root:
168    expected empty string
169    received "🦊""#
170        );
171    }
172}
173
174#[cfg(test)]
175mod test_not_empty {
176    use crate::expect;
177    use crate::expect_json_eq;
178    use pretty_assertions::assert_eq;
179    use serde_json::json;
180
181    #[test]
182    fn it_should_pass_when_string_is_not_empty() {
183        let left = json!("🦊");
184        let right = json!(expect::string().not_empty());
185
186        let output = expect_json_eq(&left, &right);
187        assert!(output.is_ok(), "assertion error: {output:#?}");
188    }
189
190    #[test]
191    fn it_should_fail_when_string_is_empty() {
192        let left = json!("");
193        let right = json!(expect::string().not_empty());
194
195        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
196        assert_eq!(
197            output,
198            r#"Json expect::string() error at root:
199    expected non-empty string
200    received """#
201        );
202    }
203}
204
205#[cfg(test)]
206mod test_len {
207    use crate::expect;
208    use crate::expect_json_eq;
209    use pretty_assertions::assert_eq;
210    use serde_json::json;
211
212    #[test]
213    fn it_should_pass_when_string_has_same_number_of_characters() {
214        let left = json!("123");
215        let right = json!(expect::string().len(3));
216
217        let output = expect_json_eq(&left, &right);
218        assert!(output.is_ok(), "assertion error: {output:#?}");
219    }
220
221    #[test]
222    fn it_should_fail_when_string_is_too_short() {
223        let left = json!("12");
224        let right = json!(expect::string().len(3));
225
226        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
227        assert_eq!(
228            output,
229            r#"Json expect::string() error at root:
230    expected string to have 3 characters, but it has 2,
231    received "12""#
232        );
233    }
234
235    #[test]
236    fn it_should_fail_when_string_is_too_long() {
237        let left = json!("1234");
238        let right = json!(expect::string().len(3));
239
240        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
241        assert_eq!(
242            output,
243            r#"Json expect::string() error at root:
244    expected string to have 3 characters, but it has 4,
245    received "1234""#
246        );
247    }
248}
249
250#[cfg(test)]
251mod test_min_len {
252    use crate::expect;
253    use crate::expect_json_eq;
254    use pretty_assertions::assert_eq;
255    use serde_json::json;
256
257    #[test]
258    fn it_should_pass_when_string_has_exactly_enough_characters() {
259        let left = json!("123");
260        let right = json!(expect::string().min_len(3));
261
262        let output = expect_json_eq(&left, &right);
263        assert!(output.is_ok(), "assertion error: {output:#?}");
264    }
265
266    #[test]
267    fn it_should_pass_when_string_has_more_than_enough_characters() {
268        let left = json!("12345");
269        let right = json!(expect::string().min_len(3));
270
271        let output = expect_json_eq(&left, &right);
272        assert!(output.is_ok(), "assertion error: {output:#?}");
273    }
274
275    #[test]
276    fn it_should_fail_when_string_is_too_short() {
277        let left = json!("12");
278        let right = json!(expect::string().min_len(3));
279
280        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
281        assert_eq!(
282            output,
283            r#"Json expect::string() error at root:
284    expected string to have at least 3 characters, but it has 2,
285    received "12""#
286        );
287    }
288}
289
290#[cfg(test)]
291mod test_max_len {
292    use crate::expect;
293    use crate::expect_json_eq;
294    use pretty_assertions::assert_eq;
295    use serde_json::json;
296
297    #[test]
298    fn it_should_pass_when_string_has_exactly_enough_characters() {
299        let left = json!("123");
300        let right = json!(expect::string().max_len(3));
301
302        let output = expect_json_eq(&left, &right);
303        assert!(output.is_ok(), "assertion error: {output:#?}");
304    }
305
306    #[test]
307    fn it_should_pass_when_string_has_less_than_enough_characters() {
308        let left = json!("12");
309        let right = json!(expect::string().max_len(5));
310
311        let output = expect_json_eq(&left, &right);
312        assert!(output.is_ok(), "assertion error: {output:#?}");
313    }
314
315    #[test]
316    fn it_should_fail_when_string_is_too_long() {
317        let left = json!("🦊🦊🦊🦊🦊🦊");
318        let right = json!(expect::string().max_len(3));
319
320        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
321        assert_eq!(
322            output,
323            r#"Json expect::string() error at root:
324    expected string to have at most 3 characters, but it has 24,
325    received "🦊🦊🦊🦊🦊🦊""#
326        );
327    }
328}