Compare commits

...

6 Commits

Author SHA1 Message Date
Abseil Team
06f2b7f800 Export Test - Do Not Merge
Simplify the fallback printing logic to have a single sequence of trial printers.

PiperOrigin-RevId: 298621376
2020-03-04 14:06:10 -05:00
Andy Soffer
dc1be8e0e6 Merge pull request #2722 from JohanMabille:warnings
PiperOrigin-RevId: 298608772
2020-03-04 14:06:01 -05:00
Andy Soffer
fe6ea0cfec Merge pull request #2716 from kuzkry:autotools-leftover
PiperOrigin-RevId: 298599235
2020-03-04 14:05:52 -05:00
Abseil Team
a6b3a029f7 Export Test - Do Not Merge
Remove public buganizer reference from googletest cookbook.

It also seems that this bug is obsolete.

PiperOrigin-RevId: 298598298
2020-03-04 14:05:44 -05:00
Johan Mabille
04e52ebe78 Fixed warnings 2020-02-21 11:55:07 +01:00
Krystian Kuzniarek
c378d7eb93 remove a dead reference to the Autotools script 2020-01-29 11:42:59 +01:00
5 changed files with 175 additions and 274 deletions

View File

@ -421,7 +421,7 @@ sadly they are side effects of C++'s limitations):
`NiceMock<StrictMock<MockFoo> >`) is **not** supported. `NiceMock<StrictMock<MockFoo> >`) is **not** supported.
2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the 2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the
destructor of `MockFoo` is not virtual. We would like to fix this, but it destructor of `MockFoo` is not virtual. We would like to fix this, but it
requires cleaning up existing tests. http://b/28934720 tracks the issue. requires cleaning up existing tests.
3. During the constructor or destructor of `MockFoo`, the mock object is *not* 3. During the constructor or destructor of `MockFoo`, the mock object is *not*
nice or strict. This may cause surprises if the constructor or destructor nice or strict. This may cause surprises if the constructor or destructor
calls a mock method on `this` object. (This behavior, however, is consistent calls a mock method on `this` object. (This behavior, however, is consistent

View File

@ -189,9 +189,9 @@ or
When Google Test uses pthread, you may need to add flags to your compiler and/or When Google Test uses pthread, you may need to add flags to your compiler and/or
linker to select the pthread library, or you'll get link errors. If you use the linker to select the pthread library, or you'll get link errors. If you use the
CMake script or the deprecated Autotools script, this is taken care of for you. CMake script, this is taken care of for you. If you use your own build script,
If you use your own build script, you'll need to read your compiler and linker's you'll need to read your compiler and linker's manual to figure out what flags
manual to figure out what flags to add. to add.
### As a Shared Library (DLL) ### As a Shared Library (DLL)

View File

@ -119,106 +119,91 @@
namespace testing { namespace testing {
// Definitions in the 'internal' and 'internal2' name spaces are // Definitions in the internal* namespaces are subject to change without notice.
// subject to change without notice. DO NOT USE THEM IN USER CODE! // DO NOT USE THEM IN USER CODE!
namespace internal2 { namespace internal {
// Prints the given number of bytes in the given object to the given
// ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count,
::std::ostream* os);
// For selecting which printer to use when a given type has neither <<
// nor PrintTo().
enum TypeKind {
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
#if GTEST_INTERNAL_HAS_STRING_VIEW
kConvertibleToStringView, // a type implicitly convertible to
// absl::string_view or std::string_view
#endif
kOtherType // anything else
};
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
// by the universal printer to print a value of type T when neither
// operator<< nor PrintTo() is defined for T, where kTypeKind is the
// "kind" of T as defined by enum TypeKind.
template <typename T, TypeKind kTypeKind>
class TypeWithoutFormatter {
public:
// This default version is called when kTypeKind is kOtherType.
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
}
};
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
const size_t kProtobufOneLinerMaxLength = 50;
template <typename T> template <typename T>
class TypeWithoutFormatter<T, kProtobuf> { void UniversalPrint(const T& value, ::std::ostream* os);
public:
static void PrintValue(const T& value, ::std::ostream* os) { // Used to print an STL-style container when the user doesn't define
std::string pretty_str = value.ShortDebugString(); // a PrintTo() for it.
if (pretty_str.length() > kProtobufOneLinerMaxLength) { struct ContainerPrinter {
pretty_str = "\n" + value.DebugString(); template <typename T,
typename = typename std::enable_if<
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value>::type>
static void PrintValue(const T& container, std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
size_t count = 0;
for (auto&& elem : container) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(elem, os) here as PrintTo() doesn't
// handle `elem` being a native array.
internal::UniversalPrint(elem, os);
++count;
} }
*os << ("<" + pretty_str + ">");
if (count > 0) {
*os << ' ';
}
*os << '}';
} }
}; };
template <typename T> // Used to print a pointer that is neither a char pointer nor a member
class TypeWithoutFormatter<T, kConvertibleToInteger> { // pointer, when the user doesn't define PrintTo() for it. (A member
public: // variable pointer or member function pointer doesn't really point to
// Since T has no << operator or PrintTo() but can be implicitly // a location in the address space. Their representation is
// converted to BiggestInt, we print it as a BiggestInt. // implementation-defined. Therefore they will be printed as raw
// // bytes.)
// Most likely T is an enum type (either named or unnamed), in which struct FunctionPointerPrinter {
// case printing it as an integer is the desired behavior. In case template <typename T, typename = typename std::enable_if<
// T is not an enum, printing it as an integer is the best we can do std::is_function<T>::value>::type>
// given that it has no user-defined printer. static void PrintValue(T* p, ::std::ostream* os) {
static void PrintValue(const T& value, ::std::ostream* os) { if (p == nullptr) {
const internal::BiggestInt kBigInt = value; *os << "NULL";
*os << kBigInt; } else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
}
} }
}; };
#if GTEST_INTERNAL_HAS_STRING_VIEW struct PointerPrinter {
template <typename T> template <typename T>
class TypeWithoutFormatter<T, kConvertibleToStringView> { static void PrintValue(T* p, ::std::ostream* os) {
public: if (p == nullptr) {
// Since T has neither operator<< nor PrintTo() but can be implicitly *os << "NULL";
// converted to absl::string_view, we print it as a absl::string_view } else {
// (or std::string_view). // T is not a function type. We just call << to print p,
// // relying on ADL to pick up user-defined << for their pointer
// Note: the implementation is further below, as it depends on // types, if any.
// internal::PrintTo symbol which is defined later in the file. *os << p;
static void PrintValue(const T& value, ::std::ostream* os); }
}
}; };
#endif
// Prints the given value to the given ostream. If the value is a namespace internal_stream {
// protocol message, its debug string is printed; if it's an enum or
// of a type implicitly convertible to BiggestInt, it's printed as an struct Sentinel;
// integer; otherwise the bytes in the value are printed. This is template <typename Char, typename CharTraits, typename T>
// what UniversalPrinter<T>::Print() does when it knows nothing about Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x);
// type T and T has neither << operator nor PrintTo().
// Check if the user has a user-defined operator<< for their type.
// //
// A user can override this behavior for a class type Foo by defining // We put this in its own namespace to inject a custom operator<< that allows us
// a << operator in the namespace where Foo is defined. // to probe the type's operator.
//
// We put this operator in namespace 'internal2' instead of 'internal'
// to simplify the implementation, as much code in 'internal' needs to
// use << in STL, which would conflict with our own << were it defined
// in 'internal'.
// //
// Note that this operator<< takes a generic std::basic_ostream<Char, // Note that this operator<< takes a generic std::basic_ostream<Char,
// CharTraits> type instead of the more restricted std::ostream. If // CharTraits> type instead of the more restricted std::ostream. If
@ -229,67 +214,105 @@ class TypeWithoutFormatter<T, kConvertibleToStringView> {
// operator<<(std::ostream&, const T&) or // operator<<(std::ostream&, const T&) or
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more // operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
// specific. // specific.
template <typename Char, typename CharTraits, typename T>
::std::basic_ostream<Char, CharTraits>& operator<<(
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
? kProtobuf
: std::is_convertible<
const T&, internal::BiggestInt>::value
? kConvertibleToInteger
:
#if GTEST_INTERNAL_HAS_STRING_VIEW
std::is_convertible<
const T&, internal::StringView>::value
? kConvertibleToStringView
:
#endif
kOtherType)>::PrintValue(x, &os);
return os;
}
} // namespace internal2
} // namespace testing
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
// magic needed for implementing UniversalPrinter won't work.
namespace testing_internal {
// Used to print a value that is not an STL-style container when the
// user doesn't define PrintTo() for it.
template <typename T> template <typename T>
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { constexpr bool UseStreamOperator() {
// With the following statement, during unqualified name lookup, return !std::is_same<decltype(std::declval<std::ostream&>()
// testing::internal2::operator<< appears as if it was declared in << std::declval<const T&>()),
// the nearest enclosing namespace that contains both Sentinel*>::value;
// ::testing_internal and ::testing::internal2, i.e. the global
// namespace. For more details, refer to the C++ Standard section
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
// testing::internal2::operator<< in case T doesn't come with a <<
// operator.
using ::testing::internal2::operator<<;
// Assuming T is defined in namespace foo, in the next statement,
// the compiler will consider all of:
//
// 1. foo::operator<< (thanks to Koenig look-up),
// 2. ::operator<< (as the current namespace is enclosed in ::),
// 3. testing::internal2::operator<< (thanks to the using statement above).
//
// The operator<< whose type matches T best will be picked.
//
// We deliberately allow #2 to be a candidate, as sometimes it's
// impossible to define #1 (e.g. when foo is ::std, defining
// anything in it is undefined behavior unless you are a compiler
// vendor.).
*os << value;
} }
} // namespace testing_internal } // namespace internal_stream
namespace testing { struct StreamPrinter {
namespace internal { template <typename T, typename = typename std::enable_if<
internal_stream::UseStreamOperator<T>()>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
*os << value;
}
};
struct ProtobufPrinter {
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
static const size_t kProtobufOneLinerMaxLength = 50;
template <typename T, typename = typename std::enable_if<
internal::IsAProtocolMessage<T>::value>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
std::string pretty_str = value.ShortDebugString();
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
pretty_str = "\n" + value.DebugString();
}
*os << ("<" + pretty_str + ">");
}
};
struct ConvertibleToIntegerPrinter {
// Since T has no << operator or PrintTo() but can be implicitly
// converted to BiggestInt, we print it as a BiggestInt.
//
// Most likely T is an enum type (either named or unnamed), in which
// case printing it as an integer is the desired behavior. In case
// T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer.
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
*os << value;
}
};
struct ConvertibleToStringViewPrinter {
#if GTEST_INTERNAL_HAS_STRING_VIEW
static void PrintValue(internal::StringView value, ::std::ostream* os) {
internal::UniversalPrint(value, os);
}
#endif
};
// Prints the given number of bytes in the given object to the given
// ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count,
::std::ostream* os);
struct FallbackPrinter {
template <typename T>
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
}
};
// Try every printer in order and return the first one that works.
template <typename T, typename E, typename Printer, typename... Printers>
struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
template <typename T, typename Printer, typename... Printers>
struct FindFirstPrinter<
T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
Printer, Printers...> {
using type = Printer;
};
// Select the best printer in the following order:
// - Print containers (they have begin/end/etc).
// - Print function pointers.
// - Print object pointers.
// - Use the stream operator, if available.
// - Print protocol buffers.
// - Print types convertible to BiggestInt.
// - Print types convertible to StringView, if available.
// - Fallback to printing the raw bytes of the object.
template <typename T>
void PrintWithFallback(const T& value, ::std::ostream* os) {
using Printer = typename FindFirstPrinter<
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
StreamPrinter, ProtobufPrinter, ConvertibleToIntegerPrinter,
ConvertibleToStringViewPrinter, FallbackPrinter>::type;
Printer::PrintValue(value, os);
}
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a // FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
// value of type ToPrint that is an operand of a comparison assertion // value of type ToPrint that is an operand of a comparison assertion
@ -388,85 +411,6 @@ std::string FormatForComparisonFailureMessage(
template <typename T> template <typename T>
class UniversalPrinter; class UniversalPrinter;
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
enum DefaultPrinterType {
kPrintContainer,
kPrintPointer,
kPrintFunctionPointer,
kPrintOther,
};
template <DefaultPrinterType type> struct WrapPrinterType {};
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
template <typename C>
void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */,
const C& container, ::std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
size_t count = 0;
for (typename C::const_iterator it = container.begin();
it != container.end(); ++it, ++count) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
// handle *it being a native array.
internal::UniversalPrint(*it, os);
}
if (count > 0) {
*os << ' ';
}
*os << '}';
}
// Used to print a pointer that is neither a char pointer nor a member
// pointer, when the user doesn't define PrintTo() for it. (A member
// variable pointer or member function pointer doesn't really point to
// a location in the address space. Their representation is
// implementation-defined. Therefore they will be printed as raw
// bytes.)
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is not a function type. We just call << to print p,
// relying on ADL to pick up user-defined << for their pointer
// types, if any.
*os << p;
}
}
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
}
}
// Used to print a non-container, non-pointer value when the user
// doesn't define PrintTo() for it.
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
const T& value, ::std::ostream* os) {
::testing_internal::DefaultPrintNonContainerTo(value, os);
}
// Prints the given value using the << operator if it has one; // Prints the given value using the << operator if it has one;
// otherwise prints the bytes in it. This is what // otherwise prints the bytes in it. This is what
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized // UniversalPrinter<T>::Print() does when PrintTo() is not specialized
@ -480,36 +424,7 @@ void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
// wants). // wants).
template <typename T> template <typename T>
void PrintTo(const T& value, ::std::ostream* os) { void PrintTo(const T& value, ::std::ostream* os) {
// DefaultPrintTo() is overloaded. The type of its first argument internal::PrintWithFallback(value, os);
// determines which version will be picked.
//
// Note that we check for container types here, prior to we check
// for protocol message types in our operator<<. The rationale is:
//
// For protocol messages, we want to give people a chance to
// override Google Mock's format by defining a PrintTo() or
// operator<<. For STL containers, other formats can be
// incompatible with Google Mock's format for the container
// elements; therefore we check for container types here to ensure
// that our format is used.
//
// Note that MSVC and clang-cl do allow an implicit conversion from
// pointer-to-function to pointer-to-object, but clang-cl warns on it.
// So don't use ImplicitlyConvertible if it can be helped since it will
// cause this warning, and use a separate overload of DefaultPrintTo for
// function pointers so that the `*os << p` in the object pointer overload
// doesn't cause that warning either.
DefaultPrintTo(
WrapPrinterType <
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value
? kPrintContainer
: !std::is_pointer<T>::value
? kPrintOther
: std::is_function<typename std::remove_pointer<T>::type>::value
? kPrintFunctionPointer
: kPrintPointer > (),
value, os);
} }
// The following list of PrintTo() overloads tells // The following list of PrintTo() overloads tells
@ -900,16 +815,6 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
} // namespace internal } // namespace internal
#if GTEST_INTERNAL_HAS_STRING_VIEW
namespace internal2 {
template <typename T>
void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
const T& value, ::std::ostream* os) {
internal::PrintTo(internal::StringView(value), os);
}
} // namespace internal2
#endif
template <typename T> template <typename T>
::std::string PrintToString(const T& value) { ::std::string PrintToString(const T& value) {
::std::stringstream ss; ::std::stringstream ss;

View File

@ -104,7 +104,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
} // namespace } // namespace
namespace internal2 { namespace internal {
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the // Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object. The delegation simplifies the implementation, which // given object. The delegation simplifies the implementation, which
@ -116,10 +116,6 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
PrintBytesInObjectToImpl(obj_bytes, count, os); PrintBytesInObjectToImpl(obj_bytes, count, os);
} }
} // namespace internal2
namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one // Depending on the value of a char (or wchar_t), we print it in one
// of three formats: // of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as is if it's a printable ASCII (e.g. 'a', '2', ' '),

View File

@ -2268,7 +2268,7 @@ static const char* const kReservedOutputTestCaseAttributes[] = {
"classname", "name", "status", "time", "type_param", "classname", "name", "status", "time", "type_param",
"value_param", "file", "line", "result", "timestamp"}; "value_param", "file", "line", "result", "timestamp"};
template <int kSize> template <size_t kSize>
std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) { std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
return std::vector<std::string>(array, array + kSize); return std::vector<std::string>(array, array + kSize);
} }