Skip to main content

asserting/
lib.rs

1//! Fluent assertions for tests in Rust that are convenient to write and easy
2//! to extend.
3//!
4//! Fluent assertions have some significant advantages - in general and
5//! particularly as provided by this crate:
6//!
7//! * express the intent of an assertion
8//! * an assertion reads more like natural english
9//! * concise and expressive assertions for more complex types like collections
10//! * distinct and more helpful error messages for specific assertions
11//! * easy spotting the difference between the expected and the actual value
12//! * chaining of multiple assertions on the same subject
13//! * soft assertions
14//!
15//! An additional benefit of `asserting` is that it highlights differences
16//! between the expected value and the actual value for failed assertions.
17//! See the documentation of the [`colored`] module for more information on
18//! "colored diffs".
19//!
20//! # Usage
21//!
22//! To write fluent assertions in tests, import this crate's `prelude`
23//! module in your test module, like so:
24//!
25//! ```
26//! use asserting::prelude::*;
27//! ```
28//!
29//! Importing the `prelude` module is the intended way to use this crate. The
30//! prelude re-exports all types, traits and functions and macros that are
31//! needed to write assertions in tests.
32//!
33//! Start writing assertion by applying the [`assert_that!`] macro to the subject
34//! to be asserted. Then call an assertion
35//! function like `is_equal_to`, like so:
36//!
37//! ```
38//! # use asserting::prelude::*;
39//! let some_result = 7 * 6;
40//! assert_that!(some_result).is_equal_to(42);
41//! ```
42//!
43//! The subject can be any expression, e.g.:
44//!
45//! ```
46//! # use asserting::prelude::*;
47//! assert_that!(6 * 8 - 6).is_equal_to(42);
48//! ```
49//!
50//! The variable or expression inside the call of the [`assert_that!`] macro is
51//! repeated in the error message when an assertion fails. For example, the
52//! assertion:
53//!
54//! ```no_run
55//! # use asserting::prelude::*;
56//! assert_that!(6 * 8 - 5).is_equal_to(42);
57//! ```
58//!
59//! will print the error message:
60//!
61//! ```console
62//! expected 6 * 8 - 5 to be equal to 42
63//!    but was: 43
64//!   expected: 42
65//! ```
66//!
67//! By default, the differences between the expected value and the actual value
68//! are highlighted using colors. See the [`colored`] module for more
69//! information on "colored diffs".
70//!
71//! # Examples
72//!
73//! ## Basic assertions
74//!
75//! ```
76//! use asserting::prelude::*;
77//!
78//! assert_that!(3 + 5).is_equal_to(8);
79//! assert_that!(69).is_not_equal_to(42);
80//!
81//! assert_that!(5).is_greater_than(3);
82//! assert_that!(42).is_at_most(99);
83//!
84//! assert_that!(-0.57).is_in_range(-1.0..=1.0);
85//! assert_that!('M').is_in_range('A'..='Z');
86//! assert_that!('M').is_not_in_range('a'..='z');
87//!
88//! let subject = "at invidunt quis placerat".to_string();
89//! assert_that!(subject).is_equal_to("at invidunt quis placerat");
90//!
91//! let subject = "justo clita in stet".to_string();
92//! assert_that!(subject).is_same_as("justo clita in stet".to_string());
93//!
94//! let subject = "anim proident eiusmod sint".to_string();
95//! assert_that!(subject).contains("eiusmod");
96//!
97//! let subject = Some("consectetur veniam at nulla".to_string());
98//! assert_that!(subject).has_value("consectetur veniam at nulla");
99//!
100//! let subject: Result<i8, String> = Ok(42);
101//! assert_that!(subject).has_value(42);
102//!
103//! let subject: Option<f64> = None;
104//! assert_that!(subject).is_none();
105//!
106//! let subject: Result<(), String> = Err("labore qui eu illum".to_string());
107//! assert_that!(subject).has_error("labore qui eu illum");
108//!
109//! let subject = vec![1, 3, 5, 7, 9, 11];
110//! assert_that!(subject).contains_exactly([1, 3, 5, 7, 9, 11]);
111//! ```
112//!
113//! ## Chaining assertions on the same subject
114//!
115//! ```
116//! use asserting::prelude::*;
117//!
118//! assert_that!("commodo nobis cum duis")
119//!     .starts_with("commodo")
120//!     .ends_with(" duis")
121//!     .has_length(22);
122//!
123//! assert_that!(vec![1, 19, 1, 29, 5, 5, 7, 23, 17, 11, 3, 23, 13, 1])
124//!     .contains_all_of([1, 11, 13, 17, 19])
125//!     .contains_only([1, 3, 5, 7, 9, 11, 13, 17, 19, 23, 29, 31, 37, 43]);
126//! ```
127//!
128//! ## Asserting some elements of a collection or an iterator
129//!
130//! Asserting some elements of a collection or an iterator:
131//!
132//! ```
133//! use asserting::prelude::*;
134//!
135//! let numbers = [2, 4, 6, 8, 10];
136//!
137//! assert_that!(numbers).each_element(|e|
138//!     e.is_greater_than(1)
139//!         .is_at_most(10)
140//! );
141//!
142//! assert_that!(numbers).any_element(|e|
143//!     e.is_equal_to(4)
144//! );
145//! ```
146//!
147//! See [`Spec::each_element()`] for more details.
148//!
149//! Assert some elements of a collection or an iterator to satisfy a predicate:
150//!
151//! ```
152//! use asserting::prelude::*;
153//!
154//! let subject = [1, 41, 43, 42, 5];
155//! assert_that!(subject).any_satisfies(|e| *e == 42);
156//!
157//! let subject = [43, 44, 45, 46, 47];
158//! assert_that!(subject).all_satisfy(|e| *e > 42);
159//!
160//! let subject = [42, 43, 44, 45, 46];
161//! assert_that!(subject).none_satisfies(|e| *e < 42);
162//! ```
163//!
164//! See [`AssertElements`] for more details.
165//!
166//! ## Asserting specific elements of a collection or an iterator
167//!
168//! Filter assertions are handy to assert specific elements of a collection or
169//! an iterator.
170//!
171//! Assert the only element of a collection or an iterator:
172//!
173//! ```
174//! use asserting::prelude::*;
175//!
176//! let subject = ["single"];
177//!
178//! assert_that!(subject).single_element().is_equal_to("single");
179//! ```
180//!
181//! Assert the first, the last, or the nth element of a collection or an iterator:
182//!
183//! ```
184//! use asserting::prelude::*;
185//!
186//! let numbers = [1, 2, 3, 4, 5];
187//!
188//! assert_that!(numbers).first_element().is_equal_to(1);
189//! assert_that!(numbers).last_element().is_equal_to(5);
190//! assert_that!(numbers).nth_element(3).is_equal_to(4);
191//! ```
192//!
193//! Filter the elements to be asserted on a condition:
194//!
195//! ```
196//! use asserting::prelude::*;
197//!
198//! let subject = [1, 2, 3, 4, 5];
199//!
200//! assert_that!(subject)
201//!     .filtered_on(|e| e & 1 == 0)
202//!     .contains_exactly_in_any_order([2, 4]);
203//!
204//! let subject = ["one", "two", "three", "four"];
205//!
206//! assert_that!(subject)
207//!     .filtered_on(|e| e.len() == 5)
208//!     .single_element()
209//!     .is_equal_to("three");
210//! ```
211//!
212//! Pick the elements of a collection or an iterator at given positions:
213//!
214//! ```
215//! use asserting::prelude::*;
216//!
217//! let subject = ["one", "two", "three", "four", "five"];
218//!
219//! assert_that!(subject)
220//!     .elements_at([0, 2, 4])
221//!     .contains_exactly(["one", "three", "five"]);
222//! ```
223//!
224//! ## Soft assertions
225//!
226//! ```should_panic
227//! use asserting::prelude::*;
228//!
229//! verify_that!("the answer to all important questions is 42")
230//!     .contains("unimportant")
231//!     .has_at_most_length(41)
232//!     .soft_panic();
233//! ```
234//!
235//! executes both assertions and prints the messages of both failing
236//! assertions in the panic message:
237//!
238//! ```console
239//! expected subject to contain "unimportant"
240//!    but was: "the answer to all important questions is 42"
241//!   expected: "unimportant"
242//!
243//! expected subject to have at most a length of 41
244//!    but was: 43
245//!   expected: <= 41
246//! ```
247//!
248//! For more details see [`Spec::soft_panic()`].
249//!
250//! ## Asserting custom types
251//!
252//! We can extract a property of a custom type and assert its value:
253//!
254//! ```
255//! # use asserting::prelude::*;
256//! struct MyStruct {
257//!     important_property: String,
258//!     other_property: f64,
259//! }
260//!
261//! let some_thing = MyStruct {
262//!     important_property: "imperdiet aliqua zzril eiusmod".into(),
263//!     other_property: 99.9,
264//! };
265//!
266//! assert_that!(some_thing).extracting(|s| s.important_property)
267//!     .is_equal_to("imperdiet aliqua zzril eiusmod");
268//!
269//! ```
270//!
271//! Or we can map a custom type that does not implement a required trait to some
272//! supported type, e.g., a tuple in this example:
273//!
274//! ```
275//! # use asserting::prelude::*;
276//! struct Point {
277//!     x: i64,
278//!     y: i64,
279//! }
280//!
281//! let target = Point { x: 12, y: -64 };
282//!
283//! assert_that!(target).mapping(|s| (s.x, s.y)).is_equal_to((12, -64));
284//! ```
285//!
286//! ## Predicate as custom assertion
287//!
288//! We can use any predicate function for a custom assertion:
289//!
290//! ```
291//! # use asserting::prelude::*;
292//! fn is_odd(value: &i32) -> bool {
293//!     value & 1 == 1
294//! }
295//!
296//! assert_that!(37).satisfies_with_message("expected my number to be odd", is_odd);
297//! ```
298//!
299//! ## Assert that some code panics or does not panic
300//!
301//! Requires crate feature `panic`.
302//!
303//! ```
304//! # #[cfg(not(feature = "panic"))]
305//! # fn main() {}
306//! # #[cfg(feature = "panic")]
307//! # fn main() {
308//! use asserting::prelude::*;
309//!
310//! fn divide(a: i32, b: i32) -> i32 {
311//!     a / b
312//! }
313//!
314//! assert_that_code!(|| { divide(7, 0); }).panics();
315//!
316//! assert_that_code!(|| { divide(7, 0); })
317//!     .panics_with_message("attempt to divide by zero");
318//!
319//! assert_that_code!(|| { divide(7, 3); }).does_not_panic();
320//! # }
321//! ```
322//!
323//! # The `assert_that` and `verify_that` functions and macros
324//!
325//! Assertions can be written in two ways. The standard way that panics when
326//! an assertion fails or the alternative way that collects failures from
327//! failed assertions which can be read later.
328//!
329//! To call assertion functions on a subject, it is wrapped into the [`Spec`]
330//! struct. This can be done by calling one of the functions:
331//!
332//! * [`assert_that`] - wraps the subject into a [`Spec`] that panics if an
333//!   assertion fails
334//! * [`verify_that`] - wraps the subject into a [`Spec`] that collects failures
335//!   from assertions, which can be read later.
336//! * [`assert_that_code`] - wraps a closure into a [`Spec`] for asserting
337//!   whether the code in the closure panics or does not panic. It panics if an
338//!   assertion fails.
339//! * [`verify_that_code`] - wraps a closure into a [`Spec`] for asserting
340//!   whether the code in the closure panics or does not panic. It collects
341//!   failures from assertions, which can be read later.
342//!
343//! 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
345//! an optional description of what we are going to assert. These attributes are
346//! all optional and must be set explicitly by the user.
347//!
348//! For convenience, a set of macros with the same names as the functions above
349//! is provided which set the expression and the code location for the user.
350//!
351//! * [`assert_that!`] - calls the [`assert_that`] function and sets the
352//!   expression inside the macro call as the expression in the [`Spec`] as well
353//!   as the location of the macro call as the code location.
354//! * [`verify_that!`] - calls the [`verify_that`] function and sets the
355//!   expression inside the macro call as the expression in the [`Spec`] as well
356//!   as the location of the macro call as the code location.
357//! * [`assert_that_code!`] - calls the [`assert_that_code`] function and sets
358//!   the expression inside the macro call as the expression in the [`Spec`] as
359//!   well as the location of the macro call as the code location.
360//! * [`verify_that_code!`] - calls the [`verify_that_code`] function and sets
361//!   the expression inside the macro call as the expression in the [`Spec`] as
362//!   well as the location of the macro call as the code location.
363//!
364//! For example, calling the macro [`assert_that!`] like so:
365//!
366//! ```
367//! # use asserting::prelude::*;
368//! assert_that!(7 * 6).is_equal_to(42);
369//! ```
370//!
371//! is equivalent to calling the function [`assert_that`] and then calling
372//! the methods [`named()`] and [`located_at()`] on the returned [`Spec`],
373//! like so:
374//!
375//! ```
376//! # use asserting::prelude::*;
377//! assert_that(7 * 6)
378//!     .named("7 * 6")
379//!     .located_at(
380//!         Location {
381//!             file: file!(),
382//!             line: line!(),
383//!             column: column!(),
384//!         }
385//!     ).is_equal_to(42);
386//! ```
387//!
388//! When using the `verfiy_*` variants of the macros or functions for each
389//! failing assertion, a failure of type [`AssertFailure`] is added to the
390//! [`Spec`]. We can read the failures collected by calling the [`failures()`]
391//! method, like so:
392//!
393//! ```
394//! # use asserting::prelude::*;
395//! let failures = verify_that!(7 * 5).is_equal_to(42).failures();
396//!
397//! assert_that!(failures).has_length(1);
398//! ```
399//!
400//! or to get a list of formatted failure messages, we can call the
401//! [`display_failures()`] method, like so:
402//!
403//! ```
404//! # use asserting::prelude::*;
405//!
406//! let failures = verify_that!(7 * 5).is_equal_to(42).display_failures();
407//!
408//! assert_that!(failures).contains_exactly([
409//!     r"expected 7 * 5 to be equal to 42
410//!    but was: 35
411//!   expected: 42
412//! "
413//! ]);
414//! ```
415//!
416//! # Custom assertions
417//!
418//! `asserting` provides 5 ways to do custom assertions:
419//!
420//! 1. Predicate functions as custom assertions used with the [`Spec::satisfies()`] method
421//! 2. Property base assertions for any type that implements a property trait
422//! 3. Custom expectations used with the [`Spec::expecting()`] method
423//! 4. Custom assertions methods
424//! 5. Custom assertions without writing an expectation
425//!
426//! > &#x1F4A1;
427//! > Often the easiest way to assert a custom type is to write a helper
428//! > function that asserts parts (e.g., fields of a struct) using existing
429//! > assertions. See the example [`assertion_function.rs`](examples/assertion_function.rs)
430//! > which demonstrates how to use a helper function for asserting a custom
431//! > struct.
432//!
433//! How to use predicate functions as custom assertions is described on the
434//! [`Spec::satisfies()`] method and in the [Examples](#predicate-as-custom-assertion)
435//! chapter above. The other 4 ways are described in the following subchapters.
436//!
437//! [`Expectation`]s enable us to write specialized assertions by combining
438//! several basic expectations. In case a custom assertion cannot be composed
439//! out of the provided expectations but writing a custom [`Expectation`] is too
440//! cumbersome, we can write a custom assertion method directly without any
441//! custom [`Expectation`]. See the
442//! [Writing custom assertions without writing an expectation](#writing-custom-assertions-without-writing-an-expectation)
443//! chapter below for an example.
444//!
445//! ## Property-based assertions
446//!
447//! Some assertions provided by `asserting` are so-called property-based
448//! assertions. They are implemented for all types that implement a related
449//! property trait.
450//!
451//! For example, the `has_length()` assertion is implemented for all types that
452//! implement the [`LengthProperty`].
453//!
454//! If we want to provide the `has_length()` assertion for a custom type, we
455//! simply need to implement the [`LengthProperty`] trait for this type.
456//!
457//! Let's assume we have a custom struct `PathWay` and we implement the
458//! [`LengthProperty`] for `PathWay`:
459//!
460//! ```
461//! use asserting::properties::LengthProperty;
462//!
463//! #[derive(Debug)]
464//! struct PathWay {
465//!     len: usize
466//! }
467//!
468//! impl LengthProperty for PathWay {
469//!     fn length_property(&self) -> usize {
470//!         self.len
471//!     }
472//! }
473//! ```
474//!
475//! Then we can assert the length of a `PathWay` using the `has_length()`
476//! assertion:
477//!
478//! ```
479//! # use asserting::properties::LengthProperty;
480//! #
481//! # #[derive(Debug)]
482//! # struct PathWay {
483//! #    len: usize
484//! # }
485//! #
486//! # impl LengthProperty for PathWay {
487//! #     fn length_property(&self) -> usize {
488//! #         self.len
489//! #     }
490//! # }
491//! use asserting::prelude::*;
492//!
493//! let some_path = PathWay { len: 27 };
494//!
495//! assert_that!(some_path).has_length(27);
496//! ```
497//!
498//! Browse the [`properties`] module to see which property traits are available.
499//!
500//! ## Writing custom expectations
501//!
502//! A custom expectation is any type that implements the [`Expectation`] trait.
503//! For example, let's assume we have a custom type `Either` and want to write
504//! an expectation that verifies that a value of type `Either` is a left value.
505//!
506//! ```no_run
507//! use asserting::spec::{DiffFormat, Expectation, Expression, Unknown};
508//! use std::fmt::Debug;
509//!
510//! #[derive(Debug)]
511//! enum Either<L, R> {
512//!     Left(L),
513//!     Right(R),
514//! }
515//!
516//! struct IsLeft;
517//!
518//! impl<L, R> Expectation<Either<L, R>> for IsLeft
519//! where
520//!     L: Debug,
521//!     R: Debug,
522//! {
523//!     fn test(&mut self, subject: &Either<L, R>) -> bool {
524//!         match subject {
525//!             Either::Left(_) => true,
526//!             _ => false,
527//!         }
528//!     }
529//!
530//!     fn message(&self, expression: &Expression<'_>, actual: &Either<L, R>, _inverted: bool, _format: &DiffFormat) -> String {
531//!         format!(
532//!             "expected {expression} is {:?}\n   but was: {actual:?}\n  expected: {:?}",
533//!             Either::Left::<_, Unknown>(Unknown),
534//!             Either::Left::<_, Unknown>(Unknown),
535//!         )
536//!      }
537//! }
538//! ```
539//!
540//! We can now use the expectation `IsLeft` with the [`Spec::expecting()`]
541//! method:
542//!
543//! ```
544//! # use asserting::spec::{DiffFormat, Expectation, Expression, Unknown};
545//! # use std::fmt::Debug;
546//! #
547//! # #[derive(Debug)]
548//! # enum Either<L, R> {
549//! #     Left(L),
550//! #     Right(R),
551//! # }
552//! #
553//! # struct IsLeft;
554//! #
555//! # impl<L, R> Expectation<Either<L, R>> for IsLeft
556//! # where
557//! #     L: Debug,
558//! #     R: Debug,
559//! # {
560//! #     fn test(&mut self, subject: &Either<L, R>) -> bool {
561//! #         match subject {
562//! #             Either::Left(_) => true,
563//! #             _ => false,
564//! #         }
565//! #     }
566//! #
567//! #     fn message(&self, expression: &Expression<'_>, actual: &Either<L, R>, _inverted: bool, _format: &DiffFormat) -> String {
568//! #         format!(
569//! #             "expected {expression} is {:?}\n   but was: {actual:?}\n  expected: {:?}",
570//! #             Either::Left::<_, Unknown>(Unknown),
571//! #             Either::Left::<_, Unknown>(Unknown),
572//! #         )
573//! #      }
574//! # }
575//! use asserting::prelude::*;
576//!
577//! let subject: Either<String, i64> = Either::Left("left value".to_string());
578//!
579//! assert_that!(subject).expecting(IsLeft);
580//! ```
581//!
582//! ## Providing a custom assertion method
583//!
584//! In the previous chapter, we implemented a custom expectation which can be
585//! used with the [`Spec::expecting()`] method. But this way is not very
586//! expressive.
587//!
588//! Additionally, we can implement a custom assertion method via an extension
589//! trait.
590//!
591//! ```
592//! # use asserting::spec::{DiffFormat, Expectation, Expression, Unknown};
593//! #
594//! # #[derive(Debug)]
595//! # enum Either<L, R> {
596//! #     Left(L),
597//! #     Right(R),
598//! # }
599//! #
600//! # struct IsLeft;
601//! #
602//! # impl<L, R> Expectation<Either<L, R>> for IsLeft
603//! # where
604//! #     L: Debug,
605//! #     R: Debug,
606//! # {
607//! #     fn test(&mut self, subject: &Either<L, R>) -> bool {
608//! #         match subject {
609//! #             Either::Left(_) => true,
610//! #             _ => false,
611//! #         }
612//! #     }
613//! #
614//! #     fn message(&self, expression: &Expression<'_>, actual: &Either<L, R>, _inverted: bool, _format: &DiffFormat) -> String {
615//! #         format!(
616//! #             "expected {expression} is {:?}\n   but was: {actual:?}\n  expected: {:?}",
617//! #             Either::Left::<_, Unknown>(Unknown),
618//! #             Either::Left::<_, Unknown>(Unknown),
619//! #         )
620//! #      }
621//! # }
622//! use asserting::spec::{FailingStrategy, Spec};
623//! use std::fmt::Debug;
624//!
625//! pub trait AssertEither {
626//!     fn is_left(self) -> Self;
627//! }
628//!
629//! impl<L, R, Q> AssertEither for Spec<'_, Either<L, R>, Q>
630//! where
631//!     L: Debug,
632//!     R: Debug,
633//!     Q: FailingStrategy,
634//! {
635//!     fn is_left(self) -> Self {
636//!         self.expecting(IsLeft)
637//!     }
638//! }
639//! ```
640//!
641//! Now we can use the assertion method `is_left()` for asserting whether a
642//! subject of type `Either` is a left value.
643//!
644//! ```
645//! # use asserting::spec::{DiffFormat, Expectation, Expression, Unknown};
646//! # use std::fmt::Debug;
647//! #
648//! # #[derive(Debug)]
649//! # enum Either<L, R> {
650//! #     Left(L),
651//! #     Right(R),
652//! # }
653//! #
654//! # struct IsLeft;
655//! #
656//! # impl<L, R> Expectation<Either<L, R>> for IsLeft
657//! # where
658//! #     L: Debug,
659//! #     R: Debug,
660//! # {
661//! #     fn test(&mut self, subject: &Either<L, R>) -> bool {
662//! #         match subject {
663//! #             Either::Left(_) => true,
664//! #             _ => false,
665//! #         }
666//! #     }
667//! #
668//! #     fn message(&self, expression: &Expression<'_>, actual: &Either<L, R>, _inverted: bool, _format: &DiffFormat) -> String {
669//! #         format!(
670//! #             "expected {expression} is {:?}\n   but was: {actual:?}\n  expected: {:?}",
671//! #             Either::Left::<_, Unknown>(Unknown),
672//! #             Either::Left::<_, Unknown>(Unknown),
673//! #         )
674//! #      }
675//! # }
676//! # use asserting::spec::{FailingStrategy, Spec};
677//! #
678//! # pub trait AssertEither {
679//! #     fn is_left(self) -> Self;
680//! # }
681//! #
682//! # impl<L, R, Q> AssertEither for Spec<'_, Either<L, R>, Q>
683//! # where
684//! #     L: Debug,
685//! #     R: Debug,
686//! #     Q: FailingStrategy,
687//! # {
688//! #     fn is_left(self) -> Self {
689//! #         self.expecting(IsLeft)
690//! #     }
691//! # }
692//! use asserting::prelude::*;
693//!
694//! let subject: Either<String, i64> = Either::Left("left value".to_string());
695//!
696//! assert_that!(subject).is_left();
697//! ```
698//!
699//! ## Writing custom assertions without writing an expectation
700//!
701//! In real world projects custom assertions are often very specific, and custom
702//! expectations will not be reusable anyway. Writing a custom assertion without
703//! having to provide a custom [`Expectation`] is most likely the preferred way.
704//!
705//! Here is a simple assertion that checks whether a person is over 18 years
706//! old:
707//!
708//! ```
709//! use asserting::prelude::*;
710//! use asserting::spec::{FailingStrategy, Spec};
711//! use std::borrow::Borrow;
712//!
713//! struct Person {
714//!     name: String,
715//!     age: u8,
716//! }
717//!
718//! trait AssertOver18 {
719//!     fn is_over_18(self) -> Self;
720//! }
721//!
722//! // we implement the trait for a generic `S: Borrow<Person>` so that the
723//! // assertion method can be called on an owned or borrowed `Person` instance
724//! impl<'a, S, R> AssertOver18 for Spec<'a, S, R>
725//! where
726//!     S: Borrow<Person>,
727//!     R: FailingStrategy,
728//! {
729//!     fn is_over_18(mut self) -> Self {
730//!         let actual = self.subject().borrow().age;
731//!         if actual < 18 {
732//!             let expression = self.expression();
733//!             self.do_fail_with_message(
734//!                 "expected {expression} to be over 18\n   but was: {actual}\n  expected: >= 18",
735//!             );
736//!         }
737//!         self
738//!     }
739//! }
740//!
741//! let person = Person { name: "Silvia".to_string(), age: 18 };
742//!
743//! assert_that!(person).is_over_18();
744//! ```
745//!
746//! [`AssertElements`]: assertions::AssertElements
747//! [`AssertFailure`]: spec::AssertFailure
748//! [`Expectation`]: spec::Expectation
749//! [`LengthProperty`]: properties::LengthProperty
750//! [`Spec`]: spec::Spec
751//! [`Spec::each_element()`]: spec::Spec::each_element
752//! [`Spec::expecting()`]: spec::Spec::expecting
753//! [`Spec::satisfies()`]: spec::Spec::satisfies
754//! [`Spec::soft_panic()`]: spec::Spec::soft_panic
755//! [`assert_that`]: spec::assert_that
756//! [`assert_that_code`]: spec::assert_that_code
757//! [`verify_that`]: spec::verify_that
758//! [`verify_that_code`]: spec::verify_that_code
759//! [`display_failures()`]: spec::Spec::display_failures
760//! [`failures()`]: spec::Spec::failures
761//! [`named()`]: spec::Spec::named
762//! [`located_at()`]: spec::Spec::located_at
763
764#![doc(html_root_url = "https://docs.rs/asserting/0.13.1")]
765#![cfg_attr(not(feature = "std"), no_std)]
766// Render feature requirements in docs.rs
767#![cfg_attr(docsrs, feature(doc_cfg))]
768
769#[cfg(not(feature = "std"))]
770#[allow(unused_imports)]
771mod std {
772    extern crate alloc;
773    pub use alloc::*;
774    pub use core::*;
775
776    pub mod borrow {
777        extern crate alloc;
778        pub use alloc::borrow::*;
779        pub use core::borrow::*;
780    }
781
782    pub mod fmt {
783        extern crate alloc;
784        pub use alloc::fmt::*;
785        pub use core::fmt::*;
786    }
787
788    pub mod slice {
789        extern crate alloc;
790        pub use alloc::slice::*;
791        pub use core::slice::*;
792    }
793
794    pub mod str {
795        extern crate alloc;
796        pub use alloc::str::*;
797        pub use core::str::*;
798    }
799
800    pub mod sync {
801        extern crate alloc;
802        pub use alloc::sync::*;
803        pub use core::sync::*;
804    }
805
806    pub mod ffi {
807        extern crate alloc;
808        pub use alloc::ffi::*;
809        pub use core::ffi::*;
810    }
811}
812
813#[cfg(feature = "std")]
814mod std {
815    pub use std::*;
816}
817
818pub mod assertions;
819pub mod colored;
820pub mod expectations;
821pub mod prelude;
822pub mod properties;
823pub mod spec;
824
825#[cfg(feature = "bigdecimal")]
826mod bigdecimal;
827mod boolean;
828mod c_string;
829mod char;
830mod char_count;
831mod collection;
832#[cfg(feature = "std")]
833mod env;
834mod equality;
835mod error;
836mod expectation_combinators;
837mod float;
838mod integer;
839mod iterator;
840mod length;
841mod map;
842#[cfg(feature = "num-bigint")]
843mod num_bigint;
844mod number;
845mod option;
846mod order;
847#[cfg(feature = "std")]
848mod os_sting;
849#[cfg(feature = "panic")]
850mod panic;
851mod predicate;
852mod range;
853mod result;
854#[cfg(feature = "rust-decimal")]
855mod rust_decimal;
856mod slice;
857mod string;
858mod vec;
859
860// test code snippets in the README.md
861#[cfg(doctest)]
862#[doc = include_str!("../README.md")]
863#[allow(dead_code)]
864type TestCodeSnippetsInReadme = ();
865
866// workaround for false positive 'unused extern crate' warnings until
867// Rust issue [#95513](https://github.com/rust-lang/rust/issues/95513) is fixed
868#[cfg(test)]
869mod dummy_extern_uses {
870    use fakeenv as _;
871    use proptest as _;
872    use time as _;
873    use version_sync as _;
874}