
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;
use serde_json::json as j;
let actual = j!({
"vampire": { "name": "Nandor the Relentless", "age": 758, "familiar": "Guillermo" },
"house": { "city": "Staten Island", "roommates": ["Laszlo", "Nadja", "Colin Robinson"] }
});
assert_that!(
actual,
json::pat!({
"vampire": json::pat!({
"name": starts_with("Nandor"),
"age": gt(500),
"familiar": eq("Guillermo"),
}),
"house": json::pat!({
"city": eq("Staten Island"),
"roommates": json::unordered_elements_are![
eq("Laszlo"),
eq("Nadja"),
contains_substring("Robinson"),
],
}),
.. })
);
Features
- Object patterns:
json::matches_pattern! / json::pat! (strict or relaxed)
- Arrays:
- Ordered:
json::elements_are!
- Unordered:
json::unordered_elements_are!
- Contains-each:
json::contains_each!
- Contained-in:
json::is_contained_in!
- Length:
json::len!
- Apply to all elements:
json::each!
- Primitives and kinds:
json::primitive!, json::is_number/integer/fractional_number/whole_number/string/boolean, json::is_true/false, json::is_null, json::is_not_null, json::is_empty_array/object
- Paths and shape:
json::has_paths, json::has_only_paths, json::has_path_with!
- Optional fields:
- Clear diagnostics that point to the failing path or element.
More Examples
Primitives
use googletest::prelude::*;
use googletest_json_serde::json;
use serde_json::json as j;
assert_that!(j!(42), json::primitive!(gt(40_i64)));
assert_that!(j!("Laszlo"), json::primitive!(starts_with("Las")));
assert_that!(j!(true), json::is_true());
assert_that!(j!(null), json::is_null());
assert_that!(j!(7), json::is_integer());
assert_that!(j!(7.0), json::is_whole_number());
assert_that!(j!(7.25), json::is_fractional_number());
Path value matching
use googletest::prelude::*;
use googletest_json_serde::json;
use serde_json::json as j;
let value = j!({"user": {"id": 7, "name": "Ada"}});
assert_that!(value, json::has_path_with!("user.name", "Ada"));
assert_that!(value, json::has_path_with!("user.id", j!(7)));
assert_that!(value, json::has_path_with!("user.name", starts_with("A")));
Predicates
use googletest::prelude::*;
use googletest_json_serde::json;
use serde_json::json as j;
assert_that!(j!(42), json::predicate(|v| v.as_i64().map_or(false, |n| n > 0)));
assert_that!(j!("Energy vampire"), json::predicate(|v| v.as_str().map_or(false, |s| s.contains("Energy"))));
Objects
use googletest::prelude::*;
use googletest_json_serde::json;
use serde_json::json as j;
assert_that!(
j!({"name": "Laszlo", "age": 310, "familiar": null}),
json::pat!({
"name": starts_with("Las"),
"age": gt(300),
"familiar": json::is_null(),
.. })
);
Arrays
use googletest::prelude::*;
use googletest_json_serde::json;
use serde_json::json as j;
assert_that!(
j!(["Nandor", 758, true]),
json::elements_are![eq("Nandor"), json::is_number(), is_true()]
);
assert_that!(
j!(["Laszlo", "Nadja", "Colin Robinson"]),
json::unordered_elements_are![eq("Colin Robinson"), "Laszlo", "Nadja"]
);
assert_that!(
j!(["familiar", 1, null]),
json::contains_each![json::is_string(), json::is_not_null()]
);
Combined Example
use googletest::prelude::*;
use googletest_json_serde::json;
use serde_json::json as j;
assert_that!(
j!({
"guests": [
{"name": "Baron Afanas", "age": 2000},
{"name": "The Guide", "age": 500}
],
"house": { "city": "Staten Island", "roommates": 4 }
}),
json::pat!({
"guests": json::unordered_elements_are![
json::pat!({ "name": starts_with("Baron"), "age": gt(1500) }),
json::pat!({ "name": eq("The Guide"), "age": ge(400) })
],
"house": json::pat!({ "city": eq("Staten Island"), "roommates": eq(4) }),
})
);
Documentation
Contributing
License
Dual-licensed under MIT or Apache-2.0.