"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "googletest/include/gtest/internal/gtest-internal.h" between
googletest-release-1.11.0.tar.gz and googletest-release-1.12.0.tar.gz

About: GoogleTest is Google's (unit) testing and mocking framework for C++ tests.

gtest-internal.h  (googletest-release-1.11.0):gtest-internal.h  (googletest-release-1.12.0)
skipping to change at line 29 skipping to change at line 29
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file declares functions and macros used internally by // This header file declares functions and macros used internally by
// Google Test. They are subject to change without notice. // Google Test. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#if GTEST_OS_LINUX #if GTEST_OS_LINUX
# include <stdlib.h> #include <stdlib.h>
# include <sys/types.h> #include <sys/types.h>
# include <sys/wait.h> #include <sys/wait.h>
# include <unistd.h> #include <unistd.h>
#endif // GTEST_OS_LINUX #endif // GTEST_OS_LINUX
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
# include <stdexcept> #include <stdexcept>
#endif #endif
#include <ctype.h> #include <ctype.h>
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>
#include <limits> #include <limits>
#include <map> #include <map>
#include <set> #include <set>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
skipping to change at line 79 skipping to change at line 82
// Due to C++ preprocessor weirdness, we need double indirection to // Due to C++ preprocessor weirdness, we need double indirection to
// concatenate two tokens when one of them is __LINE__. Writing // concatenate two tokens when one of them is __LINE__. Writing
// //
// foo ## __LINE__ // foo ## __LINE__
// //
// will result in the token foo__LINE__, instead of foo followed by // will result in the token foo__LINE__, instead of foo followed by
// the current line number. For more details, see // the current line number. For more details, see
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
// Stringifies its argument. // Stringifies its argument.
// Work around a bug in visual studio which doesn't accept code like this: // Work around a bug in visual studio which doesn't accept code like this:
// //
// #define GTEST_STRINGIFY_(name) #name // #define GTEST_STRINGIFY_(name) #name
// #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ... // #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ...
// MACRO(, x, y) // MACRO(, x, y)
// //
// Complaining about the argument to GTEST_STRINGIFY_ being empty. // Complaining about the argument to GTEST_STRINGIFY_ being empty.
// This is allowed by the spec. // This is allowed by the spec.
skipping to change at line 101 skipping to change at line 104
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, ) #define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
namespace proto2 { namespace proto2 {
class MessageLite; class MessageLite;
} }
namespace testing { namespace testing {
// Forward declarations. // Forward declarations.
class AssertionResult; // Result of an assertion. class AssertionResult; // Result of an assertion.
class Message; // Represents a failure message. class Message; // Represents a failure message.
class Test; // Represents a test. class Test; // Represents a test.
class TestInfo; // Information about a test. class TestInfo; // Information about a test.
class TestPartResult; // Result of a test part. class TestPartResult; // Result of a test part.
class UnitTest; // A collection of test suites. class UnitTest; // A collection of test suites.
template <typename T> template <typename T>
::std::string PrintToString(const T& value); ::std::string PrintToString(const T& value);
namespace internal { namespace internal {
struct TraceInfo; // Information about a trace point. struct TraceInfo; // Information about a trace point.
class TestInfoImpl; // Opaque implementation of TestInfo class TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest class UnitTestImpl; // Opaque implementation of UnitTest
// The text used in failure messages to indicate the start of the // The text used in failure messages to indicate the start of the
// stack trace. // stack trace.
GTEST_API_ extern const char kStackTraceMarker[]; GTEST_API_ extern const char kStackTraceMarker[];
// An IgnoredValue object can be implicitly constructed from ANY value. // An IgnoredValue object can be implicitly constructed from ANY value.
class IgnoredValue { class IgnoredValue {
struct Sink {}; struct Sink {};
public: public:
// This constructor template allows any value to be implicitly // This constructor template allows any value to be implicitly
// converted to IgnoredValue. The object has no data member and // converted to IgnoredValue. The object has no data member and
// doesn't try to remember anything about the argument. We // doesn't try to remember anything about the argument. We
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
// Disable the conversion if T already has a magical conversion operator. // Disable the conversion if T already has a magical conversion operator.
// Otherwise we get ambiguity. // Otherwise we get ambiguity.
template <typename T, template <typename T,
typename std::enable_if<!std::is_convertible<T, Sink>::value, typename std::enable_if<!std::is_convertible<T, Sink>::value,
int>::type = 0> int>::type = 0>
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// Appends the user-supplied message to the Google-Test-generated message. // Appends the user-supplied message to the Google-Test-generated message.
GTEST_API_ std::string AppendUserMessage( GTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg,
const std::string& gtest_msg, const Message& user_msg); const Message& user_msg);
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4275 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
/* an exported class was derived from a class that was not exported */) 4275 /* an exported class was derived from a class that was not exported */)
// This exception is thrown by (and only by) a failed Google Test // This exception is thrown by (and only by) a failed Google Test
// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions
// are enabled). We derive it from std::runtime_error, which is for // are enabled). We derive it from std::runtime_error, which is for
// errors presumably detectable only at run time. Since // errors presumably detectable only at run time. Since
// std::runtime_error inherits from std::exception, many testing // std::runtime_error inherits from std::exception, many testing
// frameworks know how to extract and print the message inside it. // frameworks know how to extract and print the message inside it.
class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
public: public:
explicit GoogleTestFailureException(const TestPartResult& failure); explicit GoogleTestFailureException(const TestPartResult& failure);
skipping to change at line 184 skipping to change at line 188
const std::vector<std::string>& left, const std::vector<std::string>& left,
const std::vector<std::string>& right); const std::vector<std::string>& right);
// Create a diff of the input strings in Unified diff format. // Create a diff of the input strings in Unified diff format.
GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left, GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,
const std::vector<std::string>& right, const std::vector<std::string>& right,
size_t context = 2); size_t context = 2);
} // namespace edit_distance } // namespace edit_distance
// Calculate the diff between 'left' and 'right' and return it in unified diff
// format.
// If not null, stores in 'total_line_count' the total number of lines found
// in left + right.
GTEST_API_ std::string DiffStrings(const std::string& left,
const std::string& right,
size_t* total_line_count);
// Constructs and returns the message for an equality assertion // Constructs and returns the message for an equality assertion
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
// //
// The first four parameters are the expressions used in the assertion // The first four parameters are the expressions used in the assertion
// and their values, as strings. For example, for ASSERT_EQ(foo, bar) // and their values, as strings. For example, for ASSERT_EQ(foo, bar)
// where foo is 5 and bar is 6, we have: // where foo is 5 and bar is 6, we have:
// //
// expected_expression: "foo" // expected_expression: "foo"
// actual_expression: "bar" // actual_expression: "bar"
// expected_value: "5" // expected_value: "5"
skipping to change at line 215 skipping to change at line 211
// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
// be inserted into the message. // be inserted into the message.
GTEST_API_ AssertionResult EqFailure(const char* expected_expression, GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
const char* actual_expression, const char* actual_expression,
const std::string& expected_value, const std::string& expected_value,
const std::string& actual_value, const std::string& actual_value,
bool ignoring_case); bool ignoring_case);
// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. // Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
GTEST_API_ std::string GetBoolAssertionFailureMessage( GTEST_API_ std::string GetBoolAssertionFailureMessage(
const AssertionResult& assertion_result, const AssertionResult& assertion_result, const char* expression_text,
const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value);
const char* actual_predicate_value,
const char* expected_predicate_value);
// This template class represents an IEEE floating-point number // This template class represents an IEEE floating-point number
// (either single-precision or double-precision, depending on the // (either single-precision or double-precision, depending on the
// template parameters). // template parameters).
// //
// The purpose of this class is to do more sophisticated number // The purpose of this class is to do more sophisticated number
// comparison. (Due to round-off error, etc, it's very unlikely that // comparison. (Due to round-off error, etc, it's very unlikely that
// two floating-points will be equal exactly. Hence a naive // two floating-points will be equal exactly. Hence a naive
// comparison by the == operation often doesn't work.) // comparison by the == operation often doesn't work.)
// //
skipping to change at line 259 skipping to change at line 253
template <typename RawType> template <typename RawType>
class FloatingPoint { class FloatingPoint {
public: public:
// Defines the unsigned integer type that has the same size as the // Defines the unsigned integer type that has the same size as the
// floating point number. // floating point number.
typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits; typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
// Constants. // Constants.
// # of bits in a number. // # of bits in a number.
static const size_t kBitCount = 8*sizeof(RawType); static const size_t kBitCount = 8 * sizeof(RawType);
// # of fraction bits in a number. // # of fraction bits in a number.
static const size_t kFractionBitCount = static const size_t kFractionBitCount =
std::numeric_limits<RawType>::digits - 1; std::numeric_limits<RawType>::digits - 1;
// # of exponent bits in a number. // # of exponent bits in a number.
static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
// The mask for the sign bit. // The mask for the sign bit.
static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1); static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
// The mask for the fraction bits. // The mask for the fraction bits.
static const Bits kFractionBitMask = static const Bits kFractionBitMask = ~static_cast<Bits>(0) >>
~static_cast<Bits>(0) >> (kExponentBitCount + 1); (kExponentBitCount + 1);
// The mask for the exponent bits. // The mask for the exponent bits.
static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
// How many ULP's (Units in the Last Place) we want to tolerate when // How many ULP's (Units in the Last Place) we want to tolerate when
// comparing two numbers. The larger the value, the more error we // comparing two numbers. The larger the value, the more error we
// allow. A 0 value means that two numbers must be exactly the same // allow. A 0 value means that two numbers must be exactly the same
// to be considered equal. // to be considered equal.
// //
// The maximum error of a single floating-point operation is 0.5 // The maximum error of a single floating-point operation is 0.5
skipping to change at line 312 skipping to change at line 306
// Reinterprets a bit pattern as a floating-point number. // Reinterprets a bit pattern as a floating-point number.
// //
// This function is needed to test the AlmostEquals() method. // This function is needed to test the AlmostEquals() method.
static RawType ReinterpretBits(const Bits bits) { static RawType ReinterpretBits(const Bits bits) {
FloatingPoint fp(0); FloatingPoint fp(0);
fp.u_.bits_ = bits; fp.u_.bits_ = bits;
return fp.u_.value_; return fp.u_.value_;
} }
// Returns the floating-point number that represent positive infinity. // Returns the floating-point number that represent positive infinity.
static RawType Infinity() { static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }
return ReinterpretBits(kExponentBitMask);
}
// Returns the maximum representable finite floating-point number. // Returns the maximum representable finite floating-point number.
static RawType Max(); static RawType Max();
// Non-static methods // Non-static methods
// Returns the bits that represents this number. // Returns the bits that represents this number.
const Bits &bits() const { return u_.bits_; } const Bits& bits() const { return u_.bits_; }
// Returns the exponent bits of this number. // Returns the exponent bits of this number.
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
// Returns the fraction bits of this number. // Returns the fraction bits of this number.
Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
// Returns the sign bit of this number. // Returns the sign bit of this number.
Bits sign_bit() const { return kSignBitMask & u_.bits_; } Bits sign_bit() const { return kSignBitMask & u_.bits_; }
skipping to change at line 351 skipping to change at line 343
// from rhs. In particular, this function: // from rhs. In particular, this function:
// //
// - returns false if either number is (or both are) NAN. // - returns false if either number is (or both are) NAN.
// - treats really large numbers as almost equal to infinity. // - treats really large numbers as almost equal to infinity.
// - thinks +0.0 and -0.0 are 0 DLP's apart. // - thinks +0.0 and -0.0 are 0 DLP's apart.
bool AlmostEquals(const FloatingPoint& rhs) const { bool AlmostEquals(const FloatingPoint& rhs) const {
// The IEEE standard says that any comparison operation involving // The IEEE standard says that any comparison operation involving
// a NAN must return false. // a NAN must return false.
if (is_nan() || rhs.is_nan()) return false; if (is_nan() || rhs.is_nan()) return false;
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
<= kMaxUlps; kMaxUlps;
} }
private: private:
// The data type used to store the actual floating-point number. // The data type used to store the actual floating-point number.
union FloatingPointUnion { union FloatingPointUnion {
RawType value_; // The raw floating-point number. RawType value_; // The raw floating-point number.
Bits bits_; // The bits that represent the number. Bits bits_; // The bits that represent the number.
}; };
// Converts an integer from the sign-and-magnitude representation to // Converts an integer from the sign-and-magnitude representation to
skipping to change at line 377 skipping to change at line 369
// For instance, // For instance,
// //
// -N + 1 (the most negative number representable using // -N + 1 (the most negative number representable using
// sign-and-magnitude) is represented by 1; // sign-and-magnitude) is represented by 1;
// 0 is represented by N; and // 0 is represented by N; and
// N - 1 (the biggest number representable using // N - 1 (the biggest number representable using
// sign-and-magnitude) is represented by 2N - 1. // sign-and-magnitude) is represented by 2N - 1.
// //
// Read http://en.wikipedia.org/wiki/Signed_number_representations // Read http://en.wikipedia.org/wiki/Signed_number_representations
// for more details on signed number representations. // for more details on signed number representations.
static Bits SignAndMagnitudeToBiased(const Bits &sam) { static Bits SignAndMagnitudeToBiased(const Bits& sam) {
if (kSignBitMask & sam) { if (kSignBitMask & sam) {
// sam represents a negative number. // sam represents a negative number.
return ~sam + 1; return ~sam + 1;
} else { } else {
// sam represents a positive number. // sam represents a positive number.
return kSignBitMask | sam; return kSignBitMask | sam;
} }
} }
// Given two numbers in the sign-and-magnitude representation, // Given two numbers in the sign-and-magnitude representation,
// returns the distance between them as an unsigned number. // returns the distance between them as an unsigned number.
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
const Bits &sam2) { const Bits& sam2) {
const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased1 = SignAndMagnitudeToBiased(sam1);
const Bits biased2 = SignAndMagnitudeToBiased(sam2); const Bits biased2 = SignAndMagnitudeToBiased(sam2);
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
} }
FloatingPointUnion u_; FloatingPointUnion u_;
}; };
// We cannot use std::numeric_limits<T>::max() as it clashes with the max() // We cannot use std::numeric_limits<T>::max() as it clashes with the max()
// macro defined by <windows.h>. // macro defined by <windows.h>.
template <> template <>
inline float FloatingPoint<float>::Max() { return FLT_MAX; } inline float FloatingPoint<float>::Max() {
return FLT_MAX;
}
template <> template <>
inline double FloatingPoint<double>::Max() { return DBL_MAX; } inline double FloatingPoint<double>::Max() {
return DBL_MAX;
}
// Typedefs the instances of the FloatingPoint template class that we // Typedefs the instances of the FloatingPoint template class that we
// care to use. // care to use.
typedef FloatingPoint<float> Float; typedef FloatingPoint<float> Float;
typedef FloatingPoint<double> Double; typedef FloatingPoint<double> Double;
// In order to catch the mistake of putting tests that use different // In order to catch the mistake of putting tests that use different
// test fixture classes in the same test suite, we need to assign // test fixture classes in the same test suite, we need to assign
// unique IDs to fixture classes and compare them. The TypeId type is // unique IDs to fixture classes and compare them. The TypeId type is
// used to hold such IDs. The user should treat TypeId as an opaque // used to hold such IDs. The user should treat TypeId as an opaque
skipping to change at line 464 skipping to change at line 460
virtual ~TestFactoryBase() {} virtual ~TestFactoryBase() {}
// Creates a test instance to run. The instance is both created and destroyed // Creates a test instance to run. The instance is both created and destroyed
// within TestInfoImpl::Run() // within TestInfoImpl::Run()
virtual Test* CreateTest() = 0; virtual Test* CreateTest() = 0;
protected: protected:
TestFactoryBase() {} TestFactoryBase() {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); TestFactoryBase(const TestFactoryBase&) = delete;
TestFactoryBase& operator=(const TestFactoryBase&) = delete;
}; };
// This class provides implementation of TeastFactoryBase interface. // This class provides implementation of TeastFactoryBase interface.
// It is used in TEST and TEST_F macros. // It is used in TEST and TEST_F macros.
template <class TestClass> template <class TestClass>
class TestFactoryImpl : public TestFactoryBase { class TestFactoryImpl : public TestFactoryBase {
public: public:
Test* CreateTest() override { return new TestClass; } Test* CreateTest() override { return new TestClass; }
}; };
skipping to change at line 513 skipping to change at line 510
// Utility functions to help SuiteApiResolver // Utility functions to help SuiteApiResolver
using SetUpTearDownSuiteFuncType = void (*)(); using SetUpTearDownSuiteFuncType = void (*)();
inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull( inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) { SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {
return a == def ? nullptr : a; return a == def ? nullptr : a;
} }
template <typename T> template <typename T>
// Note that SuiteApiResolver inherits from T because // Note that SuiteApiResolver inherits from T because
// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way // SetUpTestSuite()/TearDownTestSuite() could be protected. This way
// SuiteApiResolver can access them. // SuiteApiResolver can access them.
struct SuiteApiResolver : T { struct SuiteApiResolver : T {
// testing::Test is only forward declared at this point. So we make it a // testing::Test is only forward declared at this point. So we make it a
// dependend class for the compiler to be OK with it. // dependent class for the compiler to be OK with it.
using Test = using Test =
typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type; typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename, static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
int line_num) { int line_num) {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
SetUpTearDownSuiteFuncType test_case_fp = SetUpTearDownSuiteFuncType test_case_fp =
GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase); GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
SetUpTearDownSuiteFuncType test_suite_fp = SetUpTearDownSuiteFuncType test_suite_fp =
GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite); GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);
skipping to change at line 657 skipping to change at line 654
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// Skips to the first non-space char after the first comma in 'str'; // Skips to the first non-space char after the first comma in 'str';
// returns NULL if no comma is found in 'str'. // returns NULL if no comma is found in 'str'.
inline const char* SkipComma(const char* str) { inline const char* SkipComma(const char* str) {
const char* comma = strchr(str, ','); const char* comma = strchr(str, ',');
if (comma == nullptr) { if (comma == nullptr) {
return nullptr; return nullptr;
} }
while (IsSpace(*(++comma))) {} while (IsSpace(*(++comma))) {
}
return comma; return comma;
} }
// Returns the prefix of 'str' before the first comma in it; returns // Returns the prefix of 'str' before the first comma in it; returns
// the entire string if it contains no comma. // the entire string if it contains no comma.
inline std::string GetPrefixUntilComma(const char* str) { inline std::string GetPrefixUntilComma(const char* str) {
const char* comma = strchr(str, ','); const char* comma = strchr(str, ',');
return comma == nullptr ? str : std::string(str, comma); return comma == nullptr ? str : std::string(str, comma);
} }
// Splits a given string on a given delimiter, populating a given // Splits a given string on a given delimiter, populating a given
// vector with the fields. // vector with the fields.
void SplitString(const ::std::string& str, char delimiter, void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest); ::std::vector<::std::string>* dest);
// The default argument to the template below for the case when the user does // The default argument to the template below for the case when the user does
// not provide a name generator. // not provide a name generator.
struct DefaultNameGenerator { struct DefaultNameGenerator {
template <typename T> template <typename T>
static std::string GetName(int i) { static std::string GetName(int i) {
return StreamableToString(i); return StreamableToString(i);
} }
}; };
skipping to change at line 784 skipping to change at line 782
// something such that we can call this function in a namespace scope. // something such that we can call this function in a namespace scope.
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
class TypeParameterizedTestSuite { class TypeParameterizedTestSuite {
public: public:
static bool Register(const char* prefix, CodeLocation code_location, static bool Register(const char* prefix, CodeLocation code_location,
const TypedTestSuitePState* state, const char* case_name, const TypedTestSuitePState* state, const char* case_name,
const char* test_names, const char* test_names,
const std::vector<std::string>& type_names = const std::vector<std::string>& type_names =
GenerateNames<DefaultNameGenerator, Types>()) { GenerateNames<DefaultNameGenerator, Types>()) {
RegisterTypeParameterizedTestSuiteInstantiation(case_name); RegisterTypeParameterizedTestSuiteInstantiation(case_name);
std::string test_name = StripTrailingSpaces( std::string test_name =
GetPrefixUntilComma(test_names)); StripTrailingSpaces(GetPrefixUntilComma(test_names));
if (!state->TestExists(test_name)) { if (!state->TestExists(test_name)) {
fprintf(stderr, "Failed to get code location for test %s.%s at %s.", fprintf(stderr, "Failed to get code location for test %s.%s at %s.",
case_name, test_name.c_str(), case_name, test_name.c_str(),
FormatFileLocation(code_location.file.c_str(), FormatFileLocation(code_location.file.c_str(), code_location.line)
code_location.line).c_str()); .c_str());
fflush(stderr); fflush(stderr);
posix::Abort(); posix::Abort();
} }
const CodeLocation& test_location = state->GetCodeLocation(test_name); const CodeLocation& test_location = state->GetCodeLocation(test_name);
typedef typename Tests::Head Head; typedef typename Tests::Head Head;
// First, register the first test in 'Test' for each type in 'Types'. // First, register the first test in 'Test' for each type in 'Types'.
TypeParameterizedTest<Fixture, Head, Types>::Register( TypeParameterizedTest<Fixture, Head, Types>::Register(
prefix, test_location, case_name, test_names, 0, type_names); prefix, test_location, case_name, test_names, 0, type_names);
skipping to change at line 834 skipping to change at line 832
// Returns the current OS stack trace as an std::string. // Returns the current OS stack trace as an std::string.
// //
// The maximum number of stack frames to be included is specified by // The maximum number of stack frames to be included is specified by
// the gtest_stack_trace_depth flag. The skip_count parameter // the gtest_stack_trace_depth flag. The skip_count parameter
// specifies the number of top frames to be skipped, which doesn't // specifies the number of top frames to be skipped, which doesn't
// count against the number of frames to be included. // count against the number of frames to be included.
// //
// For example, if Foo() calls Bar(), which in turn calls // For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
UnitTest* unit_test, int skip_count); int skip_count);
// Helpers for suppressing warnings on unreachable code or constant // Helpers for suppressing warnings on unreachable code or constant
// condition. // condition.
// Always returns true. // Always returns true.
GTEST_API_ bool AlwaysTrue(); GTEST_API_ bool AlwaysTrue();
// Always returns false. // Always returns false.
inline bool AlwaysFalse() { return !AlwaysTrue(); } inline bool AlwaysFalse() { return !AlwaysTrue(); }
skipping to change at line 884 skipping to change at line 882
explicit Random(uint32_t seed) : state_(seed) {} explicit Random(uint32_t seed) : state_(seed) {}
void Reseed(uint32_t seed) { state_ = seed; } void Reseed(uint32_t seed) { state_ = seed; }
// Generates a random number from [0, range). Crashes if 'range' is // Generates a random number from [0, range). Crashes if 'range' is
// 0 or greater than kMaxRange. // 0 or greater than kMaxRange.
uint32_t Generate(uint32_t range); uint32_t Generate(uint32_t range);
private: private:
uint32_t state_; uint32_t state_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); Random(const Random&) = delete;
Random& operator=(const Random&) = delete;
}; };
// Turns const U&, U&, const U, and U all into U. // Turns const U&, U&, const U, and U all into U.
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
typename std::remove_const<typename std::remove_reference<T>::type>::type typename std::remove_const<typename std::remove_reference<T>::type>::type
// HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant // HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant
// that's true if and only if T has methods DebugString() and ShortDebugString() // that's true if and only if T has methods DebugString() and ShortDebugString()
// that return std::string. // that return std::string.
template <typename T> template <typename T>
skipping to change at line 957 skipping to change at line 956
class = decltype(::std::declval<const C&>().end()), class = decltype(::std::declval<const C&>().end()),
class = decltype(++::std::declval<Iterator&>()), class = decltype(++::std::declval<Iterator&>()),
class = decltype(*::std::declval<Iterator>()), class = decltype(*::std::declval<Iterator>()),
class = typename C::const_iterator> class = typename C::const_iterator>
IsContainer IsContainerTest(int /* dummy */) { IsContainer IsContainerTest(int /* dummy */) {
return 0; return 0;
} }
typedef char IsNotContainer; typedef char IsNotContainer;
template <class C> template <class C>
IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } IsNotContainer IsContainerTest(long /* dummy */) {
return '\0';
}
// Trait to detect whether a type T is a hash table. // Trait to detect whether a type T is a hash table.
// The heuristic used is that the type contains an inner type `hasher` and does // The heuristic used is that the type contains an inner type `hasher` and does
// not contain an inner type `reverse_iterator`. // not contain an inner type `reverse_iterator`.
// If the container is iterable in reverse, then order might actually matter. // If the container is iterable in reverse, then order might actually matter.
template <typename T> template <typename T>
struct IsHashTable { struct IsHashTable {
private: private:
template <typename U> template <typename U>
static char test(typename U::hasher*, typename U::reverse_iterator*); static char test(typename U::hasher*, typename U::reverse_iterator*);
skipping to change at line 1020 skipping to change at line 1021
// ArrayEq() compares two k-dimensional native arrays using the // ArrayEq() compares two k-dimensional native arrays using the
// elements' operator==, where k can be any integer >= 0. When k is // elements' operator==, where k can be any integer >= 0. When k is
// 0, ArrayEq() degenerates into comparing a single pair of values. // 0, ArrayEq() degenerates into comparing a single pair of values.
template <typename T, typename U> template <typename T, typename U>
bool ArrayEq(const T* lhs, size_t size, const U* rhs); bool ArrayEq(const T* lhs, size_t size, const U* rhs);
// This generic version is used when k is 0. // This generic version is used when k is 0.
template <typename T, typename U> template <typename T, typename U>
inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } inline bool ArrayEq(const T& lhs, const U& rhs) {
return lhs == rhs;
}
// This overload is used when k >= 1. // This overload is used when k >= 1.
template <typename T, typename U, size_t N> template <typename T, typename U, size_t N>
inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {
return internal::ArrayEq(lhs, N, rhs); return internal::ArrayEq(lhs, N, rhs);
} }
// This helper reduces code bloat. If we instead put its logic inside // This helper reduces code bloat. If we instead put its logic inside
// the previous ArrayEq() function, arrays with different sizes would // the previous ArrayEq() function, arrays with different sizes would
// lead to different copies of the template code. // lead to different copies of the template code.
template <typename T, typename U> template <typename T, typename U>
bool ArrayEq(const T* lhs, size_t size, const U* rhs) { bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
for (size_t i = 0; i != size; i++) { for (size_t i = 0; i != size; i++) {
if (!internal::ArrayEq(lhs[i], rhs[i])) if (!internal::ArrayEq(lhs[i], rhs[i])) return false;
return false;
} }
return true; return true;
} }
// Finds the first element in the iterator range [begin, end) that // Finds the first element in the iterator range [begin, end) that
// equals elem. Element may be a native array type itself. // equals elem. Element may be a native array type itself.
template <typename Iter, typename Element> template <typename Iter, typename Element>
Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {
for (Iter it = begin; it != end; ++it) { for (Iter it = begin; it != end; ++it) {
if (internal::ArrayEq(*it, elem)) if (internal::ArrayEq(*it, elem)) return it;
return it;
} }
return end; return end;
} }
// CopyArray() copies a k-dimensional native array using the elements' // CopyArray() copies a k-dimensional native array using the elements'
// operator=, where k can be any integer >= 0. When k is 0, // operator=, where k can be any integer >= 0. When k is 0,
// CopyArray() degenerates into copying a single value. // CopyArray() degenerates into copying a single value.
template <typename T, typename U> template <typename T, typename U>
void CopyArray(const T* from, size_t size, U* to); void CopyArray(const T* from, size_t size, U* to);
// This generic version is used when k is 0. // This generic version is used when k is 0.
template <typename T, typename U> template <typename T, typename U>
inline void CopyArray(const T& from, U* to) { *to = from; } inline void CopyArray(const T& from, U* to) {
*to = from;
}
// This overload is used when k >= 1. // This overload is used when k >= 1.
template <typename T, typename U, size_t N> template <typename T, typename U, size_t N>
inline void CopyArray(const T(&from)[N], U(*to)[N]) { inline void CopyArray(const T (&from)[N], U (*to)[N]) {
internal::CopyArray(from, N, *to); internal::CopyArray(from, N, *to);
} }
// This helper reduces code bloat. If we instead put its logic inside // This helper reduces code bloat. If we instead put its logic inside
// the previous CopyArray() function, arrays with different sizes // the previous CopyArray() function, arrays with different sizes
// would lead to different copies of the template code. // would lead to different copies of the template code.
template <typename T, typename U> template <typename T, typename U>
void CopyArray(const T* from, size_t size, U* to) { void CopyArray(const T* from, size_t size, U* to) {
for (size_t i = 0; i != size; i++) { for (size_t i = 0; i != size; i++) {
internal::CopyArray(from[i], to + i); internal::CopyArray(from[i], to + i);
skipping to change at line 1117 skipping to change at line 1120
NativeArray(const Element* array, size_t count, RelationToSourceCopy) { NativeArray(const Element* array, size_t count, RelationToSourceCopy) {
InitCopy(array, count); InitCopy(array, count);
} }
// Copy constructor. // Copy constructor.
NativeArray(const NativeArray& rhs) { NativeArray(const NativeArray& rhs) {
(this->*rhs.clone_)(rhs.array_, rhs.size_); (this->*rhs.clone_)(rhs.array_, rhs.size_);
} }
~NativeArray() { ~NativeArray() {
if (clone_ != &NativeArray::InitRef) if (clone_ != &NativeArray::InitRef) delete[] array_;
delete[] array_;
} }
// STL-style container methods. // STL-style container methods.
size_t size() const { return size_; } size_t size() const { return size_; }
const_iterator begin() const { return array_; } const_iterator begin() const { return array_; }
const_iterator end() const { return array_ + size_; } const_iterator end() const { return array_ + size_; }
bool operator==(const NativeArray& rhs) const { bool operator==(const NativeArray& rhs) const {
return size() == rhs.size() && return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin());
ArrayEq(begin(), size(), rhs.begin());
} }
private: private:
static_assert(!std::is_const<Element>::value, "Type must not be const"); static_assert(!std::is_const<Element>::value, "Type must not be const");
static_assert(!std::is_reference<Element>::value, static_assert(!std::is_reference<Element>::value,
"Type must not be a reference"); "Type must not be a reference");
// Initializes this object with a copy of the input. // Initializes this object with a copy of the input.
void InitCopy(const Element* array, size_t a_size) { void InitCopy(const Element* array, size_t a_size) {
Element* const copy = new Element[a_size]; Element* const copy = new Element[a_size];
skipping to change at line 1338 skipping to change at line 1339
#pragma clang diagnostic ignored "-Wmismatched-tags" #pragma clang diagnostic ignored "-Wmismatched-tags"
#endif #endif
template <typename... Ts> template <typename... Ts>
struct tuple_size<testing::internal::FlatTuple<Ts...>> struct tuple_size<testing::internal::FlatTuple<Ts...>>
: std::integral_constant<size_t, sizeof...(Ts)> {}; : std::integral_constant<size_t, sizeof...(Ts)> {};
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
} // namespace std } // namespace std
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ #define GTEST_MESSAGE_AT_(file, line, message, result_type) \
::testing::internal::AssertHelper(result_type, file, line, message) \ ::testing::internal::AssertHelper(result_type, file, line, message) = \
= ::testing::Message() ::testing::Message()
#define GTEST_MESSAGE_(message, result_type) \ #define GTEST_MESSAGE_(message, result_type) \
GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
#define GTEST_FATAL_FAILURE_(message) \ #define GTEST_FATAL_FAILURE_(message) \
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
#define GTEST_NONFATAL_FAILURE_(message) \ #define GTEST_NONFATAL_FAILURE_(message) \
GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
skipping to change at line 1461 skipping to change at line 1462
gtest_msg.value += "\"."; \ gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
} }
#else // GTEST_HAS_EXCEPTIONS #else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() #define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()
#endif // GTEST_HAS_EXCEPTIONS #endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_(statement, fail) \ #define GTEST_TEST_NO_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::TrueWithString gtest_msg{}) { \ if (::testing::internal::TrueWithString gtest_msg{}) { \
try { \ try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \ } \
GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
catch (...) { \ catch (...) { \
gtest_msg.value = "it throws."; \ gtest_msg.value = "it throws."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__) \
fail(("Expected: " #statement " doesn't throw an exception.\n" \ : fail(("Expected: " #statement " doesn't throw an exception.\n" \
" Actual: " + gtest_msg.value).c_str()) " Actual: " + \
gtest_msg.value) \
#define GTEST_TEST_ANY_THROW_(statement, fail) \ .c_str())
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ #define GTEST_TEST_ANY_THROW_(statement, fail) \
bool gtest_caught_any = false; \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
try { \ if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ bool gtest_caught_any = false; \
} \ try { \
catch (...) { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
gtest_caught_any = true; \ } catch (...) { \
} \ gtest_caught_any = true; \
if (!gtest_caught_any) { \ } \
if (!gtest_caught_any) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) \
fail("Expected: " #statement " throws an exception.\n" \ : fail("Expected: " #statement \
" Actual: it doesn't.") " throws an exception.\n" \
" Actual: it doesn't.")
// Implements Boolean test assertions such as EXPECT_TRUE. expression can be // Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual // either a boolean expression or an AssertionResult. text is a textual
// representation of expression as it was passed into the EXPECT_TRUE. // representation of expression as it was passed into the EXPECT_TRUE.
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar_ = \ if (const ::testing::AssertionResult gtest_ar_ = \
::testing::AssertionResult(expression)) \ ::testing::AssertionResult(expression)) \
; \ ; \
else \ else \
fail(::testing::internal::GetBoolAssertionFailureMessage(\ fail(::testing::internal::GetBoolAssertionFailureMessage( \
gtest_ar_, text, #actual, #expected).c_str()) gtest_ar_, text, #actual, #expected) \
.c_str())
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
if (::testing::internal::AlwaysTrue()) { \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \
fail("Expected: " #statement " doesn't generate new fatal " \ : fail("Expected: " #statement \
"failures in the current thread.\n" \ " doesn't generate new fatal " \
" Actual: it does.") "failures in the current thread.\n" \
" Actual: it does.")
// Expands to the name of the class that implements the given test. // Expands to the name of the class that implements the given test.
#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ #define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
test_suite_name##_##test_name##_Test test_suite_name##_##test_name##_Test
// Helper macro for defining tests. // Helper macro for defining tests.
#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \ #define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \
static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \
"test_suite_name must not be empty"); \ "test_suite_name must not be empty"); \
static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \
"test_name must not be empty"); \ "test_name must not be empty"); \
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
: public parent_class { \ : public parent_class { \
public: \ public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \
~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \ ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
test_name)); \ (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
test_name)); \ const GTEST_TEST_CLASS_NAME_(test_suite_name, \
\ test_name) &) = delete; /* NOLINT */ \
private: \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
void TestBody() override; \ (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
}; \ GTEST_TEST_CLASS_NAME_(test_suite_name, \
\ test_name) &&) noexcept = delete; /* NOLINT */ \
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ \
test_name)::test_info_ = \ private: \
::testing::internal::MakeAndRegisterTestInfo( \ void TestBody() override; \
#test_suite_name, #test_name, nullptr, nullptr, \ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \ }; \
::testing::internal::SuiteApiResolver< \ \
parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
::testing::internal::SuiteApiResolver< \ test_name)::test_info_ = \
parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ ::testing::internal::MakeAndRegisterTestInfo( \
new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \ #test_suite_name, #test_name, nullptr, nullptr, \
test_suite_name, test_name)>); \ ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
::testing::internal::SuiteApiResolver< \
parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
::testing::internal::SuiteApiResolver< \
parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
test_suite_name, test_name)>); \
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
 End of changes. 47 change blocks. 
159 lines changed or deleted 170 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)