Merge branch 'main' into container_wrapper

This commit is contained in:
Ben Dunkin 2026-07-08 20:05:38 -07:00 committed by GitHub
commit f54b34b27b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 241 additions and 124 deletions

View File

@ -4,7 +4,7 @@
cmake_minimum_required(VERSION 3.16)
project(googletest-distribution)
set(GOOGLETEST_VERSION 1.16.0)
set(GOOGLETEST_VERSION 1.18.0)
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
set(CMAKE_CXX_EXTENSIONS OFF)

View File

@ -44,35 +44,35 @@ More information about building GoogleTest can be found at
* xUnit test framework: \
Googletest is based on the [xUnit](https://en.wikipedia.org/wiki/XUnit)
testing framework, a popular architecture for unit testing
testing framework, a popular architecture for unit testing.
* Test discovery: \
Googletest automatically discovers and runs your tests, eliminating the need
to manually register your tests
to manually register your tests.
* Rich set of assertions: \
Googletest provides a variety of assertions, such as equality, inequality,
exceptions, and more, making it easy to test your code
exceptions, and more, making it easy to test your code.
* User-defined assertions: \
You can define your own assertions with Googletest, making it simple to
write tests that are specific to your code
write tests that are specific to your code.
* Death tests: \
Googletest supports death tests, which verify that your code exits in a
certain way, making it useful for testing error-handling code
certain way, making it useful for testing error-handling code.
* Fatal and non-fatal failures: \
You can specify whether a test failure should be treated as fatal or
non-fatal with Googletest, allowing tests to continue running even if a
failure occurs
failure occurs.
* Value-parameterized tests: \
Googletest supports value-parameterized tests, which run multiple times with
different input values, making it useful for testing functions that take
different inputs
different inputs.
* Type-parameterized tests: \
Googletest also supports type-parameterized tests, which run with different
data types, making it useful for testing functions that work with different
data types
data types.
* Various options for running tests: \
Googletest provides many options for running tests including running
individual tests, running tests in a specific order and running tests in
parallel
parallel.
## Supported Platforms

View File

@ -275,6 +275,7 @@
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-pp.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-internal.h"
// MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915
@ -283,6 +284,44 @@
#define GMOCK_MAYBE_5046_
#endif
#if GTEST_HAS_RTTI
namespace proto2 {
namespace internal {
// A type trait to essentially determine if `DynamicCastMessage` is available,
// since older versions of protobuf don't have this function.
template <typename T, typename = void>
static constexpr bool kHasDynamicCastMessage = false;
template <typename T>
static constexpr bool kHasDynamicCastMessage<
T, std::void_t<decltype(DynamicCastMessage<T>(
std::declval<const proto2::MessageLite*>()))>> = true;
// A helper function to call `DynamicCastMessage` if available, otherwise
// falling back to `dynamic_cast`. Note that we must declare this function in
// the `proto2` namespace because we need ADL to find the right
// `DynamicCastMessage`, and ADL only applies to unqualified function calls.
template <typename T>
const T* DynamicCastMessageForGtest(const proto2::MessageLite* msg) {
if constexpr (kHasDynamicCastMessage<T>) {
return DynamicCastMessage<T>(msg);
} else {
return dynamic_cast<const T*>(msg);
}
}
template <typename T>
T* DynamicCastMessageForGtest(proto2::MessageLite* msg) {
if constexpr (kHasDynamicCastMessage<T>) {
return DynamicCastMessage<T>(msg);
} else {
return dynamic_cast<T*>(msg);
}
}
} // namespace internal
} // namespace proto2
#endif // GTEST_HAS_RTTI
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by
clients of class B */
@ -2086,6 +2125,26 @@ class [[nodiscard]] WhenDynamicCastToMatcherBase {
static std::string GetToName() { return GetTypeName<To>(); }
template <typename From>
static auto DoDynamicCast(From& from) {
using ToType =
std::remove_const_t<std::remove_reference_t<std::remove_pointer_t<To>>>;
if constexpr (std::is_base_of_v<proto2::MessageLite, ToType>) {
if constexpr (std::is_pointer_v<To>) {
return proto2::internal::DynamicCastMessageForGtest<ToType>(from);
} else {
// We don't want an std::bad_cast here, so do the cast with pointers.
return proto2::internal::DynamicCastMessageForGtest<ToType>(&from);
}
} else if constexpr (std::is_pointer_v<To>) {
return dynamic_cast<To>(from);
} else {
// We don't want an std::bad_cast here, so do the cast with pointers.
return dynamic_cast<std::remove_reference_t<To>*>(&from);
}
}
private:
static void GetCastTypeDescription(::std::ostream* os) {
*os << "when dynamic_cast to " << GetToName() << ", ";
@ -2103,7 +2162,7 @@ class [[nodiscard]] WhenDynamicCastToMatcher
template <typename From>
bool MatchAndExplain(From from, MatchResultListener* listener) const {
To to = dynamic_cast<To>(from);
To to = this->DoDynamicCast(from);
return MatchPrintAndExplain(to, this->matcher_, listener);
}
};
@ -2119,8 +2178,7 @@ WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
template <typename From>
bool MatchAndExplain(From& from, MatchResultListener* listener) const {
// We don't want an std::bad_cast here, so do the cast with pointers.
To* to = dynamic_cast<To*>(&from);
To* to = this->DoDynamicCast(from);
if (to == nullptr) {
*listener << "which cannot be dynamic_cast to " << this->GetToName();
return false;

View File

@ -79,9 +79,22 @@ class [[nodiscard]] IsEmptyMatcher {
// Matches C-style strings.
bool MatchAndExplain(const char* s, MatchResultListener* listener) const {
if (s == nullptr) {
return false;
}
return MatchAndExplain(std::string(s), listener);
}
#if GTEST_HAS_STD_WSTRING
// Matches C-style wide strings.
bool MatchAndExplain(const wchar_t* s, MatchResultListener* listener) const {
if (s == nullptr) {
return false;
}
return MatchAndExplain(std::wstring(s), listener);
}
#endif // GTEST_HAS_STD_WSTRING
// Describes what this matcher matches.
void DescribeTo(std::ostream* os) const { *os << "is empty"; }

View File

@ -194,11 +194,11 @@ using LosslessArithmeticConvertibleImpl = std::integral_constant<
// Converting between integers of different widths is allowed so long
// as the conversion does not go from signed to unsigned.
(((sizeof(From) < sizeof(To)) &&
!(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
!(std::is_signed_v<From> && !std::is_signed_v<To>)) ||
// Converting between integers of the same width only requires the
// two types to have the same signedness.
((sizeof(From) == sizeof(To)) &&
(std::is_signed<From>::value == std::is_signed<To>::value)))
(std::is_signed_v<From> == std::is_signed_v<To>)))
) ? true
// Floating point conversions are lossless if and only if `To` is at least
// as wide as `From`.
@ -371,7 +371,7 @@ class [[nodiscard]] StlContainerView {
typedef typename type::value_type RawElement;
static const_reference ConstReference(const RawContainer& container) {
static_assert(!std::is_const<RawContainer>::value,
static_assert(!std::is_const_v<RawContainer>,
"RawContainer type must not be const");
return type(&container, RelationToSourceReference());
}
@ -394,7 +394,7 @@ class [[nodiscard]] StlContainerView<Element[N]> {
typedef const type const_reference;
static const_reference ConstReference(const Element (&array)[N]) {
static_assert(std::is_same<Element, RawElement>::value,
static_assert(std::is_same_v<Element, RawElement>,
"Element type must not be const");
return type(array, N, RelationToSourceReference());
}
@ -458,11 +458,11 @@ auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
template <typename F, typename Tuple>
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
std::forward<F>(f), std::forward<Tuple>(args),
std::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
std::make_index_sequence<
std::tuple_size_v<std::remove_reference_t<Tuple>>>())) {
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
std::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>());
std::make_index_sequence<
std::tuple_size_v<std::remove_reference_t<Tuple>>>());
}
// Template struct Function<F>, where F must be a function type, contains
@ -498,7 +498,7 @@ struct Function<R(Args...)> {
// See: https://github.com/google/googletest/issues/3931
// Can be replaced with std::tuple_element_t in C++14.
template <size_t I, typename T>
using TupleElement = typename std::tuple_element<I, T>::type;
using TupleElement = std::tuple_element_t<I, T>;
bool Base64Unescape(const std::string& encoded, std::string* decoded);

View File

@ -66,30 +66,30 @@ using ::testing::internal::BuiltInDefaultValue;
TEST(TypeTraits, Negation) {
// Direct use with std types.
static_assert(std::is_base_of<std::false_type,
internal::negation<std::true_type>>::value,
"");
static_assert(
std::is_base_of_v<std::false_type, internal::negation<std::true_type>>,
"");
static_assert(std::is_base_of<std::true_type,
internal::negation<std::false_type>>::value,
"");
static_assert(
std::is_base_of_v<std::true_type, internal::negation<std::false_type>>,
"");
// With other types that fit the requirement of a value member that is
// convertible to bool.
static_assert(std::is_base_of<
std::true_type,
internal::negation<std::integral_constant<int, 0>>>::value,
"");
static_assert(
std::is_base_of_v<std::true_type,
internal::negation<std::integral_constant<int, 0>>>,
"");
static_assert(std::is_base_of<
std::false_type,
internal::negation<std::integral_constant<int, 1>>>::value,
"");
static_assert(
std::is_base_of_v<std::false_type,
internal::negation<std::integral_constant<int, 1>>>,
"");
static_assert(std::is_base_of<
std::false_type,
internal::negation<std::integral_constant<int, -1>>>::value,
"");
static_assert(
std::is_base_of_v<std::false_type,
internal::negation<std::integral_constant<int, -1>>>,
"");
}
// Weird false/true types that aren't actually bool constants (but should still
@ -108,79 +108,76 @@ struct MyTrue : std::integral_constant<int, -1> {};
TEST(TypeTraits, Conjunction) {
// Base case: always true.
static_assert(std::is_base_of<std::true_type, internal::conjunction<>>::value,
"");
static_assert(std::is_base_of_v<std::true_type, internal::conjunction<>>, "");
// One predicate: inherits from that predicate, regardless of value.
static_assert(
std::is_base_of<MyFalse<0>, internal::conjunction<MyFalse<0>>>::value,
"");
std::is_base_of_v<MyFalse<0>, internal::conjunction<MyFalse<0>>>, "");
static_assert(
std::is_base_of<MyTrue<0>, internal::conjunction<MyTrue<0>>>::value, "");
static_assert(std::is_base_of_v<MyTrue<0>, internal::conjunction<MyTrue<0>>>,
"");
// Multiple predicates, with at least one false: inherits from that one.
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
MyTrue<2>>>::value,
std::is_base_of_v<
MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, MyTrue<2>>>,
"");
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
MyFalse<2>>>::value,
std::is_base_of_v<
MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>, MyFalse<2>>>,
"");
// Short circuiting: in the case above, additional predicates need not even
// define a value member.
struct Empty {};
static_assert(
std::is_base_of<MyFalse<1>, internal::conjunction<MyTrue<0>, MyFalse<1>,
Empty>>::value,
std::is_base_of_v<MyFalse<1>,
internal::conjunction<MyTrue<0>, MyFalse<1>, Empty>>,
"");
// All predicates true: inherits from the last.
static_assert(
std::is_base_of<MyTrue<2>, internal::conjunction<MyTrue<0>, MyTrue<1>,
MyTrue<2>>>::value,
std::is_base_of_v<MyTrue<2>,
internal::conjunction<MyTrue<0>, MyTrue<1>, MyTrue<2>>>,
"");
}
TEST(TypeTraits, Disjunction) {
// Base case: always false.
static_assert(
std::is_base_of<std::false_type, internal::disjunction<>>::value, "");
static_assert(std::is_base_of_v<std::false_type, internal::disjunction<>>,
"");
// One predicate: inherits from that predicate, regardless of value.
static_assert(
std::is_base_of<MyFalse<0>, internal::disjunction<MyFalse<0>>>::value,
"");
std::is_base_of_v<MyFalse<0>, internal::disjunction<MyFalse<0>>>, "");
static_assert(
std::is_base_of<MyTrue<0>, internal::disjunction<MyTrue<0>>>::value, "");
static_assert(std::is_base_of_v<MyTrue<0>, internal::disjunction<MyTrue<0>>>,
"");
// Multiple predicates, with at least one true: inherits from that one.
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
MyFalse<2>>>::value,
std::is_base_of_v<
MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, MyFalse<2>>>,
"");
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
MyTrue<2>>>::value,
std::is_base_of_v<
MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>, MyTrue<2>>>,
"");
// Short circuiting: in the case above, additional predicates need not even
// define a value member.
struct Empty {};
static_assert(
std::is_base_of<MyTrue<1>, internal::disjunction<MyFalse<0>, MyTrue<1>,
Empty>>::value,
std::is_base_of_v<MyTrue<1>,
internal::disjunction<MyFalse<0>, MyTrue<1>, Empty>>,
"");
// All predicates false: inherits from the last.
static_assert(
std::is_base_of<MyFalse<2>, internal::disjunction<MyFalse<0>, MyFalse<1>,
MyFalse<2>>>::value,
std::is_base_of_v<MyFalse<2>, internal::disjunction<
MyFalse<0>, MyFalse<1>, MyFalse<2>>>,
"");
}
@ -747,8 +744,8 @@ TEST(ReturnTest, ConversionRequiresConstLvalueReference) {
using R = int;
using U = std::reference_wrapper<const int>;
static_assert(std::is_convertible<const R&, U>::value, "");
static_assert(!std::is_convertible<R, U>::value, "");
static_assert(std::is_convertible_v<const R&, U>, "");
static_assert(!std::is_convertible_v<R, U>, "");
MockFunction<U()> mock;
EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19));
@ -771,11 +768,11 @@ TEST(ReturnTest, ConversionRequiresMutableLvalueReference) {
S(std::string&) {} // NOLINT
};
static_assert(std::is_convertible<std::string&, S>::value, "");
static_assert(std::is_convertible_v<std::string&, S>, "");
#ifndef _MSC_VER
static_assert(!std::is_convertible<std::string&&, S>::value, "");
static_assert(!std::is_convertible_v<std::string&&, S>, "");
#endif
static_assert(!std::is_convertible<const std::string&, S>::value, "");
static_assert(!std::is_convertible_v<const std::string&, S>, "");
// It shouldn't be possible to use the result of Return(std::string) in a
// context where an S is needed.
@ -784,9 +781,9 @@ TEST(ReturnTest, ConversionRequiresMutableLvalueReference) {
// implementation of is_convertible causes our SFINAE to be wrong.
using RA = decltype(Return(std::string()));
static_assert(!std::is_convertible<RA, Action<S()>>::value, "");
static_assert(!std::is_convertible_v<RA, Action<S()>>, "");
#ifndef _MSC_VER
static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, "");
static_assert(!std::is_convertible_v<RA, OnceAction<S()>>, "");
#endif
}
@ -803,8 +800,8 @@ TEST(ReturnTest, MoveOnlyResultType) {
// The result of Return should not be convertible to Action (so it can't be
// used with WillRepeatedly).
static_assert(!std::is_convertible<decltype(Return(std::unique_ptr<int>())),
Action<std::unique_ptr<int>()>>::value,
static_assert(!std::is_convertible_v<decltype(Return(std::unique_ptr<int>())),
Action<std::unique_ptr<int>()>>,
"");
}
@ -2196,7 +2193,7 @@ TEST(MoveOnlyArgumentsTest, ReturningActions) {
EXPECT_EQ(x, 3);
}
ACTION(ReturnArity) { return std::tuple_size<args_type>::value; }
ACTION(ReturnArity) { return std::tuple_size_v<args_type>; }
TEST(ActionMacro, LargeArity) {
EXPECT_EQ(

View File

@ -937,7 +937,7 @@ namespace {
template <typename Expected, typename F>
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
const internal::MockFunction<F>&) {
return std::is_same<F, Expected>::value;
return std::is_same_v<F, Expected>;
}
} // namespace

View File

@ -1092,8 +1092,20 @@ TEST(IsEmptyTest, MatchesCString) {
const char b[] = "x";
EXPECT_TRUE(m.Matches(a));
EXPECT_FALSE(m.Matches(b));
EXPECT_FALSE(m.Matches(nullptr));
}
#if GTEST_HAS_STD_WSTRING
TEST(IsEmptyTest, MatchesCWideString) {
const Matcher<const wchar_t*> m = IsEmpty();
const wchar_t a[] = L"";
const wchar_t b[] = L"x";
EXPECT_TRUE(m.Matches(a));
EXPECT_FALSE(m.Matches(b));
EXPECT_FALSE(m.Matches(nullptr));
}
#endif // GTEST_HAS_STD_WSTRING
// Tests that IsNull() matches any NULL pointer of any type.
TEST(IsNullTest, MatchesNullPointer) {
Matcher<int*> m1 = IsNull();

View File

@ -813,7 +813,7 @@ class SampleVariantIntString {
template <typename T>
friend bool holds_alternative(const SampleVariantIntString& value) {
return value.has_int_ == std::is_same<T, int>::value;
return value.has_int_ == std::is_same_v<T, int>;
}
template <typename T>

View File

@ -123,8 +123,7 @@ struct GtestGreaterThanMatcher {
};
template <typename T>
GtestGreaterThanMatcher<typename std::decay<T>::type> GtestGreaterThan(
T&& rhs) {
GtestGreaterThanMatcher<std::decay_t<T>> GtestGreaterThan(T&& rhs) {
return {rhs};
}

View File

@ -320,11 +320,15 @@ function(install_project)
foreach(t ${ARGN})
get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME)
get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG)
get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)
get_target_property(t_pdb_output_directory ${t} COMPILE_PDB_OUTPUT_DIRECTORY)
get_target_property(t_shared_pdb_name ${t} PDB_NAME)
get_target_property(t_shared_pdb_name_debug ${t} PDB_NAME_DEBUG)
get_target_property(t_shared_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)
install(FILES
"${t_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<$<CONFIG:Debug>:${t_pdb_name_debug}>$<$<NOT:$<CONFIG:Debug>>:${t_pdb_name}>.pdb"
"$<$<STREQUAL:$<TARGET_PROPERTY:${t},TYPE>,STATIC_LIBRARY>:${t_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<IF:$<CONFIG:Debug>,${t_pdb_name_debug},${t_pdb_name}>.pdb>"
"$<$<STREQUAL:$<TARGET_PROPERTY:${t},TYPE>,SHARED_LIBRARY>:${t_shared_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<IF:$<CONFIG:Debug>,${t_shared_pdb_name_debug},${t_shared_pdb_name}>.pdb>"
COMPONENT "${PROJECT_NAME}"
DESTINATION ${CMAKE_INSTALL_LIBDIR}
DESTINATION $<IF:$<STREQUAL:$<TARGET_PROPERTY:${t},TYPE>,STATIC_LIBRARY>,${CMAKE_INSTALL_LIBDIR},${CMAKE_INSTALL_BINDIR}>
OPTIONAL)
endforeach()
endif()

View File

@ -161,8 +161,7 @@ class GTEST_API_ [[nodiscard]] AssertionResult {
template <typename T>
explicit AssertionResult(
const T& success,
typename std::enable_if<
!std::is_convertible<T, AssertionResult>::value>::type*
std::enable_if_t<!std::is_convertible_v<T, AssertionResult>>*
/*enabler*/
= nullptr)
: success_(success) {}

View File

@ -277,8 +277,8 @@ class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
Init(impl);
}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
template <typename M,
typename = typename std::remove_reference_t<M>::is_gtest_matcher>
MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT
Init(std::forward<M>(m));
}
@ -363,11 +363,10 @@ class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
// from the impl, but some users really want to get their impl back when
// they call GetDescriber().
// We use std::get on a tuple as a workaround of not having `if constexpr`.
return std::get<(
std::is_convertible<decltype(&P::Get(m)),
const MatcherDescriberInterface*>::value
? 1
: 0)>(std::make_tuple(&m, &P::Get(m)));
return std::get<(std::is_convertible_v<decltype(&P::Get(m)),
const MatcherDescriberInterface*>
? 1
: 0)>(std::make_tuple(&m, &P::Get(m)));
}
template <typename P>
@ -396,8 +395,8 @@ class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
template <typename M>
static constexpr bool IsInlined() {
return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
std::is_trivially_copy_constructible<M>::value &&
std::is_trivially_destructible<M>::value;
std::is_trivially_copy_constructible_v<M> &&
std::is_trivially_destructible_v<M>;
}
template <typename M, bool = MatcherBase::IsInlined<M>()>
@ -444,7 +443,7 @@ class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
template <typename M>
void Init(M&& m) {
using MM = typename std::decay<M>::type;
using MM = std::decay_t<M>;
using Policy = ValuePolicy<MM>;
vtable_ = GetVTable<Policy>();
Policy::Init(*this, std::forward<M>(m));
@ -473,14 +472,12 @@ class [[nodiscard]] Matcher : public internal::MatcherBase<T> {
: internal::MatcherBase<T>(impl) {}
template <typename U>
explicit Matcher(
const MatcherInterface<U>* impl,
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
nullptr)
explicit Matcher(const MatcherInterface<U>* impl,
std::enable_if_t<!std::is_same_v<U, const U&>>* = nullptr)
: internal::MatcherBase<T>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
template <typename M,
typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
// Implicit constructor here allows people to write
@ -509,8 +506,8 @@ Matcher<const std::string&> : public internal::MatcherBase<const std::string&> {
explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<const std::string&>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
template <typename M,
typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
@ -533,8 +530,8 @@ Matcher<std::string> : public internal::MatcherBase<std::string> {
explicit Matcher(const MatcherInterface<std::string>* impl)
: internal::MatcherBase<std::string>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
template <typename M,
typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<std::string>(std::forward<M>(m)) {}
@ -559,8 +556,8 @@ class GTEST_API_ [[nodiscard]] Matcher<const internal::StringView&>
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
: internal::MatcherBase<const internal::StringView&>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
template <typename M,
typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
}
@ -587,8 +584,8 @@ class GTEST_API_ [[nodiscard]] Matcher<internal::StringView>
explicit Matcher(const MatcherInterface<internal::StringView>* impl)
: internal::MatcherBase<internal::StringView>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
template <typename M,
typename = typename std::remove_reference_t<M>::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
@ -815,8 +812,8 @@ class [[nodiscard]] ImplicitCastEqMatcher {
StoredRhs stored_rhs_;
};
template <typename T, typename = typename std::enable_if<
std::is_constructible<std::string, T>::value>::type>
template <typename T,
typename = std::enable_if_t<std::is_constructible_v<std::string, T>>>
using StringLike = T;
// Implements polymorphic matchers MatchesRegex(regex) and

View File

@ -863,8 +863,8 @@ void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
GTEST_INTENTIONAL_CONST_COND_POP_()
*os << ", ";
}
UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
std::get<I - 1>(t), os);
UniversalPrinter<std::tuple_element_t<I - 1, T>>::Print(std::get<I - 1>(t),
os);
}
template <typename... Types>
@ -1218,7 +1218,7 @@ template <typename Tuple>
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
Strings result;
TersePrintPrefixToStrings(
value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
value, std::integral_constant<size_t, std::tuple_size_v<Tuple>>(),
&result);
return result;
}

