Crate googletest_json_serde

Crate googletest_json_serde 

Source
Expand description

Logo

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.

Crates.io CI Docs.rs License

§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!
  • 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

§Contributing

§License

Dual-licensed under MIT or Apache-2.0.

Modules§

json

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.
valueDeprecated
Matches a JSON string, number, or boolean against the given matcher.

Functions§

any_valueDeprecated
Matches JSON values that are not null.
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_false
Matches the JSON boolean false value.
is_fractional_number
Matches JSON numbers that have a non-zero fractional part.
is_integer
Matches JSON numbers that are integers.
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 true value.
is_whole_number
Matches JSON numbers whose fractional part is zero (e.g., 2 or 2.0).
predicate
Builds a JSON matcher from an arbitrary predicate function.