Expand description
Overview | Installation | Usage | Features | More Examples | Documentation | Contributing | License
A set of matcher macros for ergonomic JSON testing with googletest-rust.
These tiny, focused matchers make it effortless to assert on serde_json::Value in Rust tests.
§Overview
googletest-json-serde adds focused matcher macros for JSON so your Rust tests read like intent, not plumbing. It handles heterogeneous arrays, deep object patterns, path checks, and produces readable failure messages with path context.
§Installation
Add as a dev-dependency:
cargo add googletest-json-serde --dev§Usage
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
let actual = json!({
"vampire": { "name": "Nandor the Relentless", "age": 758, "familiar": "Guillermo" },
"house": { "city": "Staten Island", "roommates": ["Laszlo", "Nadja", "Colin Robinson"] }
});
assert_that!(
actual,
j::pat!({
"vampire": {
"name": starts_with("Nandor"),
"age": gt(500),
"familiar": eq("Guillermo"),
},
"house": {
"city": eq("Staten Island"),
"roommates": j::unordered_elements_are![
eq("Laszlo"),
eq("Nadja"),
contains_substring("Robinson"),
],
},
.. // allow extra fields
})
);§Features
- Object patterns:
j::matches_pattern!/j::pat!(strict or relaxed)
- Arrays:
- Ordered:
j::elements_are! - Unordered:
j::unordered_elements_are! - Contains-each:
j::contains_each! - Contained-in:
j::is_contained_in! - Length:
j::len! - Apply to all elements:
j::each! - Type guard:
j::each_is_string()/number/boolean/null/array/object
- Ordered:
- Primitives and kinds:
j::primitive!,j::is_number/integer/fractional_number/whole_number/string/boolean,j::is_true/false,j::is_null,j::is_not_null,j::is_empty_string/non_empty_string,j::is_empty_array/object,j::is_non_empty_array/object
- Paths and shape:
j::has_paths,j::has_only_paths,j::has_path_with!
- Adapters (bridge to native matchers):
j::as_string,j::as_bool,j::as_i64(and other number types),j::as_array,j::as_object
- Optional fields:
j::optional!
- Clear diagnostics that point to the failing path or element.
§More Examples
§Primitives
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
assert_that!(json!(42), j::primitive!(gt(40_i64)));
assert_that!(json!("Laszlo"), j::primitive!(starts_with("Las")));
assert_that!(json!(true), j::is_true());
assert_that!(json!(null), j::is_null());
assert_that!(json!(7), j::is_integer());
assert_that!(json!(7.0), j::is_whole_number());
assert_that!(json!(7.25), j::is_fractional_number());§Adapters (Bridge to native matchers)
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
// Bridge to native googletest matchers with explicit type unwrapping
assert_that!(json!("123-ABC"), j::as_string(matches_regex(r"\d{3}-[A-Z]+")));
assert_that!(json!(std::f64::consts::PI), j::as_f64(near(std::f64::consts::PI, 0.01)));
assert_that!(json!([1, 2, 3]), j::as_array(contains(j::as_i64(eq(2)))));§Path value matching
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
let value = json!({"user": {"id": 7, "name": "Ada"}});
assert_that!(value, j::has_path_with!("user.name", "Ada"));
assert_that!(value, j::has_path_with!("user.id", json!(7)));
assert_that!(value, j::has_path_with!("user.name", starts_with("A")));§Predicates
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
assert_that!(json!(42), j::predicate(|v| v.as_i64().map_or(false, |n| n > 0)));
assert_that!(json!("Energy vampire"), j::predicate(|v| v.as_str().map_or(false, |s| s.contains("Energy"))));§Objects
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
assert_that!(
json!({"name": "Laszlo", "age": 310, "familiar": null}),
j::pat!({
"name": starts_with("Las"),
"age": gt(300),
"familiar": j::is_null(),
.. // allow extras like hobbies or cursed hats
})
);§Arrays
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
assert_that!(
json!(["Nandor", 758, true]),
j::elements_are![eq("Nandor"), j::is_number(), is_true()]
);
assert_that!(
json!(["Laszlo", "Nadja", "Colin Robinson"]),
j::unordered_elements_are![eq("Colin Robinson"), "Laszlo", "Nadja"]
);
assert_that!(
json!(["familiar", 1, null]),
j::contains_each![j::is_string(), j::is_not_null()]
);
assert_that!(
json!(["Nandor", "Nadja"]),
j::each_is_string()
);§Combined Example
use googletest::prelude::*;
use googletest_json_serde::json as j;
use serde_json::json;
assert_that!(
json!({
"guests": [
{"name": "Baron Afanas", "age": 2000},
{"name": "The Guide", "age": 500}
],
"house": { "city": "Staten Island", "roommates": 4 },
"ignored": true
}),
j::pat!({
"guests": j::unordered_elements_are![
j::pat!({ "name": starts_with("Baron"), "age": gt(1500) }),
j::pat!({ "name": eq("The Guide"), "age": ge(400) })
],
"house": { "city": eq("Staten Island"), "roommates": eq(4) },
..
})
);§Documentation
- API reference: https://docs.rs/googletest-json-serde
- Crate: https://crates.io/crates/googletest-json-serde
- More usage patterns live in
tests/andsanity/tests/sanity_test.rs.
§Contributing
- Issues: https://github.com/chege/googletest-json-serde/issues
- Contributions welcome! See CONTRIBUTING.md.
§License
Dual-licensed under MIT or Apache-2.0.
Modules§
Macros§
- contains_
each - Matches a JSON array that contains distinct matches for each provided matcher, ignoring order.
- each
- Matches every element of a JSON array against the same matcher.
- elements_
are - Matches a JSON array against a list of matchers in order.
- has_
path_ with - Matches a JSON leaf at the given path against the provided matcher.
- is_
contained_ in - Matches a JSON array where every element satisfies one of the provided matchers without reuse.
- len
- Matches the length of a JSON array against a literal or matcher.
- matches_
pattern - Matches a JSON object against a pattern of key-value matchers.
- optional
- Matches a JSON field that may be absent, null, or satisfy an inner matcher.
- pat
- Matches a JSON object against a pattern of key-value matchers.
- primitive
- Matches a JSON string, number, or boolean against the given matcher.
- unordered_
elements_ are - Matches a JSON array whose elements pair one-to-one with the provided matchers, ignoring order.
- value
Deprecated - Matches a JSON string, number, or boolean against the given matcher.
Functions§
- any_
value Deprecated - Matches JSON values that are not null.
- as_
array - Matches a JSON array value against a native matcher for
&Vec<Value>. - as_bool
- Matches a JSON boolean value against a native boolean matcher.
- as_f64
- Matches a JSON number value as an f64 against a native f64 matcher.
- as_i8
- Matches a JSON number value as an i8 against a native i8 matcher.
- as_i16
- Matches a JSON number value as an i16 against a native i16 matcher.
- as_i32
- Matches a JSON number value as an i32 against a native i32 matcher.
- as_i64
- Matches a JSON number value as an i64 against a native i64 matcher.
- as_
object - Matches a JSON object value against a native matcher for
&Map<String, Value>. - as_
string - Matches a JSON string value against a native string matcher.
- as_u8
- Matches a JSON number value as a u8 against a native u8 matcher.
- as_u16
- Matches a JSON number value as a u16 against a native u16 matcher.
- as_u32
- Matches a JSON number value as a u32 against a native u32 matcher.
- as_u64
- Matches a JSON number value as a u64 against a native u64 matcher.
- as_
usize - Matches a JSON number value as a usize against a native usize matcher.
- each_
is_ array - Matches JSON arrays whose elements are all JSON arrays.
- each_
is_ boolean - Matches JSON arrays whose elements are all JSON booleans.
- each_
is_ null - Matches JSON arrays whose elements are all JSON null.
- each_
is_ number - Matches JSON arrays whose elements are all JSON numbers.
- each_
is_ object - Matches JSON arrays whose elements are all JSON objects.
- each_
is_ string - Matches JSON arrays whose elements are all JSON strings.
- has_
only_ paths - Matches a JSON object whose paths are exactly the provided set (no extras or missing).
- has_
paths - Matches a JSON object that contains all specified paths (order-agnostic, extras allowed).
- is_
array - Matches JSON array values.
- is_
boolean - Matches JSON boolean values.
- is_
empty_ array - Matches an empty JSON array (
[]). - is_
empty_ object - Matches an empty JSON object (
{}). - is_
empty_ string - Matches an empty JSON string (
""). - is_
false - Matches the JSON boolean
falsevalue. - is_
fractional_ number - Matches JSON numbers that have a non-zero fractional part.
- is_
integer - Matches JSON numbers that are integers.
- is_
non_ empty_ array - Matches a non-empty JSON array.
- is_
non_ empty_ object - Matches a non-empty JSON object.
- is_
non_ empty_ string - Matches a non-empty JSON string.
- is_
not_ null - Matches JSON values that are not null.
- is_null
- Matches JSON null values.
- is_
number - Matches JSON number values.
- is_
object - Matches JSON object values.
- is_
string - Matches JSON string values.
- is_true
- Matches the JSON boolean
truevalue. - is_
whole_ number - Matches JSON numbers whose fractional part is zero (e.g.,
2or2.0). - predicate
- Builds a JSON matcher from an arbitrary predicate function.