googletest/lib.rs
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
17extern crate googletest_macro;
18
19#[cfg(test)]
20extern crate quickcheck;
21
22#[macro_use]
23pub mod assertions;
24pub mod description;
25pub mod fixtures;
26#[macro_use]
27pub mod fmt;
28pub mod internal;
29pub mod matcher;
30pub mod matcher_support;
31pub mod matchers;
32
33pub use googletest_macro::__abbreviated_stringify;
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/// ```
49pub 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::OrFail;
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
68pub use googletest_macro::gtest;
69pub use googletest_macro::test;
70
71use 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.
94pub 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]
125pub fn verify_current_test_outcome() -> Result<()> {
126 TestOutcome::get_current_test_outcome()
127}
128
129/// Adds to `Result` support for GoogleTest Rust functionality.
130pub 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 /// ```
149 fn and_log_failure(self);
150
151 /// If `self` is a `Result::Err`, writes to `stdout` with a failure report
152 /// and the message returned by `provider`.
153 ///
154 /// This is equivalent to combining [`GoogleTestSupport::and_log_failure`]
155 /// with a call to [`GoogleTestSupport::with_failure_message`].
156 ///
157 /// Example:
158 ///
159 /// ```
160 /// # use googletest::GoogleTestSupport;
161 /// # use googletest::assertions::verify_eq;
162 /// # use googletest::internal::test_outcome::TestOutcome;
163 /// # TestOutcome::init_current_test_outcome();
164 /// let actual = 0;
165 /// verify_eq!(actual, 42)
166 /// .and_log_failure_with_message(|| format!("Actual {} was wrong!", actual));
167 /// # TestOutcome::close_current_test_outcome::<&str>(Ok(())).unwrap_err();
168 /// ```
169 fn and_log_failure_with_message(self, provider: impl FnOnce() -> String)
170 where
171 Self: Sized,
172 {
173 self.with_failure_message(provider).and_log_failure();
174 }
175
176 /// Adds `message` to the logged failure message if `self` is a
177 /// `Result::Err`. Otherwise, does nothing.
178 ///
179 /// If this method is called more than once, only `message` from the last
180 /// invocation is output.
181 ///
182 /// For example:
183 ///
184 /// ```
185 /// # use googletest::prelude::*;
186 /// # fn should_fail() -> Result<()> {
187 /// let actual = 0;
188 /// verify_that!(actual, eq(42)).failure_message("Actual was wrong!")?;
189 /// # Ok(())
190 /// # }
191 /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual was wrong"))))
192 /// # .unwrap();
193 /// ```
194 ///
195 /// results in the following failure message:
196 ///
197 /// ```text
198 /// Expected: actual equal to 42
199 /// but was: 0
200 /// Actual was wrong!
201 /// ```
202 ///
203 /// One can pass a `String` too:
204 ///
205 /// ```
206 /// # use googletest::prelude::*;
207 /// # fn should_fail() -> Result<()> {
208 /// let actual = 0;
209 /// verify_that!(actual, eq(42))
210 /// .failure_message(format!("Actual {} was wrong!", actual))?;
211 /// # Ok(())
212 /// # }
213 /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual 0 was wrong"))))
214 /// # .unwrap();
215 /// ```
216 ///
217 /// However, consider using [`GoogleTestSupport::with_failure_message`]
218 /// instead in that case to avoid unnecessary memory allocation when the
219 /// message is not needed.
220 fn failure_message(self, message: impl Into<String>) -> Self;
221
222 /// Adds the output of the closure `provider` to the logged failure message
223 /// if `self` is a `Result::Err`. Otherwise, does nothing.
224 ///
225 /// This is analogous to [`GoogleTestSupport::failure_message`] but
226 /// only executes the closure `provider` if it actually produces the
227 /// message, thus saving possible memory allocation.
228 ///
229 /// ```
230 /// # use googletest::prelude::*;
231 /// # fn should_fail() -> Result<()> {
232 /// let actual = 0;
233 /// verify_that!(actual, eq(42))
234 /// .with_failure_message(|| format!("Actual {} was wrong!", actual))?;
235 /// # Ok(())
236 /// # }
237 /// # verify_that!(should_fail(), err(displays_as(contains_substring("Actual 0 was wrong"))))
238 /// # .unwrap();
239 /// ```
240 fn with_failure_message(self, provider: impl FnOnce() -> String) -> Self;
241}
242
243impl<T> GoogleTestSupport for std::result::Result<T, TestAssertionFailure> {
244 fn and_log_failure(self) {
245 TestOutcome::ensure_test_context_present();
246 if let Err(failure) = self {
247 failure.log();
248 }
249 }
250
251 fn failure_message(mut self, message: impl Into<String>) -> Self {
252 if let Err(ref mut failure) = self {
253 failure.custom_message = Some(message.into());
254 }
255 self
256 }
257
258 fn with_failure_message(mut self, provider: impl FnOnce() -> String) -> Self {
259 if let Err(ref mut failure) = self {
260 failure.custom_message = Some(provider());
261 }
262 self
263 }
264}
265
266/// Provides an extension method for converting an arbitrary type into
267/// `googletest`'s [`Result`] type.
268///
269/// A type can implement this trait to provide an easy way to return immediately
270/// from a test in conjunction with the `?` operator. This is useful for
271/// [`Option`] and [`Result`][std::result::Result] types whose `Result::Err`
272/// variant does not implement [`std::error::Error`].
273///
274/// If `Result::Err` implements [`std::error::Error`] you can just use the `?`
275/// operator directly.
276///
277/// ```ignore
278/// #[test]
279/// fn should_work() -> googletest::Result<()> {
280/// let value = something_which_can_fail().or_fail()?;
281/// let value = something_which_can_fail_with_option().or_fail()?;
282/// ...
283/// }
284///
285/// fn something_which_can_fail() -> std::result::Result<T, String> { ... }
286/// fn something_which_can_fail_with_option() -> Option<T> { ... }
287/// ```
288pub trait OrFail {
289 /// The success type of the test result.
290 type Output;
291
292 /// Converts a value into a [`Result`] containing
293 /// either the [`Self::Output`] type or a [`TestAssertionFailure`].
294 ///
295 /// The most frequently used implementations convert
296 /// `Result<T, E>` into `Result<T, TestAssertionFailure>` and
297 /// `Option<T>` into `Result<T, TestAssertionFailure>`.
298 fn or_fail(self) -> Result<Self::Output>;
299}
300
301impl<T, E: std::fmt::Debug> OrFail for std::result::Result<T, E> {
302 type Output = T;
303
304 #[track_caller]
305 fn or_fail(self) -> std::result::Result<T, TestAssertionFailure> {
306 match self {
307 Ok(t) => Ok(t),
308 Err(e) => Err(TestAssertionFailure::create(format!("{e:?}"))),
309 }
310 }
311}
312
313impl<T> OrFail for Option<T> {
314 type Output = T;
315
316 #[track_caller]
317 fn or_fail(self) -> std::result::Result<T, TestAssertionFailure> {
318 match self {
319 Some(t) => Ok(t),
320 None => Err(TestAssertionFailure::create(format!(
321 "called `Option::or_fail()` on a `Option::<{}>::None` value",
322 std::any::type_name::<T>()
323 ))),
324 }
325 }
326}