expect_json/expects/ops/expect_string/
expect_string.rs

1use crate::expect_op;
2use crate::ops::expect_string::ExpectStringSubOp;
3use crate::Context;
4use crate::ExpectOp;
5use crate::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 is_empty(mut self) -> Self {
20        self.sub_ops.push(ExpectStringSubOp::IsEmpty);
21        self
22    }
23
24    pub fn is_not_empty(mut self) -> Self {
25        self.sub_ops.push(ExpectStringSubOp::IsNotEmpty);
26        self
27    }
28
29    pub fn min_len(mut self, min_len: usize) -> Self {
30        self.sub_ops.push(ExpectStringSubOp::MinLen(min_len));
31        self
32    }
33
34    pub fn max_len(mut self, max_len: usize) -> Self {
35        self.sub_ops.push(ExpectStringSubOp::MaxLen(max_len));
36        self
37    }
38
39    pub fn contains<S>(mut self, expected_sub_string: S) -> Self
40    where
41        S: Into<String>,
42    {
43        self.sub_ops
44            .push(ExpectStringSubOp::Contains(expected_sub_string.into()));
45        self
46    }
47}
48
49impl ExpectOp for ExpectString {
50    fn on_string(&self, context: &mut Context, received: &str) -> ExpectOpResult<()> {
51        for sub_op in &self.sub_ops {
52            sub_op.on_string(self, context, received)?;
53        }
54
55        Ok(())
56    }
57
58    fn supported_types(&self) -> &'static [JsonType] {
59        &[JsonType::String]
60    }
61}
62
63#[cfg(test)]
64mod test_contains {
65    use crate::expect;
66    use crate::expect_json_eq;
67    use pretty_assertions::assert_eq;
68    use serde_json::json;
69
70    #[test]
71    fn it_should_be_equal_for_identical_strings() {
72        let left = json!("1, 2, 3");
73        let right = json!(expect::string().contains("1, 2, 3"));
74
75        let output = expect_json_eq(&left, &right);
76        assert!(output.is_ok());
77    }
78
79    #[test]
80    fn it_should_be_equal_for_partial_matches_in_middle() {
81        let left = json!("0, 1, 2, 3, 4");
82        let right = json!(expect::string().contains("1, 2, 3"));
83
84        let output = expect_json_eq(&left, &right);
85        assert!(output.is_ok());
86    }
87
88    #[test]
89    fn it_should_be_ok_for_empty_contains() {
90        let left = json!("0, 1, 2, 3, 4, 5");
91        let right = json!(expect::string().contains(""));
92
93        let output = expect_json_eq(&left, &right);
94        assert!(output.is_ok());
95    }
96
97    #[test]
98    fn it_should_error_for_totall_different_values() {
99        let left = json!("1, 2, 3");
100        let right = json!(expect::string().contains("a, b, c"));
101
102        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
103        assert_eq!(
104            output,
105            r#"Json string at root does not contain expected value:
106    expected string to contain "a, b, c", but it was not found.
107    received "1, 2, 3""#
108        );
109    }
110}
111
112#[cfg(test)]
113mod test_is_empty {
114    use crate::expect;
115    use crate::expect_json_eq;
116    use pretty_assertions::assert_eq;
117    use serde_json::json;
118
119    #[test]
120    fn it_should_pass_when_string_is_empty() {
121        let left = json!("");
122        let right = json!(expect::string().is_empty());
123
124        let output = expect_json_eq(&left, &right);
125        assert!(output.is_ok(), "assertion error: {output:#?}");
126    }
127
128    #[test]
129    fn it_should_fail_when_string_is_not_empty() {
130        let left = json!("🦊");
131        let right = json!(expect::string().is_empty());
132
133        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
134        assert_eq!(
135            output,
136            format!(
137                r#"Json expect::string() error at root:
138    expected empty string
139    received "🦊""#
140            )
141        );
142    }
143}
144
145#[cfg(test)]
146mod test_is_not_empty {
147    use crate::expect;
148    use crate::expect_json_eq;
149    use pretty_assertions::assert_eq;
150    use serde_json::json;
151
152    #[test]
153    fn it_should_pass_when_string_is_not_empty() {
154        let left = json!("🦊");
155        let right = json!(expect::string().is_not_empty());
156
157        let output = expect_json_eq(&left, &right);
158        assert!(output.is_ok(), "assertion error: {output:#?}");
159    }
160
161    #[test]
162    fn it_should_fail_when_string_is_empty() {
163        let left = json!("");
164        let right = json!(expect::string().is_not_empty());
165
166        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
167        assert_eq!(
168            output,
169            format!(
170                r#"Json expect::string() error at root:
171    expected non-empty string
172    received """#
173            )
174        );
175    }
176}
177
178#[cfg(test)]
179mod test_min_len {
180    use crate::expect;
181    use crate::expect_json_eq;
182    use pretty_assertions::assert_eq;
183    use serde_json::json;
184
185    #[test]
186    fn it_should_pass_when_string_has_exactly_enough_characters() {
187        let left = json!("123");
188        let right = json!(expect::string().min_len(3));
189
190        let output = expect_json_eq(&left, &right);
191        assert!(output.is_ok(), "assertion error: {output:#?}");
192    }
193
194    #[test]
195    fn it_should_pass_when_string_has_more_than_enough_characters() {
196        let left = json!("12345");
197        let right = json!(expect::string().min_len(3));
198
199        let output = expect_json_eq(&left, &right);
200        assert!(output.is_ok(), "assertion error: {output:#?}");
201    }
202
203    #[test]
204    fn it_should_fail_when_string_is_too_short() {
205        let left = json!("12");
206        let right = json!(expect::string().min_len(3));
207
208        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
209        assert_eq!(
210            output,
211            format!(
212                r#"Json expect::string() error at root:
213    expected string to have at least 3 characters, but it has 2,
214    received "12""#
215            )
216        );
217    }
218}
219
220#[cfg(test)]
221mod test_max_len {
222    use crate::expect;
223    use crate::expect_json_eq;
224    use pretty_assertions::assert_eq;
225    use serde_json::json;
226
227    #[test]
228    fn it_should_pass_when_string_has_exactly_enough_characters() {
229        let left = json!("123");
230        let right = json!(expect::string().max_len(3));
231
232        let output = expect_json_eq(&left, &right);
233        assert!(output.is_ok(), "assertion error: {output:#?}");
234    }
235
236    #[test]
237    fn it_should_pass_when_string_has_less_than_enough_characters() {
238        let left = json!("12");
239        let right = json!(expect::string().max_len(5));
240
241        let output = expect_json_eq(&left, &right);
242        assert!(output.is_ok(), "assertion error: {output:#?}");
243    }
244
245    #[test]
246    fn it_should_fail_when_string_is_too_long() {
247        let left = json!("🦊🦊🦊🦊🦊🦊");
248        let right = json!(expect::string().max_len(3));
249
250        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
251        assert_eq!(
252            output,
253            format!(
254                r#"Json expect::string() error at root:
255    expected string to have at most 3 characters, but it has 24,
256    received "🦊🦊🦊🦊🦊🦊""#
257            )
258        );
259    }
260}