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