Skip to main content

test_that/
assertions.rs

1// Copyright 2022 Google LLC
2// Copyright 2026 Bradford Hovinen <bradford@hovinen.me>
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16// There are no visible documentation elements in this module; the declarative
17// macros are documented at the top level.
18#![doc(hidden)]
19
20/// Checks whether the `Matcher` given by the second argument matches the first
21/// argument.
22///
23/// Evaluates to `Result::Ok(())` if the matcher matches and
24/// `Result::Err(TestAssertionFailure)` if it does not. The caller must then
25/// decide how to handle the `Err` variant. It has a few options:
26///
27///  * Abort the current function with the `?` operator. This requires that the
28///    function return a suitable `Result`.
29///  * Log the test failure and continue by calling the method
30///    `and_log_failure`.
31///
32/// Of course, one can also use all other standard methods on `Result`.
33///
34/// **Invoking this macro by itself does not cause a test failure to be recorded
35/// or output.** The resulting `Result` must be handled as described above to
36/// cause the test to be recorded as a failure.
37///
38/// Example:
39/// ```
40/// # use test_that::prelude::*;
41/// # fn should_pass() -> TestResult<()> {
42/// verify_that!(42, eq(42))?; // This will pass.
43/// # Ok(())
44/// # }
45/// # should_pass().unwrap();
46/// # fn should_fail() -> TestResult<()> {
47/// # #[cfg(feature = "std")]
48/// # test_that::internal::test_outcome::TestOutcome::init_current_test_outcome();
49/// verify_that!(42, eq(123)).and_log_failure();
50///             // This will log a test failure and allow execution to continue.
51/// let _ = verify_that!(42, eq(123)); // This will do nothing.
52/// verify_that!(42, eq(123))?; // This will fail, returning immediately.
53/// verify_that!(42, eq(0))?; // This will not run.
54/// # #[cfg(feature = "std")]
55/// # { test_that::internal::test_outcome::TestOutcome::close_current_test_outcome::<&str>(Ok(())).unwrap_err(); }
56/// # Ok(())
57/// # }
58/// # verify_that!(should_fail(), err(displays_as(contains_substring("Expected: is equal to 123"))))
59/// #     .unwrap();
60/// ```
61///
62/// This macro has special support for matching against containers. Namely:
63///   * `verify_that!(actual, [m1, m2, ...])` is equivalent to
64///     `verify_that!(actual, contains_exactly![m1, m2, ...].in_order())`
65///   * `verify_that!(actual, {m1, m2, ...})` is equivalent to
66///     `verify_that!(actual, contains_exactly![m1, m2, ...])`
67#[macro_export]
68macro_rules! verify_that {
69    ($actual:expr, $($expected:tt)+) => {
70        $crate::assertions::internal::check_matcher(
71            &$actual,
72            $crate::__matcher_expr!($($expected)+),
73            stringify!($actual),
74            $crate::internal::source_location::SourceLocation::new(file!(), line!(), column!()),
75        )
76    };
77}
78
79#[doc(hidden)]
80#[macro_export]
81macro_rules! __matcher_expr {
82    ([$($m:tt)*]) => {
83        $crate::matchers::containers::contains_exactly![$($m)*].in_order()
84    };
85    ({$($m:tt)*}) => {
86        $crate::matchers::containers::contains_exactly![$($m)*]
87    };
88    ($expected:expr $(,)?) => { $expected };
89}
90
91/// Asserts that the given predicate applied to the given arguments returns
92/// true.
93///
94/// Similarly to [`verify_that`], this evaluates to a `Result` whose `Ok`
95/// variant indicates that the given predicate returned true and whose `Err`
96/// variant indicates that it returned false.
97///
98/// The failure message contains detailed information about the arguments. For
99/// example:
100///
101/// ```
102/// # use test_that::prelude::*;
103/// fn equals_modulo(a: i32, b: i32, n: i32) -> bool { a % n == b % n }
104///
105/// # /* The attribute macro would prevent the function from being compiled in a doctest.
106/// #[test]
107/// # */
108/// fn test() -> TestResult<()> {
109///     let a = 1;
110///     let b = 7;
111///     let n = 5;
112///     verify_pred!(equals_modulo(a, b, n))?;
113///     Ok(())
114/// }
115/// # verify_that!(
116/// #     test(),
117/// #     err(displays_as(contains_substring("equals_modulo(a, b, n) was false with")))
118/// # ).unwrap();
119/// ```
120///
121/// This results in the following message:
122///
123/// ```text
124/// equals_modulo(a, b, n) was false with
125///   a = 1,
126///   b = 7,
127///   n = 5
128/// ```
129///
130/// The function passed to this macro must return `bool`. Each of the arguments
131/// must evaluate to a type implementing [`std::fmt::Debug`]. The debug output
132/// is used to construct the failure message.
133///
134/// The predicate can also be a method on a struct, e.g.:
135///
136/// ```ignore
137/// struct AStruct {};
138///
139/// impl AStruct {
140///   fn equals_modulo(...) {...}
141/// }
142///
143/// verify_pred!((AStruct {}).equals_modulo(a, b, n))?;
144/// ```
145///
146/// **Warning:** This macro assumes that the arguments passed to the predicate
147/// are either *variables* or *calls to pure functions*. If two subsequent
148/// invocations to any of the expressions passed as arguments result in
149/// different values, then the output message of a test failure will deviate
150/// from the values actually passed to the predicate. For this reason, *always
151/// assign the outputs of non-pure functions to variables before using them in
152/// this macro. For example:
153///
154/// ```ignore
155/// let output = generate_random_number();  // Assigned outside of verify_pred.
156/// verify_pred!(is_sufficiently_random(output))?;
157/// ```
158#[macro_export]
159macro_rules! verify_pred {
160    ([$($predicate:tt)*]($($arg:tt),* $(,)?)) => {
161        if !$($predicate)*($($arg),*) {
162            $crate::assertions::internal::report_failed_predicate(
163                concat!(stringify!($($predicate)*), stringify!(($($arg),*))),
164                $crate::__alloc::vec![$((($crate::__alloc::format!(concat!(stringify!($arg), " = {:?}"), $arg)))),*],
165                $crate::internal::source_location::SourceLocation::new(
166                    file!(),
167                    line!(),
168                    column!(),
169                ),
170            )
171        } else {
172            Ok(())
173        }
174    };
175
176    ([$($predicate:tt)*] $first:tt $($rest:tt)*) => {
177        $crate::verify_pred!([$($predicate)* $first] $($rest)*)
178    };
179
180    ($first:tt $($rest:tt)*) => {
181        $crate::verify_pred!([$first] $($rest)*)
182    };
183}
184
185/// Evaluates to a `Result` which contains an `Err` variant with the given test
186/// failure message.
187///
188/// This can be used to force the test to fail if its execution reaches a
189/// particular point. For example:
190///
191/// ```ignore
192/// match some_value {
193///     ExpectedVariant => {...}
194///     UnwantedVaraint => {
195///         fail!("This thing which should not happen happened anyway")?;
196///     }
197/// }
198/// ```
199///
200/// One may include formatted arguments in the failure message:
201///
202/// ```ignore
203/// match some_value {
204///     ExpectedVariant => {...}
205///     UnwantedVaraint => {
206///         fail!("This thing which should not happen happened anyway: {}", some_value)?;
207///     }
208/// }
209/// ```
210///
211/// One may also omit the message, in which case the test failure message will
212/// be generic:
213///
214/// ```ignore
215/// match some_value {
216///     ExpectedVariant => {...}
217///     UnwantedVaraint => {
218///         fail!()?;
219///     }
220/// }
221/// ```
222///
223/// Unlike `panic!` but analogously to [`verify_that`] and [`verify_pred`], this
224/// macro has no effect on the flow of control but instead returns a `Result`
225/// which must be handled by the invoking function. This can be done with the
226/// question mark operator (as above) or the method
227/// [`and_log_failure`](crate::TestResultExt::and_log_failure).
228#[macro_export]
229macro_rules! fail {
230    ($($message:expr),+) => {{
231        // We wrap this in a function so that we can annotate it with the must_use attribute.
232        // must_use on expressions is still experimental.
233        #[must_use = "The assertion result must be evaluated to affect the test result."]
234        fn create_fail_result(message: $crate::__alloc::string::String) -> $crate::TestResult<()> {
235            Err($crate::internal::test_outcome::TestAssertionFailure::create($crate::__alloc::format!(
236                "{}\n{}",
237                message,
238                $crate::internal::source_location::SourceLocation::new(
239                    file!(),
240                    line!(),
241                    column!(),
242                ),
243            )))
244        }
245        create_fail_result($crate::__alloc::format!($($message),*))
246    }};
247
248    () => { $crate::fail!("Test failed") };
249}
250
251/// Matches the given value against the given matcher, panicking if it does not
252/// match.
253///
254/// ```should_panic
255/// # use test_that::prelude::*;
256/// # fn should_fail() {
257/// let value = 2;
258/// assert_that!(value, eq(3));  // Fails and panics.
259/// # }
260/// # should_fail();
261/// ```
262///
263/// This is analogous to assertions in most Rust test libraries, where a failed
264/// assertion causes a panic.
265///
266/// One may optionally add arguments which will be formatted and appended to a
267/// failure message. For example:
268///
269/// ```should_panic
270/// # use test_that::prelude::*;
271/// # fn should_fail() {
272/// let value = 2;
273/// let extra_information = "Some additional information";
274/// assert_that!(value, eq(3), "Test failed. Extra information: {extra_information}.");
275/// # }
276/// # should_fail();
277/// ```
278///
279/// This is output as follows:
280///
281/// ```text
282/// Value of: value
283/// Expected: is equal to 3
284/// Actual: 2,
285///   which isn't equal to 3
286///   at ...
287/// Test failed. Extra information: Some additional information.
288/// ```
289///
290/// **Note for users of [GoogleTest for C++](http://google.github.io/googletest/):**
291/// This differs from the `ASSERT_THAT` macro in that it panics rather
292/// than triggering an early return from the invoking function. To get behaviour
293/// equivalent to `ASSERT_THAT`, use [`verify_that!`] with the `?` operator.
294#[macro_export]
295macro_rules! assert_that {
296    ($actual:expr, $expected:expr $(,)?) => {
297        match $crate::verify_that!($actual, $expected) {
298            Ok(_) => {}
299            Err(e) => {
300                // The extra newline before the assertion failure message makes the failure a
301                // bit easier to read when there's some generic boilerplate from the panic.
302                panic!("\n{}", e);
303            }
304        }
305    };
306
307    ($actual:expr, $expected:expr, $($format_args:expr),* $(,)?) => {{
308        use $crate::TestResultExt;
309        match $crate::verify_that!($actual, $expected)
310            .with_failure_message(|| $crate::__alloc::format!($($format_args),*))
311        {
312            Ok(_) => {}
313            Err(e) => {
314                // The extra newline before the assertion failure message makes the failure a
315                // bit easier to read when there's some generic boilerplate from the panic.
316                panic!("\n{}", e);
317            }
318        }
319    }};
320}
321
322/// Asserts that the given predicate applied to the given arguments returns
323/// true, panicking if it does not.
324///
325/// **Note for users of [GoogleTest for C++](http://google.github.io/googletest/):**
326/// This differs from the `ASSERT_PRED*` family of macros in that it panics
327/// rather than triggering an early return from the invoking function. To get
328/// behaviour equivalent to `ASSERT_PRED*`, use [`verify_pred!`] with the `?`
329/// operator.
330#[macro_export]
331macro_rules! assert_pred {
332    ($($content:tt)*) => {
333        match $crate::verify_pred!($($content)*) {
334            Ok(_) => {}
335            Err(e) => {
336                // The extra newline before the assertion failure message makes the failure a
337                // bit easier to read when there's some generic boilerplate from the panic.
338                panic!("\n{}", e);
339            }
340        }
341    };
342}
343
344/// Matches the given value against the given matcher, marking the test as
345/// failed but continuing execution if it does not match.
346///
347/// This is a *non-fatal* assertion: the test continues
348/// execution in the event of assertion failure.
349///
350/// This can only be invoked inside tests with the
351/// [`test_that::test`][crate::test] attribute. The assertion must
352/// occur in the same thread as that running the test itself.
353///
354/// Invoking this macro is equivalent to using
355/// [`and_log_failure`](crate::TestResultExt::and_log_failure) as follows:
356///
357/// ```ignore
358/// verify_that!(actual, expected).and_log_failure()
359/// ```
360///
361/// One may optionally add arguments which will be formatted and appended to a
362/// failure message. For example:
363///
364/// ```
365/// # use test_that::prelude::*;
366/// # fn should_fail() -> std::result::Result<(), test_that::internal::test_outcome::TestFailure> {
367/// # test_that::internal::test_outcome::TestOutcome::init_current_test_outcome();
368/// let value = 2;
369/// let extra_information = "Some additional information";
370/// expect_that!(value, eq(3), "Test failed. Extra information: {extra_information}.");
371/// # test_that::internal::test_outcome::TestOutcome::close_current_test_outcome::<&str>(Ok(()))
372/// # }
373/// # should_fail().unwrap_err();
374/// ```
375///
376/// This is output as follows:
377///
378/// ```text
379/// Value of: value
380/// Expected: is equal to 3
381/// Actual: 2,
382///   which isn't equal to 3
383///   at ...
384/// Test failed. Extra information: Some additional information.
385/// ```
386#[cfg(feature = "non-fatal-assertions")]
387#[macro_export]
388macro_rules! expect_that {
389    ($actual:expr, $expected:expr $(,)?) => {{
390        use $crate::TestResultExt;
391        $crate::verify_that!($actual, $expected).and_log_failure();
392    }};
393
394    ($actual:expr, $expected:expr, $($format_args:expr),* $(,)?) => {{
395        use $crate::TestResultExt;
396        $crate::verify_that!($actual, $expected)
397            .with_failure_message(|| $crate::__alloc::format!($($format_args),*))
398            .and_log_failure()
399    }};
400}
401
402/// Asserts that the given predicate applied to the given arguments returns
403/// true, failing the test but continuing execution if not.
404///
405/// This is a *non-fatal* predicate assertion: the test
406/// continues execution in the event of assertion failure.
407///
408/// This can only be invoked inside tests with the
409/// [`test_that::test`][crate::test] attribute. The assertion must
410/// occur in the same thread as that running the test itself.
411///
412/// Invoking this macro is equivalent to using
413/// [`and_log_failure`](crate::TestResultExt::and_log_failure) as follows:
414///
415/// ```ignore
416/// verify_pred!(predicate(...)).and_log_failure()
417/// ```
418#[cfg(feature = "non-fatal-assertions")]
419#[macro_export]
420macro_rules! expect_pred {
421    ($($content:tt)*) => {{
422        use $crate::TestResultExt;
423        $crate::verify_pred!($($content)*).and_log_failure();
424    }};
425}
426
427/// Functions for use only by the procedural macros in this module.
428///
429/// **For internal use only. API stability is not guaranteed!**
430#[doc(hidden)]
431pub mod internal {
432    use crate::{
433        internal::{source_location::SourceLocation, test_outcome::TestAssertionFailure},
434        matcher::{Matcher, MatcherResult, create_assertion_failure},
435    };
436    use core::fmt::Debug;
437
438    /// Checks whether the matcher `expected` matches the value `actual`, adding
439    /// a test failure report if it does not match.
440    ///
441    /// Returns `Ok(())` if the value matches and `Err(())` if it does not
442    /// match.
443    ///
444    /// **For internal use only. API stability is not guaranteed!**
445    #[must_use = "The assertion result must be evaluated to affect the test result."]
446    pub fn check_matcher<T: Debug + ?Sized>(
447        actual: &T,
448        expected: impl Matcher<T>,
449        actual_expr: &'static str,
450        source_location: SourceLocation,
451    ) -> Result<(), TestAssertionFailure> {
452        match expected.matches(actual) {
453            MatcherResult::Match => Ok(()),
454            MatcherResult::NoMatch => {
455                Err(create_assertion_failure(&expected, actual, actual_expr, source_location))
456            }
457        }
458    }
459
460    /// Constructs a `Result::Err(TestAssertionFailure)` for a predicate failure
461    /// as produced by the macro [`crate::verify_pred`].
462    ///
463    /// This intended only for use by the macro [`crate::verify_pred`].
464    ///
465    /// **For internal use only. API stability is not guaranteed!**
466    #[must_use = "The assertion result must be evaluated to affect the test result."]
467    pub fn report_failed_predicate(
468        actual_expr: &'static str,
469        formatted_arguments: alloc::vec::Vec<alloc::string::String>,
470        source_location: SourceLocation,
471    ) -> Result<(), TestAssertionFailure> {
472        Err(TestAssertionFailure::create(alloc::format!(
473            "{} was false with\n  {}\n{}",
474            actual_expr,
475            formatted_arguments.join(",\n  "),
476            source_location,
477        )))
478    }
479}