1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #![doc = include_str!("../crate_docs.md")]
16 
17 extern crate googletest_macro;
18 
19 #[cfg(test)]
20 extern crate quickcheck;
21 
22 #[macro_use]
23 pub mod assertions;
24 pub mod description;
25 pub mod internal;
26 pub mod matcher;
27 pub mod matcher_support;
28 pub mod matchers;
29 
30 /// Re-exports of the symbols in this crate which are most likely to be used.
31 ///
32 /// This includes:
33 ///  * All assertion macros,
34 ///  * Traits and type definitions normally used by tests, and
35 ///  * All built-in matchers.
36 ///
37 /// Typically, one imports everything in the prelude in one's test module:
38 ///
39 /// ```
40 /// mod tests {
41 ///     use googletest::prelude::*;
42 /// }
43 /// ```
44 pub mod prelude {
45     pub use super::matcher::Matcher;
46     pub use super::matchers::*;
47     pub use super::verify_current_test_outcome;
48     pub use super::GoogleTestSupport;
49     pub use super::IntoTestResult;
50     pub use super::Result;
51     // Assert macros
52     pub use super::{assert_that, expect_pred, expect_that, fail, verify_pred, verify_that};
53 }
54 
55 pub use googletest_macro::test;
56 
57 use internal::test_outcome::{TestAssertionFailure, TestOutcome};
58 
59 /// A `Result` whose `Err` variant indicates a test failure.
60 ///
61 /// The assertions [`verify_that!`][crate::verify_that],
62 /// [`verify_pred!`][crate::verify_pred], and [`fail!`][crate::fail] evaluate
63 /// to `Result<()>`. A test function may return `Result<()>` in combination with
64 /// those macros to abort immediately on assertion failure.
65 ///
66 /// This can be used with subroutines which may cause the test to fatally fail
67 /// and which return some value needed by the caller. For example:
68 ///
69 /// ```ignore
70 /// fn load_file_content_as_string() -> Result<String> {
71 ///     let file_stream = load_file().err_to_test_failure()?;
72 ///     Ok(file_stream.to_string())
73 /// }
74 /// ```
75 ///
76 /// The `Err` variant contains a [`TestAssertionFailure`] which carries the data
77 /// of the (fatal) assertion failure which generated this result. Non-fatal
78 /// assertion failures, which log the failure and report the test as having
79 /// failed but allow it to continue running, are not encoded in this type.
80 pub type Result<T> = std::result::Result<T, TestAssertionFailure>;
81 
82 /// Returns a [`Result`] corresponding to the outcome of the currently running
83 /// test.
84 ///
85 /// This returns `Result::Err` precisely if the current test has recorded at
86 /// least one test assertion failure via [`expect_that!`][crate::expect_that],
87 /// [`expect_pred!`][crate::expect_pred], or
88 /// [`GoogleTestSupport::and_log_failure`]. It can be used in concert with the
89 /// `?` operator to continue execution of the test conditionally on there not
90 /// having been any failure yet.
91 ///
92 /// This requires the use of the [`#[googletest::test]`][crate::test] attribute
93 /// macro.
94 ///
95 /// ```
96 /// # use googletest::prelude::*;
97 /// # /* Make sure this also compiles as a doctest.
98 /// #[googletest::test]
99 /// # */
100 /// # fn foo() -> u32 { 1 }
101 /// # fn bar() -> u32 { 2 }
102 /// fn should_fail_and_not_execute_last_assertion() -> Result<()> {
103 /// #   googletest::internal::test_outcome::TestOutcome::init_current_test_outcome();
104 ///     expect_that!(foo(), eq(2));     // May fail, but will not abort the test.
105 ///     expect_that!(bar(), gt(1));     // May fail, but will not abort the test.
106 ///     verify_current_test_outcome()?; // Aborts the test if one of the previous assertions failed.
107 ///     verify_that!(foo(), gt(0))      // Does not execute if the line above aborts.
108 /// }
109 /// # verify_that!(should_fail_and_not_execute_last_assertion(), err(displays_as(contains_substring("Test failed")))).unwrap();
110 /// ```
verify_current_test_outcome() -> Result<()>111 pub fn verify_current_test_outcome() -> Result<()> {
112     TestOutcome::get_current_test_outcome()
113 }
114 
115 /// Adds to `Result` support for GoogleTest Rust functionality.
116 pub trait GoogleTestSupport {
117     /// If `self` is a `Result::Err`, writes to `stdout` a failure report
118     /// and marks the test failed. Otherwise, does nothing.
119     ///
120     /// This can be used for non-fatal test assertions, for example:
121     ///
122     /// ```
123     /// # use googletest::prelude::*;
124     /// # use googletest::internal::test_outcome::TestOutcome;
125     /// # TestOutcome::init_current_test_outcome();
126     /// let actual = 42;
127     /// verify_that!(actual, eq(42)).and_log_failure();
128     ///                                  // Test still passing; nothing happens
129     /// verify_that!(actual, eq(10)).and_log_failure();
130     ///                          // Test now fails and failure output to stdout
131     /// verify_that!(actual, eq(100)).and_log_failure();
132     ///               // Test still fails and new failure also output to stdout
133     /// # TestOutcome::close_current_test_outcome::<&str>(Ok(())).unwrap_err();
134     /// ```
and_log_failure(self)135     fn and_log_failure(self);
136 
137     /// Adds `message` to the logged failure message if `self` is a
138     /// `Result::Err`. Otherwise, does nothing.
139     ///
140     /// If this method is called more than once, only `message` from the last
141     /// invocation is output.
142     ///
143     /// For example:
144     ///
145     /// ```
146     /// # use googletest::prelude::*;
147     /// # fn should_fail() -> Result<()> {
148     /// let actual = 0;
149     /// verify_that!(actual, eq(42)).failure_message("Actual was wrong!")?;
150     /// # Ok(())
151     /// # }
152     /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual was wrong"))))
153     /// #     .unwrap();
154     /// ```
155     ///
156     /// results in the following failure message:
157     ///
158     /// ```text
159     /// Expected: actual equal to 42
160     ///   but was: 0
161     /// Actual was wrong!
162     /// ```
163     ///
164     /// One can pass a `String` too:
165     ///
166     /// ```
167     /// # use googletest::prelude::*;
168     /// # fn should_fail() -> Result<()> {
169     /// let actual = 0;
170     /// verify_that!(actual, eq(42))
171     ///    .failure_message(format!("Actual {} was wrong!", actual))?;
172     /// # Ok(())
173     /// # }
174     /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual 0 was wrong"))))
175     /// #     .unwrap();
176     /// ```
177     ///
178     /// However, consider using [`GoogleTestSupport::with_failure_message`]
179     /// instead in that case to avoid unnecessary memory allocation when the
180     /// message is not needed.
failure_message(self, message: impl Into<String>) -> Self181     fn failure_message(self, message: impl Into<String>) -> Self;
182 
183     /// Adds the output of the closure `provider` to the logged failure message
184     /// if `self` is a `Result::Err`. Otherwise, does nothing.
185     ///
186     /// This is analogous to [`GoogleTestSupport::failure_message`] but
187     /// only executes the closure `provider` if it actually produces the
188     /// message, thus saving possible memory allocation.
189     ///
190     /// ```
191     /// # use googletest::prelude::*;
192     /// # fn should_fail() -> Result<()> {
193     /// let actual = 0;
194     /// verify_that!(actual, eq(42))
195     ///    .with_failure_message(|| format!("Actual {} was wrong!", actual))?;
196     /// # Ok(())
197     /// # }
198     /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual 0 was wrong"))))
199     /// #     .unwrap();
200     /// ```
with_failure_message(self, provider: impl FnOnce() -> String) -> Self201     fn with_failure_message(self, provider: impl FnOnce() -> String) -> Self;
202 }
203 
204 impl<T> GoogleTestSupport for std::result::Result<T, TestAssertionFailure> {
and_log_failure(self)205     fn and_log_failure(self) {
206         TestOutcome::ensure_text_context_present();
207         if let Err(failure) = self {
208             failure.log();
209         }
210     }
211 
failure_message(mut self, message: impl Into<String>) -> Self212     fn failure_message(mut self, message: impl Into<String>) -> Self {
213         if let Err(ref mut failure) = self {
214             failure.custom_message = Some(message.into());
215         }
216         self
217     }
218 
with_failure_message(mut self, provider: impl FnOnce() -> String) -> Self219     fn with_failure_message(mut self, provider: impl FnOnce() -> String) -> Self {
220         if let Err(ref mut failure) = self {
221             failure.custom_message = Some(provider());
222         }
223         self
224     }
225 }
226 
227 /// Provides an extension method for converting an arbitrary type into a
228 /// [`Result`].
229 ///
230 /// A type can implement this trait to provide an easy way to return immediately
231 /// from a test in conjunction with the `?` operator. This is useful for
232 /// [`Result`][std::result::Result] types whose `Result::Err` variant does not
233 /// implement [`std::error::Error`].
234 ///
235 /// There is an implementation of this trait for [`anyhow::Error`] (which does
236 /// not implement `std::error::Error`) when the `anyhow` feature is enabled.
237 /// Importing this trait allows one to easily map [`anyhow::Error`] to a test
238 /// failure:
239 ///
240 /// ```ignore
241 /// #[test]
242 /// fn should_work() -> Result<()> {
243 ///     let value = something_which_can_fail().into_test_result()?;
244 ///     ...
245 /// }
246 ///
247 /// fn something_which_can_fail() -> anyhow::Result<...> { ... }
248 /// ```
249 pub trait IntoTestResult<T> {
250     /// Converts this instance into a [`Result`].
251     ///
252     /// Typically, the `Self` type is itself a [`std::result::Result`]. This
253     /// method should then map the `Err` variant to a [`TestAssertionFailure`]
254     /// and leave the `Ok` variant unchanged.
into_test_result(self) -> Result<T>255     fn into_test_result(self) -> Result<T>;
256 }
257 
258 #[cfg(feature = "anyhow")]
259 impl<T> IntoTestResult<T> for std::result::Result<T, anyhow::Error> {
into_test_result(self) -> std::result::Result<T, TestAssertionFailure>260     fn into_test_result(self) -> std::result::Result<T, TestAssertionFailure> {
261         self.map_err(|e| TestAssertionFailure::create(format!("{e}")))
262     }
263 }
264 
265 #[cfg(feature = "proptest")]
266 impl<OkT, CaseT: std::fmt::Debug> IntoTestResult<OkT>
267     for std::result::Result<OkT, proptest::test_runner::TestError<CaseT>>
268 {
into_test_result(self) -> std::result::Result<OkT, TestAssertionFailure>269     fn into_test_result(self) -> std::result::Result<OkT, TestAssertionFailure> {
270         self.map_err(|e| TestAssertionFailure::create(format!("{e}")))
271     }
272 }
273