Skip to main content

expect_json/expect/ops/expect_array/
expect_array.rs

1use crate::JsonType;
2use crate::expect::ExpectObject;
3use crate::expect::ops::expect_array::ExpectArraySubOp;
4use crate::expect_core::Context;
5use crate::expect_core::ExpectOp;
6use crate::expect_core::ExpectOpResult;
7use crate::expect_core::expect_op;
8use serde_json::Value;
9use std::fmt::Debug;
10
11#[expect_op(internal, name = "array")]
12#[derive(Debug, Clone, Default, PartialEq)]
13pub struct ExpectArray {
14    sub_ops: Vec<ExpectArraySubOp>,
15}
16
17impl ExpectArray {
18    pub(crate) fn new() -> Self {
19        Self { sub_ops: vec![] }
20    }
21
22    pub fn empty(mut self) -> Self {
23        self.sub_ops.push(ExpectArraySubOp::Empty);
24        self
25    }
26
27    pub fn not_empty(mut self) -> Self {
28        self.sub_ops.push(ExpectArraySubOp::NotEmpty);
29        self
30    }
31
32    pub fn len(mut self, len: usize) -> Self {
33        self.sub_ops.push(ExpectArraySubOp::Len(len));
34        self
35    }
36
37    pub fn min_len(mut self, min_len: usize) -> Self {
38        self.sub_ops.push(ExpectArraySubOp::MinLen(min_len));
39        self
40    }
41
42    pub fn max_len(mut self, max_len: usize) -> Self {
43        self.sub_ops.push(ExpectArraySubOp::MaxLen(max_len));
44        self
45    }
46
47    pub fn contains<I, V>(mut self, expected_values: I) -> Self
48    where
49        I: IntoIterator<Item = V>,
50        V: Into<Value>,
51    {
52        let inner_expected_values = expected_values
53            .into_iter()
54            .map(Into::into)
55            .collect::<Vec<_>>();
56        self.sub_ops
57            .push(ExpectArraySubOp::Contains(inner_expected_values));
58        self
59    }
60
61    /// Expects all values in the array match the expected values in some order.
62    /// This can be an exact value, or an `ExpectOp`.
63    /// The lengths of the arrays must be equal.
64    pub fn eq_unordered<I, V>(mut self, expected_values: I) -> Self
65    where
66        I: IntoIterator<Item = V>,
67        V: Into<Value>,
68    {
69        let inner_expected_values = expected_values
70            .into_iter()
71            .map(Into::into)
72            .collect::<Vec<_>>();
73        self.sub_ops
74            .push(ExpectArraySubOp::EqUnordered(inner_expected_values));
75        self
76    }
77
78    /// Expects all values in the array match the expected value.
79    /// This can be an exact value, or an `ExpectOp`.
80    ///
81    /// Note an empty array will match this.
82    ///
83    /// ```rust
84    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
85    /// #
86    /// # use axum::Router;
87    /// # use axum::extract::Json;
88    /// # use axum::routing::get;
89    /// # use axum_test::TestServer;
90    /// # use serde_json::json;
91    /// #
92    /// # let server = TestServer::new(Router::new());
93    /// #
94    /// use axum_test::expect_json;
95    ///
96    /// let server = TestServer::new(Router::new());
97    ///
98    /// server.get(&"/users")
99    ///     .await
100    ///     .assert_json(&expect_json::array().all(
101    ///         json!({
102    ///             "name": expect_json::string().not_empty(),
103    ///             "email": expect_json::email(),
104    ///         })
105    ///     ));
106    /// #
107    /// # Ok(()) }
108    /// ```
109    pub fn all<V>(mut self, expected: V) -> Self
110    where
111        V: Into<Value>,
112    {
113        self.sub_ops
114            .push(ExpectArraySubOp::AllEqual(expected.into()));
115        self
116    }
117
118    /// Expects all values to be an object, containing the expected value.
119    ///
120    /// # Example Usage
121    /// ```rust
122    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
123    /// #
124    /// # use axum::Router;
125    /// # use axum::extract::Json;
126    /// # use axum::routing::get;
127    /// # use axum_test::TestServer;
128    /// # use serde_json::json;
129    /// #
130    /// # let server = TestServer::new(Router::new());
131    /// #
132    /// use axum_test::expect_json;
133    ///
134    /// let server = TestServer::new(Router::new());
135    ///
136    /// server.get(&"/users")
137    ///     .await
138    ///     .assert_json(&expect_json::array().all_contains(json!({
139    ///         "name": expect_json::string().not_empty(),
140    ///         "email": expect_json::email(),
141    ///     })));
142    /// #
143    /// # Ok(()) }
144    /// ```
145    ///
146    /// # Equivalent Usage
147    ///
148    /// This is shorthand for using [`ExpectArray::all`] and [`ExpectObject::contains`], like so:
149    /// ```rust
150    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
151    /// #
152    /// # use axum::Router;
153    /// # use axum::extract::Json;
154    /// # use axum::routing::get;
155    /// # use axum_test::TestServer;
156    /// # use serde_json::json;
157    /// #
158    /// # let server = TestServer::new(Router::new());
159    /// #
160    /// use axum_test::expect_json;
161    ///
162    /// let server = TestServer::new(Router::new());
163    ///
164    /// server.get(&"/users")
165    ///     .await
166    ///     .assert_json(&expect_json::array().all(
167    ///         expect_json::object().contains(json!({
168    ///             "name": expect_json::string().not_empty(),
169    ///             "email": expect_json::email(),
170    ///         }))
171    ///     ));
172    /// #
173    /// # Ok(()) }
174    /// ```
175    pub fn all_contains<V>(mut self, expected: V) -> Self
176    where
177        V: Into<Value>,
178    {
179        let obj_contains = ExpectObject::new().contains(expected);
180        self.sub_ops
181            .push(ExpectArraySubOp::AllEqual(obj_contains.into()));
182
183        self
184    }
185
186    /// Expects all values in the array are unique. No duplicates.
187    ///
188    /// ```rust
189    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
190    /// #
191    /// # use axum::Router;
192    /// # use axum::extract::Json;
193    /// # use axum::routing::get;
194    /// # use axum_test::TestServer;
195    /// # use serde_json::json;
196    /// #
197    /// # let server = TestServer::new(Router::new());
198    /// #
199    /// use axum_test::expect_json;
200    ///
201    /// let server = TestServer::new(Router::new());
202    ///
203    /// server.get(&"/users")
204    ///     .await
205    ///     .assert_json(&json!({
206    ///         // expect an array of unique UUIDs
207    ///         "user_ids": expect_json::array()
208    ///             .all(expect_json::uuid())
209    ///             .unique(),
210    ///     }));
211    /// #
212    /// # Ok(()) }
213    /// ```
214    pub fn unique(mut self) -> Self {
215        self.sub_ops.push(ExpectArraySubOp::AllUnique);
216        self
217    }
218}
219
220impl ExpectOp for ExpectArray {
221    fn on_array(&self, context: &mut Context, received: &[Value]) -> ExpectOpResult<()> {
222        for sub_op in &self.sub_ops {
223            sub_op.on_array(self, context, received)?;
224        }
225
226        Ok(())
227    }
228
229    fn debug_supported_types(&self) -> &'static [JsonType] {
230        &[JsonType::Array]
231    }
232}
233
234#[cfg(test)]
235mod test_contains {
236    use crate::expect;
237    use crate::expect_json_eq;
238    use pretty_assertions::assert_eq;
239    use serde_json::json;
240
241    #[test]
242    fn it_should_be_equal_for_identical_numeric_arrays() {
243        let left = json!([1, 2, 3]);
244        let right = json!(expect::array().contains([1, 2, 3]));
245
246        let output = expect_json_eq(&left, &right);
247        assert!(output.is_ok());
248    }
249
250    #[test]
251    fn it_should_be_equal_for_reversed_identical_numeric_arrays() {
252        let left = json!([1, 2, 3]);
253        let right = json!(expect::array().contains([3, 2, 1]));
254
255        let output = expect_json_eq(&left, &right);
256        assert!(output.is_ok());
257    }
258
259    #[test]
260    fn it_should_be_equal_for_partial_contains() {
261        let left = json!([0, 1, 2, 3, 4, 5]);
262        let right = json!(expect::array().contains([1, 2, 3]));
263
264        let output = expect_json_eq(&left, &right);
265        assert!(output.is_ok());
266    }
267
268    #[test]
269    fn it_should_error_for_totall_different_values() {
270        let left = json!([0, 1, 2, 3]);
271        let right = json!(expect::array().contains([4, 5, 6]));
272
273        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
274        assert_eq!(
275            output,
276            r#"Json array at root does not contain expected value:
277    expected array to contain 4, but it was not found.
278    received [0, 1, 2, 3]"#
279        );
280    }
281
282    #[test]
283    fn it_should_be_ok_for_empty_contains() {
284        let left = json!([0, 1, 2, 3]);
285        let right = json!(expect::array().contains([] as [u32; 0]));
286
287        let output = expect_json_eq(&left, &right);
288        assert!(output.is_ok());
289    }
290
291    #[test]
292    fn it_should_error_if_used_against_the_wrong_type() {
293        let left = json!("🦊");
294        let right = json!(expect::array().contains([4, 5, 6]));
295
296        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
297        assert_eq!(
298            output,
299            r#"Json expect::array() at root, received wrong type:
300    expected array
301    received string "🦊""#
302        );
303    }
304
305    #[test]
306    fn it_should_handle_nested_contains() {
307        let left = json!([
308            {
309                "text": "Hello",
310                "author": "Jane Candle"
311            },
312            {
313                "text": "Goodbye",
314                "author": "John Lighthouse"
315            }
316        ]);
317
318        let right = json!(expect::array().contains([json!({
319            "text": "Hello",
320            "author": expect::string().contains("Jane"),
321        }),]));
322
323        let output = expect_json_eq(&left, &right);
324        assert!(output.is_ok(), "{}", output.unwrap_err().to_string());
325    }
326
327    #[test]
328    fn it_should_fail_nested_contains_that_do_not_match() {
329        let left = json!([
330            {
331                "text": "Hello",
332                "author": "Jane Candle"
333            },
334            {
335                "text": "Goodbye",
336                "author": "John Lighthouse"
337            }
338        ]);
339
340        let right = json!(expect::array().contains([json!({
341            "text": "Hello",
342            "author": expect::string().contains("🦊"),
343        }),]));
344
345        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
346        assert_eq!(
347            output,
348            r#"Json array at root does not contain expected value:
349    expected array to contain {
350        "author": expect::string(),
351        "text": "Hello"
352    }, but it was not found.
353    received [
354        {
355            "author": "Jane Candle",
356            "text": "Hello"
357        },
358        {
359            "author": "John Lighthouse",
360            "text": "Goodbye"
361        }
362    ]"#
363        );
364    }
365}
366
367#[cfg(test)]
368mod test_empty {
369    use crate::expect;
370    use crate::expect_json_eq;
371    use pretty_assertions::assert_eq;
372    use serde_json::json;
373
374    #[test]
375    fn it_should_pass_when_array_is_empty() {
376        let left = json!([]);
377        let right = json!(expect::array().empty());
378
379        let output = expect_json_eq(&left, &right);
380        assert!(output.is_ok(), "assertion error: {output:#?}");
381    }
382
383    #[test]
384    fn it_should_fail_when_array_is_not_empty() {
385        let left = json!([1, 2, 3]);
386        let right = json!(expect::array().empty());
387
388        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
389        assert_eq!(
390            output,
391            r#"Json expect::array() error at root:
392    expected empty array
393    received [1, 2, 3]"#
394        );
395    }
396}
397
398#[cfg(test)]
399mod test_not_empty {
400    use crate::expect;
401    use crate::expect_json_eq;
402    use pretty_assertions::assert_eq;
403    use serde_json::json;
404
405    #[test]
406    fn it_should_pass_when_array_is_not_empty() {
407        let left = json!([1]);
408        let right = json!(expect::array().not_empty());
409
410        let output = expect_json_eq(&left, &right);
411        assert!(output.is_ok(), "assertion error: {output:#?}");
412    }
413
414    #[test]
415    fn it_should_fail_when_array_is_empty() {
416        let left = json!([]);
417        let right = json!(expect::array().not_empty());
418
419        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
420        assert_eq!(
421            output,
422            r#"Json expect::array() error at root:
423    expected non-empty array
424    received []"#
425        );
426    }
427}
428
429#[cfg(test)]
430mod test_min_len {
431    use crate::expect;
432    use crate::expect_json_eq;
433    use pretty_assertions::assert_eq;
434    use serde_json::json;
435
436    #[test]
437    fn it_should_pass_when_array_has_exactly_enough_elements() {
438        let left = json!([1, 2, 3]);
439        let right = json!(expect::array().min_len(3));
440
441        let output = expect_json_eq(&left, &right);
442        assert!(output.is_ok(), "assertion error: {output:#?}");
443    }
444
445    #[test]
446    fn it_should_pass_when_array_has_more_than_enough_elements() {
447        let left = json!([1, 2, 3, 4, 5]);
448        let right = json!(expect::array().min_len(3));
449
450        let output = expect_json_eq(&left, &right);
451        assert!(output.is_ok(), "assertion error: {output:#?}");
452    }
453
454    #[test]
455    fn it_should_fail_when_array_has_too_few_elements() {
456        let left = json!([1, 2, 3]);
457        let right = json!(expect::array().min_len(4));
458
459        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
460        assert_eq!(
461            output,
462            r#"Json expect::array() error at root:
463    expected array to have at least 4 elements, but it has 3.
464    received [1, 2, 3]"#
465        );
466    }
467}
468
469#[cfg(test)]
470mod test_len {
471    use crate::expect;
472    use crate::expect_json_eq;
473    use pretty_assertions::assert_eq;
474    use serde_json::json;
475
476    #[test]
477    fn it_should_pass_when_array_has_exactly_enough_elements() {
478        let left = json!([1, 2, 3]);
479        let right = json!(expect::array().len(3));
480
481        let output = expect_json_eq(&left, &right);
482        assert!(output.is_ok(), "assertion error: {output:#?}");
483    }
484
485    #[test]
486    fn it_should_fail_when_array_has_more_than_enough_elements() {
487        let left = json!([1, 2, 3, 4, 5]);
488        let right = json!(expect::array().len(3));
489
490        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
491        assert_eq!(
492            output,
493            r#"Json expect::array() error at root:
494    expected array to have 3 elements, but it has 5.
495    received [1, 2, 3, 4, 5]"#
496        );
497    }
498
499    #[test]
500    fn it_should_fail_when_array_has_too_few_elements() {
501        let left = json!([1, 2, 3]);
502        let right = json!(expect::array().len(4));
503
504        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
505        assert_eq!(
506            output,
507            r#"Json expect::array() error at root:
508    expected array to have 4 elements, but it has 3.
509    received [1, 2, 3]"#
510        );
511    }
512}
513
514#[cfg(test)]
515mod test_max_len {
516    use crate::expect;
517    use crate::expect_json_eq;
518    use pretty_assertions::assert_eq;
519    use serde_json::json;
520
521    #[test]
522    fn it_should_pass_when_array_has_exactly_enough_elements() {
523        let left = json!([1, 2, 3]);
524        let right = json!(expect::array().max_len(3));
525
526        let output = expect_json_eq(&left, &right);
527        assert!(output.is_ok(), "assertion error: {output:#?}");
528    }
529
530    #[test]
531    fn it_should_pass_when_array_has_less_than_enough_elements() {
532        let left = json!([1, 2]);
533        let right = json!(expect::array().max_len(6));
534
535        let output = expect_json_eq(&left, &right);
536        assert!(output.is_ok(), "assertion error: {output:#?}");
537    }
538
539    #[test]
540    fn it_should_fail_when_array_has_too_few_elements() {
541        let left = json!([1, 2, 3, 4]);
542        let right = json!(expect::array().max_len(3));
543
544        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
545        assert_eq!(
546            output,
547            r#"Json expect::array() error at root:
548    expected array to have at most 3 elements, but it has 4.
549    received [1, 2, 3, 4]"#
550        );
551    }
552}
553
554#[cfg(test)]
555mod test_eq_unordered {
556    use crate::expect;
557    use crate::expect_json_eq;
558    use pretty_assertions::assert_eq;
559    use serde_json::json;
560
561    #[test]
562    fn it_should_pass_when_arrays_match_unordered() {
563        let left = json!([1, 2, 3]);
564        let right = json!(expect::array().eq_unordered([3, 2, 1]));
565
566        let output = expect_json_eq(&left, &right);
567        assert!(output.is_ok(), "assertion error: {output:#?}");
568    }
569
570    #[test]
571    fn it_should_fail_when_arrays_do_not_match_unordered() {
572        let left = json!([1, 2, 3]);
573        let right = json!(expect::array().eq_unordered([4, 5, 6]));
574
575        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
576        assert_eq!(
577            output,
578            r#"Json expect::array() error at root, mismatch:
579    expected array (up to order): [4, 5, 6],
580    received array: [1, 2, 3]"#
581        );
582    }
583
584    #[test]
585    fn it_should_fail_when_arrays_have_different_lengths() {
586        let left = json!([1, 2, 3]);
587        let right = json!(expect::array().eq_unordered([1, 2, 3, 4]));
588        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
589        assert_eq!(
590            output,
591            r#"Json expect::array() error at root, mismatch:
592    expected array (up to order): [1, 2, 3, 4],
593    received array: [1, 2, 3]"#
594        );
595    }
596
597    #[test]
598    fn it_should_pass_with_complex_matches() {
599        let left = json!(["Alice", "Bob", "Charlie"]);
600        let right = json!(expect::array().eq_unordered([
601            expect::string().contains("C"),
602            expect::string().contains("A"),
603            expect::string().contains("B"),
604        ]));
605        let output = expect_json_eq(&left, &right);
606        assert!(output.is_ok(), "assertion error: {output:#?}");
607    }
608
609    #[test]
610    fn it_should_pass_not_using_greedy_matching() {
611        // If we used greedy matching, "Alice" would match to the first expect::string(),
612        // then "Charlie" would fail.
613        let left = json!(["Alice", "Bob", "Charlie"]);
614        let right = json!(expect::array().eq_unordered([
615            expect::string(),
616            expect::string().contains("B"),
617            expect::string().contains("A"),
618        ]));
619        let output = expect_json_eq(&left, &right);
620        assert!(output.is_ok(), "assertion error: {output:#?}");
621    }
622
623    #[test]
624    fn it_should_pass_with_equal_elements() {
625        let left = json!(["Alice", "Alice", "Alice"]);
626        let right = json!(expect::array().eq_unordered([
627            expect::string().contains("A"),
628            expect::string().contains("A"),
629            expect::string().contains("A"),
630        ]));
631        let output = expect_json_eq(&left, &right);
632        assert!(output.is_ok(), "assertion error: {output:#?}");
633    }
634
635    #[test]
636    fn it_should_pass_on_a_multiset_with_bijection() {
637        let left = json!(["Alice", "Alice", "Bob"]);
638        let right = json!(expect::array().eq_unordered(["Bob", "Alice", "Alice"]));
639        let output = expect_json_eq(&left, &right);
640        assert!(output.is_ok(), "assertion error: {output:#?}");
641    }
642
643    #[test]
644    fn it_should_fail_when_there_is_no_bijection() {
645        // Both "Bob" and "Boris" should match the same expect::string().contains("B"),
646        // so there is no way to have a perfect matching.
647        let left = json!(["Alice", "Bob", "Boris"]);
648        let right = json!(expect::array().eq_unordered([
649            expect::string().contains("A"),
650            expect::string().contains("A"),
651            expect::string().contains("B"),
652        ]));
653        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
654        assert_eq!(
655            output,
656            r#"Json expect::array() error at root, mismatch:
657    expected array (up to order): [
658        expect::string(),
659        expect::string(),
660        expect::string()
661    ],
662    received array: ["Alice", "Bob", "Boris"]"#
663        );
664    }
665}
666
667#[cfg(test)]
668mod test_all {
669    use crate::expect;
670    use crate::expect_json_eq;
671    use pretty_assertions::assert_eq;
672    use serde_json::json;
673
674    #[test]
675    fn it_should_pass_when_array_is_empty() {
676        let left = json!([]);
677        let right = json!(expect::array().all(expect::string()));
678
679        let output = expect_json_eq(&left, &right);
680        assert!(output.is_ok(), "assertion error: {output:#?}");
681    }
682
683    #[test]
684    fn it_should_pass_with_mix_of_operations() {
685        let left = json!([
686            "123e4567-e89b-12d3-a456-426614174000",
687            "123e4567-e89b-12d3-a456-426614174001",
688            "123e4567-e89b-12d3-a456-426614174002",
689        ]);
690        let right = json!(expect::array().all(expect::uuid()).len(3).unique());
691
692        let output = expect_json_eq(&left, &right);
693        assert!(output.is_ok(), "assertion error: {output:#?}");
694    }
695
696    #[test]
697    fn it_should_fail_with_mix_of_operations() {
698        let left = json!([
699            "123e4567-e89b-12d3-a456-426614174000",
700            "123e4567-e89b-12d3-a456-426614174001",
701            "123e4567-e89b-12d3-a456-426614174002",
702            "123e4567-e89b-12d3-a456-426614174003",
703        ]);
704        let right = json!(expect::array().all(expect::uuid()).len(3).unique());
705
706        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
707        assert_eq!(
708            output,
709            r#"Json expect::array() error at root:
710    expected array to have 3 elements, but it has 4.
711    received ["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001", "123e4567-e89b-12d3-a456-426614174002", "123e4567-e89b-12d3-a456-426614174003"]"#
712        );
713    }
714
715    #[test]
716    fn it_should_fail_when_array_values_do_not_match_expect_op() {
717        let left = json!([1, 2, 3]);
718        let right = json!(expect::array().all(expect::string()));
719
720        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
721        assert_eq!(
722            output,
723            r#"Json expect::string() at root[0], received wrong type:
724    expected string
725    received integer 1
726    received full array [1, 2, 3]"#
727        );
728    }
729
730    #[test]
731    fn it_should_fail_when_array_values_do_not_match_values() {
732        let left = json!([1, 2, 3]);
733        let right = json!(expect::array().all("🦊"));
734
735        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
736        assert_eq!(
737            output,
738            r#"Json values at root[0] are different types:
739    expected string "🦊"
740    received integer 1
741    received full array [1, 2, 3]"#
742        );
743    }
744
745    #[test]
746    fn it_should_pass_when_array_values_do_match_expect_op() {
747        let left = json!(["alice@example.com", "bob@example.com"]);
748        let right = json!(expect::array().all(expect::email()));
749
750        let output = expect_json_eq(&left, &right);
751        assert!(output.is_ok(), "assertion error: {output:#?}");
752    }
753
754    #[test]
755    fn it_should_pass_when_array_values_do_match_values() {
756        let left = json!([1, 1, 1]);
757        let right = json!(expect::array().all(1));
758
759        let output = expect_json_eq(&left, &right);
760        assert!(output.is_ok(), "assertion error: {output:#?}");
761    }
762
763    #[test]
764    fn it_should_pass_when_array_values_do_match_complex_objects() {
765        let left = json!([
766            {
767                "name": "Alice Candles",
768                "email": "alice@example.com"
769            },
770            {
771                "name": "Bob Kettles",
772                "email": "bob@example.com"
773            },
774        ]);
775
776        let right = json!(expect::array().all(json!({
777            "name": expect::string().not_empty(),
778            "email": expect::email(),
779        })));
780
781        let output = expect_json_eq(&left, &right);
782        assert!(output.is_ok(), "assertion error: {output:#?}");
783    }
784
785    #[test]
786    fn it_should_not_pass_when_array_values_do_not_match_complex_objects() {
787        let left = json!([
788            {
789                "name": "Alice Candles",
790                "email": "alice@example.com"
791            },
792            {
793                "name": "",
794                "email": "bob@example.com"
795            },
796        ]);
797
798        let right = json!(expect::array().all(json!({
799            "name": expect::string().not_empty(),
800            "email": expect::email(),
801        })));
802
803        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
804        assert_eq!(
805            output,
806            r#"Json expect::string() error at root[1].name:
807    expected non-empty string
808    received ""
809    received full array [
810        {
811            "email": "alice@example.com",
812            "name": "Alice Candles"
813        },
814        {
815            "email": "bob@example.com",
816            "name": ""
817        }
818    ]"#
819        );
820    }
821
822    #[test]
823    fn it_should_pass_with_nested_contains() {
824        let left = json!([
825            {
826                "name": "Alice Candles",
827                "email": "alice@example.com"
828            },
829            {
830                "name": "Bob Kettles",
831                "email": "bob@example.com"
832            },
833        ]);
834
835        let right = json!(expect::array().all(expect::object().contains(json!({
836            "name": expect::string().not_empty(),
837        })),));
838
839        let output = expect_json_eq(&left, &right);
840        assert!(output.is_ok(), "assertion error: {output:#?}");
841    }
842}
843
844#[cfg(test)]
845mod test_unique {
846    use crate::expect;
847    use crate::expect_json_eq;
848    use pretty_assertions::assert_eq;
849    use serde_json::json;
850
851    #[test]
852    fn it_should_pass_when_array_is_empty() {
853        let left = json!([]);
854        let right = json!(expect::array().unique());
855
856        let output = expect_json_eq(&left, &right);
857        assert!(output.is_ok(), "assertion error: {output:#?}");
858    }
859
860    #[test]
861    fn it_should_fail_when_array_is_not_unique() {
862        let left = json!([1, 1, 2]);
863        let right = json!(expect::array().unique());
864
865        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
866        assert_eq!(
867            output,
868            r#"Json expect::array() error at root[1],
869    expected array to contain all unique values.
870    found duplicate 1
871    received full array [1, 1, 2]"#
872        );
873    }
874}