expect_json/expects/ops/contains/
array_contains.rs

1use crate::expects::SerializeExpectOp;
2use crate::internals::objects::ArrayObject;
3use crate::internals::types::ValueType;
4use crate::internals::Context;
5use crate::internals::JsonExpectOp;
6use crate::internals::JsonValueEqError;
7use crate::internals::JsonValueEqResult;
8use serde::Deserialize;
9use serde::Serialize;
10use serde_json::Value;
11use std::collections::HashSet;
12
13#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
14pub struct ArrayContains {
15    values: Vec<Value>,
16}
17
18impl ArrayContains {
19    pub(crate) fn new(values: Vec<Value>) -> Self {
20        Self { values }
21    }
22}
23
24impl JsonExpectOp for ArrayContains {
25    fn on_array<'a>(
26        self,
27        context: &mut Context<'a>,
28        received_values: &'a [Value],
29    ) -> JsonValueEqResult<()> {
30        let received_items_in_set = received_values.iter().collect::<HashSet<&'a Value>>();
31
32        for expected in self.values {
33            if !received_items_in_set.contains(&expected) {
34                return Err(JsonValueEqError::ContainsNotFound {
35                    context: context.to_static(),
36                    json_type: ValueType::Array,
37                    expected: expected.into(),
38                    received: ArrayObject::from(received_values.to_owned()).into(),
39                });
40            }
41        }
42
43        Ok(())
44    }
45}
46
47impl From<ArrayContains> for SerializeExpectOp {
48    fn from(contains: ArrayContains) -> Self {
49        SerializeExpectOp::ArrayContains(contains)
50    }
51}
52
53#[cfg(test)]
54mod test_array_contains {
55    use crate::expect;
56    use crate::expect_json_eq;
57    use pretty_assertions::assert_eq;
58    use serde_json::json;
59
60    #[test]
61    fn it_should_be_equal_for_identical_numeric_arrays() {
62        let left = json!([1, 2, 3]);
63        let right = json!(expect.contains([1, 2, 3]));
64
65        let output = expect_json_eq(&left, &right);
66        assert!(output.is_ok());
67    }
68
69    #[test]
70    fn it_should_be_equal_for_reversed_identical_numeric_arrays() {
71        let left = json!([1, 2, 3]);
72        let right = json!(expect.contains([3, 2, 1]));
73
74        let output = expect_json_eq(&left, &right);
75        assert!(output.is_ok());
76    }
77
78    #[test]
79    fn it_should_be_equal_for_partial_contains() {
80        let left = json!([0, 1, 2, 3, 4, 5]);
81        let right = json!(expect.contains([1, 2, 3]));
82
83        let output = expect_json_eq(&left, &right);
84        assert!(output.is_ok());
85    }
86
87    #[test]
88    fn it_should_error_for_totall_different_values() {
89        let left = json!([0, 1, 2, 3]);
90        let right = json!(expect.contains([4, 5, 6]));
91
92        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
93        assert_eq!(
94            output,
95            r#"Json array at root does not contain expected value:
96    expected array to contain 4, but it was not found.
97    received [0, 1, 2, 3]"#
98        );
99    }
100
101    #[test]
102    fn it_should_be_ok_for_empty_contains() {
103        let left = json!([0, 1, 2, 3]);
104        let right = json!(expect.contains(&[] as &'static [u32]));
105
106        let output = expect_json_eq(&left, &right);
107        assert!(output.is_ok());
108    }
109}