googletest_json_serde/matchers/
each_is_matcher.rs

1use crate::matchers::__internal_unstable_do_not_depend_on_these;
2use crate::matchers::__internal_unstable_do_not_depend_on_these::JsonPredicateMatcher;
3use googletest::description::Description;
4use serde_json::Value;
5
6fn describe_kind(value: &Value) -> &'static str {
7    match value {
8        Value::Null => "JSON null",
9        Value::Bool(_) => "JSON boolean",
10        Value::Number(_) => "JSON number",
11        Value::String(_) => "JSON string",
12        Value::Array(_) => "JSON array",
13        Value::Object(_) => "JSON object",
14    }
15}
16
17fn build_each_is_type(
18    kind: &'static str,
19    predicate: impl Fn(&Value) -> bool + Copy + 'static,
20) -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
21    JsonPredicateMatcher::new(
22        move |v| match v {
23            Value::Array(a) => a.iter().all(predicate),
24            _ => false,
25        },
26        format!("a JSON array whose elements are {}", kind),
27        "which is not a JSON array",
28    )
29    .with_explain_fn(move |v| match v {
30        Value::Array(a) => a
31            .iter()
32            .enumerate()
33            .find(|(_, el)| !predicate(el))
34            .map(|(idx, el)| {
35                Description::new().text(format!(
36                    "which contains a {} at index {}",
37                    describe_kind(el),
38                    idx
39                ))
40            })
41            .unwrap_or_else(|| Description::new().text("which is an empty JSON array")),
42        _ => __internal_unstable_do_not_depend_on_these::describe_json_type(v),
43    })
44}
45
46/// Matches JSON arrays whose elements are all JSON strings.
47///
48/// # Examples
49///
50/// ```rust
51/// # use googletest::prelude::*;
52/// # use googletest_json_serde::json;
53/// # use serde_json::json as j;
54/// assert_that!(j!( ["a", "b" ]), json::each_is_string());
55/// assert_that!(j!([1, "b"]), not(json::each_is_string()));
56/// ```
57pub fn each_is_string() -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
58    build_each_is_type("JSON string", |v| v.is_string())
59}
60
61/// Matches JSON arrays whose elements are all JSON numbers.
62///
63/// # Examples
64///
65/// ```rust
66/// # use googletest::prelude::*;
67/// # use googletest_json_serde::json;
68/// # use serde_json::json as j;
69/// assert_that!(j!([1, 2, 3]), json::each_is_number());
70/// assert_that!(j!([1, "b"]), not(json::each_is_number()));
71/// ```
72pub fn each_is_number() -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
73    build_each_is_type("JSON number", |v| v.is_number())
74}
75
76/// Matches JSON arrays whose elements are all JSON booleans.
77///
78/// # Examples
79///
80/// ```rust
81/// # use googletest::prelude::*;
82/// # use googletest_json_serde::json;
83/// # use serde_json::json as j;
84/// assert_that!(j!([true, false]), json::each_is_boolean());
85/// assert_that!(j!([true, 1]), not(json::each_is_boolean()));
86/// ```
87pub fn each_is_boolean() -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
88    build_each_is_type("JSON boolean", |v| v.is_boolean())
89}
90
91/// Matches JSON arrays whose elements are all JSON null.
92///
93/// # Examples
94///
95/// ```rust
96/// # use googletest::prelude::*;
97/// # use googletest_json_serde::json;
98/// # use serde_json::json as j;
99/// assert_that!(j!([null, null]), json::each_is_null());
100/// assert_that!(j!([null, true]), not(json::each_is_null()));
101/// ```
102pub fn each_is_null() -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
103    build_each_is_type("JSON null", |v| v.is_null())
104}
105
106/// Matches JSON arrays whose elements are all JSON arrays.
107///
108/// # Examples
109///
110/// ```rust
111/// # use googletest::prelude::*;
112/// # use googletest_json_serde::json;
113/// # use serde_json::json as j;
114/// assert_that!(j!([[1], [2]]), json::each_is_array());
115/// assert_that!(j!([[1], {"a": 1}]), not(json::each_is_array()));
116/// ```
117pub fn each_is_array() -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
118    build_each_is_type("JSON array", |v| v.is_array())
119}
120
121/// Matches JSON arrays whose elements are all JSON objects.
122///
123/// # Examples
124///
125/// ```rust
126/// # use googletest::prelude::*;
127/// # use googletest_json_serde::json;
128/// # use serde_json::json as j;
129/// assert_that!(j!([{ "a": 1 }, { "b": 2 }]), json::each_is_object());
130/// assert_that!(j!([{ "a": 1 }, [1]]), not(json::each_is_object()));
131/// ```
132pub fn each_is_object() -> JsonPredicateMatcher<impl Fn(&Value) -> bool, String, &'static str> {
133    build_each_is_type("JSON object", |v| v.is_object())
134}