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