251 lines · c
1// Copyright 2007, Google Inc.2// All rights reserved.3//4// Redistribution and use in source and binary forms, with or without5// modification, are permitted provided that the following conditions are6// met:7//8// * Redistributions of source code must retain the above copyright9// notice, this list of conditions and the following disclaimer.10// * Redistributions in binary form must reproduce the above11// copyright notice, this list of conditions and the following disclaimer12// in the documentation and/or other materials provided with the13// distribution.14// * Neither the name of Google Inc. nor the names of its15// contributors may be used to endorse or promote products derived from16// this software without specific prior written permission.17//18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 30// Utilities for testing Google Test itself and code that uses Google Test31// (e.g. frameworks built on top of Google Test).32 33#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_34#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_35 36#include <string>37 38#include "gtest/gtest.h"39 40GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \41/* class A needs to have dll-interface to be used by clients of class B */)42 43namespace testing {44 45// This helper class can be used to mock out Google Test failure reporting46// so that we can test Google Test or code that builds on Google Test.47//48// An object of this class appends a TestPartResult object to the49// TestPartResultArray object given in the constructor whenever a Google Test50// failure is reported. It can either intercept only failures that are51// generated in the same thread that created this object or it can intercept52// all generated failures. The scope of this mock object can be controlled with53// the second argument to the two arguments constructor.54class GTEST_API_ ScopedFakeTestPartResultReporter55 : public TestPartResultReporterInterface {56 public:57 // The two possible mocking modes of this object.58 enum InterceptMode {59 INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.60 INTERCEPT_ALL_THREADS // Intercepts all failures.61 };62 63 // The c'tor sets this object as the test part result reporter used64 // by Google Test. The 'result' parameter specifies where to report the65 // results. This reporter will only catch failures generated in the current66 // thread. DEPRECATED67 explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);68 69 // Same as above, but you can choose the interception scope of this object.70 ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,71 TestPartResultArray* result);72 73 // The d'tor restores the previous test part result reporter.74 ~ScopedFakeTestPartResultReporter() override;75 76 // Appends the TestPartResult object to the TestPartResultArray77 // received in the constructor.78 //79 // This method is from the TestPartResultReporterInterface80 // interface.81 void ReportTestPartResult(const TestPartResult& result) override;82 83 private:84 void Init();85 86 const InterceptMode intercept_mode_;87 TestPartResultReporterInterface* old_reporter_;88 TestPartResultArray* const result_;89 90 ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =91 delete;92 ScopedFakeTestPartResultReporter& operator=(93 const ScopedFakeTestPartResultReporter&) = delete;94};95 96namespace internal {97 98// A helper class for implementing EXPECT_FATAL_FAILURE() and99// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given100// TestPartResultArray contains exactly one failure that has the given101// type and contains the given substring. If that's not the case, a102// non-fatal failure will be generated.103class GTEST_API_ SingleFailureChecker {104 public:105 // The constructor remembers the arguments.106 SingleFailureChecker(const TestPartResultArray* results,107 TestPartResult::Type type, const std::string& substr);108 ~SingleFailureChecker();109 110 private:111 const TestPartResultArray* const results_;112 const TestPartResult::Type type_;113 const std::string substr_;114 115 SingleFailureChecker(const SingleFailureChecker&) = delete;116 SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;117};118 119} // namespace internal120 121} // namespace testing122 123GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251124 125// A set of macros for testing Google Test assertions or code that's expected126// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but127// not a non-fatal failure, as from EXPECT_EQ). It verifies that the given128// statement will cause exactly one fatal Google Test failure with 'substr'129// being part of the failure message.130//131// There are two different versions of this macro. EXPECT_FATAL_FAILURE only132// affects and considers failures generated in the current thread and133// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.134//135// The verification of the assertion is done correctly even when the statement136// throws an exception or aborts the current function.137//138// Known restrictions:139// - 'statement' cannot reference local non-static variables or140// non-static members of the current object.141// - 'statement' cannot return a value.142// - You cannot stream a failure message to this macro.143//144// Note that even though the implementations of the following two145// macros are much alike, we cannot refactor them to use a common146// helper macro, due to some peculiarity in how the preprocessor147// works. The AcceptsMacroThatExpandsToUnprotectedComma test in148// gtest_unittest.cc will fail to compile if we do that.149#define EXPECT_FATAL_FAILURE(statement, substr) \150 do { \151 class GTestExpectFatalFailureHelper { \152 public: \153 static void Execute() { statement; } \154 }; \155 ::testing::TestPartResultArray gtest_failures; \156 ::testing::internal::SingleFailureChecker gtest_checker( \157 >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \158 { \159 ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \160 ::testing::ScopedFakeTestPartResultReporter:: \161 INTERCEPT_ONLY_CURRENT_THREAD, \162 >est_failures); \163 GTestExpectFatalFailureHelper::Execute(); \164 } \165 } while (::testing::internal::AlwaysFalse())166 167#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \168 do { \169 class GTestExpectFatalFailureHelper { \170 public: \171 static void Execute() { statement; } \172 }; \173 ::testing::TestPartResultArray gtest_failures; \174 ::testing::internal::SingleFailureChecker gtest_checker( \175 >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \176 { \177 ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \178 ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \179 >est_failures); \180 GTestExpectFatalFailureHelper::Execute(); \181 } \182 } while (::testing::internal::AlwaysFalse())183 184// A macro for testing Google Test assertions or code that's expected to185// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,186// but not from an ASSERT_EQ). It asserts that the given statement will cause187// exactly one non-fatal Google Test failure with 'substr' being part of the188// failure message.189//190// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only191// affects and considers failures generated in the current thread and192// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.193//194// 'statement' is allowed to reference local variables and members of195// the current object.196//197// The verification of the assertion is done correctly even when the statement198// throws an exception or aborts the current function.199//200// Known restrictions:201// - You cannot stream a failure message to this macro.202//203// Note that even though the implementations of the following two204// macros are much alike, we cannot refactor them to use a common205// helper macro, due to some peculiarity in how the preprocessor206// works. If we do that, the code won't compile when the user gives207// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that208// expands to code containing an unprotected comma. The209// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc210// catches that.211//212// For the same reason, we have to write213// if (::testing::internal::AlwaysTrue()) { statement; }214// instead of215// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)216// to avoid an MSVC warning on unreachable code.217#define EXPECT_NONFATAL_FAILURE(statement, substr) \218 do { \219 ::testing::TestPartResultArray gtest_failures; \220 ::testing::internal::SingleFailureChecker gtest_checker( \221 >est_failures, ::testing::TestPartResult::kNonFatalFailure, \222 (substr)); \223 { \224 ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \225 ::testing::ScopedFakeTestPartResultReporter:: \226 INTERCEPT_ONLY_CURRENT_THREAD, \227 >est_failures); \228 if (::testing::internal::AlwaysTrue()) { \229 statement; \230 } \231 } \232 } while (::testing::internal::AlwaysFalse())233 234#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \235 do { \236 ::testing::TestPartResultArray gtest_failures; \237 ::testing::internal::SingleFailureChecker gtest_checker( \238 >est_failures, ::testing::TestPartResult::kNonFatalFailure, \239 (substr)); \240 { \241 ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \242 ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \243 >est_failures); \244 if (::testing::internal::AlwaysTrue()) { \245 statement; \246 } \247 } \248 } while (::testing::internal::AlwaysFalse())249 250#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_251