14 unstable releases (3 breaking)
Uses new Rust 2024
| new 0.4.5 | Dec 3, 2025 |
|---|---|
| 0.4.4 | Nov 30, 2025 |
| 0.3.1 | Nov 2, 2025 |
| 0.3.0 | Oct 26, 2025 |
| 0.1.0 | Sep 29, 2025 |
#163 in Testing
112 downloads per month
125KB
2.5K
SLoC
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;
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"),
],
}),
.. // allow extra fields
})
);
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!
- Ordered:
- 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:
json::optional!
- 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(),
.. // allow extras like hobbies or cursed hats
})
);
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
- 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.
Dependencies
~3–5MB
~95K SLoC