use crate::expect_op::expect_op;
use crate::expect_op::ExpectOp;
use crate::internals::objects::ArrayObject;
use crate::expect_op::Context;
use crate::ExpectOpError;
use crate::ExpectOpResult;
use crate::JsonType;
use serde_json::Value;
use std::collections::HashSet;
#[expect_op(internal)]
#[derive(Clone, Debug, PartialEq)]
pub struct ArrayContainsNot {
values: Vec<Value>,
}
impl ArrayContainsNot {
pub(crate) fn new(values: Vec<Value>) -> Self {
Self { values }
}
}
impl ExpectOp for ArrayContainsNot {
fn on_array(&self, context: &mut Context<'_>, received_values: &[Value]) -> ExpectOpResult<()> {
let received_items_in_set = received_values.iter().collect::<HashSet<&Value>>();
for expected in &self.values {
if received_items_in_set.contains(&expected) {
return Err(ExpectOpError::ContainsFound {
context: context.to_static(),
json_type: JsonType::Array,
expected: expected.clone().into(),
received: ArrayObject::from(received_values.to_owned()).into(),
});
}
}
Ok(())
}
fn supported_types(&self) -> &'static [JsonType] {
&[JsonType::Array]
}
}
#[cfg(test)]
mod test_array_contains_not {
use crate::expect;
use crate::expect_json_eq;
use pretty_assertions::assert_eq;
use serde_json::json;
#[test]
fn it_should_error_for_identical_numeric_arrays() {
let left = json!([1, 2, 3]);
let right = json!(expect.not.contains([1, 2, 3]));
let output = expect_json_eq(&left, &right).unwrap_err().to_string();
assert_eq!(
output,
r#"Json array at root contains value was expecting to not be there:
expected array to not contain 1, but it was found.
received [1, 2, 3]"#
);
}
#[test]
fn it_should_errorfor_reversed_identical_numeric_arrays() {
let left = json!([1, 2, 3]);
let right = json!(expect.not.contains([3, 2, 1]));
let output = expect_json_eq(&left, &right).unwrap_err().to_string();
assert_eq!(
output,
r#"Json array at root contains value was expecting to not be there:
expected array to not contain 3, but it was found.
received [1, 2, 3]"#
);
}
#[test]
fn it_should_error_for_partial_contains() {
let left = json!([0, 1, 2, 3, 4, 5]);
let right = json!(expect.not.contains([1, 2, 3]));
let output = expect_json_eq(&left, &right).unwrap_err().to_string();
assert_eq!(
output,
r#"Json array at root contains value was expecting to not be there:
expected array to not contain 1, but it was found.
received [0, 1, 2, 3, 4, 5]"#
);
}
#[test]
fn it_should_be_ok_for_totall_different_values() {
let left = json!([0, 1, 2, 3]);
let right = json!(expect.not.contains([4, 5, 6]));
let output = expect_json_eq(&left, &right);
assert!(output.is_ok());
}
#[test]
fn it_should_be_ok_for_empty_contains() {
let left = json!([0, 1, 2, 3]);
let right = json!(expect.not.contains(&[] as &'static [u32]));
let output = expect_json_eq(&left, &right);
assert!(output.is_ok());
}
}