Skip to main content

assert4rs/
lib.rs

1//! Fluent assertions for Rust.
2//!
3//! This crate provides a fluent API for writing assertions in tests.
4//! All assertions start with [`Assert::that`] and can be chained:
5//!
6//! ```
7//! use assert4rs::Assert;
8//!
9//! Assert::that("foo")
10//!     .is("foo")
11//!     .is_not("bar");
12//! ```
13//!
14//! Type-specific assertions are available for [`Option`], [`Result`],
15//! and [`Vec`]:
16//!
17//! ```
18//! use assert4rs::Assert;
19//!
20//! Assert::that(Some(42)).unwrap().is_gt(0);
21//! Assert::that(vec![1, 2, 3]).contains(&2);
22//! ```
23//!
24//! Values can be transformed with [`Assert::map`] to apply further
25//! assertions:
26//!
27//! ```
28//! use assert4rs::Assert;
29//!
30//! Assert::that("3")
31//!     .map(|v| v.parse::<i32>().unwrap())
32//!     .is(3);
33//! ```
34
35pub mod equals;
36pub mod option;
37pub mod result;
38pub mod string;
39pub mod vec;
40
41/// Entry point for the [Assert] DSL.
42///
43/// [Assert] provides a fluent API for assertions. An [Assert] holds
44/// the `actual` value that can be used in assertion statements.
45///
46/// ```
47/// # use assert4rs::Assert;
48/// Assert::that(3).is(3);
49/// ```
50///
51/// It takes ownership of self and returns ownership back so that
52/// assertions can be chained in fluent manner.
53///
54/// Like in the following example:
55///
56/// ```
57/// # use assert4rs::Assert;
58/// Assert::that("foo")
59///     .is("foo")
60///     .is_not("bar");
61/// ```
62pub struct Assert<T> {
63    actual: T,
64}
65
66impl<T> Assert<T> {
67    /// Create an [Assert] instance for the `actual` value.
68    ///
69    /// All assertions start with `Assert::that(actual)`.
70    pub fn that(actual: T) -> Self {
71        Assert { actual }
72    }
73
74    /// Maps the `actual` value using lambda `f`.
75    ///
76    /// This method is intended to map the actual value in order to
77    /// apply further assertions.
78    ///
79    /// ```
80    /// # use assert4rs::Assert;
81    /// Assert::that("3")
82    ///     .map(|v| v.parse::<i32>().unwrap())
83    ///     .is(3);
84    /// ```
85    ///
86    /// ```should_panic
87    /// # use assert4rs::Assert;
88    /// Assert::that(2).map(|v| v + 2).is(3);
89    /// ```
90    pub fn map<R>(self, f: impl FnOnce(T) -> R) -> Assert<R> {
91        Assert::that(f(self.actual))
92    }
93}