Skip to content

Commit c3ff361

Browse files
committed
Accept any T: Serialize rather than just serde_json::Value
1 parent 050a1eb commit c3ff361

File tree

5 files changed

+134
-44
lines changed

5 files changed

+134
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
66

77
## Unreleased
88

9-
None.
9+
- All methods now accept any `T: Serialize` rather than just `serde_json::Value`.
1010

1111
### Breaking changes
1212

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extend = "0.1.0"
1919

2020
[dev-dependencies]
2121
version-sync = "0.8"
22+
serde = { version = "1.0.80", features = ["derive"] }
2223

2324
[badges]
2425
travis-ci = { repository = "davidpdrsn/assert-json-diff", branch = "master" }

src/diff.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ macro_rules! direct_compare {
5151
});
5252
}
5353
}
54-
}
54+
};
5555
}
5656

5757
impl<'a, 'b> Folder<'a> for DiffFolder<'a, 'b> {
@@ -323,6 +323,7 @@ trait Folder<'a> {
323323
mod test {
324324
#[allow(unused_imports)]
325325
use super::*;
326+
use serde_json::json;
326327

327328
#[test]
328329
fn test_diffing_leaf_json() {

src/lib.rs

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
//! This crate includes macros for comparing two JSON values. It is designed to give much
2-
//! more helpful error messages than the standard [`assert_eq!`]. It basically does a diff of the
3-
//! two objects and tells you the exact differences. This is useful when asserting that two large
4-
//! JSON objects are the same.
1+
//! This crate includes macros for comparing two serializable values by diffing their JSON
2+
//! representations. It is designed to give much more helpful error messages than the standard
3+
//! [`assert_eq!`]. It basically does a diff of the two objects and tells you the exact
4+
//! differences. This is useful when asserting that two large JSON objects are the same.
55
//!
6-
//! It uses the [`serde_json::Value`] type to represent JSON.
6+
//! It uses the [serde] and [serde_json] to perform the serialization.
77
//!
8-
//! [`serde_json::Value`]: https://docs.serde.rs/serde_json/value/enum.Value.html
8+
//! [serde]: https://crates.io/crates/serde
9+
//! [serde_json]: https://crates.io/crates/serde_json
910
//! [`assert_eq!`]: https://doc.rust-lang.org/std/macro.assert_eq.html
1011
//!
1112
//! ## Partial matching
@@ -14,10 +15,8 @@
1415
//! [`assert_json_include`](macro.assert_json_include.html):
1516
//!
1617
//! ```should_panic
17-
//! #[macro_use]
18-
//! extern crate assert_json_diff;
19-
//! #[macro_use]
20-
//! extern crate serde_json;
18+
//! use assert_json_diff::assert_json_include;
19+
//! use serde_json::json;
2120
//!
2221
//! fn main() {
2322
//! let a = json!({
@@ -82,10 +81,8 @@
8281
//! of the JSON without having to specify the whole thing. For example this test passes:
8382
//!
8483
//! ```
85-
//! #[macro_use]
86-
//! extern crate assert_json_diff;
87-
//! #[macro_use]
88-
//! extern crate serde_json;
84+
//! use assert_json_diff::assert_json_include;
85+
//! use serde_json::json;
8986
//!
9087
//! fn main() {
9188
//! assert_json_include!(
@@ -102,10 +99,8 @@
10299
//! However `expected` cannot contain additional data so this test fails:
103100
//!
104101
//! ```should_panic
105-
//! #[macro_use]
106-
//! extern crate assert_json_diff;
107-
//! #[macro_use]
108-
//! extern crate serde_json;
102+
//! use assert_json_diff::assert_json_include;
103+
//! use serde_json::json;
109104
//!
110105
//! fn main() {
111106
//! assert_json_include!(
@@ -130,10 +125,8 @@
130125
//! If you want to ensure two JSON values are *exactly* the same, use [`assert_json_eq`](macro.assert_json_eq.html).
131126
//!
132127
//! ```rust,should_panic
133-
//! #[macro_use]
134-
//! extern crate assert_json_diff;
135-
//! #[macro_use]
136-
//! extern crate serde_json;
128+
//! use assert_json_diff::assert_json_eq;
129+
//! use serde_json::json;
137130
//!
138131
//! fn main() {
139132
//! assert_json_eq!(
@@ -164,13 +157,8 @@
164157
)]
165158
#![doc(html_root_url = "https://docs.rs/assert-json-diff/1.0.3")]
166159

167-
extern crate serde;
168-
#[allow(unused_imports)]
169-
#[macro_use]
170-
extern crate serde_json;
171-
172160
use diff::{diff, Mode};
173-
use serde_json::Value;
161+
use serde::Serialize;
174162

