• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 fixtures;
26 #[macro_use]
27 pub mod fmt;
28 pub mod internal;
29 pub mod matcher;
30 pub mod matcher_support;
31 pub mod matchers;
32 
33 pub use googletest_macro::{__abbreviated_stringify, __googletest_macro_verify_pred};
34 
35 /// Re-exports of the symbols in this crate which are most likely to be used.
36 ///
37 /// This includes:
38 ///  * All assertion macros,
39 ///  * Traits and type definitions normally used by tests, and
40 ///  * All built-in matchers.
41 ///
42 /// Typically, one imports everything in the prelude in one's test module:
43 ///
44 /// ```
45 /// mod tests {
46 ///     use googletest::prelude::*;
47 /// }
48 /// ```
49 pub mod prelude {
50     pub use super::fixtures::{ConsumableFixture, Fixture, FixtureOf, StaticFixture};
51     pub use super::gtest;
52     pub use super::matcher::{Matcher, MatcherBase};
53     pub use super::matchers::*;
54     pub use super::verify_current_test_outcome;
55     pub use super::GoogleTestSupport;
56     pub use super::IntoTestResult;
57     pub use super::Result;
58     // Assert macros
59     pub use super::{
60         add_failure, add_failure_at, assert_pred, assert_that, expect_eq, expect_false,
61         expect_float_eq, expect_ge, expect_gt, expect_le, expect_lt, expect_ne, expect_near,
62         expect_pred, expect_that, expect_true, fail, succeed, verify_eq, verify_false,
63         verify_float_eq, verify_ge, verify_gt, verify_le, verify_lt, verify_ne, verify_near,
64         verify_pred, verify_that, verify_true,
65     };
66 }
67 
68 pub use googletest_macro::gtest;
69 pub use googletest_macro::test;
70 
71 use internal::test_outcome::{TestAssertionFailure, TestOutcome};
72 
73 /// A `Result` whose `Err` variant indicates a test failure.
74 ///
75 /// The assertions [`verify_that!`][crate::verify_that],
76 /// [`verify_pred!`][crate::verify_pred], and [`fail!`][crate::fail] evaluate
77 /// to `Result<()>`. A test function may return `Result<()>` in combination with
78 /// those macros to abort immediately on assertion failure.
79 ///
80 /// This can be used with subroutines which may cause the test to fatally fail
81 /// and which return some value needed by the caller. For example:
82 ///
83 /// ```ignore
84 /// fn load_file_content_as_string() -> Result<String> {
85 ///     let file_stream = load_file().err_to_test_failure()?;
86 ///     Ok(file_stream.to_string())
87 /// }
88 /// ```
89 ///
90 /// The `Err` variant contains a [`TestAssertionFailure`] which carries the data
91 /// of the (fatal) assertion failure which generated this result. Non-fatal
92 /// assertion failures, which log the failure and report the test as having
93 /// failed but allow it to continue running, are not encoded in this type.
94 pub type Result<T> = std::result::Result<T, TestAssertionFailure>;
95 
96 /// Returns a [`Result`] corresponding to the outcome of the currently running
97 /// test.
98 ///
99 /// This returns `Result::Err` precisely if the current test has recorded at
100 /// least one test assertion failure via [`expect_that!`][crate::expect_that],
101 /// [`expect_pred!`][crate::expect_pred], or
102 /// [`GoogleTestSupport::and_log_failure`]. It can be used in concert with the
103 /// `?` operator to continue execution of the test conditionally on there not
104 /// having been any failure yet.
105 ///
106 /// This requires the use of the [`#[gtest]`][crate::gtest] attribute macro.
107 ///
108 /// ```
109 /// # use googletest::prelude::*;
110 /// # /* Make sure this also compiles as a doctest.
111 /// #[gtest]
112 /// # */
113 /// # fn foo() -> u32 { 1 }
114 /// # fn bar() -> u32 { 2 }
115 /// fn should_fail_and_not_execute_last_assertion() -> Result<()> {
116 /// #   googletest::internal::test_outcome::TestOutcome::init_current_test_outcome();
117 ///     expect_that!(foo(), eq(2));     // May fail, but will not abort the test.
118 ///     expect_that!(bar(), gt(1));     // May fail, but will not abort the test.
119 ///     verify_current_test_outcome()?; // Aborts the test if one of the previous assertions failed.
120 ///     verify_that!(foo(), gt(0))      // Does not execute if the line above aborts.
121 /// }
122 /// # verify_that!(should_fail_and_not_execute_last_assertion(), err(displays_as(contains_substring("Test failed")))).unwrap();
123 /// ```
124 #[track_caller]
verify_current_test_outcome() -> Result<()>125 pub fn verify_current_test_outcome() -> Result<()> {
126     TestOutcome::get_current_test_outcome()
127 }
128 
129 /// Adds to `Result` support for GoogleTest Rust functionality.
130 pub trait GoogleTestSupport {
131     /// If `self` is a `Result::Err`, writes to `stdout` a failure report
132     /// and marks the test failed. Otherwise, does nothing.
133     ///
134     /// This can be used for non-fatal test assertions, for example:
135     ///
136     /// ```
137     /// # use googletest::prelude::*;
138     /// # use googletest::internal::test_outcome::TestOutcome;
139     /// # TestOutcome::init_current_test_outcome();
140     /// let actual = 42;
141     /// verify_that!(actual, eq(42)).and_log_failure();
142     ///                                  // Test still passing; nothing happens
143     /// verify_that!(actual, eq(10)).and_log_failure();
144     ///                          // Test now fails and failure output to stdout
145     /// verify_that!(actual, eq(100)).and_log_failure();
146     ///               // Test still fails and new failure also output to stdout
147     /// # TestOutcome::close_current_test_outcome::<&str>(Ok(())).unwrap_err();
148     /// ```
and_log_failure(self)149     fn and_log_failure(self);
150 
151     /// Adds `message` to the logged failure message if `self` is a
152     /// `Result::Err`. Otherwise, does nothing.
153     ///
154     /// If this method is called more than once, only `message` from the last
155     /// invocation is output.
156     ///
157     /// For example:
158     ///
159     /// ```
160     /// # use googletest::prelude::*;
161     /// # fn should_fail() -> Result<()> {
162     /// let actual = 0;
163     /// verify_that!(actual, eq(42)).failure_message("Actual was wrong!")?;
164     /// # Ok(())
165     /// # }
166     /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual was wrong"))))
167     /// #     .unwrap();
168     /// ```
169     ///
170     /// results in the following failure message:
171     ///
172     /// ```text
173     /// Expected: actual equal to 42
174     ///   but was: 0
175     /// Actual was wrong!
176     /// ```
177     ///
178     /// One can pass a `String` too:
179     ///
180     /// ```
181     /// # use googletest::prelude::*;
182     /// # fn should_fail() -> Result<()> {
183     /// let actual = 0;
184     /// verify_that!(actual, eq(42))
185     ///    .failure_message(format!("Actual {} was wrong!", actual))?;
186     /// # Ok(())
187     /// # }
188     /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual 0 was wrong"))))
189     /// #     .unwrap();
190     /// ```
191     ///
192     /// However, consider using [`GoogleTestSupport::with_failure_message`]
193     /// instead in that case to avoid unnecessary memory allocation when the
194     /// message is not needed.
failure_message(self, message: impl Into<String>) -> Self195     fn failure_message(self, message: impl Into<String>) -> Self;
196 
197     /// Adds the output of the closure `provider` to the logged failure message
198     /// if `self` is a `Result::Err`. Otherwise, does nothing.
199     ///
200     /// This is analogous to [`GoogleTestSupport::failure_message`] but
201     /// only executes the closure `provider` if it actually produces the
202     /// message, thus saving possible memory allocation.
203     ///
204     /// ```
205     /// # use googletest::prelude::*;
206     /// # fn should_fail() -> Result<()> {
207     /// let actual = 0;
208     /// verify_that!(actual, eq(42))
209     ///    .with_failure_message(|| format!("Actual {} was wrong!", actual))?;
210     /// # Ok(())
211     /// # }
212     /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual 0 was wrong"))))
213     /// #     .unwrap();
214     /// ```
with_failure_message(self, provider: impl FnOnce() -> String) -> Self215     fn with_failure_message(self, provider: impl FnOnce() -> String) -> Self;
216 }
217 
218 impl<T> GoogleTestSupport for std::result::Result<T, TestAssertionFailure> {
and_log_failure(self)219     fn and_log_failure(self) {
220         TestOutcome::ensure_test_context_present();
221         if let Err(failure) = self {
222             failure.log();
223         }
224     }
225 
failure_message(mut self, message: impl Into<String>) -> Self226     fn failure_message(mut self, message: impl Into<String>) -> Self {
227         if let Err(ref mut failure) = self {
228             failure.custom_message = Some(message.into());
229         }
230         self
231     }
232 
with_failure_message(mut self, provider: impl FnOnce() -> String) -> Self233     fn with_failure_message(mut self, provider: impl FnOnce() -> String) -> Self {
234         if let Err(ref mut failure) = self {
235             failure.custom_message = Some(provider());
236         }
237         self
238     }
239 }
240 
241 /// Provides an extension method for converting an arbitrary type into a
242 /// [`Result`].
243 ///
244 /// A type can implement this trait to provide an easy way to return immediately
245 /// from a test in conjunction with the `?` operator. This is useful for
246 /// [`Option`] and [`Result`][std::result::Result] types whose `Result::Err`
247 /// variant does not implement [`std::error::Error`].
248 ///
249 /// If `Result::Err` implements [`std::error::Error`] you can just use the `?`
250 /// operator directly.
251 ///
252 /// ```ignore
253 /// #[test]
254 /// fn should_work() -> googletest::Result<()> {
255 ///     let value = something_which_can_fail().into_test_result()?;
256 ///     let value = something_which_can_fail_with_option().into_test_result()?;
257 ///     ...
258 /// }
259 ///
260 /// fn something_which_can_fail() -> std::result::Result<T, String> { ... }
261 /// fn something_which_can_fail_with_option() -> Option<T> { ... }
262 /// ```
263 pub trait IntoTestResult<T> {
264     /// Converts this instance into a [`Result`].
265     ///
266     /// Typically, the `Self` type is itself an implementation of the
267     /// [`std::ops::Try`] trait. This method should then map the `Residual`
268     /// variant to a [`TestAssertionFailure`] and leave the `Output` variant
269     /// unchanged.
into_test_result(self) -> Result<T>270     fn into_test_result(self) -> Result<T>;
271 }
272 
273 impl<T, E: std::fmt::Debug> IntoTestResult<T> for std::result::Result<T, E> {
274     #[track_caller]
into_test_result(self) -> std::result::Result<T, TestAssertionFailure>275     fn into_test_result(self) -> std::result::Result<T, TestAssertionFailure> {
276         match self {
277             Ok(t) => Ok(t),
278             Err(e) => Err(TestAssertionFailure::create(format!("{e:?}"))),
279         }
280     }
281 }
282 
283 impl<T> IntoTestResult<T> for Option<T> {
284     #[track_caller]
into_test_result(self) -> std::result::Result<T, TestAssertionFailure>285     fn into_test_result(self) -> std::result::Result<T, TestAssertionFailure> {
286         match self {
287             Some(t) => Ok(t),
288             None => Err(TestAssertionFailure::create(format!(
289                 "called `Option::into_test_result()` on a `Option::<{}>::None` value",
290                 std::any::type_name::<T>()
291             ))),
292         }
293     }
294 }
295