"Fossies" - the Fresh Open Source Software Archive  

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

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

gtest-internal.h  (googletest-release-1.10.0):gtest-internal.h  (googletest-release-1.11.0)
skipping to change at line 37 skipping to change at line 37
// (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 // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GTEST_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 <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"
#include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-filepath.h"
skipping to change at line 81 skipping to change at line 82
// //
// 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.
#define GTEST_STRINGIFY_(name) #name // Work around a bug in visual studio which doesn't accept code like this:
//
// #define GTEST_STRINGIFY_(name) #name
// #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ...
// MACRO(, x, y)
//
// Complaining about the argument to GTEST_STRINGIFY_ being empty.
// This is allowed by the spec.
#define GTEST_STRINGIFY_HELPER_(name, ...) #name
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
namespace proto2 { class Message; } namespace proto2 {
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.
skipping to change at line 278 skipping to change at line 290
// 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
// units in the last place. On Intel CPU's, all floating-point // units in the last place. On Intel CPU's, all floating-point
// calculations are done with 80-bit precision, while double has 64 // calculations are done with 80-bit precision, while double has 64
// bits. Therefore, 4 should be enough for ordinary use. // bits. Therefore, 4 should be enough for ordinary use.
// //
// See the following article for more details on ULP: // See the following article for more details on ULP:
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-number s-2012-edition/ // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-number s-2012-edition/
static const size_t kMaxUlps = 4; static const uint32_t kMaxUlps = 4;
// Constructs a FloatingPoint from a raw floating-point number. // Constructs a FloatingPoint from a raw floating-point number.
// //
// On an Intel CPU, passing a non-normalized NAN (Not a Number) // On an Intel CPU, passing a non-normalized NAN (Not a Number)
// around may change its bits, although the new value is guaranteed // around may change its bits, although the new value is guaranteed
// to be also a NAN. Therefore, don't expect this constructor to // to be also a NAN. Therefore, don't expect this constructor to
// preserve the bits in x when x is a NAN. // preserve the bits in x when x is a NAN.
explicit FloatingPoint(const RawType& x) { u_.value_ = x; } explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
// Static methods // Static methods
skipping to change at line 511 skipping to change at line 523
// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way // SetUpTestSuite()/TearDownTestSuite() could be protected. Ths 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. // dependend 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_
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);
GTEST_CHECK_(!test_case_fp || !test_suite_fp) GTEST_CHECK_(!test_case_fp || !test_suite_fp)
<< "Test can not provide both SetUpTestSuite and SetUpTestCase, please " << "Test can not provide both SetUpTestSuite and SetUpTestCase, please "
"make sure there is only one present at " "make sure there is only one present at "
<< filename << ":" << line_num; << filename << ":" << line_num;
return test_case_fp != nullptr ? test_case_fp : test_suite_fp; return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
#else
(void)(filename);
(void)(line_num);
return &T::SetUpTestSuite;
#endif
} }
static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename, static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
int line_num) { int line_num) {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
SetUpTearDownSuiteFuncType test_case_fp = SetUpTearDownSuiteFuncType test_case_fp =
GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase); GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
SetUpTearDownSuiteFuncType test_suite_fp = SetUpTearDownSuiteFuncType test_suite_fp =
GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite); GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);
GTEST_CHECK_(!test_case_fp || !test_suite_fp) GTEST_CHECK_(!test_case_fp || !test_suite_fp)
<< "Test can not provide both TearDownTestSuite and TearDownTestCase," << "Test can not provide both TearDownTestSuite and TearDownTestCase,"
" please make sure there is only one present at" " please make sure there is only one present at"
<< filename << ":" << line_num; << filename << ":" << line_num;
return test_case_fp != nullptr ? test_case_fp : test_suite_fp; return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
#else
(void)(filename);
(void)(line_num);
return &T::TearDownTestSuite;
#endif
} }
}; };
// Creates a new TestInfo object and registers it with Google Test; // Creates a new TestInfo object and registers it with Google Test;
// returns the created object. // returns the created object.
// //
// Arguments: // Arguments:
// //
// test_suite_name: name of the test suite // test_suite_name: name of the test suite
// name: name of the test // name: name of the test
// type_param the name of the test's type parameter, or NULL if // type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test. // this is not a typed or a type-parameterized test.
// value_param text representation of the test's value parameter, // value_param: text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test. // or NULL if this is not a type-parameterized test.
// code_location: code location where the test is defined // code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test suite // set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite // tear_down_tc: pointer to the function that tears down the test suite
// factory: pointer to the factory that creates a test object. // factory: pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume // The newly created TestInfo instance will assume
// ownership of the factory object. // ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo( GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param, const char* test_suite_name, const char* name, const char* type_param,
const char* value_param, CodeLocation code_location, const char* value_param, CodeLocation code_location,
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory); TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
// If *pstr starts with the given prefix, modifies *pstr to be right // If *pstr starts with the given prefix, modifies *pstr to be right
// past the prefix and returns true; otherwise leaves *pstr unchanged // past the prefix and returns true; otherwise leaves *pstr unchanged
// and returns false. None of pstr, *pstr, and prefix can be NULL. // and returns false. None of pstr, *pstr, and prefix can be NULL.
GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
// State of the definition of a type-parameterized test suite. // State of the definition of a type-parameterized test suite.
class GTEST_API_ TypedTestSuitePState { class GTEST_API_ TypedTestSuitePState {
public: public:
TypedTestSuitePState() : registered_(false) {} TypedTestSuitePState() : registered_(false) {}
// Adds the given test name to defined_test_names_ and return true // Adds the given test name to defined_test_names_ and return true
// if the test suite hasn't been registered; otherwise aborts the // if the test suite hasn't been registered; otherwise aborts the
skipping to change at line 610 skipping to change at line 632
const CodeLocation& GetCodeLocation(const std::string& test_name) const { const CodeLocation& GetCodeLocation(const std::string& test_name) const {
RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name); RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);
GTEST_CHECK_(it != registered_tests_.end()); GTEST_CHECK_(it != registered_tests_.end());
return it->second; return it->second;
} }
// Verifies that registered_tests match the test names in // Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or // defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise. // aborts the program otherwise.
const char* VerifyRegisteredTestNames( const char* VerifyRegisteredTestNames(const char* test_suite_name,
const char* file, int line, const char* registered_tests); const char* file, int line,
const char* registered_tests);
private: private:
typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap; typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap;
bool registered_; bool registered_;
RegisteredTestsMap registered_tests_; RegisteredTestsMap registered_tests_;
}; };
// Legacy API is deprecated but still available // Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
skipping to change at line 665 skipping to change at line 688
return StreamableToString(i); return StreamableToString(i);
} }
}; };
template <typename Provided = DefaultNameGenerator> template <typename Provided = DefaultNameGenerator>
struct NameGeneratorSelector { struct NameGeneratorSelector {
typedef Provided type; typedef Provided type;
}; };
template <typename NameGenerator> template <typename NameGenerator>
void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {} void GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}
template <typename NameGenerator, typename Types> template <typename NameGenerator, typename Types>
void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) { void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
result->push_back(NameGenerator::template GetName<typename Types::Head>(i)); result->push_back(NameGenerator::template GetName<typename Types::Head>(i));
GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result, GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,
i + 1); i + 1);
} }
template <typename NameGenerator, typename Types> template <typename NameGenerator, typename Types>
std::vector<std::string> GenerateNames() { std::vector<std::string> GenerateNames() {
skipping to change at line 732 skipping to change at line 755
code_location, code_location,
case_name, case_name,
test_names, test_names,
index + 1, index + 1,
type_names); type_names);
} }
}; };
// The base case for the compile time recursion. // The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, class TestSel> template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, Types0> { class TypeParameterizedTest<Fixture, TestSel, internal::None> {
public: public:
static bool Register(const char* /*prefix*/, const CodeLocation&, static bool Register(const char* /*prefix*/, const CodeLocation&,
const char* /*case_name*/, const char* /*test_names*/, const char* /*case_name*/, const char* /*test_names*/,
int /*index*/, int /*index*/,
const std::vector<std::string>& = const std::vector<std::string>& =
std::vector<std::string>() /*type_names*/) { std::vector<std::string>() /*type_names*/) {
return true; return true;
} }
}; };
GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
CodeLocation code_location);
GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
const char* case_name);
// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register() // TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()
// registers *all combinations* of 'Tests' and 'Types' with Google // registers *all combinations* of 'Tests' and 'Types' with Google
// Test. The return value is insignificant - we just need to return // Test. The return value is insignificant - we just need to return
// 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);
std::string test_name = StripTrailingSpaces( std::string test_name = StripTrailingSpaces(
GetPrefixUntilComma(test_names)); 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).c_str()); code_location.line).c_str());
fflush(stderr); fflush(stderr);
posix::Abort(); posix::Abort();
} }
skipping to change at line 784 skipping to change at line 813
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail, return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
Types>::Register(prefix, code_location, Types>::Register(prefix, code_location,
state, case_name, state, case_name,
SkipComma(test_names), SkipComma(test_names),
type_names); type_names);
} }
}; };
// The base case for the compile time recursion. // The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestSuite<Fixture, Templates0, Types> { class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
public: public:
static bool Register(const char* /*prefix*/, const CodeLocation&, static bool Register(const char* /*prefix*/, const CodeLocation&,
const TypedTestSuitePState* /*state*/, const TypedTestSuitePState* /*state*/,
const char* /*case_name*/, const char* /*test_names*/, const char* /*case_name*/, const char* /*test_names*/,
const std::vector<std::string>& = const std::vector<std::string>& =
std::vector<std::string>() /*type_names*/) { std::vector<std::string>() /*type_names*/) {
return true; return true;
} }
}; };
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// 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.
skipping to change at line 828 skipping to change at line 855
// Helper for suppressing false warning from Clang on a const char* // Helper for suppressing false warning from Clang on a const char*
// variable declared in a conditional expression always being NULL in // variable declared in a conditional expression always being NULL in
// the else branch. // the else branch.
struct GTEST_API_ ConstCharPtr { struct GTEST_API_ ConstCharPtr {
ConstCharPtr(const char* str) : value(str) {} ConstCharPtr(const char* str) : value(str) {}
operator bool() const { return true; } operator bool() const { return true; }
const char* value; const char* value;
}; };
// Helper for declaring std::string within 'if' statement
// in pre C++17 build environment.
struct TrueWithString {
TrueWithString() = default;
explicit TrueWithString(const char* str) : value(str) {}
explicit TrueWithString(const std::string& str) : value(str) {}
explicit operator bool() const { return true; }
std::string value;
};
// A simple Linear Congruential Generator for generating random // A simple Linear Congruential Generator for generating random
// numbers with a uniform distribution. Unlike rand() and srand(), it // numbers with a uniform distribution. Unlike rand() and srand(), it
// doesn't use global state (and therefore can't interfere with user // doesn't use global state (and therefore can't interfere with user
// code). Unlike rand_r(), it's portable. An LCG isn't very random, // code). Unlike rand_r(), it's portable. An LCG isn't very random,
// but it's good enough for our purposes. // but it's good enough for our purposes.
class GTEST_API_ Random { class GTEST_API_ Random {
public: public:
static const UInt32 kMaxRange = 1u << 31; static const uint32_t kMaxRange = 1u << 31;
explicit Random(UInt32 seed) : state_(seed) {} explicit Random(uint32_t seed) : state_(seed) {}
void Reseed(UInt32 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 Generate(UInt32 range); uint32_t Generate(uint32_t range);
private: private:
UInt32 state_; uint32_t state_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
}; };
// 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
// IsAProtocolMessage<T>::value is a compile-time bool constant that's // HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant
// true if and only if T is type proto2::Message or a subclass of it. // that's true if and only if T has methods DebugString() and ShortDebugString()
// that return std::string.
template <typename T> template <typename T>
struct IsAProtocolMessage class HasDebugStringAndShortDebugString {
: public bool_constant< private:
std::is_convertible<const T*, const ::proto2::Message*>::value> {}; template <typename C>
static auto CheckDebugString(C*) -> typename std::is_same<
std::string, decltype(std::declval<const C>().DebugString())>::type;
template <typename>
static std::false_type CheckDebugString(...);
template <typename C>
static auto CheckShortDebugString(C*) -> typename std::is_same<
std::string, decltype(std::declval<const C>().ShortDebugString())>::type;
template <typename>
static std::false_type CheckShortDebugString(...);
using HasDebugStringType = decltype(CheckDebugString<T>(nullptr));
using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr));
public:
static constexpr bool value =
HasDebugStringType::value && HasShortDebugStringType::value;
};
template <typename T>
constexpr bool HasDebugStringAndShortDebugString<T>::value;
// When the compiler sees expression IsContainerTest<C>(0), if C is an // When the compiler sees expression IsContainerTest<C>(0), if C is an
// STL-style container class, the first overload of IsContainerTest // STL-style container class, the first overload of IsContainerTest
// will be viable (since both C::iterator* and C::const_iterator* are // will be viable (since both C::iterator* and C::const_iterator* are
// valid types and NULL can be implicitly converted to them). It will // valid types and NULL can be implicitly converted to them). It will
// be picked over the second overload as 'int' is a perfect match for // be picked over the second overload as 'int' is a perfect match for
// the type of argument 0. If C::iterator or C::const_iterator is not // the type of argument 0. If C::iterator or C::const_iterator is not
// a valid type, the first overload is not viable, and the second // a valid type, the first overload is not viable, and the second
// overload will be picked. Therefore, we can determine whether C is // overload will be picked. Therefore, we can determine whether C is
// a container class by checking the type of IsContainerTest<C>(0). // a container class by checking the type of IsContainerTest<C>(0).
skipping to change at line 1095 skipping to change at line 1154
// Initializes this object with a reference of the input. // Initializes this object with a reference of the input.
void InitRef(const Element* array, size_t a_size) { void InitRef(const Element* array, size_t a_size) {
array_ = array; array_ = array;
size_ = a_size; size_ = a_size;
clone_ = &NativeArray::InitRef; clone_ = &NativeArray::InitRef;
} }
const Element* array_; const Element* array_;
size_t size_; size_t size_;
void (NativeArray::*clone_)(const Element*, size_t); void (NativeArray::*clone_)(const Element*, size_t);
GTEST_DISALLOW_ASSIGN_(NativeArray);
}; };
// Backport of std::index_sequence. // Backport of std::index_sequence.
template <size_t... Is> template <size_t... Is>
struct IndexSequence { struct IndexSequence {
using type = IndexSequence; using type = IndexSequence;
}; };
// Double the IndexSequence, and one if plus_one is true. // Double the IndexSequence, and one if plus_one is true.
template <bool plus_one, typename T, size_t sizeofT> template <bool plus_one, typename T, size_t sizeofT>
skipping to change at line 1120 skipping to change at line 1177
using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>; using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
}; };
template <size_t... I, size_t sizeofT> template <size_t... I, size_t sizeofT>
struct DoubleSequence<false, IndexSequence<I...>, sizeofT> { struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
using type = IndexSequence<I..., (sizeofT + I)...>; using type = IndexSequence<I..., (sizeofT + I)...>;
}; };
// Backport of std::make_index_sequence. // Backport of std::make_index_sequence.
// It uses O(ln(N)) instantiation depth. // It uses O(ln(N)) instantiation depth.
template <size_t N> template <size_t N>
struct MakeIndexSequence struct MakeIndexSequenceImpl
: DoubleSequence<N % 2 == 1, typename MakeIndexSequence<N / 2>::type, : DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
N / 2>::type {}; N / 2>::type {};
template <> template <>
struct MakeIndexSequence<0> : IndexSequence<> {}; struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
template <size_t N>
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
template <typename... T>
using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
// FIXME: This implementation of ElemFromList is O(1) in instantiation depth, template <size_t>
// but it is O(N^2) in total instantiations. Not sure if this is the best struct Ignore {
// tradeoff, as it will make it somewhat slow to compile. Ignore(...); // NOLINT
template <typename T, size_t, size_t> };
struct ElemFromListImpl {};
template <typename>
template <typename T, size_t I> struct ElemFromListImpl;
struct ElemFromListImpl<T, I, I> { template <size_t... I>
using type = T; struct ElemFromListImpl<IndexSequence<I...>> {
}; // We make Ignore a template to solve a problem with MSVC.
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
// Get the Nth element from T... // MSVC doesn't understand how to deal with that pack expansion.
// It uses O(1) instantiation depth. // Use `0 * I` to have a single instantiation of Ignore.
template <size_t N, typename I, typename... T> template <typename R>
struct ElemFromList; static R Apply(Ignore<0 * I>..., R (*)(), ...);
};
template <size_t N, size_t... I, typename... T>
struct ElemFromList<N, IndexSequence<I...>, T...> template <size_t N, typename... T>
: ElemFromListImpl<T, N, I>... {}; struct ElemFromList {
using type =
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
static_cast<T (*)()>(nullptr)...));
};
struct FlatTupleConstructTag {};
template <typename... T> template <typename... T>
class FlatTuple; class FlatTuple;
template <typename Derived, size_t I> template <typename Derived, size_t I>
struct FlatTupleElemBase; struct FlatTupleElemBase;
template <typename... T, size_t I> template <typename... T, size_t I>
struct FlatTupleElemBase<FlatTuple<T...>, I> { struct FlatTupleElemBase<FlatTuple<T...>, I> {
using value_type = using value_type = typename ElemFromList<I, T...>::type;
typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type,
T...>::type;
FlatTupleElemBase() = default; FlatTupleElemBase() = default;
explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {} template <typename Arg>
explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)
: value(std::forward<Arg>(t)) {}
value_type value; value_type value;
}; };
template <typename Derived, typename Idx> template <typename Derived, typename Idx>
struct FlatTupleBase; struct FlatTupleBase;
template <size_t... Idx, typename... T> template <size_t... Idx, typename... T>
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
: FlatTupleElemBase<FlatTuple<T...>, Idx>... { : FlatTupleElemBase<FlatTuple<T...>, Idx>... {
using Indices = IndexSequence<Idx...>; using Indices = IndexSequence<Idx...>;
FlatTupleBase() = default; FlatTupleBase() = default;
explicit FlatTupleBase(T... t) template <typename... Args>
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {} explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
: FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},
std::forward<Args>(args))... {}
template <size_t I>
const typename ElemFromList<I, T...>::type& Get() const {
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
}
template <size_t I>
typename ElemFromList<I, T...>::type& Get() {
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
}
template <typename F>
auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
return std::forward<F>(f)(Get<Idx>()...);
}
template <typename F>
auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
return std::forward<F>(f)(Get<Idx>()...);
}
}; };
// Analog to std::tuple but with different tradeoffs. // Analog to std::tuple but with different tradeoffs.
// This class minimizes the template instantiation depth, thus allowing more // This class minimizes the template instantiation depth, thus allowing more
// elements that std::tuple would. std::tuple has been seen to require an // elements than std::tuple would. std::tuple has been seen to require an
// instantiation depth of more than 10x the number of elements in some // instantiation depth of more than 10x the number of elements in some
// implementations. // implementations.
// FlatTuple and ElemFromList are not recursive and have a fixed depth // FlatTuple and ElemFromList are not recursive and have a fixed depth
// regardless of T... // regardless of T...
// MakeIndexSequence, on the other hand, it is recursive but with an // MakeIndexSequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)). // instantiation depth of O(ln(N)).
template <typename... T> template <typename... T>
class FlatTuple class FlatTuple
: private FlatTupleBase<FlatTuple<T...>, : private FlatTupleBase<FlatTuple<T...>,
typename MakeIndexSequence<sizeof...(T)>::type> { typename MakeIndexSequence<sizeof...(T)>::type> {
using Indices = typename FlatTuple::FlatTupleBase::Indices; using Indices = typename FlatTupleBase<
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
public: public:
FlatTuple() = default; FlatTuple() = default;
explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {} template <typename... Args>
explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)
template <size_t I> : FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}
const typename ElemFromList<I, Indices, T...>::type& Get() const {
return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
template <size_t I> using FlatTuple::FlatTupleBase::Apply;
typename ElemFromList<I, Indices, T...>::type& Get() { using FlatTuple::FlatTupleBase::Get;
return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
}; };
// Utility functions to be called with static_assert to induce deprecation // Utility functions to be called with static_assert to induce deprecation
// warnings. // warnings.
GTEST_INTERNAL_DEPRECATED( GTEST_INTERNAL_DEPRECATED(
"INSTANTIATE_TEST_CASE_P is deprecated, please use " "INSTANTIATE_TEST_CASE_P is deprecated, please use "
"INSTANTIATE_TEST_SUITE_P") "INSTANTIATE_TEST_SUITE_P")
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; } constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
GTEST_INTERNAL_DEPRECATED( GTEST_INTERNAL_DEPRECATED(
skipping to change at line 1235 skipping to change at line 1322
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; } constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
GTEST_INTERNAL_DEPRECATED( GTEST_INTERNAL_DEPRECATED(
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use " "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
"INSTANTIATE_TYPED_TEST_SUITE_P") "INSTANTIATE_TYPED_TEST_SUITE_P")
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
namespace std {
// Some standard library implementations use `struct tuple_size` and some use
// `class tuple_size`. Clang warns about the mismatch.
// https://reviews.llvm.org/D55466
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmismatched-tags"
#endif
template <typename... Ts>
struct tuple_size<testing::internal::FlatTuple<Ts...>>
: std::integral_constant<size_t, sizeof...(Ts)> {};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} // 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)
skipping to change at line 1257 skipping to change at line 1360
#define GTEST_SUCCESS_(message) \ #define GTEST_SUCCESS_(message) \
GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
#define GTEST_SKIP_(message) \ #define GTEST_SKIP_(message) \
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip) return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
// Suppress MSVC warning 4072 (unreachable code) for the code following // Suppress MSVC warning 4072 (unreachable code) for the code following
// statement if it returns or throws (or doesn't return or throw in some // statement if it returns or throws (or doesn't return or throw in some
// situations). // situations).
// NOTE: The "else" is important to keep this expansion to prevent a top-level
// "else" from attaching to our "if".
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
if (::testing::internal::AlwaysTrue()) { statement; } if (::testing::internal::AlwaysTrue()) { \
statement; \
} else /* NOLINT */ \
static_assert(true, "") // User must have a semicolon after expansion.
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ #if GTEST_HAS_EXCEPTIONS
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::ConstCharPtr gtest_msg = "") { \ namespace testing {
bool gtest_caught_expected = false; \ namespace internal {
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ class NeverThrown {
} \ public:
catch (expected_exception const&) { \ const char* what() const noexcept {
gtest_caught_expected = true; \ return "this exception should never be thrown";
} \ }
catch (...) { \ };
gtest_msg.value = \
"Expected: " #statement " throws an exception of type " \ } // namespace internal
#expected_exception ".\n Actual: it throws a different type."; \ } // namespace testing
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \ #if GTEST_HAS_RTTI
if (!gtest_caught_expected) { \
gtest_msg.value = \ #define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))
"Expected: " #statement " throws an exception of type " \
#expected_exception ".\n Actual: it throws nothing."; \ #else // GTEST_HAS_RTTI
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \ #define GTEST_EXCEPTION_TYPE_(e) \
} else \ std::string { "an std::exception-derived error" }
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
fail(gtest_msg.value) #endif // GTEST_HAS_RTTI
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (typename std::conditional< \
std::is_same<typename std::remove_cv<typename std::remove_reference< \
expected_exception>::type>::type, \
std::exception>::value, \
const ::testing::internal::NeverThrown&, const std::exception&>::type \
e) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)
#endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::TrueWithString gtest_msg{}) { \
bool gtest_caught_expected = false; \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (expected_exception const&) { \
gtest_caught_expected = true; \
} \
GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (...) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws a different type."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
if (!gtest_caught_expected) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws nothing."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
} else /*NOLINT*/ \
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \
: fail(gtest_msg.value.c_str())
#if GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
catch (std::exception const& e) { \
gtest_msg.value = "it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()
#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::AlwaysTrue()) { \ 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_() \
catch (...) { \ catch (...) { \
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: it throws.") " Actual: " + gtest_msg.value).c_str())
#define GTEST_TEST_ANY_THROW_(statement, fail) \ #define GTEST_TEST_ANY_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ if (::testing::internal::AlwaysTrue()) { \
bool gtest_caught_any = false; \ bool gtest_caught_any = false; \
try { \ try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \ } \
catch (...) { \ catch (...) { \
gtest_caught_any = true; \ gtest_caught_any = true; \
skipping to change at line 1320 skipping to change at line 1497
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 " throws an exception.\n" \
" Actual: it doesn't.") " 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
// represenation 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) \ #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
skipping to change at line 1357 skipping to change at line 1534
// 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)() {} \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \
~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
\ \
private: \ private: \
virtual void TestBody(); \ void TestBody() override; \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
}; \ }; \
\ \
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::test_info_ = \ test_name)::test_info_ = \
::testing::internal::MakeAndRegisterTestInfo( \ ::testing::internal::MakeAndRegisterTestInfo( \
#test_suite_name, #test_name, nullptr, nullptr, \ #test_suite_name, #test_name, nullptr, nullptr, \
::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \ ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
::testing::internal::SuiteApiResolver< \ ::testing::internal::SuiteApiResolver< \
parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
::testing::internal::SuiteApiResolver< \ ::testing::internal::SuiteApiResolver< \
parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \ new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
test_suite_name, test_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 // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
 End of changes. 52 change blocks. 
103 lines changed or deleted 283 lines changed or added

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