View File

@ -2164,7 +2164,7 @@ class GTEST_API_ [[nodiscard]] ScopedTrace {
// to cause a compiler error.
template <typename T1, typename T2>
constexpr bool StaticAssertTypeEq() noexcept {
static_assert(std::is_same<T1, T2>::value, "T1 and T2 are not the same type");
static_assert(std::is_same_v<T1, T2>, "T1 and T2 are not the same type");
return true;
}
@ -2310,7 +2310,7 @@ template <int&... ExplicitParameterBarrier, typename Factory>
TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
const char* type_param, const char* value_param,
const char* file, int line, Factory factory) {
using TestT = typename std::remove_pointer<decltype(factory())>::type;
using TestT = std::remove_pointer_t<decltype(factory())>;
class FactoryImpl : public internal::TestFactoryBase {
public:

View File

@ -96,6 +96,12 @@
namespace proto2 {
class [[nodiscard]] MessageLite;
// Dummy forward declaration of `DynamicCastMessage`. Does not match any actual
// overloads of `DynamicCastMessage`, but can be used to assist name resolution
// in templates.
template <typename T>
T DynamicCastMessage() = delete;
}
namespace testing {

View File

@ -2411,9 +2411,7 @@ using StringView = ::std::string_view;
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
#endif
#if (defined(__cpp_lib_three_way_comparison) || \
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
#if defined(__cpp_lib_three_way_comparison)
#define GTEST_INTERNAL_HAS_COMPARE_LIB 1
#else
#define GTEST_INTERNAL_HAS_COMPARE_LIB 0

View File

@ -114,8 +114,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
// char32_t.
template <typename CharType>
char32_t ToChar32(CharType in) {
return static_cast<char32_t>(
static_cast<typename std::make_unsigned<CharType>::type>(in));
return static_cast<char32_t>(static_cast<std::make_unsigned_t<CharType>>(in));
}
} // namespace

View File

@ -6732,6 +6732,12 @@ static const char kColorEncodedHelpMessage[] =
"recreate_environments_when_repeating@D\n"
" Sets up and tears down the global test environment on each repeat\n"
" of the test.\n"
" @G--" GTEST_FLAG_PREFIX_
"fail_fast@D\n"
" Stop running tests after the first failure.\n"
" @G--" GTEST_FLAG_PREFIX_
"fail_if_no_test_linked@D\n"
" Fail if no test is linked into the test program.\n"
"\n"
"Test Output:\n"
" @G--" GTEST_FLAG_PREFIX_
@ -6744,6 +6750,9 @@ static const char kColorEncodedHelpMessage[] =
"print_time=0@D\n"
" Don't print the elapsed time of each test.\n"
" @G--" GTEST_FLAG_PREFIX_
"print_utf8=0@D\n"
" Don't print UTF-8 characters as text.\n"
" @G--" GTEST_FLAG_PREFIX_
"output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_
"@Y|@G:@YFILE_PATH]@D\n"
" Generate a JSON or XML report in the given directory or with the "
@ -6760,6 +6769,9 @@ static const char kColorEncodedHelpMessage[] =
" @G--" GTEST_FLAG_PREFIX_
"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
" Set the default death test style.\n"
" @G--" GTEST_FLAG_PREFIX_
"death_test_use_fork@D\n"
" Use fork() instead of clone() to spawn death test child processes.\n"
#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_
"break_on_failure@D\n"
@ -6772,6 +6784,9 @@ static const char kColorEncodedHelpMessage[] =
"catch_exceptions=0@D\n"
" Do not report exceptions as test failures. Instead, allow them\n"
" to crash the program or throw a pop-up (on Windows).\n"
" @G--" GTEST_FLAG_PREFIX_
"stack_trace_depth=@Y[NUMBER]@D\n"
" Maximum number of stack frames to print when an assertion fails.\n"
"\n"
"Except for @G--" GTEST_FLAG_PREFIX_
"list_tests@D, you can alternatively set "

View File

@ -0,0 +1,9 @@
edition = "2024";
package testing.internal.dynamic_cast_message_test;
message FooMessage {
int32 int_field = 1;
}
message BarMessage {}

View File

@ -64,6 +64,7 @@ IS_WINDOWS = os.name == 'nt'
PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
FLAG_PREFIX = '--gtest_'
DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
DEATH_TEST_USE_FORK_FLAG = FLAG_PREFIX + 'death_test_use_fork'
STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to'
LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
@ -90,19 +91,27 @@ HELP_REGEX = re.compile(
+ FLAG_PREFIX
+ r'random_seed=.*'
+ FLAG_PREFIX
+ r'fail_fast.*'
+ FLAG_PREFIX
+ r'fail_if_no_test_linked.*'
+ FLAG_PREFIX
+ r'color=.*'
+ FLAG_PREFIX
+ r'brief.*'
+ FLAG_PREFIX
+ r'print_time.*'
+ FLAG_PREFIX
+ r'print_utf8.*'
+ FLAG_PREFIX
+ r'output=.*'
+ FLAG_PREFIX
+ r'break_on_failure.*'
+ FLAG_PREFIX
+ r'throw_on_failure.*'
+ FLAG_PREFIX
+ r'catch_exceptions=0.*',
+ r'catch_exceptions=0.*'
+ FLAG_PREFIX
+ r'stack_trace_depth=.*',
re.DOTALL,
)
@ -151,8 +160,10 @@ class GTestHelpTest(gtest_test_utils.TestCase):
if SUPPORTS_DEATH_TESTS and not IS_WINDOWS:
self.assertIn(DEATH_TEST_STYLE_FLAG, output)
self.assertIn(DEATH_TEST_USE_FORK_FLAG, output)
else:
self.assertNotIn(DEATH_TEST_STYLE_FLAG, output)
self.assertNotIn(DEATH_TEST_USE_FORK_FLAG, output)
def test_runs_tests_without_help_flag(self):
"""Verifies correct behavior when no help flag is specified.