175163
mod core_ext;
176164
mod diff;
@@ -184,8 +172,8 @@ mod diff;
184172
#[macro_export]
185173
macro_rules! assert_json_include {
186174
(actual: $actual:expr, expected: $expected:expr) => {{
187-
let actual: serde_json::Value = $actual;
188-
let expected: serde_json::Value = $expected;
175+
let actual = $actual;
176+
let expected = $expected;
189177
if let Err(error) = $crate::assert_json_include_no_panic(&actual, &expected) {
190178
panic!("\n\n{}\n\n", error);
191179
}
@@ -209,8 +197,8 @@ macro_rules! assert_json_include {
209197
#[macro_export]
210198
macro_rules! assert_json_eq {
211199
($lhs:expr, $rhs:expr) => {{
212-
let lhs: serde_json::Value = $lhs;
213-
let rhs: serde_json::Value = $rhs;
200+
let lhs = $lhs;
201+
let rhs = $rhs;
214202
if let Err(error) = $crate::assert_json_eq_no_panic(&lhs, &rhs) {
215203
panic!("\n\n{}\n\n", error);
216204
}
@@ -225,7 +213,14 @@ macro_rules! assert_json_eq {
225213
/// Instead it returns a `Result` where the error is the message that would be passed to `panic!`.
226214
/// This is might be useful if you want to control how failures are reported and don't want to deal
227215
/// with panics.
228-
pub fn assert_json_include_no_panic(actual: &Value, expected: &Value) -> Result<(), String> {
216+
pub fn assert_json_include_no_panic<Actual, Expected>(
217+
actual: &Actual,
218+
expected: &Expected,
219+
) -> Result<(), String>
220+
where
221+
Actual: Serialize,
222+
Expected: Serialize,
223+
{
229224
assert_json_no_panic(actual, expected, Mode::Lenient)
230225
}
231226

@@ -234,12 +229,33 @@ pub fn assert_json_include_no_panic(actual: &Value, expected: &Value) -> Result<
234229
/// Instead it returns a `Result` where the error is the message that would be passed to `panic!`.
235230
/// This is might be useful if you want to control how failures are reported and don't want to deal
236231
/// with panics.
237-
pub fn assert_json_eq_no_panic(lhs: &Value, rhs: &Value) -> Result<(), String> {
232+
pub fn assert_json_eq_no_panic<Lhs, Rhs>(lhs: &Lhs, rhs: &Rhs) -> Result<(), String>
233+
where
234+
Lhs: Serialize,
235+
Rhs: Serialize,
236+
{
238237
assert_json_no_panic(lhs, rhs, Mode::Strict)
239238
}
240239

241-
fn assert_json_no_panic(lhs: &Value, rhs: &Value, mode: Mode) -> Result<(), String> {
242-
let diffs = diff(lhs, rhs, mode);
240+
fn assert_json_no_panic<Lhs, Rhs>(lhs: &Lhs, rhs: &Rhs, mode: Mode) -> Result<(), String>
241+
where
242+
Lhs: Serialize,
243+
Rhs: Serialize,
244+
{
245+
let lhs = serde_json::to_value(lhs).unwrap_or_else(|err| {
246+
panic!(
247+
"Couldn't convert left hand side value to JSON. Serde error: {}",
248+
err
249+
)
250+
});
251+
let rhs = serde_json::to_value(rhs).unwrap_or_else(|err| {
252+
panic!(
253+
"Couldn't convert right hand side value to JSON. Serde error: {}",
254+
err
255+
)
256+
});
257+
258+
let diffs = diff(&lhs, &rhs, mode);
243259

244260
if diffs.is_empty() {
245261
Ok(())
@@ -256,6 +272,7 @@ fn assert_json_no_panic(lhs: &Value, rhs: &Value, mode: Mode) -> Result<(), Stri
256272
#[cfg(test)]
257273
mod tests {
258274
use super::*;
275+
use serde_json::{json, Value};
259276
use std::fmt::Write;
260277

261278
#[test]

tests/integration_test.rs

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
#[macro_use]
2-
extern crate assert_json_diff;
3-
#[macro_use]
4-
extern crate serde_json;
5-
6-
use assert_json_diff::{assert_json_eq_no_panic, assert_json_include_no_panic};
1+
use serde::Serialize;
2+
use assert_json_diff::{
3+
assert_json_eq, assert_json_eq_no_panic, assert_json_include, assert_json_include_no_panic,
4+
};
5+
use serde_json::json;
76

87
#[test]
98
fn can_pass() {
@@ -62,3 +61,75 @@ fn exact_match_without_panicing() {
6261

6362
assert!(assert_json_eq_no_panic(&json!([1, 2, 3]), &json!("foo")).is_err());
6463
}
64+
65+
#[derive(Serialize)]
66+
struct User {
67+
id: i32,
68+
username: String
69+
}
70+
71+
#[test]
72+
fn include_with_serializable() {
73+
let user = User {
74+
id: 1,
75+
username: "bob".to_string(),
76+
};
77+
78+
assert_json_include!(
79+
actual: json!({
80+
"id": 1,
81+
"username": "bob",
82+
"email": "bob@example.com"
83+
}),
84+
expected: user,
85+
);
86+
}
87+
88+
#[test]
89+
fn include_with_serializable_ref() {
90+
let user = User {
91+
id: 1,
92+
username: "bob".to_string(),
93+
};
94+
95+
assert_json_include!(
96+
actual: &json!({
97+
"id": 1,
98+
"username": "bob",
99+
"email": "bob@example.com"
100+
}),
101+
expected: &user,
102+
);
103+
}
104+
105+
#[test]
106+
fn eq_with_serializable() {
107+
let user = User {
108+
id: 1,
109+
username: "bob".to_string(),
110+
};
111+
112+
assert_json_eq!(
113+
json!({
114+
"id": 1,
115+
"username": "bob"
116+
}),
117+
user,
118+
);
119+
}
120+
121+
#[test]
122+
fn eq_with_serializable_ref() {
123+
let user = User {
124+
id: 1,
125+
username: "bob".to_string(),
126+
};
127+
128+
assert_json_eq!(
129+
&json!({
130+
"id": 1,
131+
"username": "bob"
132+
}),
133+
&user,
134+
);
135+
}

0 commit comments

Comments
 (0)