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 |