1// Copyright 2007, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Author: wan@google.com (Zhanyong Wan)
31//
32// Utilities for testing Google Test itself and code that uses Google Test
33// (e.g. frameworks built on top of Google Test).
34
35#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
36#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
37
38#include "gtest/gtest.h"
39
40namespace testing {
41
42// This helper class can be used to mock out Google Test failure reporting
43// so that we can test Google Test or code that builds on Google Test.
44//
45// An object of this class appends a TestPartResult object to the
46// TestPartResultArray object given in the constructor whenever a Google Test
47// failure is reported. It can either intercept only failures that are
48// generated in the same thread that created this object or it can intercept
49// all generated failures. The scope of this mock object can be controlled with
50// the second argument to the two arguments constructor.
51class GTEST_API_ ScopedFakeTestPartResultReporter
52    : public TestPartResultReporterInterface {
53 public:
54  // The two possible mocking modes of this object.
55  enum InterceptMode {
56    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.
57    INTERCEPT_ALL_THREADS           // Intercepts all failures.
58  };
59
60  // The c'tor sets this object as the test part result reporter used
61  // by Google Test.  The 'result' parameter specifies where to report the
62  // results. This reporter will only catch failures generated in the current
63  // thread. DEPRECATED
64  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
65
66  // Same as above, but you can choose the interception scope of this object.
67  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
68                                   TestPartResultArray* result);
69
70  // The d'tor restores the previous test part result reporter.
71  ~ScopedFakeTestPartResultReporter() override;
72
73  // Appends the TestPartResult object to the TestPartResultArray
74  // received in the constructor.
75  //
76  // This method is from the TestPartResultReporterInterface
77  // interface.
78  void ReportTestPartResult(const TestPartResult &result) override;
79
80 private:
81  void Init();
82
83  const InterceptMode intercept_mode_;
84  TestPartResultReporterInterface* old_reporter_;
85  TestPartResultArray* const result_;
86
87  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
88};
89
90namespace internal {
91
92// A helper class for implementing EXPECT_FATAL_FAILURE() and
93// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given
94// TestPartResultArray contains exactly one failure that has the given
95// type and contains the given substring.  If that's not the case, a
96// non-fatal failure will be generated.
97class GTEST_API_ SingleFailureChecker {
98 public:
99  // The constructor remembers the arguments.
100  SingleFailureChecker(const TestPartResultArray* results,
101                       TestPartResult::Type type,
102                       const string& substr);
103  ~SingleFailureChecker();
104 private:
105  const TestPartResultArray* const results_;
106  const TestPartResult::Type type_;
107  const string substr_;
108
109  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
110};
111
112}  // namespace internal
113
114}  // namespace testing
115
116// A set of macros for testing Google Test assertions or code that's expected
117// to generate Google Test fatal failures.  It verifies that the given
118// statement will cause exactly one fatal Google Test failure with 'substr'
119// being part of the failure message.
120//
121// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
122// affects and considers failures generated in the current thread and
123// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
124//
125// The verification of the assertion is done correctly even when the statement
126// throws an exception or aborts the current function.
127//
128// Known restrictions:
129//   - 'statement' cannot reference local non-static variables or
130//     non-static members of the current object.
131//   - 'statement' cannot return a value.
132//   - You cannot stream a failure message to this macro.
133//
134// Note that even though the implementations of the following two
135// macros are much alike, we cannot refactor them to use a common
136// helper macro, due to some peculiarity in how the preprocessor
137// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in
138// gtest_unittest.cc will fail to compile if we do that.
139#define EXPECT_FATAL_FAILURE(statement, substr) \
140  do { \
141    class GTestExpectFatalFailureHelper {\
142     public:\
143      static void Execute() { statement; }\
144    };\
145    ::testing::TestPartResultArray gtest_failures;\
146    ::testing::internal::SingleFailureChecker gtest_checker(\
147        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
148    {\
149      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
150          ::testing::ScopedFakeTestPartResultReporter:: \
151          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
152      GTestExpectFatalFailureHelper::Execute();\
153    }\
154  } while (::testing::internal::AlwaysFalse())
155
156#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
157  do { \
158    class GTestExpectFatalFailureHelper {\
159     public:\
160      static void Execute() { statement; }\
161    };\
162    ::testing::TestPartResultArray gtest_failures;\
163    ::testing::internal::SingleFailureChecker gtest_checker(\
164        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
165    {\
166      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
167          ::testing::ScopedFakeTestPartResultReporter:: \
168          INTERCEPT_ALL_THREADS, &gtest_failures);\
169      GTestExpectFatalFailureHelper::Execute();\
170    }\
171  } while (::testing::internal::AlwaysFalse())
172
173// A macro for testing Google Test assertions or code that's expected to
174// generate Google Test non-fatal failures.  It asserts that the given
175// statement will cause exactly one non-fatal Google Test failure with 'substr'
176// being part of the failure message.
177//
178// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
179// affects and considers failures generated in the current thread and
180// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
181//
182// 'statement' is allowed to reference local variables and members of
183// the current object.
184//
185// The verification of the assertion is done correctly even when the statement
186// throws an exception or aborts the current function.
187//
188// Known restrictions:
189//   - You cannot stream a failure message to this macro.
190//
191// Note that even though the implementations of the following two
192// macros are much alike, we cannot refactor them to use a common
193// helper macro, due to some peculiarity in how the preprocessor
194// works.  If we do that, the code won't compile when the user gives
195// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
196// expands to code containing an unprotected comma.  The
197// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
198// catches that.
199//
200// For the same reason, we have to write
201//   if (::testing::internal::AlwaysTrue()) { statement; }
202// instead of
203//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
204// to avoid an MSVC warning on unreachable code.
205#define EXPECT_NONFATAL_FAILURE(statement, substr) \
206  do {\
207    ::testing::TestPartResultArray gtest_failures;\
208    ::testing::internal::SingleFailureChecker gtest_checker(\
209        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
210        (substr));\
211    {\
212      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
213          ::testing::ScopedFakeTestPartResultReporter:: \
214          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
215      if (::testing::internal::AlwaysTrue()) { statement; }\
216    }\
217  } while (::testing::internal::AlwaysFalse())
218
219#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
220  do {\
221    ::testing::TestPartResultArray gtest_failures;\
222    ::testing::internal::SingleFailureChecker gtest_checker(\
223        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
224        (substr));\
225    {\
226      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
227          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
228          &gtest_failures);\
229      if (::testing::internal::AlwaysTrue()) { statement; }\
230    }\
231  } while (::testing::internal::AlwaysFalse())
232
233#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
234