Skip to content

Commit b2829e9

Browse files
committed
doc: mention field-by-field recursive comparison in the crate level documentation
1 parent a0b5fb4 commit b2829e9

2 files changed

Lines changed: 96 additions & 9 deletions

File tree

src/lib.rs

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! particularly as provided by this crate:
66
//!
77
//! * express the intent of an assertion
8-
//! * an assertion reads more like natural english
8+
//! * an assertion reads more like natural English
99
//! * concise and expressive assertions for more complex types like collections
1010
//! * distinct and more helpful error messages for specific assertions
1111
//! * easy spotting the difference between the expected and the actual value
@@ -320,6 +320,85 @@
320320
//! # }
321321
//! ```
322322
//!
323+
//! ## Field-by-field recursive comparison
324+
//!
325+
//! Requires crate feature `recursive`.
326+
//!
327+
//! The recursive comparison mode compares the subject and the expected value
328+
//! field-by-field recursively. The recursive comparison mode is available for
329+
//! all types that implement [`serde::Serialize`].
330+
//!
331+
//! Basic usage:
332+
//!
333+
//! ```
334+
//! # #[cfg(not(feature = "recursive"))]
335+
//! # fn main() {}
336+
//! # #[cfg(feature = "recursive")]
337+
//! # fn main() {
338+
//! use asserting::prelude::*;
339+
//! use serde::Serialize;
340+
//!
341+
//! #[derive(Serialize)]
342+
//! struct Address {
343+
//! id: u64,
344+
//! street: String,
345+
//! city: String,
346+
//! zip: u16,
347+
//! }
348+
//!
349+
//! #[derive(Serialize)]
350+
//! struct Person {
351+
//! id: u64,
352+
//! name: String,
353+
//! age: u8,
354+
//! address: Address,
355+
//! }
356+
//!
357+
//! let person = Person {
358+
//! id: 123,
359+
//! name: "Silvia".into(),
360+
//! age: 25,
361+
//! address: Address {
362+
//! id: 92,
363+
//! street: "Second Street".into(),
364+
//! city: "New York".into(),
365+
//! zip: 12345,
366+
//! }
367+
//! };
368+
//!
369+
//! // ignore some fields
370+
//! assert_that!(&person)
371+
//! .using_recursive_comparison()
372+
//! .ignoring_fields(["id", "address.id", "address.street"])
373+
//! .is_equal_to(Person {
374+
//! id: 0,
375+
//! name: "Silvia".into(),
376+
//! age: 25,
377+
//! address: Address {
378+
//! id: 0,
379+
//! street: "Main Street".into(),
380+
//! city: "New York".into(),
381+
//! zip: 12345,
382+
//! }
383+
//! });
384+
//!
385+
//! // assert only fields relevant for a testcase
386+
//! assert_that!(person)
387+
//! .using_recursive_comparison()
388+
//! .ignoring_not_expected_fields()
389+
//! .is_equivalent_to(value!({
390+
//! name: "Silvia",
391+
//! age: 25_u8,
392+
//! address: {
393+
//! zip: 12345_u16,
394+
//! }
395+
//! }));
396+
//! # }
397+
//! ```
398+
//!
399+
//! A more in-depth description of the recursive comparison mode is given in the
400+
//! [`recursive_comparison`] module.
401+
//!
323402
//! # The `assert_that` and `verify_that` functions and macros
324403
//!
325404
//! Assertions can be written in two ways. The standard way that panics when
@@ -341,7 +420,7 @@
341420
//! failures from assertions, which can be read later.
342421
//!
343422
//! The [`Spec`] can hold additional information about the subject, such as the
344-
//! expression we are asserting, the code location of the assert statement and
423+
//! expression we are asserting, the code location of the assert statement, and
345424
//! an optional description of what we are going to assert. These attributes are
346425
//! all optional and must be set explicitly by the user.
347426
//!
@@ -760,6 +839,7 @@
760839
//! [`failures()`]: spec::GetFailures::failures
761840
//! [`named()`]: spec::Spec::named
762841
//! [`located_at()`]: spec::Spec::located_at
842+
//! [`serde::Serialize`]: serde_core::Serialize
763843
764844
#![doc(html_root_url = "https://docs.rs/asserting/0.13.1")]
765845
#![cfg_attr(not(feature = "std"), no_std)]

src/recursive_comparison/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@
88
//! There are several scenarios where recursive comparison is useful:
99
//!
1010
//! * comparing types that have similar fields, like an entity and a DTO
11-
//! representation of the same type in the application's domain.
11+
//! representation of the same thing in the application's domain.
1212
//! * comparing only fields that are relevant for a specific test case and
1313
//! ignoring others.
1414
//! * comparing types field-by-field but ignoring fields, where the actual value
1515
//! may vary like for IDs or timestamps.
1616
//! * comparing types that implement `Serialize` but not `PartialEq` or `Debug`
1717
//!
18-
//! Recursive comparison provides detailed failure messages in case of a failing
18+
//! Recursive comparison provides detailed failure reports in case of a failing
1919
//! assertion. The failure details contain a list of fields, for which the
2020
//! actual value is not equal to the expected one. This is another reason why
2121
//! recursive comparison might be the preferred way, especially when comparing
22-
//! structs that have many fields and/or contain sub-structs.
22+
//! structs that have many fields and/or contain nested structs.
2323
//!
24-
//! Recursive comparison is started by calling the `using_recursive_comparison`
25-
//! method.
24+
//! The recursive comparison mode starts after calling the
25+
//! `using_recursive_comparison` method.
2626
//!
2727
//! Recursive comparison is not symmetrical since it is limited to the fields
2828
//! of the subject (actual value). It gathers the actual fields of the subject
29-
//! and compares them to the corresponding fields haven the same name in the
29+
//! and compares them to the corresponding fields having the same name in the
3030
//! expected value.
3131
//!
3232
//! Structs, enums, and tuples in the subject and expected value do not
@@ -37,9 +37,16 @@
3737
//! value is only equal to the expected field if the names and values are equal
3838
//! and the expected value is of type `u8` too.
3939
//!
40-
//! The recursive comparison is limited down to a max depth of 128 levels,
40+
//! Recursive comparison is limited down to a max depth of 128 levels,
4141
//! which is the default max depth of [`serde::Serialize`].
4242
//!
43+
//! The recursive comparison mode provides the following capabilities:
44+
//!
45+
//! * [Ignoring fields in the comparison](#ignoring-some-fields)
46+
//! * [Comparing only specified fields](RecursiveComparison::comparing_only_fields)
47+
//! * [Ignoring all fields that are not present in the expected value](#ignoring-not-expected-fields)
48+
//! * [Comparing only relevant fields](#comparing-only-relevant-fields)
49+
//!
4350
//! # Examples
4451
//!
4552
//! ## Comparing structs with several fields and nested structs

0 commit comments

Comments
 (0)