3rdparty: Update googletest to v1.18.0

This commit is contained in:
JordanTheToaster
2026-09-19 13:52:30 -04:00
committed by Ty
parent 48227982cf
commit 9ae602429c
36 changed files with 1468 additions and 980 deletions
+1
View File
@@ -55,6 +55,7 @@ Russ Cox <[email protected]>
Russ Rufer <[email protected]>
Sean Mcafee <[email protected]>
Sigurður Ásgeirsson <[email protected]>
Soyeon Kim <[email protected]>
Sverre Sundsdal <[email protected]>
Szymon Sobik <[email protected]>
Takeshi Yoshino <[email protected]>
+13 -12
View File
@@ -8,12 +8,13 @@ Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository.
#### Release 1.17.0
#### Release 1.18.0
[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is
[Release 1.18.0](https://github.com/google/googletest/releases/tag/v1.18.0) is
now available.
The 1.17.x branch [requires at least C++17]((https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
The 1.18.x branch
[requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
#### Continuous Integration
@@ -43,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
+62 -56
View File
@@ -196,7 +196,7 @@ struct BuiltInDefaultValueGetter<T, false> {
// other type T, the built-in default T value is undefined, and the
// function will abort the process.
template <typename T>
class BuiltInDefaultValue {
class [[nodiscard]] BuiltInDefaultValue {
public:
// This function returns true if and only if type T has a built-in default
// value.
@@ -211,7 +211,7 @@ class BuiltInDefaultValue {
// This partial specialization says that we use the same built-in
// default value for T and const T.
template <typename T>
class BuiltInDefaultValue<const T> {
class [[nodiscard]] BuiltInDefaultValue<const T> {
public:
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
static T Get() { return BuiltInDefaultValue<T>::Get(); }
@@ -220,7 +220,7 @@ class BuiltInDefaultValue<const T> {
// This partial specialization defines the default values for pointer
// types.
template <typename T>
class BuiltInDefaultValue<T*> {
class [[nodiscard]] BuiltInDefaultValue<T*> {
public:
static bool Exists() { return true; }
static T* Get() { return nullptr; }
@@ -383,7 +383,7 @@ typename std::add_const<T>::type& as_const(T& t) {
// Specialized for function types below.
template <typename F>
class OnceAction;
class [[nodiscard]] OnceAction;
// An action that can only be used once.
//
@@ -421,27 +421,26 @@ class OnceAction;
// A less-contrived example would be an action that returns an arbitrary type,
// whose &&-qualified call operator is capable of dealing with move-only types.
template <typename Result, typename... Args>
class OnceAction<Result(Args...)> final {
class [[nodiscard]] OnceAction<Result(Args...)> final {
private:
// True iff we can use the given callable type (or lvalue reference) directly
// via StdFunctionAdaptor.
template <typename Callable>
using IsDirectlyCompatible = internal::conjunction<
// It must be possible to capture the callable in StdFunctionAdaptor.
std::is_constructible<typename std::decay<Callable>::type, Callable>,
// The callable must be compatible with our signature.
internal::is_callable_r<Result, typename std::decay<Callable>::type,
Args...>>;
internal::is_callable_r<Result, std::decay_t<Callable>, Args...>,
// It must be possible to capture the callable in StdFunctionAdaptor.
std::is_constructible<std::decay_t<Callable>, Callable>>;
// True iff we can use the given callable type via StdFunctionAdaptor once we
// ignore incoming arguments.
template <typename Callable>
using IsCompatibleAfterIgnoringArguments = internal::conjunction<
// It must be possible to capture the callable in a lambda.
std::is_constructible<typename std::decay<Callable>::type, Callable>,
// The callable must be invocable with zero arguments, returning something
// convertible to Result.
internal::is_callable_r<Result, typename std::decay<Callable>::type>>;
internal::is_callable_r<Result, std::decay_t<Callable>>,
// It must be possible to capture the callable in a lambda.
std::is_constructible<std::decay_t<Callable>, Callable>>;
public:
// Construct from a callable that is directly compatible with our mocked
@@ -574,7 +573,7 @@ class OnceAction<Result(Args...)> final {
// // Sets the default value for type T to be foo.
// DefaultValue<T>::Set(foo);
template <typename T>
class DefaultValue {
class [[nodiscard]] DefaultValue {
public:
// Sets the default value for type T; requires T to be
// copy-constructable and have a public destructor.
@@ -651,7 +650,7 @@ class DefaultValue {
// This partial specialization allows a user to set default values for
// reference types.
template <typename T>
class DefaultValue<T&> {
class [[nodiscard]] DefaultValue<T&> {
public:
// Sets the default value for type T&.
static void Set(T& x) { // NOLINT
@@ -685,7 +684,7 @@ class DefaultValue<T&> {
// This specialization allows DefaultValue<void>::Get() to
// compile.
template <>
class DefaultValue<void> {
class [[nodiscard]] DefaultValue<void> {
public:
static bool Exists() { return true; }
static void Get() {}
@@ -701,7 +700,7 @@ T* DefaultValue<T&>::address_ = nullptr;
// Implement this interface to define an action for function type F.
template <typename F>
class ActionInterface {
class [[nodiscard]] ActionInterface {
public:
typedef typename internal::Function<F>::Result Result;
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
@@ -721,7 +720,7 @@ class ActionInterface {
};
template <typename F>
class Action;
class [[nodiscard]] Action;
// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)
// object that represents an action to be taken when a mock function of type
@@ -730,7 +729,7 @@ class Action;
// can view an object implementing ActionInterface<F> as a concrete action
// (including its current state), and an Action<F> object as a handle to it.
template <typename R, typename... Args>
class Action<R(Args...)> {
class [[nodiscard]] Action<R(Args...)> {
private:
using F = R(Args...);
@@ -869,7 +868,7 @@ class Action<R(Args...)> {
// the definition of Return(void) and SetArgumentPointee<N>(value) for
// complete examples.
template <typename Impl>
class PolymorphicAction {
class [[nodiscard]] PolymorphicAction {
public:
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
@@ -929,7 +928,7 @@ struct ByMoveWrapper {
// The general implementation of Return(R). Specializations follow below.
template <typename R>
class ReturnAction final {
class [[nodiscard]] ReturnAction final {
public:
explicit ReturnAction(R value) : value_(std::move(value)) {}
@@ -1095,7 +1094,7 @@ class ReturnAction final {
// the const call operator, checking at runtime that it isn't called more than
// once, since the user has declared their intent to do so by using ByMove.
template <typename T>
class ReturnAction<ByMoveWrapper<T>> final {
class [[nodiscard]] ReturnAction<ByMoveWrapper<T>> final {
public:
explicit ReturnAction(ByMoveWrapper<T> wrapper)
: state_(new State(std::move(wrapper.payload))) {}
@@ -1122,7 +1121,7 @@ class ReturnAction<ByMoveWrapper<T>> final {
};
// Implements the ReturnNull() action.
class ReturnNullAction {
class [[nodiscard]] ReturnNullAction {
public:
// Allows ReturnNull() to be used in any pointer-returning function. In C++11
// this is enforced by returning nullptr, and in non-C++11 by asserting a
@@ -1134,7 +1133,7 @@ class ReturnNullAction {
};
// Implements the Return() action.
class ReturnVoidAction {
class [[nodiscard]] ReturnVoidAction {
public:
// Allows Return() to be used in any void-returning function.
template <typename Result, typename ArgumentTuple>
@@ -1147,7 +1146,7 @@ class ReturnVoidAction {
// in any function that returns a reference to the type of x,
// regardless of the argument types.
template <typename T>
class ReturnRefAction {
class [[nodiscard]] ReturnRefAction {
public:
// Constructs a ReturnRefAction object from the reference to be returned.
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
@@ -1188,7 +1187,7 @@ class ReturnRefAction {
// used in any function that returns a reference to the type of x,
// regardless of the argument types.
template <typename T>
class ReturnRefOfCopyAction {
class [[nodiscard]] ReturnRefOfCopyAction {
public:
// Constructs a ReturnRefOfCopyAction object from the reference to
// be returned.
@@ -1229,7 +1228,7 @@ class ReturnRefOfCopyAction {
// Implements the polymorphic ReturnRoundRobin(v) action, which can be
// used in any function that returns the element_type of v.
template <typename T>
class ReturnRoundRobinAction {
class [[nodiscard]] ReturnRoundRobinAction {
public:
explicit ReturnRoundRobinAction(std::vector<T> values) {
GTEST_CHECK_(!values.empty())
@@ -1257,7 +1256,7 @@ class ReturnRoundRobinAction {
};
// Implements the polymorphic DoDefault() action.
class DoDefaultAction {
class [[nodiscard]] DoDefaultAction {
public:
// This template type conversion operator allows DoDefault() to be
// used in any function.
@@ -1270,7 +1269,7 @@ class DoDefaultAction {
// Implements the Assign action to set a given pointer referent to a
// particular value.
template <typename T1, typename T2>
class AssignAction {
class [[nodiscard]] AssignAction {
public:
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
@@ -1289,7 +1288,7 @@ class AssignAction {
// Implements the SetErrnoAndReturn action to simulate return from
// various system calls and libc functions.
template <typename T>
class SetErrnoAndReturnAction {
class [[nodiscard]] SetErrnoAndReturnAction {
public:
SetErrnoAndReturnAction(int errno_value, T result)
: errno_(errno_value), result_(result) {}
@@ -1331,22 +1330,6 @@ struct InvokeMethodAction {
}
};
// Implements the InvokeWithoutArgs(f) action. The template argument
// FunctionImpl is the implementation type of f, which can be either a
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
// Action<F> as long as f's type is compatible with F.
template <typename FunctionImpl>
struct InvokeWithoutArgsAction {
FunctionImpl function_impl;
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
// compatible with f.
template <typename... Args>
auto operator()(const Args&...) -> decltype(function_impl()) {
return function_impl();
}
};
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
template <class Class, typename MethodPtr>
struct InvokeMethodWithoutArgsAction {
@@ -1397,7 +1380,7 @@ class IgnoreResultAction {
void Perform(const ArgumentTuple& args) override {
// Performs the action and ignores its result.
action_.Perform(args);
(void)action_.Perform(args);
}
private:
@@ -1503,11 +1486,11 @@ struct WithArgsAction {
};
template <typename... Actions>
class DoAllAction;
class [[nodiscard]] DoAllAction;
// Base case: only a single action.
template <typename FinalAction>
class DoAllAction<FinalAction> {
class [[nodiscard]] DoAllAction<FinalAction> {
public:
struct UserConstructorTag {};
@@ -1561,7 +1544,7 @@ class DoAllAction<FinalAction> {
// Recursive case: support N actions by calling the initial action and then
// calling through to the base class containing N-1 actions.
template <typename InitialAction, typename... OtherActions>
class DoAllAction<InitialAction, OtherActions...>
class [[nodiscard]] DoAllAction<InitialAction, OtherActions...>
: private DoAllAction<OtherActions...> {
private:
using Base = DoAllAction<OtherActions...>;
@@ -1796,11 +1779,24 @@ struct SetArrayArgumentAction {
};
template <size_t k>
struct DeleteArgAction {
class [[nodiscard]] DeleteArgAction {
public:
template <typename... Args>
void operator()(const Args&... args) const {
delete std::get<k>(std::tie(args...));
DoDelete(std::get<k>(std::tie(args...)));
}
private:
template <typename T>
static void DoDelete(T* ptr) {
delete ptr;
}
template <typename T>
[[deprecated(
"DeleteArg<N> used for a non-pointer argument, it was likely migrated "
"to a smart pointer type. This action should be removed.")]]
static void DoDelete(T&) {}
};
template <typename Ptr>
@@ -1866,6 +1862,13 @@ struct RethrowAction {
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
typedef internal::IgnoredValue Unused;
// Deprecated single-argument DoAll.
template <typename Action>
GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
typename std::decay<Action>::type DoAll(Action&& action) {
return std::forward<Action>(action);
}
// Creates an action that does actions a1, a2, ..., sequentially in
// each invocation. All but the last action will have a readonly view of the
// arguments.
@@ -2031,10 +2034,11 @@ PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
// Various overloads for Invoke().
// Legacy function.
// Actions can now be implicitly constructed from callables. No need to create
// wrapper objects.
// This function exists for backwards compatibility.
template <typename FunctionImpl>
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
"Actions can now be implicitly constructed from callables. No need to "
"create wrapper objects using Invoke().")
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
return std::forward<FunctionImpl>(function_impl);
}
@@ -2049,9 +2053,11 @@ internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
// Creates an action that invokes 'function_impl' with no argument.
template <typename FunctionImpl>
internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
InvokeWithoutArgs(FunctionImpl function_impl) {
return {std::move(function_impl)};
GTEST_INTERNAL_DEPRECATE_AND_INLINE(
"Actions can now be implicitly constructed from zero-argument callables. "
"No need to create wrapper objects using InvokeWithoutArgs().")
std::decay_t<FunctionImpl> InvokeWithoutArgs(FunctionImpl&& function_impl) {
return std::forward<FunctionImpl>(function_impl);
}
// Creates an action that invokes the given method on the given object
@@ -63,7 +63,7 @@ namespace testing {
// management as Cardinality objects can now be copied like plain values.
// The implementation of a cardinality.
class CardinalityInterface {
class [[nodiscard]] CardinalityInterface {
public:
virtual ~CardinalityInterface() = default;
@@ -88,7 +88,7 @@ class CardinalityInterface {
// object that specifies how many times a mock function is expected to
// be called. The implementation of Cardinality is just a std::shared_ptr
// to const CardinalityInterface. Don't inherit from Cardinality!
class GTEST_API_ Cardinality {
class GTEST_API_ [[nodiscard]] Cardinality {
public:
// Constructs a null cardinality. Needed for storing Cardinality
// objects in STL containers.
File diff suppressed because it is too large Load Diff
@@ -61,7 +61,7 @@ namespace internal {
// Implements the polymorphic IsEmpty matcher, which
// can be used as a Matcher<T> as long as T is either a container that defines
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
class IsEmptyMatcher {
class [[nodiscard]] IsEmptyMatcher {
public:
// Matches anything that defines empty() and size().
template <typename MatcheeContainerType>
@@ -76,9 +76,22 @@ class 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"; }
@@ -71,11 +71,11 @@
namespace testing {
template <class MockClass>
class NiceMock;
class [[nodiscard]] NiceMock;
template <class MockClass>
class NaggyMock;
class [[nodiscard]] NaggyMock;
template <class MockClass>
class StrictMock;
class [[nodiscard]] StrictMock;
namespace internal {
template <typename T>
@@ -108,7 +108,7 @@ constexpr bool HasStrictnessModifier() {
#endif
template <typename Base>
class NiceMockImpl {
class [[nodiscard]] NiceMockImpl {
public:
NiceMockImpl() {
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
@@ -120,7 +120,7 @@ class NiceMockImpl {
};
template <typename Base>
class NaggyMockImpl {
class [[nodiscard]] NaggyMockImpl {
public:
NaggyMockImpl() {
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
@@ -132,7 +132,7 @@ class NaggyMockImpl {
};
template <typename Base>
class StrictMockImpl {
class [[nodiscard]] StrictMockImpl {
public:
StrictMockImpl() {
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
@@ -146,7 +146,7 @@ class StrictMockImpl {
} // namespace internal
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
: private internal::NiceMockImpl<MockClass>,
public MockClass {
public:
@@ -187,7 +187,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
};
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
: private internal::NaggyMockImpl<MockClass>,
public MockClass {
static_assert(!internal::HasStrictnessModifier<MockClass>(),
@@ -229,7 +229,7 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
};
template <class MockClass>
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
: private internal::StrictMockImpl<MockClass>,
public MockClass {
public:
@@ -1292,10 +1292,10 @@ class MockSpec {
: function_mocker_(function_mocker), matchers_(matchers) {}
// Adds a new default action spec to the function mocker and returns
// the newly created spec.
internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,
int line, const char* obj,
const char* call) {
// the newly created spec. .WillByDefault() must be called on the returned
// object.
[[nodiscard]] internal::OnCallSpec<F>& InternalDefaultActionSetAt(
const char* file, int line, const char* obj, const char* call) {
LogWithLocation(internal::kInfo, file, line,
std::string("ON_CALL(") + obj + ", " + call + ") invoked");
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
@@ -1467,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// function have been satisfied. If not, it will report Google Test
// non-fatal failures for the violations.
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
VerifyAndClearExpectationsLocked();
Mock::UnregisterLocked(this);
ClearDefaultActionsLocked();
@@ -1530,7 +1530,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
UntypedOnCallSpecs specs_to_delete;
untyped_on_call_specs_.swap(specs_to_delete);
g_gmock_mutex.Unlock();
g_gmock_mutex.unlock();
for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();
it != specs_to_delete.end(); ++it) {
delete static_cast<const OnCallSpec<F>*>(*it);
@@ -1538,7 +1538,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// Lock the mutex again, since the caller expects it to be locked when we
// return.
g_gmock_mutex.Lock();
g_gmock_mutex.lock();
}
// Returns the result of invoking this mock function with the given
@@ -1646,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args);
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
if (exp == nullptr) { // A match wasn't found.
this->FormatUnexpectedCallMessageLocked(args, what, why);
@@ -1957,6 +1957,11 @@ struct SignatureOf<R(Args...)> {
using type = R(Args...);
};
template <typename R, typename... Args>
struct SignatureOf<R(Args...) const> {
using type = R(Args...);
};
template <template <typename> class C, typename F>
struct SignatureOf<C<F>,
typename std::enable_if<std::is_function<F>::value>::type>
@@ -2132,9 +2137,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// second argument is an internal type derived from the method signature. The
// failure to disambiguate two overloads of this method in the ON_CALL statement
// is how we block callers from setting expectations on overloaded methods.
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
nullptr) \
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
((mock_expr).gmock_##call)(::testing::internal::WithoutMatchers::Get(), \
nullptr) \
.Setter(__FILE__, __LINE__, #mock_expr, #call)
#define ON_CALL(obj, call) \
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <iterator>
#include <ostream> // NOLINT
#include <string>
#include <type_traits>
@@ -193,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`.
@@ -220,7 +221,7 @@ using LosslessArithmeticConvertible =
// This interface knows how to report a Google Mock failure (either
// non-fatal or fatal).
class FailureReporterInterface {
class [[nodiscard]] FailureReporterInterface {
public:
// The type of a failure (either non-fatal or fatal).
enum FailureType { kNonfatal, kFatal };
@@ -296,14 +297,13 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
//
// ON_CALL(mock, Method({}, nullptr))...
//
class WithoutMatchers {
class [[nodiscard]] WithoutMatchers {
private:
WithoutMatchers() {}
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
};
WithoutMatchers() = default;
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
public:
GTEST_API_ static WithoutMatchers Get();
};
// Invalid<T>() is usable as an expression of type T, but will terminate
// the program with an assertion failure if actually run. This is useful
@@ -323,6 +323,24 @@ inline T Invalid() {
#endif
}
void GetValueType(const void*);
template <class T>
typename std::iterator_traits<
decltype(std::begin(std::declval<T&>()))>::value_type
GetValueType(T*);
template <class T, class = void>
struct RangeTraits {
typedef decltype(internal::GetValueType(
static_cast<std::remove_reference_t<T>*>(nullptr))) value_type;
};
template <class T>
struct RangeTraits<T, std::conditional_t<true, void, typename T::value_type>> {
typedef typename T::value_type value_type;
};
// Given a raw type (i.e. having no top-level reference or const
// modifier) RawContainer that's either an STL-style container or a
// native array, class StlContainerView<RawContainer> has the
@@ -340,13 +358,13 @@ inline T Invalid() {
// This generic version is used when RawContainer itself is already an
// STL-style container.
template <class RawContainer>
class StlContainerView {
class [[nodiscard]] StlContainerView {
public:
typedef RawContainer type;
typedef const type& const_reference;
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 container;
}
@@ -355,7 +373,7 @@ class StlContainerView {
// This specialization is used when RawContainer is a native array type.
template <typename Element, size_t N>
class StlContainerView<Element[N]> {
class [[nodiscard]] StlContainerView<Element[N]> {
public:
typedef typename std::remove_const<Element>::type RawElement;
typedef internal::NativeArray<RawElement> type;
@@ -367,7 +385,7 @@ class 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());
}
@@ -379,7 +397,7 @@ class StlContainerView<Element[N]> {
// This specialization is used when RawContainer is a native array
// represented as a (pointer, size) tuple.
template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
class [[nodiscard]] StlContainerView< ::std::tuple<ElementPointer, Size> > {
public:
typedef typename std::remove_const<
typename std::pointer_traits<ElementPointer>::element_type>::type
@@ -429,14 +447,13 @@ auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
// Apply the function to a tuple of arguments.
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>())) {
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
std::forward<F>(f), std::forward<Tuple>(args),
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
@@ -472,7 +489,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);
@@ -86,11 +86,11 @@
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) \
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
GTEST_API_ ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
#define GMOCK_DECLARE_int32_(name) \
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
#define GMOCK_DECLARE_string_(name) \
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
GTEST_API_ ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
#define GMOCK_FLAG_SET(name, value) \
@@ -25,16 +25,18 @@
// GMOCK_PP_NARG(x, y) => 2
// GMOCK_PP_NARG(PAIR) => 2
//
// Requires: the number of arguments after expansion is at most 15.
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
// Requires: the number of arguments after expansion is at most 31.
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_32ND((__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, \
21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, \
8, 7, 6, 5, 4, 3, 2, 1, 0))
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// returns 0. Requires no more than 15 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_16TH( \
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
// returns 0. Requires no more than 31 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_32ND((__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
0, 0))
// Returns the first argument.
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
@@ -51,7 +53,7 @@
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`.
//
// Requires: * the number of arguments after expansion is at most 15.
// Requires: * the number of arguments after expansion is at most 31.
// * If the argument is a macro, it must be able to be called with one
// argument.
//
@@ -104,7 +106,7 @@
// GMOCK_PP_NARG0(x, y) => 2
// GMOCK_PP_NARG0(PAIR) => 2
//
// Requires: * the number of arguments after expansion is at most 15.
// Requires: * the number of arguments after expansion is at most 31.
// * If the argument is a macro, it must be able to be called with one
// argument.
#define GMOCK_PP_NARG0(...) \
@@ -127,7 +129,7 @@
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
// Requires: * |_Macro| can be called with 3 arguments.
// * |_Tuple| expansion has no more than 15 elements.
// * |_Tuple| expansion has no more than 31 elements.
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
(0, _Macro, _Data, _Tuple)
@@ -135,20 +137,21 @@
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
// Empty if _K = 0.
// Requires: * |_Macro| can be called with 3 arguments.
// * |_K| literal between 0 and 15
// * |_K| literal between 0 and 31
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
// Increments the argument, requires the argument to be between 0 and 15.
// Increments the argument, requires the argument to be between 0 and 31.
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
// Returns comma if _i != 0. Requires _i to be between 0 and 15.
// Returns comma if _i != 0. Requires _i to be between 0 and 31.
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
// Internal details follow. Do not use any of these symbols outside of this
// file or we will break your code.
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE \
(, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , )
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
@@ -164,12 +167,13 @@
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
// define one per possible macro that relies on this behavior. Note "_Args" must
// be parenthesized.
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#define GMOCK_PP_INTERNAL_16TH(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_32ND( \
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
_17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \
_32, ...) \
_32
#define GMOCK_PP_INTERNAL_32ND(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_32ND _Args)
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
@@ -198,6 +202,22 @@
#define GMOCK_PP_INTERNAL_INC_13 14
#define GMOCK_PP_INTERNAL_INC_14 15
#define GMOCK_PP_INTERNAL_INC_15 16
#define GMOCK_PP_INTERNAL_INC_16 17
#define GMOCK_PP_INTERNAL_INC_17 18
#define GMOCK_PP_INTERNAL_INC_18 19
#define GMOCK_PP_INTERNAL_INC_19 20
#define GMOCK_PP_INTERNAL_INC_20 21
#define GMOCK_PP_INTERNAL_INC_21 22
#define GMOCK_PP_INTERNAL_INC_22 23
#define GMOCK_PP_INTERNAL_INC_23 24
#define GMOCK_PP_INTERNAL_INC_24 25
#define GMOCK_PP_INTERNAL_INC_25 26
#define GMOCK_PP_INTERNAL_INC_26 27
#define GMOCK_PP_INTERNAL_INC_27 28
#define GMOCK_PP_INTERNAL_INC_28 29
#define GMOCK_PP_INTERNAL_INC_29 30
#define GMOCK_PP_INTERNAL_INC_30 31
#define GMOCK_PP_INTERNAL_INC_31 32
#define GMOCK_PP_INTERNAL_COMMA_IF_0
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
@@ -214,6 +234,22 @@
#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_16 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_17 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_18 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_19 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_20 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_21 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_22 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_23 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_24 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_25 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_26 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_27 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_28 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_29 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_30 ,
#define GMOCK_PP_INTERNAL_COMMA_IF_31 ,
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
_Macro(_i, _Data, _element)
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
@@ -275,5 +311,69 @@
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_16(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_17(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_16(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_18(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_17(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_19(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_18(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_20(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_19(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_21(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_20(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_22(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_21(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_23(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_22(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_24(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_23(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_25(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_24(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_26(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_25(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_27(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_26(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_28(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_27(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_29(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_28(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_30(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_29(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_31(_i, _Macro, _Data, _Tuple) \
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_30(GMOCK_PP_INC(_i), _Macro, _Data, \
(GMOCK_PP_TAIL _Tuple))
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
+2 -2
View File
@@ -156,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
if (!LogIsVisible(severity)) return;
// Ensures that logs from different threads don't interleave.
MutexLock l(&g_log_mutex);
MutexLock l(g_log_mutex);
if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
@@ -188,7 +188,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
std::cout << ::std::flush;
}
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
GTEST_API_ WithoutMatchers WithoutMatchers::Get() { return WithoutMatchers(); }
GTEST_API_ void IllegalDoDefault(const char* file, int line) {
internal::Assert(
+17 -17
View File
@@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
GTEST_LOCK_EXCLUDED_(mutex_) {
bool should_check = false;
{
MutexLock l(&mutex_);
MutexLock l(mutex_);
if (!action_count_checked_) {
action_count_checked_ = true;
should_check = true;
@@ -293,7 +293,7 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
Log(kWarning,
msg +
"\nNOTE: You can safely ignore the above warning unless this "
"call should not happen. Do not suppress it by blindly adding "
"call should not happen. Do not suppress it by adding "
"an EXPECT_CALL() if you don't mean to enforce the call. "
"See "
"https://github.com/google/googletest/blob/main/docs/"
@@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
{
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
mock_obj_ = mock_obj;
}
Mock::Register(mock_obj, this);
@@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// We protect name_ under g_gmock_mutex in case this mock function
// is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
mock_obj_ = mock_obj;
name_ = name;
}
@@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
{
// We protect mock_obj_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
"MockObject() must not be called before RegisterOwner() or "
"SetOwnerAndName() has been called.");
@@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
{
// We protect name_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
Assert(name_ != nullptr, __FILE__, __LINE__,
"Name() must not be called before SetOwnerAndName() has "
"been called.");
@@ -436,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
UntypedExpectations expectations_to_delete;
untyped_expectations_.swap(expectations_to_delete);
g_gmock_mutex.Unlock();
g_gmock_mutex.unlock();
expectations_to_delete.clear();
g_gmock_mutex.Lock();
g_gmock_mutex.lock();
return expectations_met;
}
@@ -490,7 +490,7 @@ class MockObjectRegistry {
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
int leaked_count = 0;
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
@@ -559,7 +559,7 @@ UninterestingCallReactionMap() {
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
internal::CallReaction reaction)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
UninterestingCallReactionMap()[mock_obj] = reaction;
}
@@ -590,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
// entry in the call-reaction table should be removed.
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
}
@@ -598,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
// made on the given mock object.
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
return (UninterestingCallReactionMap().count(
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
? internal::intToCallReaction(
@@ -611,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
// objects.
void Mock::AllowLeak(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].leakable = true;
}
@@ -620,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj)
// Test non-fatal failures and returns false.
bool Mock::VerifyAndClearExpectations(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
return VerifyAndClearExpectationsLocked(mock_obj);
}
@@ -629,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
// verification was successful.
bool Mock::VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
ClearDefaultActionsLocked(mock_obj);
return VerifyAndClearExpectationsLocked(mock_obj);
}
@@ -679,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
}
@@ -689,7 +689,7 @@ void Mock::Register(const void* mock_obj,
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
const char* file, int line)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
if (state.first_used_file == nullptr) {
state.first_used_file = file;
+4 -4
View File
@@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with
```
git clone https://github.com/google/googletest.git -b v1.17.0
git clone https://github.com/google/googletest.git -b v1.18.0
cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output.
cd build
@@ -145,9 +145,9 @@ We list the most frequently used macros below. For a complete list, see file
### Multi-threaded Tests
GoogleTest is thread-safe where the pthread library is available. After
`#include <gtest/gtest.h>`, you can check the
`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
`#defined` to 1, no if it's undefined.).
`#include <gtest/gtest.h>`, you can check the `GTEST_IS_THREADSAFE` macro to see
whether this is the case (yes if the macro is `#defined` to 1, no if it's
undefined.).
If GoogleTest doesn't correctly detect whether pthread is available in your
environment, you can force it with
@@ -137,7 +137,7 @@ namespace testing {
class [[nodiscard]] AssertionResult;
#endif // !SWIG
class GTEST_API_ AssertionResult {
class GTEST_API_ [[nodiscard]] AssertionResult {
public:
// Copy constructor.
// Used in EXPECT_TRUE/FALSE(assertion_result).
@@ -158,14 +158,18 @@ class GTEST_API_ AssertionResult {
// The second parameter prevents this overload from being considered if
// the argument is implicitly convertible to AssertionResult. In that case
// we want AssertionResult's copy constructor to be used.
template <typename T>
explicit AssertionResult(
const T& success,
typename std::enable_if<
!std::is_convertible<T, AssertionResult>::value>::type*
/*enabler*/
= nullptr)
: success_(success) {}
template <typename T,
std::enable_if_t<!std::is_convertible_v<T, AssertionResult> &&
!std::is_trivially_constructible_v<bool, T>,
int> = 0>
explicit AssertionResult(T&& success) : success_(std::forward<T>(success)) {}
// Similar to the mutable overload, but for cases where mutability is
// unnecessary or problematic (e.g., bitfields).
template <typename T,
std::enable_if_t<!std::is_convertible_v<const T&, AssertionResult>,
int> = 0>
explicit AssertionResult(const T& success) : success_(success) {}
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_POP_()
@@ -227,6 +231,24 @@ class GTEST_API_ AssertionResult {
std::unique_ptr< ::std::string> message_;
};
namespace internal {
// A pair containing the result that an assertion is evaluating, and the
// expected result (true, false).
//
// Contains a conversion operator that indicates whether the two match.
struct AssertionResultExpectation {
testing::AssertionResult assertion_result;
bool expected_result;
explicit operator bool() const {
bool converted(assertion_result);
return converted == expected_result;
}
};
} // namespace internal
// Makes a successful assertion result.
GTEST_API_ AssertionResult AssertionSuccess();
@@ -192,7 +192,7 @@ GTEST_API_ bool InDeathTestChild();
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
// Tests that an exit code describes a normal exit with a given exit code.
class GTEST_API_ ExitedWithCode {
class GTEST_API_ [[nodiscard]] ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
ExitedWithCode(const ExitedWithCode&) = default;
@@ -206,7 +206,7 @@ class GTEST_API_ ExitedWithCode {
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
// Tests that an exit code describes an exit due to termination by a
// given signal.
class GTEST_API_ KilledBySignal {
class GTEST_API_ [[nodiscard]] KilledBySignal {
public:
explicit KilledBySignal(int signum);
bool operator()(int exit_status) const;
@@ -317,7 +317,7 @@ class GTEST_API_ KilledBySignal {
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
(void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
+129 -66
View File
@@ -40,10 +40,12 @@
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#include <atomic>
#include <cstddef>
#include <functional>
#include <memory>
#include <ostream>
#include <string>
#include <string_view>
#include <type_traits>
#include "gtest/gtest-printers.h"
@@ -75,7 +77,7 @@ namespace testing {
// 2. a factory function that creates a Matcher<T> object from a
// FooMatcherMatcher.
class MatchResultListener {
class [[nodiscard]] MatchResultListener {
public:
// Creates a listener object with the given underlying ostream. The
// listener does not own the ostream, and does not dereference it
@@ -111,7 +113,7 @@ inline MatchResultListener::~MatchResultListener() = default;
// An instance of a subclass of this knows how to describe itself as a
// matcher.
class GTEST_API_ MatcherDescriberInterface {
class GTEST_API_ [[nodiscard]] MatcherDescriberInterface {
public:
virtual ~MatcherDescriberInterface() = default;
@@ -137,7 +139,7 @@ class GTEST_API_ MatcherDescriberInterface {
// The implementation of a matcher.
template <typename T>
class MatcherInterface : public MatcherDescriberInterface {
class [[nodiscard]] MatcherInterface : public MatcherDescriberInterface {
public:
// Returns true if and only if the matcher matches x; also explains the
// match result to 'listener' if necessary (see the next paragraph), in
@@ -180,7 +182,7 @@ class MatcherInterface : public MatcherDescriberInterface {
namespace internal {
// A match result listener that ignores the explanation.
class DummyMatchResultListener : public MatchResultListener {
class [[nodiscard]] DummyMatchResultListener : public MatchResultListener {
public:
DummyMatchResultListener() : MatchResultListener(nullptr) {}
@@ -192,7 +194,7 @@ class DummyMatchResultListener : public MatchResultListener {
// A match result listener that forwards the explanation to a given
// ostream. The difference between this and MatchResultListener is
// that the former is concrete.
class StreamMatchResultListener : public MatchResultListener {
class [[nodiscard]] StreamMatchResultListener : public MatchResultListener {
public:
explicit StreamMatchResultListener(::std::ostream* os)
: MatchResultListener(os) {}
@@ -225,7 +227,7 @@ struct SharedPayload : SharedPayloadBase {
// from it. We put functionalities common to all Matcher<T>
// specializations here to avoid code duplication.
template <typename T>
class MatcherBase : private MatcherDescriberInterface {
class [[nodiscard]] MatcherBase : private MatcherDescriberInterface {
public:
// Returns true if and only if the matcher matches x; also explains the
// match result to 'listener'.
@@ -276,8 +278,8 @@ class 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));
}
@@ -296,12 +298,12 @@ class MatcherBase : private MatcherDescriberInterface {
return *this;
}
MatcherBase(MatcherBase&& other)
MatcherBase(MatcherBase&& other) noexcept
: vtable_(other.vtable_), buffer_(other.buffer_) {
other.vtable_ = nullptr;
}
MatcherBase& operator=(MatcherBase&& other) {
MatcherBase& operator=(MatcherBase&& other) noexcept {
if (this == &other) return *this;
Destroy();
vtable_ = other.vtable_;
@@ -362,11 +364,10 @@ class 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>
@@ -395,8 +396,8 @@ class 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>()>
@@ -443,7 +444,7 @@ class 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));
@@ -460,7 +461,7 @@ class MatcherBase : private MatcherDescriberInterface {
// implementation of Matcher<T> is just a std::shared_ptr to const
// MatcherInterface<T>. Don't inherit from Matcher!
template <typename T>
class Matcher : public internal::MatcherBase<T> {
class [[nodiscard]] Matcher : public internal::MatcherBase<T> {
public:
// Constructs a null matcher. Needed for storing Matcher objects in STL
// containers. A default-constructed matcher is not yet initialized. You
@@ -472,35 +473,42 @@ class 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
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
Matcher(T value); // NOLINT
// Implicit constructor here allows people to write
// EXPECT_THAT(foo, nullptr) instead of EXPECT_THAT(foo, IsNull()) for smart
// pointer types.
//
// The second argument is needed to avoid capturing literal '0'.
template <typename U>
Matcher(U, // NOLINT
std::enable_if_t<std::is_same_v<U, std::nullptr_t>>* = nullptr);
};
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected.
template <>
class GTEST_API_ Matcher<const std::string&>
: public internal::MatcherBase<const std::string&> {
class GTEST_API_ [[nodiscard]]
Matcher<const std::string&> : public internal::MatcherBase<const std::string&> {
public:
Matcher() = default;
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)) {}
@@ -513,8 +521,8 @@ class GTEST_API_ Matcher<const std::string&>
};
template <>
class GTEST_API_ Matcher<std::string>
: public internal::MatcherBase<std::string> {
class GTEST_API_ [[nodiscard]]
Matcher<std::string> : public internal::MatcherBase<std::string> {
public:
Matcher() = default;
@@ -523,8 +531,8 @@ class GTEST_API_ Matcher<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)) {}
@@ -536,12 +544,11 @@ class GTEST_API_ Matcher<std::string>
Matcher(const char* s); // NOLINT
};
#if GTEST_INTERNAL_HAS_STRING_VIEW
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string_view
// matcher is expected.
template <>
class GTEST_API_ Matcher<const internal::StringView&>
class GTEST_API_ [[nodiscard]] Matcher<const internal::StringView&>
: public internal::MatcherBase<const internal::StringView&> {
public:
Matcher() = default;
@@ -549,8 +556,8 @@ class GTEST_API_ 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)) {
}
@@ -562,12 +569,12 @@ class GTEST_API_ Matcher<const internal::StringView&>
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
// Allows the user to pass std::string_views directly.
Matcher(internal::StringView s); // NOLINT
};
template <>
class GTEST_API_ Matcher<internal::StringView>
class GTEST_API_ [[nodiscard]] Matcher<internal::StringView>
: public internal::MatcherBase<internal::StringView> {
public:
Matcher() = default;
@@ -577,8 +584,8 @@ class GTEST_API_ 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)) {}
@@ -589,10 +596,9 @@ class GTEST_API_ Matcher<internal::StringView>
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
// Allows the user to pass std::string_views directly.
Matcher(internal::StringView s); // NOLINT
};
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Prints a matcher in a human-readable format.
template <typename T>
@@ -614,7 +620,7 @@ std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
//
// See the definition of NotNull() for a complete example.
template <class Impl>
class PolymorphicMatcher {
class [[nodiscard]] PolymorphicMatcher {
public:
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
@@ -689,7 +695,7 @@ namespace internal {
// The following template definition assumes that the Rhs parameter is
// a "bare" type (i.e. neither 'const T' nor 'T&').
template <typename D, typename Rhs, typename Op>
class ComparisonBase {
class [[nodiscard]] ComparisonBase {
public:
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
@@ -722,7 +728,8 @@ class ComparisonBase {
};
template <typename Rhs>
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
class [[nodiscard]] EqMatcher
: public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
public:
explicit EqMatcher(const Rhs& rhs)
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
@@ -730,7 +737,7 @@ class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
static const char* NegatedDesc() { return "isn't equal to"; }
};
template <typename Rhs>
class NeMatcher
class [[nodiscard]] NeMatcher
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
public:
explicit NeMatcher(const Rhs& rhs)
@@ -739,7 +746,8 @@ class NeMatcher
static const char* NegatedDesc() { return "is equal to"; }
};
template <typename Rhs>
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
class [[nodiscard]] LtMatcher
: public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
public:
explicit LtMatcher(const Rhs& rhs)
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
@@ -747,7 +755,8 @@ class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
static const char* NegatedDesc() { return "isn't <"; }
};
template <typename Rhs>
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
class [[nodiscard]] GtMatcher
: public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
public:
explicit GtMatcher(const Rhs& rhs)
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
@@ -755,7 +764,7 @@ class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
static const char* NegatedDesc() { return "isn't >"; }
};
template <typename Rhs>
class LeMatcher
class [[nodiscard]] LeMatcher
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
public:
explicit LeMatcher(const Rhs& rhs)
@@ -764,7 +773,7 @@ class LeMatcher
static const char* NegatedDesc() { return "isn't <="; }
};
template <typename Rhs>
class GeMatcher
class [[nodiscard]] GeMatcher
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
public:
explicit GeMatcher(const Rhs& rhs)
@@ -773,24 +782,68 @@ class GeMatcher
static const char* NegatedDesc() { return "isn't >="; }
};
template <typename T, typename = typename std::enable_if<
std::is_constructible<std::string, T>::value>::type>
using StringLike = T;
// Same as `EqMatcher<Rhs>`, except that the `rhs` is stored as `StoredRhs` and
// must be implicitly convertible to `Rhs`.
template <typename Rhs, typename StoredRhs>
class [[nodiscard]] ImplicitCastEqMatcher {
public:
explicit ImplicitCastEqMatcher(const StoredRhs& rhs) : stored_rhs_(rhs) {}
using is_gtest_matcher = void;
template <typename Lhs>
bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
return lhs == rhs();
}
void DescribeTo(std::ostream* os) const {
*os << "is equal to ";
UniversalPrint(rhs(), os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "isn't equal to ";
UniversalPrint(rhs(), os);
}
private:
Rhs rhs() const { return ImplicitCast_<Rhs>(stored_rhs_); }
StoredRhs stored_rhs_;
};
// Dummy function (never defined) whose return type evaluates to std::string if
// the given type is a string-like type that can be converted to std::string,
// either directly or through an intermediate std::string_view.
template <class T>
extern std::enable_if_t<std::is_constructible_v<std::string, T>, std::string>
ResolveAsString(const void* /* preferred */);
#if GTEST_HAS_STD_WSTRING
// Same as above, but for std::wstring. In cases where both conversions are
// possible, this overload takes lower priority.
template <class T>
extern std::enable_if_t<std::is_constructible_v<std::wstring, T>, std::wstring>
ResolveAsString(... /* fallback */);
#endif
// Evaluates to the std::basic_string type that the given string-like type can
// be converted to. Prefers std::string over std::wstring if both are possible.
// Fails in a SFINAE-friendly way if no conversion was viable.
template <typename T>
using StringType = decltype(ResolveAsString<T>(nullptr));
// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
class MatchesRegexMatcher {
class [[nodiscard]] MatchesRegexMatcher {
public:
MatchesRegexMatcher(const RE* regex, bool full_match)
: regex_(regex), full_match_(full_match) {}
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const {
return MatchAndExplain(std::string(s), listener);
}
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
@@ -805,7 +858,7 @@ class MatchesRegexMatcher {
// Matches anything that can convert to std::string.
//
// This is a template, not just a plain function with const std::string&,
// because absl::string_view has some interfering non-explicit constructors.
// because std::string_view has some interfering non-explicit constructors.
template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
@@ -838,9 +891,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
}
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const internal::StringLike<T>& regex) {
return MatchesRegex(new internal::RE(std::string(regex)));
std::enable_if_t<std::is_constructible_v<internal::RE, internal::StringType<T>>,
PolymorphicMatcher<internal::MatchesRegexMatcher>>
MatchesRegex(const T& regex) {
return MatchesRegex(new internal::RE(internal::StringType<T>(regex)));
}
// Matches a string that contains regular expression 'regex'.
@@ -850,9 +904,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
}
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const internal::StringLike<T>& regex) {
return ContainsRegex(new internal::RE(std::string(regex)));
std::enable_if_t<std::is_constructible_v<internal::RE, internal::StringType<T>>,
PolymorphicMatcher<internal::MatchesRegexMatcher>>
ContainsRegex(const T& regex) {
return ContainsRegex(new internal::RE(internal::StringType<T>(regex)));
}
// Creates a polymorphic matcher that matches anything equal to x.
@@ -863,13 +918,21 @@ inline internal::EqMatcher<T> Eq(T x) {
return internal::EqMatcher<T>(x);
}
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'.
template <typename T>
Matcher<T>::Matcher(T value) {
*this = Eq(value);
}
// Constructs a Matcher<T> from nullptr. The constructed matcher matches any
// value that is equal to nullptr.
template <typename T>
template <typename U>
Matcher<T>::Matcher(U, std::enable_if_t<std::is_same_v<U, std::nullptr_t>>*) {
*this = Eq(nullptr);
}
// Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity.
@@ -129,7 +129,7 @@ class GTEST_API_ Message {
int>::type = 0
#endif // GTEST_HAS_ABSL
>
inline Message& operator<<(const T& val) {
Message& operator<<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
@@ -155,7 +155,7 @@ class GTEST_API_ Message {
template <typename T,
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0>
inline Message& operator<<(const T& val) {
Message& operator<<(const T& val) {
// ::operator<< is needed here for a similar reason as with the non-Abseil
// version above
using ::operator<<;
+107 -94
View File
@@ -104,15 +104,19 @@
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <any>
#include <functional>
#include <memory>
#include <optional>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <variant>
#include <vector>
#ifdef GTEST_HAS_ABSL
@@ -245,8 +249,8 @@ struct StreamPrinter {
// ADL (possibly involving implicit conversions).
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
// lookup properly when we do it in the template parameter list.)
static auto PrintValue(const T& value,
::std::ostream* os) -> decltype((void)(*os << value)) {
static auto PrintValue(const T& value, ::std::ostream* os)
-> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
@@ -287,11 +291,9 @@ struct ConvertibleToIntegerPrinter {
};
struct ConvertibleToStringViewPrinter {
#if GTEST_INTERNAL_HAS_STRING_VIEW
static void PrintValue(internal::StringView value, ::std::ostream* os) {
internal::UniversalPrint(value, os);
}
#endif
};
#ifdef GTEST_HAS_ABSL
@@ -378,7 +380,7 @@ void PrintWithFallback(const T& value, ::std::ostream* os) {
// The default case.
template <typename ToPrint, typename OtherOperand>
class FormatForComparison {
class [[nodiscard]] FormatForComparison {
public:
static ::std::string Format(const ToPrint& value) {
return ::testing::PrintToString(value);
@@ -387,7 +389,7 @@ class FormatForComparison {
// Array.
template <typename ToPrint, size_t N, typename OtherOperand>
class FormatForComparison<ToPrint[N], OtherOperand> {
class [[nodiscard]] FormatForComparison<ToPrint[N], OtherOperand> {
public:
static ::std::string Format(const ToPrint* value) {
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
@@ -473,7 +475,7 @@ std::string FormatForComparisonFailureMessage(const T1& value,
// function template), as we need to partially specialize it for
// reference types, which cannot be done with function templates.
template <typename T>
class UniversalPrinter;
class [[nodiscard]] UniversalPrinter;
// Prints the given value using the << operator if it has one;
// otherwise prints the bytes in it. This is what
@@ -521,11 +523,15 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
inline void PrintTo(char16_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
// Also see https://github.com/google/googletest/issues/4762.
PrintTo(static_cast<char32_t>(c), os);
}
#ifdef __cpp_lib_char8_t
inline void PrintTo(char8_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
// Also see https://github.com/google/googletest/issues/4762.
PrintTo(static_cast<char32_t>(c), os);
}
#endif
@@ -695,46 +701,63 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
}
}
// Overloads for ::std::string.
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
// Overloads for ::std::string and std::string_view
GTEST_API_ void PrintStringTo(std::string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os);
}
inline void PrintTo(std::string_view s, ::std::ostream* os) {
PrintStringTo(s, os);
}
// Overloads for ::std::u8string
// Overloads for ::std::u8string and ::std::u8string_view
#ifdef __cpp_lib_char8_t
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
GTEST_API_ void PrintU8StringTo(::std::u8string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
PrintU8StringTo(s, os);
}
inline void PrintTo(::std::u8string_view s, ::std::ostream* os) {
PrintU8StringTo(s, os);
}
#endif
// Overloads for ::std::u16string
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
// Overloads for ::std::u16string and ::std::u16string_view
GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
PrintU16StringTo(s, os);
}
inline void PrintTo(::std::u16string_view s, ::std::ostream* os) {
PrintU16StringTo(s, os);
}
// Overloads for ::std::u32string
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
// Overloads for ::std::u32string and ::std::u32string_view
GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os);
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
PrintU32StringTo(s, os);
}
inline void PrintTo(::std::u32string_view s, ::std::ostream* os) {
PrintU32StringTo(s, os);
}
// Overloads for ::std::wstring.
// Overloads for ::std::wstring and ::std::wstring_view
#if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os);
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
PrintWideStringTo(s, os);
}
inline void PrintTo(::std::wstring_view s, ::std::ostream* os) {
PrintWideStringTo(s, os);
}
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Overload for internal::StringView.
// Overload for internal::StringView. Needed for build configurations where
// internal::StringView is an alias for absl::string_view, but absl::string_view
// is a distinct type from std::string_view.
template <int&... ExplicitArgumentBarrier, typename T = internal::StringView,
std::enable_if_t<!std::is_same_v<T, std::string_view>, int> = 0>
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
PrintTo(::std::string(sp), os);
PrintStringTo(sp, os);
}
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
@@ -836,8 +859,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>
@@ -862,7 +885,7 @@ void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
// Implements printing a non-reference type T by letting the compiler
// pick the right overload of PrintTo() for T.
template <typename T>
class UniversalPrinter {
class [[nodiscard]] UniversalPrinter {
public:
// MSVC warns about adding const to a function type, so we want to
// disable the warning.
@@ -888,16 +911,13 @@ class UniversalPrinter {
// Remove any const-qualifiers before passing a type to UniversalPrinter.
template <typename T>
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
#if GTEST_INTERNAL_HAS_ANY
// Printer for std::any / absl::any
class [[nodiscard]] UniversalPrinter<const T> : public UniversalPrinter<T> {};
// Printer for std::any
template <>
class UniversalPrinter<Any> {
class [[nodiscard]] UniversalPrinter<std::any> {
public:
static void Print(const Any& value, ::std::ostream* os) {
static void Print(const std::any& value, ::std::ostream* os) {
if (value.has_value()) {
*os << "value of type " << GetTypeName(value);
} else {
@@ -906,7 +926,7 @@ class UniversalPrinter<Any> {
}
private:
static std::string GetTypeName(const Any& value) {
static std::string GetTypeName(const std::any& value) {
#if GTEST_HAS_RTTI
return internal::GetTypeName(value.type());
#else
@@ -916,67 +936,60 @@ class UniversalPrinter<Any> {
}
};
#endif // GTEST_INTERNAL_HAS_ANY
#if GTEST_INTERNAL_HAS_OPTIONAL
// Printer for std::optional / absl::optional
// Printer for std::optional
template <typename T>
class UniversalPrinter<Optional<T>> {
class [[nodiscard]] UniversalPrinter<std::optional<T>> {
public:
static void Print(const Optional<T>& value, ::std::ostream* os) {
*os << '(';
static void Print(const std::optional<T>& value, ::std::ostream* os) {
if (!value) {
*os << "nullopt";
UniversalPrint(std::nullopt, os);
} else {
*os << '(';
UniversalPrint(*value, os);
*os << ')';
}
*os << ')';
}
};
template <>
class UniversalPrinter<decltype(Nullopt())> {
class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
public:
static void Print(decltype(Nullopt()), ::std::ostream* os) {
*os << "(nullopt)";
}
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
};
#endif // GTEST_INTERNAL_HAS_OPTIONAL
#if GTEST_INTERNAL_HAS_VARIANT
// Printer for std::variant / absl::variant
struct UniversalPrinterVisitor {
template <typename T>
void operator()(const T& arg) const {
*os << "'" << GetTypeName<T>() << "(index = " << index << ")' with value ";
UniversalPrint(arg, os);
}
::std::ostream* os;
std::size_t index;
};
// Printer for std::variant
template <typename... T>
class UniversalPrinter<Variant<T...>> {
class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
public:
static void Print(const Variant<T...>& value, ::std::ostream* os) {
*os << '(';
#ifdef GTEST_HAS_ABSL
absl::visit(Visitor{os, value.index()}, value);
#else
std::visit(Visitor{os, value.index()}, value);
#endif // GTEST_HAS_ABSL
*os << ')';
}
private:
struct Visitor {
template <typename U>
void operator()(const U& u) const {
*os << "'" << GetTypeName<U>() << "(index = " << index
<< ")' with value ";
UniversalPrint(u, os);
static void Print(const std::variant<T...>& value, ::std::ostream* os) {
if (value.valueless_by_exception()) {
*os << "(valueless)";
} else {
*os << '(';
std::visit(UniversalPrinterVisitor{os, value.index()}, value);
*os << ')';
}
::std::ostream* os;
std::size_t index;
};
}
};
#endif // GTEST_INTERNAL_HAS_VARIANT
// Printer for std::monostate
template <>
class [[nodiscard]] UniversalPrinter<std::monostate> {
public:
static void Print(std::monostate, ::std::ostream* os) {
*os << "(monostate)";
}
};
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
@@ -1025,7 +1038,7 @@ GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
// Implements printing an array type T[N].
template <typename T, size_t N>
class UniversalPrinter<T[N]> {
class [[nodiscard]] UniversalPrinter<T[N]> {
public:
// Prints the given array, omitting some elements when there are too
// many.
@@ -1036,7 +1049,7 @@ class UniversalPrinter<T[N]> {
// Implements printing a reference type T&.
template <typename T>
class UniversalPrinter<T&> {
class [[nodiscard]] UniversalPrinter<T&> {
public:
// MSVC warns about adding const to a function type, so we want to
// disable the warning.
@@ -1059,35 +1072,35 @@ class UniversalPrinter<T&> {
// NUL-terminated string (but not the pointer) is printed.
template <typename T>
class UniversalTersePrinter {
class [[nodiscard]] UniversalTersePrinter {
public:
static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os);
}
};
template <typename T>
class UniversalTersePrinter<T&> {
class [[nodiscard]] UniversalTersePrinter<T&> {
public:
static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os);
}
};
template <typename T>
class UniversalTersePrinter<std::reference_wrapper<T>> {
class [[nodiscard]] UniversalTersePrinter<std::reference_wrapper<T>> {
public:
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
UniversalTersePrinter<T>::Print(value.get(), os);
}
};
template <typename T, size_t N>
class UniversalTersePrinter<T[N]> {
class [[nodiscard]] UniversalTersePrinter<T[N]> {
public:
static void Print(const T (&value)[N], ::std::ostream* os) {
UniversalPrinter<T[N]>::Print(value, os);
}
};
template <>
class UniversalTersePrinter<const char*> {
class [[nodiscard]] UniversalTersePrinter<const char*> {
public:
static void Print(const char* str, ::std::ostream* os) {
if (str == nullptr) {
@@ -1098,12 +1111,12 @@ class UniversalTersePrinter<const char*> {
}
};
template <>
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
};
class [[nodiscard]]
UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {};
#ifdef __cpp_lib_char8_t
template <>
class UniversalTersePrinter<const char8_t*> {
class [[nodiscard]] UniversalTersePrinter<const char8_t*> {
public:
static void Print(const char8_t* str, ::std::ostream* os) {
if (str == nullptr) {
@@ -1114,12 +1127,12 @@ class UniversalTersePrinter<const char8_t*> {
}
};
template <>
class UniversalTersePrinter<char8_t*>
class [[nodiscard]] UniversalTersePrinter<char8_t*>
: public UniversalTersePrinter<const char8_t*> {};
#endif
template <>
class UniversalTersePrinter<const char16_t*> {
class [[nodiscard]] UniversalTersePrinter<const char16_t*> {
public:
static void Print(const char16_t* str, ::std::ostream* os) {
if (str == nullptr) {
@@ -1130,11 +1143,11 @@ class UniversalTersePrinter<const char16_t*> {
}
};
template <>
class UniversalTersePrinter<char16_t*>
class [[nodiscard]] UniversalTersePrinter<char16_t*>
: public UniversalTersePrinter<const char16_t*> {};
template <>
class UniversalTersePrinter<const char32_t*> {
class [[nodiscard]] UniversalTersePrinter<const char32_t*> {
public:
static void Print(const char32_t* str, ::std::ostream* os) {
if (str == nullptr) {
@@ -1145,12 +1158,12 @@ class UniversalTersePrinter<const char32_t*> {
}
};
template <>
class UniversalTersePrinter<char32_t*>
class [[nodiscard]] UniversalTersePrinter<char32_t*>
: public UniversalTersePrinter<const char32_t*> {};
#if GTEST_HAS_STD_WSTRING
template <>
class UniversalTersePrinter<const wchar_t*> {
class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
public:
static void Print(const wchar_t* str, ::std::ostream* os) {
if (str == nullptr) {
@@ -1163,7 +1176,7 @@ class UniversalTersePrinter<const wchar_t*> {
#endif
template <>
class UniversalTersePrinter<wchar_t*> {
class [[nodiscard]] UniversalTersePrinter<wchar_t*> {
public:
static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os);
@@ -1212,7 +1225,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;
}
+2 -2
View File
@@ -51,7 +51,7 @@ namespace testing {
// generated in the same thread that created this object or it can intercept
// all generated failures. The scope of this mock object can be controlled with
// the second argument to the two arguments constructor.
class GTEST_API_ ScopedFakeTestPartResultReporter
class GTEST_API_ [[nodiscard]] ScopedFakeTestPartResultReporter
: public TestPartResultReporterInterface {
public:
// The two possible mocking modes of this object.
@@ -100,7 +100,7 @@ namespace internal {
// TestPartResultArray contains exactly one failure that has the given
// type and contains the given substring. If that's not the case, a
// non-fatal failure will be generated.
class GTEST_API_ SingleFailureChecker {
class GTEST_API_ [[nodiscard]] SingleFailureChecker {
public:
// The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results,
@@ -37,6 +37,7 @@
#include <iosfwd>
#include <ostream>
#include <string>
#include <string_view>
#include <vector>
#include "gtest/internal/gtest-internal.h"
@@ -51,7 +52,7 @@ namespace testing {
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
//
// Don't inherit from TestPartResult as its destructor is not virtual.
class GTEST_API_ TestPartResult {
class GTEST_API_ [[nodiscard]] TestPartResult {
public:
// The possible outcomes of a test part (i.e. an assertion or an
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
@@ -65,10 +66,10 @@ class GTEST_API_ TestPartResult {
// C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestPartResult object.
TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
const char* a_message)
TestPartResult(Type a_type, std::string_view a_file_name, int a_line_number,
std::string_view a_message)
: type_(a_type),
file_name_(a_file_name == nullptr ? "" : a_file_name),
file_name_(a_file_name),
line_number_(a_line_number),
summary_(ExtractSummary(a_message)),
message_(a_message) {}
@@ -112,7 +113,7 @@ class GTEST_API_ TestPartResult {
// Gets the summary of the failure message by omitting the stack
// trace in it.
static std::string ExtractSummary(const char* message);
static std::string ExtractSummary(std::string_view message);
// The name of the source file where the test part took place, or
// "" if the source file is unknown.
@@ -131,7 +132,7 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
//
// Don't inherit from TestPartResultArray as its destructor is not
// virtual.
class GTEST_API_ TestPartResultArray {
class GTEST_API_ [[nodiscard]] TestPartResultArray {
public:
TestPartResultArray() = default;
@@ -152,7 +153,7 @@ class GTEST_API_ TestPartResultArray {
};
// This interface knows how to report a test part result.
class GTEST_API_ TestPartResultReporterInterface {
class GTEST_API_ [[nodiscard]] TestPartResultReporterInterface {
public:
virtual ~TestPartResultReporterInterface() = default;
@@ -167,7 +168,7 @@ namespace internal {
// reported, it only delegates the reporting to the former result reporter.
// The original result reporter is restored in the destructor.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
class GTEST_API_ HasNewFatalFailureHelper
class GTEST_API_ [[nodiscard]] HasNewFatalFailureHelper
: public TestPartResultReporterInterface {
public:
HasNewFatalFailureHelper();
@@ -45,18 +45,18 @@
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
class [[nodiscard]] FooTest : public testing::Test {
public:
...
typedef std::list<T> List;
using List = ::std::list<T>;
static T shared_;
T value_;
};
// Next, associate a list of types with the test suite, which will be
// repeated for each type in the list. The typedef is necessary for
// repeated for each type in the list. The using-declaration is necessary for
// the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes;
using MyTypes = ::testing::Types<char, int, unsigned int>;
TYPED_TEST_SUITE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type
@@ -123,7 +123,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... }
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
class [[nodiscard]] FooTest : public testing::Test {
...
};
@@ -157,7 +157,7 @@ REGISTER_TYPED_TEST_SUITE_P(FooTest,
// argument to the INSTANTIATE_* macro is a prefix that will be added
// to the actual test suite name. Remember to pick unique prefixes for
// different instances.
typedef testing::Types<char, int, unsigned int> MyTypes;
using MyTypes = ::testing::Types<char, int, unsigned int>;
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type
+44 -34
View File
@@ -57,6 +57,7 @@
#include <set>
#include <sstream>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
@@ -136,6 +137,10 @@ GTEST_DECLARE_int32_(repeat);
// only torn down once, for the last.
GTEST_DECLARE_bool_(recreate_environments_when_repeating);
// Together these flags determine which tests are run if the test is sharded.
GTEST_DECLARE_int32_(shard_index);
GTEST_DECLARE_int32_(total_shards);
// This flag controls whether Google Test includes Google Test internal
// stack frames in failure stack traces.
GTEST_DECLARE_bool_(show_internal_stack_frames);
@@ -193,7 +198,7 @@ std::set<std::string>* GetIgnoredParameterizedTestSuites();
// A base class that prevents subclasses from being copyable.
// We do this instead of using '= delete' so as to avoid triggering warnings
// inside user code regarding any of our declarations.
class GTestNonCopyable {
class [[nodiscard]] GTestNonCopyable {
public:
GTestNonCopyable() = default;
GTestNonCopyable(const GTestNonCopyable&) = delete;
@@ -206,15 +211,15 @@ class GTestNonCopyable {
// The friend relationship of some of these classes is cyclic.
// If we don't forward declare them the compiler might confuse the classes
// in friendship clauses with same named classes on the scope.
class Test;
class TestSuite;
class [[nodiscard]] Test;
class [[nodiscard]] TestSuite;
// Old API is still available but deprecated
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
using TestCase = TestSuite;
#endif
class TestInfo;
class UnitTest;
class [[nodiscard]] TestInfo;
class [[nodiscard]] UnitTest;
// The abstract class that all tests inherit from.
//
@@ -239,7 +244,7 @@ class UnitTest;
// TEST_F(FooTest, Baz) { ... }
//
// Test is not copyable.
class GTEST_API_ Test {
class GTEST_API_ [[nodiscard]] Test {
public:
friend class TestInfo;
@@ -366,7 +371,7 @@ typedef internal::TimeInMillis TimeInMillis;
// output as a key/value string pair.
//
// Don't inherit from TestProperty as its destructor is not virtual.
class TestProperty {
class [[nodiscard]] TestProperty {
public:
// C'tor. TestProperty does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
@@ -396,7 +401,7 @@ class TestProperty {
// the Test.
//
// TestResult is not copyable.
class GTEST_API_ TestResult {
class GTEST_API_ [[nodiscard]] TestResult {
public:
// Creates an empty TestResult.
TestResult();
@@ -530,7 +535,7 @@ class GTEST_API_ TestResult {
// The constructor of TestInfo registers itself with the UnitTest
// singleton such that the RUN_ALL_TESTS() macro knows which tests to
// run.
class GTEST_API_ TestInfo {
class GTEST_API_ [[nodiscard]] TestInfo {
public:
// Destructs a TestInfo object. This function is not virtual, so
// don't inherit from TestInfo.
@@ -669,7 +674,7 @@ class GTEST_API_ TestInfo {
// A test suite, which consists of a vector of TestInfos.
//
// TestSuite is not copyable.
class GTEST_API_ TestSuite {
class GTEST_API_ [[nodiscard]] TestSuite {
public:
// Creates a TestSuite with the given name.
//
@@ -890,7 +895,7 @@ class GTEST_API_ TestSuite {
// available.
// 2. You cannot use ASSERT_* directly in a constructor or
// destructor.
class Environment {
class [[nodiscard]] Environment {
public:
// The d'tor is virtual as we need to subclass Environment.
virtual ~Environment() = default;
@@ -911,7 +916,7 @@ class Environment {
#if GTEST_HAS_EXCEPTIONS
// Exception which can be thrown from TestEventListener::OnTestPartResult.
class GTEST_API_ AssertionException
class GTEST_API_ [[nodiscard]] AssertionException
: public internal::GoogleTestFailureException {
public:
explicit AssertionException(const TestPartResult& result)
@@ -922,7 +927,7 @@ class GTEST_API_ AssertionException
// The interface for tracing execution of tests. The methods are organized in
// the order the corresponding events are fired.
class TestEventListener {
class [[nodiscard]] TestEventListener {
public:
virtual ~TestEventListener() = default;
@@ -989,7 +994,7 @@ class TestEventListener {
// the methods they override will not be caught during the build. For
// comments about each method please see the definition of TestEventListener
// above.
class EmptyTestEventListener : public TestEventListener {
class [[nodiscard]] EmptyTestEventListener : public TestEventListener {
public:
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
void OnTestIterationStart(const UnitTest& /*unit_test*/,
@@ -1019,7 +1024,7 @@ class EmptyTestEventListener : public TestEventListener {
};
// TestEventListeners lets users add listeners to track events in Google Test.
class GTEST_API_ TestEventListeners {
class GTEST_API_ [[nodiscard]] TestEventListeners {
public:
TestEventListeners();
~TestEventListeners();
@@ -1110,7 +1115,7 @@ class GTEST_API_ TestEventListeners {
//
// This class is thread-safe as long as the methods are called
// according to their specification.
class GTEST_API_ UnitTest {
class GTEST_API_ [[nodiscard]] UnitTest {
public:
// Gets the singleton UnitTest object. The first time this method
// is called, a UnitTest object is constructed and returned.
@@ -1246,7 +1251,7 @@ class GTEST_API_ UnitTest {
// eventually call this to report their results. The user code
// should use the assertion macros instead of calling this directly.
void AddTestPartResult(TestPartResult::Type result_type,
const char* file_name, int line_number,
std::string_view file_name, int line_number,
const std::string& message,
const std::string& os_stack_trace)
GTEST_LOCK_EXCLUDED_(mutex_);
@@ -1398,7 +1403,7 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
}
class EqHelper {
class [[nodiscard]] EqHelper {
public:
// This templatized version is for the general case.
template <
@@ -1610,18 +1615,23 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
double val1, double val2,
double abs_error);
using GoogleTest_NotSupported_OnFunctionReturningNonVoid = void;
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// A class that enables one to stream messages to assertion macros
class GTEST_API_ AssertHelper {
class GTEST_API_ [[nodiscard]] AssertHelper {
public:
// Constructor.
AssertHelper(TestPartResult::Type type, const char* file, int line,
const char* message);
AssertHelper(TestPartResult::Type type, std::string_view file, int line,
std::string_view message);
~AssertHelper();
// Message assignment is a semantic trick to enable assertion
// streaming; see the GTEST_MESSAGE_ macro below.
void operator=(const Message& message) const;
GoogleTest_NotSupported_OnFunctionReturningNonVoid operator=(
const Message& message) const;
private:
// We put our data in a struct so that the size of the AssertHelper class can
@@ -1629,12 +1639,12 @@ class GTEST_API_ AssertHelper {
// re-using stack space even for temporary variables, so every EXPECT_EQ
// reserves stack space for another AssertHelper.
struct AssertHelperData {
AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,
const char* msg)
AssertHelperData(TestPartResult::Type t, std::string_view srcfile,
int line_num, std::string_view msg)
: type(t), file(srcfile), line(line_num), message(msg) {}
TestPartResult::Type const type;
const char* const file;
const std::string_view file;
int const line;
std::string const message;
@@ -1686,14 +1696,14 @@ class GTEST_API_ AssertHelper {
// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
template <typename T>
class WithParamInterface {
class [[nodiscard]] WithParamInterface {
public:
typedef T ParamType;
virtual ~WithParamInterface() = default;
// The current parameter value. Is also available in the test fixture's
// constructor.
static const ParamType& GetParam() {
[[nodiscard]] static const ParamType& GetParam() {
GTEST_CHECK_(parameter_ != nullptr)
<< "GetParam() can only be called inside a value-parameterized test "
<< "-- did you intend to write TEST_P instead of TEST_F?";
@@ -1720,7 +1730,8 @@ const T* WithParamInterface<T>::parameter_ = nullptr;
// WithParamInterface, and can just inherit from ::testing::TestWithParam.
template <typename T>
class TestWithParam : public Test, public WithParamInterface<T> {};
class [[nodiscard]] TestWithParam : public Test,
public WithParamInterface<T> {};
// Macros for indicating success/failure in test code.
@@ -1807,14 +1818,13 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
#define GTEST_EXPECT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_NONFATAL_FAILURE_)
#define GTEST_EXPECT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
#define GTEST_EXPECT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, true, false, \
GTEST_NONFATAL_FAILURE_)
#define GTEST_ASSERT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)
#define GTEST_ASSERT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_FATAL_FAILURE_)
#define GTEST_ASSERT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, true, false, GTEST_FATAL_FAILURE_)
// Define these macros to 1 to omit the definition of the corresponding
// EXPECT or ASSERT, which clashes with some users' own code.
@@ -2068,7 +2078,7 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
// Example:
// testing::ScopedTrace trace("file.cc", 123, "message");
//
class GTEST_API_ ScopedTrace {
class GTEST_API_ [[nodiscard]] ScopedTrace {
public:
// The c'tor pushes the given source file location and message onto
// a trace stack maintained by Google Test.
@@ -2153,7 +2163,7 @@ class GTEST_API_ 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;
}
@@ -2299,7 +2309,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:
@@ -43,6 +43,7 @@
#include <memory>
#include <string>
#include <string_view>
#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h"
@@ -63,6 +64,10 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
std::string_view regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
@@ -96,7 +101,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// by wait(2)
// exit code: The integer code passed to exit(3), _Exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
class GTEST_API_ [[nodiscard]] DeathTest {
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
@@ -172,7 +177,7 @@ class GTEST_API_ DeathTest {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
class [[nodiscard]] DeathTestFactory {
public:
virtual ~DeathTestFactory() = default;
virtual bool Create(const char* statement,
@@ -181,7 +186,7 @@ class DeathTestFactory {
};
// A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory {
class [[nodiscard]] DefaultDeathTestFactory : public DeathTestFactory {
public:
bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test) override;
@@ -229,7 +234,8 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != nullptr) { \
std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
const std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr( \
gtest_dt); \
switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
@@ -256,19 +262,19 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// must accept a streamed message even though the message is never printed.
// The regex object is not evaluated, but it is used to prevent "unused"
// warnings and to avoid an expression that doesn't compile in debug mode.
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else if (!::testing::internal::AlwaysTrue()) { \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
} else \
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else if (!::testing::internal::AlwaysTrue()) { \
(void)::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
} else \
::testing::Message()
// A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
class [[nodiscard]] InternalRunDeathTestFlag {
public:
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
int a_write_fd)
@@ -67,7 +67,7 @@ namespace internal {
// Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc.
class GTEST_API_ FilePath {
class GTEST_API_ [[nodiscard]] FilePath {
public:
FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
@@ -95,7 +95,13 @@
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
namespace proto2 {
class MessageLite;
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 {
@@ -115,15 +121,15 @@ template <typename T>
namespace internal {
struct TraceInfo; // Information about a trace point.
class TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest
class [[nodiscard]] TestInfoImpl; // Opaque implementation of TestInfo
class [[nodiscard]] UnitTestImpl; // Opaque implementation of UnitTest
// The text used in failure messages to indicate the start of the
// stack trace.
GTEST_API_ extern const char kStackTraceMarker[];
// An IgnoredValue object can be implicitly constructed from ANY value.
class IgnoredValue {
class [[nodiscard]] IgnoredValue {
struct Sink {};
public:
@@ -155,7 +161,8 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
// errors presumably detectable only at run time. Since
// std::runtime_error inherits from std::exception, many testing
// frameworks know how to extract and print the message inside it.
class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
class GTEST_API_ [[nodiscard]] GoogleTestFailureException
: public ::std::runtime_error {
public:
explicit GoogleTestFailureException(const TestPartResult& failure);
};
@@ -242,7 +249,7 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage(
//
// RawType: the raw floating-point type (either float or double)
template <typename RawType>
class FloatingPoint {
class [[nodiscard]] FloatingPoint {
public:
// Defines the unsigned integer type that has the same size as the
// floating point number.
@@ -392,7 +399,7 @@ typedef FloatingPoint<double> Double;
typedef const void* TypeId;
template <typename T>
class TypeIdHelper {
class [[nodiscard]] TypeIdHelper {
public:
// dummy_ must not have a const type. Otherwise an overly eager
// compiler (e.g. MSVC 7.1 & 8.0) may try to merge
@@ -424,7 +431,7 @@ GTEST_API_ TypeId GetTestTypeId();
// Defines the abstract factory interface that creates instances
// of a Test object.
class TestFactoryBase {
class [[nodiscard]] TestFactoryBase {
public:
virtual ~TestFactoryBase() = default;
@@ -443,7 +450,7 @@ class TestFactoryBase {
// This class provides implementation of TestFactoryBase interface.
// It is used in TEST and TEST_F macros.
template <class TestClass>
class TestFactoryImpl : public TestFactoryBase {
class [[nodiscard]] TestFactoryImpl : public TestFactoryBase {
public:
Test* CreateTest() override { return new TestClass; }
};
@@ -570,7 +577,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* 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.
class GTEST_API_ TypedTestSuitePState {
class GTEST_API_ [[nodiscard]] TypedTestSuitePState {
public:
TypedTestSuitePState() : registered_(false) {}
@@ -685,7 +692,7 @@ std::vector<std::string> GenerateNames() {
// Implementation note: The GTEST_TEMPLATE_ macro declares a template
// template parameter. It's defined in gtest-type-util.h.
template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
class TypeParameterizedTest {
class [[nodiscard]] TypeParameterizedTest {
public:
// 'index' is the index of the test in the type list 'Types'
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
@@ -723,7 +730,7 @@ class TypeParameterizedTest {
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
class [[nodiscard]] TypeParameterizedTest<Fixture, TestSel, internal::None> {
public:
static bool Register(const char* /*prefix*/, CodeLocation,
const char* /*case_name*/, const char* /*test_names*/,
@@ -744,7 +751,7 @@ GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
// Test. The return value is insignificant - we just need to return
// something such that we can call this function in a namespace scope.
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
class TypeParameterizedTestSuite {
class [[nodiscard]] TypeParameterizedTestSuite {
public:
static bool Register(const char* prefix, CodeLocation code_location,
const TypedTestSuitePState* state, const char* case_name,
@@ -782,7 +789,7 @@ class TypeParameterizedTestSuite {
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
class [[nodiscard]] TypeParameterizedTestSuite<Fixture, internal::None, Types> {
public:
static bool Register(const char* /*prefix*/, const CodeLocation&,
const TypedTestSuitePState* /*state*/,
@@ -838,7 +845,7 @@ struct TrueWithString {
// 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,
// but it's good enough for our purposes.
class GTEST_API_ Random {
class GTEST_API_ [[nodiscard]] Random {
public:
static const uint32_t kMaxRange = 1u << 31;
@@ -864,7 +871,7 @@ class GTEST_API_ Random {
// that's true if and only if T has methods DebugString() and ShortDebugString()
// that return std::string.
template <typename T>
class HasDebugStringAndShortDebugString {
class [[nodiscard]] HasDebugStringAndShortDebugString {
private:
template <typename C>
static auto CheckDebugString(C*) -> typename std::is_same<
@@ -1064,7 +1071,7 @@ struct RelationToSourceCopy {};
// this requirement. Element can be an array type itself (hence
// multi-dimensional arrays are supported).
template <typename Element>
class NativeArray {
class [[nodiscard]] NativeArray {
public:
// STL-style container typedefs.
typedef Element value_type;
@@ -1150,7 +1157,7 @@ struct ElemFromList {
struct FlatTupleConstructTag {};
template <typename... T>
class FlatTuple;
class [[nodiscard]] FlatTuple;
template <typename Derived, size_t I>
struct FlatTupleElemBase;
@@ -1209,7 +1216,7 @@ struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
// std::make_index_sequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)).
template <typename... T>
class FlatTuple
class [[nodiscard]] FlatTuple
: private FlatTupleBase<FlatTuple<T...>,
std::make_index_sequence<sizeof...(T)>> {
using Indices =
@@ -1317,7 +1324,7 @@ struct tuple_size<testing::internal::FlatTuple<Ts...>>
namespace testing {
namespace internal {
class NeverThrown {
class [[nodiscard]] NeverThrown {
public:
const char* what() const noexcept {
return "this exception should never be thrown";
@@ -1444,15 +1451,14 @@ class NeverThrown {
// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual
// representation of expression as it was passed into the EXPECT_TRUE.
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar_ = \
::testing::AssertionResult(expression)) \
; \
else \
fail(::testing::internal::GetBoolAssertionFailureMessage( \
gtest_ar_, text, #actual, #expected) \
.c_str())
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::internal::AssertionResultExpectation gtest_are_ = { \
::testing::AssertionResult(expression), expected}) \
; \
else /* NOLINT */ \
fail(::testing::internal::GetBoolAssertionFailureMessage( \
gtest_are_.assertion_result, text, #actual, #expected))
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
@@ -90,14 +90,14 @@ GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
const CodeLocation& code_location);
template <typename>
class ParamGeneratorInterface;
class [[nodiscard]] ParamGeneratorInterface;
template <typename>
class ParamGenerator;
class [[nodiscard]] ParamGenerator;
// Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>.
template <typename T>
class ParamIteratorInterface {
class [[nodiscard]] ParamIteratorInterface {
public:
virtual ~ParamIteratorInterface() = default;
// A pointer to the base generator instance.
@@ -127,7 +127,7 @@ class ParamIteratorInterface {
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
// and implements the const forward iterator concept.
template <typename T>
class ParamIterator {
class [[nodiscard]] ParamIterator {
public:
typedef T value_type;
typedef const T& reference;
@@ -169,7 +169,7 @@ class ParamIterator {
// ParamGeneratorInterface<T> is the binary interface to access generators
// defined in other translation units.
template <typename T>
class ParamGeneratorInterface {
class [[nodiscard]] ParamGeneratorInterface {
public:
typedef T ParamType;
@@ -186,7 +186,7 @@ class ParamGeneratorInterface {
// ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable.
template <typename T>
class ParamGenerator {
class [[nodiscard]] ParamGenerator {
public:
typedef ParamIterator<T> iterator;
@@ -210,7 +210,7 @@ class ParamGenerator {
// operator<().
// This class is used in the Range() function.
template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> {
class [[nodiscard]] RangeGenerator : public ParamGeneratorInterface<T> {
public:
RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin),
@@ -296,7 +296,8 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
// since the source can be located on the stack, and the generator
// is likely to persist beyond that stack frame.
template <typename T>
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
class [[nodiscard]] ValuesInIteratorRangeGenerator
: public ParamGeneratorInterface<T> {
public:
template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
@@ -396,7 +397,7 @@ void TestNotEmpty(const T&) {}
// Stores a parameter value and later creates tests parameterized with that
// value.
template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase {
class [[nodiscard]] ParameterizedTestFactory : public TestFactoryBase {
public:
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter)
@@ -418,7 +419,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
// TestMetaFactoryBase is a base class for meta-factories that create
// test factories for passing into MakeAndRegisterTestInfo function.
template <class ParamType>
class TestMetaFactoryBase {
class [[nodiscard]] TestMetaFactoryBase {
public:
virtual ~TestMetaFactoryBase() = default;
@@ -434,7 +435,7 @@ class TestMetaFactoryBase {
// it for each Test/Parameter value combination. Thus it needs meta factory
// creator class.
template <class TestSuite>
class TestMetaFactory
class [[nodiscard]] TestMetaFactory
: public TestMetaFactoryBase<typename TestSuite::ParamType> {
public:
using ParamType = typename TestSuite::ParamType;
@@ -460,7 +461,7 @@ class TestMetaFactory
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
// a collection of pointers to the ParameterizedTestSuiteInfo objects
// and calls RegisterTests() on each of them when asked.
class ParameterizedTestSuiteInfoBase {
class [[nodiscard]] ParameterizedTestSuiteInfoBase {
public:
virtual ~ParameterizedTestSuiteInfoBase() = default;
@@ -503,7 +504,8 @@ GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
// test suite. It registers tests with all values generated by all
// generators when asked.
template <class TestSuite>
class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
class [[nodiscard]] ParameterizedTestSuiteInfo
: public ParameterizedTestSuiteInfoBase {
public:
// ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and
@@ -688,7 +690,7 @@ using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
// ParameterizedTestSuiteInfo descriptors.
class ParameterizedTestSuiteRegistry {
class [[nodiscard]] ParameterizedTestSuiteRegistry {
public:
ParameterizedTestSuiteRegistry() = default;
~ParameterizedTestSuiteRegistry() {
@@ -762,7 +764,7 @@ class ParameterizedTestSuiteRegistry {
// Keep track of what type-parameterized test suite are defined and
// where as well as which are intatiated. This allows susequently
// identifying suits that are defined but never used.
class TypeParameterizedTestSuiteRegistry {
class [[nodiscard]] TypeParameterizedTestSuiteRegistry {
public:
// Add a suite definition
void RegisterTestSuite(const char* test_suite_name,
@@ -801,7 +803,7 @@ namespace internal {
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
template <typename... Ts>
class ValueArray {
class [[nodiscard]] ValueArray {
public:
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
@@ -822,7 +824,7 @@ class ValueArray {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
template <typename... T>
class CartesianProductGenerator
class [[nodiscard]] CartesianProductGenerator
: public ParamGeneratorInterface<::std::tuple<T...>> {
public:
typedef ::std::tuple<T...> ParamType;
@@ -939,7 +941,7 @@ class CartesianProductGenerator
};
template <class... Gen>
class CartesianProductHolder {
class [[nodiscard]] CartesianProductHolder {
public:
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
template <typename... T>
@@ -953,7 +955,8 @@ class CartesianProductHolder {
};
template <typename From, typename To, typename Func>
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
class [[nodiscard]] ParamGeneratorConverter
: public ParamGeneratorInterface<To> {
public:
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
: generator_(std::move(gen)), converter_(std::move(converter)) {}
@@ -1023,7 +1026,7 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
template <class GeneratedT,
typename StdFunction =
std::function<const GeneratedT&(const GeneratedT&)>>
class ParamConverterGenerator {
class [[nodiscard]] ParamConverterGenerator {
public:
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
: generator_(std::move(g)), converter_(Identity) {}
@@ -119,6 +119,8 @@
#define GTEST_OS_NXP_QN9090 1
#elif defined(NRF52)
#define GTEST_OS_NRF52 1
#elif defined(__EMSCRIPTEN__)
#define GTEST_OS_EMSCRIPTEN 1
#endif // __CYGWIN__
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
@@ -198,21 +198,8 @@
// suppressed (constant conditional).
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
// is suppressed.
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
// UniversalPrinter<absl::any> specializations.
// Always defined to 0 or 1.
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>
// or
// UniversalPrinter<absl::optional>
// specializations. Always defined to 0 or 1.
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
// specializations. Always defined to 0 or 1
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
// Matcher<absl::string_view>
// specializations. Always defined to 0 or 1.
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
// UniversalPrinter<absl::variant>
// specializations. Always defined to 0 or 1.
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.
// GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.
// GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.
@@ -306,9 +293,10 @@
#include <limits>
#include <locale>
#include <memory>
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
#include <ostream>
#include <string>
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
#include <string_view>
#include <tuple>
#include <type_traits>
#include <vector>
@@ -376,18 +364,24 @@
#define GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
// Clang on Windows does not understand MSVC's pragma warning.
// We need clang-specific way to disable function deprecation warning.
#ifdef __clang__
#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
// Pragmas to disable function deprecation warnings.
#if defined(__clang__)
#define GTEST_DISABLE_DEPRECATED_PUSH_() \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"")
#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma("clang diagnostic pop")
#define GTEST_DISABLE_DEPRECATED_POP_() _Pragma("clang diagnostic pop")
#elif defined(__GNUC__)
#define GTEST_DISABLE_DEPRECATED_PUSH_() \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define GTEST_DISABLE_DEPRECATED_POP_() _Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
#define GTEST_DISABLE_DEPRECATED_PUSH_() GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
#define GTEST_DISABLE_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
#else
#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
#define GTEST_DISABLE_DEPRECATED_PUSH_()
#define GTEST_DISABLE_DEPRECATED_POP_()
#endif
// Brings in definitions for functions used in the testing::internal::posix
@@ -606,7 +600,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \
defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS))
defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS) || \
(defined(GTEST_OS_EMSCRIPTEN) && defined(__EMSCRIPTEN_PTHREADS__)))
#define GTEST_HAS_PTHREAD 1
#else
#define GTEST_HAS_PTHREAD 0
@@ -677,12 +672,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))
// Death tests require a file system to work properly.
#if GTEST_HAS_FILE_SYSTEM
#define GTEST_HAS_DEATH_TEST 1
#endif // GTEST_HAS_FILE_SYSTEM
#endif
// Determines whether the Premature Exit file can be created.
// Created by default when Death tests are supported, but other platforms can
// use the Premature exit file without Death test support (e.g. for detecting
// crashes).
#if GTEST_HAS_DEATH_TEST || \
(defined(GTEST_OS_EMSCRIPTEN) && GTEST_HAS_FILE_SYSTEM)
#define GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE 1
#endif
// Determines whether to support type-driven tests.
// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
@@ -835,11 +840,13 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_API_
#ifdef _MSC_VER
#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllimport)
#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
#if defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllexport)
#elif defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllimport)
#endif
#elif GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(gnu::visibility)
#define GTEST_API_ [[gnu::visibility("default")]]
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
#define GTEST_API_ __attribute__((visibility("default")))
#endif // _MSC_VER
@@ -930,7 +937,7 @@ namespace internal {
// A secret type that Google Test users don't know about. It has no
// accessible constructors on purpose. Therefore it's impossible to create a
// Secret object, which is what we want.
class Secret {
class [[nodiscard]] Secret {
Secret(const Secret&) = delete;
};
@@ -943,21 +950,21 @@ GTEST_API_ bool IsTrue(bool condition);
#ifdef GTEST_USES_RE2
// This is almost `using RE = ::RE2`, except it is copy-constructible, and it
// needs to disambiguate the `std::string`, `absl::string_view`, and `const
// needs to disambiguate the `std::string`, `std::string_view`, and `const
// char*` constructors.
class GTEST_API_ RE {
class GTEST_API_ [[nodiscard]] RE {
public:
RE(absl::string_view regex) : regex_(regex) {} // NOLINT
RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT
RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT
RE(std::string_view regex) : regex_(regex) {} // NOLINT
RE(const char* regex) : RE(std::string_view(regex)) {} // NOLINT
RE(const std::string& regex) : RE(std::string_view(regex)) {} // NOLINT
RE(const RE& other) : RE(other.pattern()) {}
const std::string& pattern() const { return regex_.pattern(); }
static bool FullMatch(absl::string_view str, const RE& re) {
static bool FullMatch(std::string_view str, const RE& re) {
return RE2::FullMatch(str, re.regex_);
}
static bool PartialMatch(absl::string_view str, const RE& re) {
static bool PartialMatch(std::string_view str, const RE& re) {
return RE2::PartialMatch(str, re.regex_);
}
@@ -971,7 +978,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
// Regular Expression syntax.
class GTEST_API_ RE {
class GTEST_API_ [[nodiscard]] RE {
public:
// A copy constructor is required by the Standard to initialize object
// references from r-values.
@@ -1040,7 +1047,7 @@ enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };
// Formats log entry severity, provides a stream object for streaming the
// log message, and terminates the message with a newline when going out of
// scope.
class GTEST_API_ GTestLog {
class GTEST_API_ [[nodiscard]] GTestLog {
public:
GTestLog(GTestLogSeverity severity, const char* file, int line);
@@ -1203,7 +1210,7 @@ void ClearInjectableArgvs();
#ifdef GTEST_OS_WINDOWS
// Provides leak-safe Windows kernel handle ownership.
// Used in death tests and in threading support.
class GTEST_API_ AutoHandle {
class GTEST_API_ [[nodiscard]] AutoHandle {
public:
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
// avoid including <windows.h> in this header file. Including <windows.h> is
@@ -1237,9 +1244,6 @@ class GTEST_API_ AutoHandle {
// Nothing to do here.
#else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
// Allows a controller thread to pause execution of newly created
// threads until notified. Instances of this class must be created
// and destroyed in the controller thread.
@@ -1247,7 +1251,40 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
// This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly.
// TODO(b/203539622): Replace unconditionally with absl::Notification.
class GTEST_API_ Notification {
#ifdef GTEST_OS_WINDOWS_MINGW
// GCC version < 13 with the win32 thread model does not provide std::mutex and
// std::condition_variable in the <mutex> and <condition_variable> headers. So
// we implement the Notification class using a Windows manual-reset event. See
// https://gcc.gnu.org/gcc-13/changes.html#windows.
class GTEST_API_ [[nodiscard]] Notification {
public:
Notification();
Notification(const Notification&) = delete;
Notification& operator=(const Notification&) = delete;
~Notification();
// Notifies all threads created with this notification to start. Must
// be called from the controller thread.
void Notify();
// Blocks until the controller thread notifies. Must be called from a test
// thread.
void WaitForNotification();
private:
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
// avoid including <windows.h> in this header file. Including <windows.h> is
// undesirable because it defines a lot of symbols and macros that tend to
// conflict with client code. This assumption is verified by
// WindowsTypesTest.HANDLEIsVoidStar.
typedef void* Handle;
Handle event_;
};
#else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
class GTEST_API_ [[nodiscard]] Notification {
public:
Notification() : notified_(false) {}
Notification(const Notification&) = delete;
@@ -1274,6 +1311,7 @@ class GTEST_API_ Notification {
bool notified_;
};
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_OS_WINDOWS_MINGW
#endif // GTEST_HAS_NOTIFICATION_
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
@@ -1286,7 +1324,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// in order to call its Run(). Introducing ThreadWithParamBase as a
// non-templated base class for ThreadWithParam allows us to bypass this
// problem.
class ThreadWithParamBase {
class [[nodiscard]] ThreadWithParamBase {
public:
virtual ~ThreadWithParamBase() = default;
virtual void Run() = 0;
@@ -1316,7 +1354,7 @@ extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
// These classes are only for testing Google Test's own constructs. Do
// not use them in user tests, either directly or indirectly.
template <typename T>
class ThreadWithParam : public ThreadWithParamBase {
class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
public:
typedef void UserThreadFunc(T);
@@ -1382,7 +1420,7 @@ class ThreadWithParam : public ThreadWithParamBase {
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
//
// (A non-static Mutex is defined/declared in the usual way).
class GTEST_API_ Mutex {
class GTEST_API_ [[nodiscard]] Mutex {
public:
enum MutexType { kStatic = 0, kDynamic = 1 };
// We rely on kStaticMutex being 0 as it is to what the linker initializes
@@ -1398,9 +1436,9 @@ class GTEST_API_ Mutex {
Mutex();
~Mutex();
void Lock();
void lock();
void Unlock();
void unlock();
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability.
@@ -1435,14 +1473,13 @@ class GTEST_API_ Mutex {
// platforms. That macro is used as a defensive measure to prevent against
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
// "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock {
class [[nodiscard]] GTestMutexLock {
public:
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
~GTestMutexLock() { mutex_->Unlock(); }
explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
~GTestMutexLock() { mutex_.unlock(); }
private:
Mutex* const mutex_;
Mutex& mutex_;
GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
@@ -1452,14 +1489,14 @@ typedef GTestMutexLock MutexLock;
// Base class for ValueHolder<T>. Allows a caller to hold and delete a value
// without knowing its type.
class ThreadLocalValueHolderBase {
class [[nodiscard]] ThreadLocalValueHolderBase {
public:
virtual ~ThreadLocalValueHolderBase() {}
virtual ~ThreadLocalValueHolderBase() = default;
};
// Provides a way for a thread to send notifications to a ThreadLocal
// regardless of its parameter type.
class ThreadLocalBase {
class [[nodiscard]] ThreadLocalBase {
public:
// Creates a new ValueHolder<T> object holding a default value passed to
// this ThreadLocal<T>'s constructor and returns it. It is the caller's
@@ -1468,8 +1505,8 @@ class ThreadLocalBase {
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
protected:
ThreadLocalBase() {}
virtual ~ThreadLocalBase() {}
ThreadLocalBase() = default;
virtual ~ThreadLocalBase() = default;
private:
ThreadLocalBase(const ThreadLocalBase&) = delete;
@@ -1479,7 +1516,7 @@ class ThreadLocalBase {
// Maps a thread to a set of ThreadLocals that have values instantiated on that
// thread and notifies them when the thread exits. A ThreadLocal instance is
// expected to persist until all threads it has values on have terminated.
class GTEST_API_ ThreadLocalRegistry {
class GTEST_API_ [[nodiscard]] ThreadLocalRegistry {
public:
// Registers thread_local_instance as having value on the current thread.
// Returns a value that can be used to identify the thread from other threads.
@@ -1491,14 +1528,14 @@ class GTEST_API_ ThreadLocalRegistry {
const ThreadLocalBase* thread_local_instance);
};
class GTEST_API_ ThreadWithParamBase {
class GTEST_API_ [[nodiscard]] ThreadWithParamBase {
public:
void Join();
protected:
class Runnable {
public:
virtual ~Runnable() {}
virtual ~Runnable() = default;
virtual void Run() = 0;
};
@@ -1511,20 +1548,20 @@ class GTEST_API_ ThreadWithParamBase {
// Helper class for testing Google Test's multi-threading constructs.
template <typename T>
class ThreadWithParam : public ThreadWithParamBase {
class [[nodiscard]] ThreadWithParam : public ThreadWithParamBase {
public:
typedef void UserThreadFunc(T);
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
virtual ~ThreadWithParam() {}
~ThreadWithParam() override = default;
private:
class RunnableImpl : public Runnable {
public:
RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
virtual ~RunnableImpl() {}
virtual void Run() { func_(param_); }
~RunnableImpl() override = default;
void Run() override { func_(param_); }
private:
UserThreadFunc* const func_;
@@ -1566,7 +1603,7 @@ class ThreadWithParam : public ThreadWithParamBase {
// object managed by Google Test will be leaked as long as all threads
// using Google Test have exited when main() returns.
template <typename T>
class ThreadLocal : public ThreadLocalBase {
class [[nodiscard]] ThreadLocal : public ThreadLocalBase {
public:
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
explicit ThreadLocal(const T& value)
@@ -1607,8 +1644,8 @@ class ThreadLocal : public ThreadLocalBase {
class ValueHolderFactory {
public:
ValueHolderFactory() {}
virtual ~ValueHolderFactory() {}
ValueHolderFactory() = default;
virtual ~ValueHolderFactory() = default;
virtual ValueHolder* MakeNewHolder() const = 0;
private:
@@ -1618,7 +1655,7 @@ class ThreadLocal : public ThreadLocalBase {
class DefaultValueHolderFactory : public ValueHolderFactory {
public:
DefaultValueHolderFactory() {}
DefaultValueHolderFactory() = default;
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private:
@@ -1651,17 +1688,17 @@ class ThreadLocal : public ThreadLocalBase {
#elif GTEST_HAS_PTHREAD
// MutexBase and Mutex implement mutex on pthreads-based platforms.
class MutexBase {
class [[nodiscard]] MutexBase {
public:
// Acquires this mutex.
void Lock() {
void lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self();
has_owner_ = true;
}
// Releases this mutex.
void Unlock() {
void unlock() {
// Since the lock is being released the owner_ field should no longer be
// considered valid. We don't protect writing to has_owner_ here, as it's
// the caller's responsibility to ensure that the current thread holds the
@@ -1709,7 +1746,7 @@ class MutexBase {
// The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise.
class Mutex : public MutexBase {
class [[nodiscard]] Mutex : public MutexBase {
public:
Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
@@ -1727,14 +1764,13 @@ class Mutex : public MutexBase {
// platforms. That macro is used as a defensive measure to prevent against
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
// "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock {
class [[nodiscard]] GTestMutexLock {
public:
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
~GTestMutexLock() { mutex_->Unlock(); }
explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
~GTestMutexLock() { mutex_.unlock(); }
private:
MutexBase* const mutex_;
MutexBase& mutex_;
GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
@@ -1748,7 +1784,7 @@ typedef GTestMutexLock MutexLock;
// C-linkage. Therefore it cannot be templatized to access
// ThreadLocal<T>. Hence the need for class
// ThreadLocalValueHolderBase.
class GTEST_API_ ThreadLocalValueHolderBase {
class GTEST_API_ [[nodiscard]] ThreadLocalValueHolderBase {
public:
virtual ~ThreadLocalValueHolderBase() = default;
};
@@ -1761,7 +1797,7 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
// Implements thread-local storage on pthreads-based systems.
template <typename T>
class GTEST_API_ ThreadLocal {
class GTEST_API_ [[nodiscard]] ThreadLocal {
public:
ThreadLocal()
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
@@ -1874,11 +1910,11 @@ class GTEST_API_ ThreadLocal {
// mutex is not supported - using Google Test in multiple threads is not
// supported on such platforms.
class Mutex {
class [[nodiscard]] Mutex {
public:
Mutex() {}
void Lock() {}
void Unlock() {}
void lock() {}
void unlock() {}
void AssertHeld() const {}
};
@@ -1892,15 +1928,15 @@ class Mutex {
// platforms. That macro is used as a defensive measure to prevent against
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
// "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock {
class [[nodiscard]] GTestMutexLock {
public:
explicit GTestMutexLock(Mutex*) {} // NOLINT
explicit GTestMutexLock(Mutex&) {} // NOLINT
};
typedef GTestMutexLock MutexLock;
template <typename T>
class GTEST_API_ ThreadLocal {
class GTEST_API_ [[nodiscard]] ThreadLocal {
public:
ThreadLocal() : value_() {}
explicit ThreadLocal(const T& value) : value_(value) {}
@@ -2090,7 +2126,7 @@ inline int IsATTY(int fd) {
// Functions deprecated by MSVC 8.0.
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
GTEST_DISABLE_DEPRECATED_PUSH_()
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
// StrError() aren't needed on Windows CE at this time and thus not
@@ -2152,7 +2188,7 @@ inline const char* GetEnv(const char* name) {
#endif
}
GTEST_DISABLE_MSC_DEPRECATED_POP_()
GTEST_DISABLE_DEPRECATED_POP_()
#ifdef GTEST_OS_WINDOWS_MOBILE
// Windows CE has no C library. The abort() function is used in
@@ -2208,7 +2244,7 @@ constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();
// needs. Other types can be easily added in the future if need
// arises.
template <size_t size>
class TypeWithSize {
class [[nodiscard]] TypeWithSize {
public:
// This prevents the user from using TypeWithSize<N> with incorrect
// values of N.
@@ -2217,7 +2253,7 @@ class TypeWithSize {
// The specialization for size 4.
template <>
class TypeWithSize<4> {
class [[nodiscard]] TypeWithSize<4> {
public:
using Int = std::int32_t;
using UInt = std::uint32_t;
@@ -2225,7 +2261,7 @@ class TypeWithSize<4> {
// The specialization for size 8.
template <>
class TypeWithSize<8> {
class [[nodiscard]] TypeWithSize<8> {
public:
using Int = std::int64_t;
using UInt = std::uint64_t;
@@ -2255,11 +2291,11 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
// Macros for declaring flags.
#define GTEST_DECLARE_bool_(name) \
ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
GTEST_API_ ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
#define GTEST_DECLARE_int32_(name) \
ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
#define GTEST_DECLARE_string_(name) \
ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
GTEST_API_ ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
#define GTEST_FLAG_SAVER_ ::absl::FlagSaver
@@ -2273,22 +2309,29 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_DECLARE_bool_(name); \
namespace testing { \
GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_DECLARE_int32_(name); \
namespace testing { \
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_DECLARE_string_(name); \
namespace testing { \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
// Macros for declaring flags.
//
// We also need to declare the flag in the public namespace to avoid triggering
// -Wmissing-variable-declarations warnings, as reported here:
// https://github.com/google/googletest/issues/4897
#define GTEST_DECLARE_bool_(name) \
namespace testing { \
GTEST_API_ extern bool GTEST_FLAG(name); \
@@ -2335,71 +2378,11 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal
} // namespace testing
#ifdef GTEST_HAS_ABSL
// Always use absl::any for UniversalPrinter<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_ANY 1
#include "absl/types/any.h"
namespace testing {
namespace internal {
using Any = ::absl::any;
} // namespace internal
} // namespace testing
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate)
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \
[[deprecated(msg), clang::annotate("inline-me")]]
#else
#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
(!defined(_MSC_VER) || GTEST_HAS_RTTI))
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_ANY 1
#include <any>
namespace testing {
namespace internal {
using Any = ::std::any;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::any is not
// supported.
#endif // __cpp_lib_any
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_ANY
#define GTEST_INTERNAL_HAS_ANY 0
#endif
#ifdef GTEST_HAS_ABSL
// Always use absl::optional for UniversalPrinter<> specializations if
// googletest is built with absl support.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
#include "absl/types/optional.h"
namespace testing {
namespace internal {
template <typename T>
using Optional = ::absl::optional<T>;
inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
} // namespace internal
} // namespace testing
#else
#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
#include <optional>
namespace testing {
namespace internal {
template <typename T>
using Optional = ::std::optional<T>;
inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::optional is not
// supported.
#endif // __cpp_lib_optional
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_OPTIONAL
#define GTEST_INTERNAL_HAS_OPTIONAL 0
#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]]
#endif
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
@@ -2414,7 +2397,6 @@ inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
#ifdef GTEST_HAS_ABSL
// Always use absl::string_view for Matcher<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include "absl/strings/string_view.h"
namespace testing {
namespace internal {
@@ -2422,62 +2404,17 @@ using StringView = ::absl::string_view;
} // namespace internal
} // namespace testing
#else
#if defined(__cpp_lib_string_view) || \
(GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations.
namespace testing {
namespace internal {
using StringView = std::string_view;
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_ABSL
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include <string_view>
namespace testing {
namespace internal {
using StringView = ::std::string_view;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::string_view is not
// supported.
#endif // __cpp_lib_string_view
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW
#define GTEST_INTERNAL_HAS_STRING_VIEW 0
#endif
#ifdef GTEST_HAS_ABSL
// Always use absl::variant for UniversalPrinter<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_VARIANT 1
#include "absl/types/variant.h"
namespace testing {
namespace internal {
template <typename... T>
using Variant = ::absl::variant<T...>;
} // namespace internal
} // namespace testing
#else
#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_VARIANT 1
#include <variant>
namespace testing {
namespace internal {
template <typename... T>
using Variant = ::std::variant<T...>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::variant is not supported.
#endif // __cpp_lib_variant
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_VARIANT
#define GTEST_INTERNAL_HAS_VARIANT 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
@@ -60,7 +60,7 @@ namespace testing {
namespace internal {
// String - an abstract class holding static string utilities.
class GTEST_API_ String {
class GTEST_API_ [[nodiscard]] String {
public:
// Static utility methods
@@ -166,7 +166,7 @@ class GTEST_API_ String {
private:
String(); // Not meant to be instantiated.
}; // class String
}; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".
+6 -9
View File
@@ -246,15 +246,12 @@ GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);
// be created, prints an error and exits.
void WriteToShardStatusFileIfNeeded();
// Checks whether sharding is enabled by examining the relevant
// environment variable values. If the variables are present,
// but inconsistent (e.g., shard_index >= total_shards), prints
// an error and exits. If in_subprocess_for_death_test, sharding is
// Checks whether sharding is enabled by examining the relevant flag values.
// If the flags are set, but inconsistent (e.g., shard_index >= total_shards),
// prints an error and exits. If in_subprocess_for_death_test, sharding is
// disabled because it must only be applied to the original test
// process. Otherwise, we could filter out death tests we intended to execute.
GTEST_API_ bool ShouldShard(const char* total_shards_str,
const char* shard_index_str,
bool in_subprocess_for_death_test);
GTEST_API_ bool ShouldShard(bool in_subprocess_for_death_test);
// Parses the environment variable var as a 32-bit integer. If it is unset,
// returns default_val. If it is not a 32-bit integer, prints an error and
@@ -590,7 +587,7 @@ class GTEST_API_ UnitTestImpl {
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
const TestSuite* GetTestSuite(int i) const {
const int index = GetElementOr(test_suite_indices_, i, -1);
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];
}
// Legacy API is deprecated but still available
@@ -1109,7 +1106,7 @@ class StreamingListener : public EmptyTestEventListener {
GTEST_CHECK_(sockfd_ != -1)
<< "Send() can be called only when there is a connection.";
const auto len = static_cast<size_t>(message.length());
const size_t len = message.length();
if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_;
-2
View File
@@ -59,7 +59,6 @@ Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
// s.
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const internal::StringView&>::Matcher(const std::string& s) {
@@ -93,6 +92,5 @@ Matcher<internal::StringView>::Matcher(const char* s) {
Matcher<internal::StringView>::Matcher(internal::StringView s) {
*this = Eq(std::string(s));
}
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
} // namespace testing
+34 -15
View File
@@ -89,6 +89,7 @@
#include "gtest/gtest-message.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
#include "src/gtest-internal-inl.h"
@@ -302,6 +303,22 @@ bool AutoHandle::IsCloseable() const {
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
}
#if !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
Notification::Notification() {
// Create a manual-reset event object.
event_ = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
GTEST_CHECK_(event_ != nullptr);
}
Notification::~Notification() { ::CloseHandle(event_); }
void Notification::Notify() { GTEST_CHECK_(::SetEvent(event_)); }
void Notification::WaitForNotification() {
GTEST_CHECK_(::WaitForSingleObject(event_, INFINITE) == WAIT_OBJECT_0);
}
#endif // !GTEST_HAS_NOTIFICATION_ && defined(GTEST_OS_WINDOWS_MINGW)
Mutex::Mutex()
: owner_thread_id_(0),
type_(kDynamic),
@@ -320,13 +337,13 @@ Mutex::~Mutex() {
}
}
void Mutex::Lock() {
void Mutex::lock() {
ThreadSafeLazyInit();
::EnterCriticalSection(critical_section_);
owner_thread_id_ = ::GetCurrentThreadId();
}
void Mutex::Unlock() {
void Mutex::unlock() {
ThreadSafeLazyInit();
// We don't protect writing to owner_thread_id_ here, as it's the
// caller's responsibility to ensure that the current thread holds the
@@ -499,7 +516,7 @@ class ThreadLocalRegistryImpl {
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
DWORD current_thread = ::GetCurrentThreadId();
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos =
@@ -532,7 +549,7 @@ class ThreadLocalRegistryImpl {
// Clean up the ThreadLocalValues data structure while holding the lock, but
// defer the destruction of the ThreadLocalValueHolderBases.
{
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
for (ThreadIdToThreadLocals::iterator it =
@@ -559,7 +576,7 @@ class ThreadLocalRegistryImpl {
// Clean up the ThreadIdToThreadLocals data structure while holding the
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
{
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos =
@@ -729,7 +746,7 @@ void RE::Init(const char* regex) {
char* const full_pattern = new char[full_regex_len];
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
is_valid_ = regcomp(&full_regex_, full_pattern, reg_flags) == 0;
int error = regcomp(&full_regex_, full_pattern, reg_flags);
// We want to call regcomp(&partial_regex_, ...) even if the
// previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's
@@ -738,13 +755,13 @@ void RE::Init(const char* regex) {
// Some implementation of POSIX regex (e.g. on at least some
// versions of Cygwin) doesn't accept the empty string as a valid
// regex. We change it to an equivalent form "()" to be safe.
if (is_valid_) {
if (!error) {
const char* const partial_regex = (*regex == '\0') ? "()" : regex;
is_valid_ = regcomp(&partial_regex_, partial_regex, reg_flags) == 0;
error = regcomp(&partial_regex_, partial_regex, reg_flags);
}
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression.";
is_valid_ = error == 0;
EXPECT_EQ(error, 0) << "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression.";
delete[] full_pattern;
}
@@ -1052,7 +1069,7 @@ GTestLog::~GTestLog() {
// Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
GTEST_DISABLE_DEPRECATED_PUSH_()
namespace {
@@ -1078,10 +1095,12 @@ class CapturedStream {
0, // Generate unique file name.
temp_file_path);
GTEST_CHECK_(success != 0)
<< "Unable to create a temporary file in " << temp_dir_path;
<< "Failed to create temporary file in " << temp_dir_path
<< " with error " << ::GetLastError();
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
GTEST_CHECK_(captured_fd != -1)
<< "Unable to open temporary file " << temp_file_path;
<< "Failed to open temporary file " << temp_file_path << " with error "
<< ::GetLastError();
filename_ = temp_file_path;
#else
// There's no guarantee that a test has write access to the current
@@ -1183,7 +1202,7 @@ class CapturedStream {
CapturedStream& operator=(const CapturedStream&) = delete;
};
GTEST_DISABLE_MSC_DEPRECATED_POP_()
GTEST_DISABLE_DEPRECATED_POP_()
static CapturedStream* g_captured_stderr = nullptr;
static CapturedStream* g_captured_stdout = nullptr;
+11 -12
View File
@@ -50,7 +50,7 @@
#include <iomanip>
#include <ios>
#include <ostream> // NOLINT
#include <string>
#include <string_view>
#include <type_traits>
#include "gtest/internal/gtest-port.h"
@@ -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
@@ -333,14 +332,14 @@ void PrintTo(__int128_t v, ::std::ostream* os) {
// Prints the given array of characters to the ostream. CharType must be either
// char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters
// and may not be NUL-terminated.
// The array starts at begin (which may be nullptr) and contains len characters.
// The array may include '\0' characters and may not be NUL-terminated.
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
const char* const quote_prefix = GetCharWidthPrefix(*begin);
const char* const quote_prefix = GetCharWidthPrefix(CharType());
*os << quote_prefix << "\"";
bool is_previous_hex = false;
CharFormat print_format = kAsIs;
@@ -516,13 +515,13 @@ bool IsValidUTF8(const char* str, size_t length) {
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
if (!ContainsUnprintableControlCodes(str, length) &&
IsValidUTF8(str, length)) {
*os << "\n As Text: \"" << str << "\"";
*os << "\n As Text: \"" << std::string_view(str, length) << "\"";
}
}
} // anonymous namespace
void PrintStringTo(const ::std::string& s, ostream* os) {
void PrintStringTo(std::string_view s, ostream* os) {
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG_GET(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os);
@@ -531,21 +530,21 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
}
#ifdef __cpp_lib_char8_t
void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
void PrintU8StringTo(::std::u8string_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif
void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
void PrintU16StringTo(::std::u16string_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
void PrintU32StringTo(::std::u32string_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
void PrintWideStringTo(::std::wstring_view s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif // GTEST_HAS_STD_WSTRING
+5 -3
View File
@@ -34,7 +34,9 @@
#include <ostream>
#include <string>
#include <string_view>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
@@ -42,9 +44,9 @@ namespace testing {
// Gets the summary of the failure message by omitting the stack trace
// in it.
std::string TestPartResult::ExtractSummary(const char* message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
return stack_trace == nullptr ? message : std::string(message, stack_trace);
std::string TestPartResult::ExtractSummary(const std::string_view message) {
auto stack_trace = message.find(internal::kStackTraceMarker);
return std::string(message.substr(0, stack_trace));
}
// Prints a TestPartResult object.
+140 -74
View File
@@ -58,6 +58,7 @@
#include <ostream> // NOLINT
#include <set>
#include <sstream>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -269,6 +270,13 @@ GTEST_DEFINE_bool_(
"True if and only if the test should fail if no test case (including "
"disabled test cases) is linked.");
GTEST_DEFINE_bool_(
fail_if_no_test_selected,
testing::internal::BoolFromGTestEnv("fail_if_no_test_selected", false),
"True if and only if the test should fail if no test case is selected to "
"run. A test case is selected to run if it is not disabled and is matched "
"by the filter flag so that it starts executing.");
GTEST_DEFINE_bool_(
also_run_disabled_tests,
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
@@ -399,6 +407,18 @@ GTEST_DEFINE_bool_(
"if exceptions are enabled or exit the program with a non-zero code "
"otherwise. For use with an external test framework.");
GTEST_DEFINE_int32_(
shard_index,
testing::internal::Int32FromEnvOrDie(testing::kTestShardIndex, -1),
"The zero-based index of the shard to run. A value of -1 "
"(the default) indicates that sharding is disabled.");
GTEST_DEFINE_int32_(
total_shards,
testing::internal::Int32FromEnvOrDie(testing::kTestTotalShards, -1),
"The total number of shards to use when running tests in parallel. "
"A value of -1 (the default) indicates that sharding is disabled.");
#if GTEST_USE_OWN_FLAGFILE_FLAG_
GTEST_DEFINE_string_(
flagfile, testing::internal::StringFromGTestEnv("flagfile", ""),
@@ -478,6 +498,15 @@ bool ShouldEmitStackTraceForResultType(TestPartResult::Type type) {
// AssertHelper constructor.
AssertHelper::AssertHelper(TestPartResult::Type type, const char* file,
int line, const char* message)
: AssertHelper(
type, file == nullptr ? std::string_view() : std::string_view(file),
line,
message == nullptr ? std::string_view() : std::string_view(message)) {
}
AssertHelper::AssertHelper(TestPartResult::Type type,
const std::string_view file, int line,
const std::string_view message)
: data_(new AssertHelperData(type, file, line, message)) {}
AssertHelper::~AssertHelper() { delete data_; }
@@ -706,7 +735,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
const char* const gtest_output_flag = s.c_str();
std::string format = GetOutputFormat();
if (format.empty()) format = std::string(kDefaultOutputFormat);
if (format.empty()) format = kDefaultOutputFormat;
const char* const colon = strchr(gtest_output_flag, ':');
if (colon == nullptr)
@@ -868,7 +897,11 @@ class PositiveAndNegativeUnitTestFilter {
// and does not match the negative filter.
bool MatchesTest(const std::string& test_suite_name,
const std::string& test_name) const {
#ifdef GTEST_HAS_ABSL
return MatchesName(absl::StrCat(test_suite_name, ".", test_name));
#else
return MatchesName(test_suite_name + "." + test_name);
#endif
}
// Returns true if and only if name matches the positive filter and does not
@@ -1079,14 +1112,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
// Returns the global test part result reporter.
TestPartResultReporterInterface*
UnitTestImpl::GetGlobalTestPartResultReporter() {
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
internal::MutexLock lock(global_test_part_result_reporter_mutex_);
return global_test_part_result_reporter_;
}
// Sets the global test part result reporter.
void UnitTestImpl::SetGlobalTestPartResultReporter(
TestPartResultReporterInterface* reporter) {
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
internal::MutexLock lock(global_test_part_result_reporter_mutex_);
global_test_part_result_reporter_ = reporter;
}
@@ -1176,7 +1209,7 @@ int UnitTestImpl::test_to_run_count() const {
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
return os_stack_trace_getter()->CurrentStackTrace(
static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1
GTEST_FLAG_GET(stack_trace_depth), skip_count + 1
// Skips the user-specified number of frames plus this function
// itself.
); // NOLINT
@@ -1488,17 +1521,17 @@ class Hunk {
// Print a unified diff header for one hunk.
// The format is
// "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
// where the left/right parts are omitted if unnecessary.
// where the left/right lengths are omitted if unnecessary.
void PrintHeader(std::ostream* ss) const {
*ss << "@@ ";
if (removes_) {
*ss << "-" << left_start_ << "," << (removes_ + common_);
size_t left_length = removes_ + common_;
size_t right_length = adds_ + common_;
*ss << "@@ " << "-" << left_start_;
if (left_length != 1) {
*ss << "," << left_length;
}
if (removes_ && adds_) {
*ss << " ";
}
if (adds_) {
*ss << "+" << right_start_ << "," << (adds_ + common_);
*ss << " " << "+" << right_start_;
if (right_length != 1) {
*ss << "," << right_length;
}
*ss << " @@\n";
}
@@ -2340,7 +2373,7 @@ void TestResult::RecordProperty(const std::string& xml_element,
if (!ValidateTestProperty(xml_element, test_property)) {
return;
}
internal::MutexLock lock(&test_properties_mutex_);
internal::MutexLock lock(test_properties_mutex_);
const std::vector<TestProperty>::iterator property_with_matching_key =
std::find_if(test_properties_.begin(), test_properties_.end(),
internal::TestPropertyKeyIs(test_property.key()));
@@ -2540,8 +2573,9 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
// AddTestPartResult.
UnitTest::GetInstance()->AddTestPartResult(
result_type,
nullptr, // No info about the source file where the exception occurred.
-1, // We have no info on which line caused the exception.
std::string_view(), // No info about the source file where the exception
// occurred.
-1, // We have no info on which line caused the exception.
message,
""); // No stack trace, either.
}
@@ -2666,7 +2700,7 @@ Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
}
// Runs the given method and catches and reports C++ and/or SEH-style
// exceptions, if they are supported; returns the 0-value for type
// exceptions, if they are supported; returns the default-value for type
// Result in case of an SEH exception.
template <class T, typename Result>
Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
@@ -2714,7 +2748,7 @@ Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
TestPartResult::kFatalFailure,
FormatCxxExceptionMessage(nullptr, location));
}
return static_cast<Result>(0);
return Result();
#else
return HandleSehExceptionsInMethodIfSupported(object, method, location);
#endif // GTEST_HAS_EXCEPTIONS
@@ -3298,6 +3332,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
const bool term_supports_color =
term != nullptr && (String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") ||
String::CStringEquals(term, "xterm-ghostty") ||
String::CStringEquals(term, "xterm-kitty") ||
String::CStringEquals(term, "alacritty") ||
String::CStringEquals(term, "screen") ||
@@ -3452,11 +3487,11 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
filter);
}
if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n",
if (internal::ShouldShard(false)) {
const int32_t shard_index = GTEST_FLAG_GET(shard_index);
ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %d.\n",
static_cast<int>(shard_index) + 1,
internal::posix::GetEnv(kTestTotalShards));
GTEST_FLAG_GET(total_shards));
}
if (GTEST_FLAG_GET(shuffle)) {
@@ -4204,8 +4239,7 @@ void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
for (;;) {
const char* const next_segment = strstr(segment, "]]>");
if (next_segment != nullptr) {
stream->write(segment,
static_cast<std::streamsize>(next_segment - segment));
stream->write(segment, next_segment - segment);
*stream << "]]>]]&gt;<![CDATA[";
segment = next_segment + strlen("]]>");
} else {
@@ -4347,8 +4381,8 @@ void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,
internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number());
const std::string summary = location + "\n" + part.summary();
*stream << " <skipped message=\""
<< EscapeXmlAttribute(summary.c_str()) << "\">";
*stream << " <skipped message=\"" << EscapeXmlAttribute(summary)
<< "\">";
const std::string detail = location + "\n" + part.message();
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
*stream << "</skipped>\n";
@@ -5080,7 +5114,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
void* caller_frame = nullptr;
{
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
caller_frame = caller_frame_;
}
@@ -5119,12 +5153,12 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
caller_frame = nullptr;
}
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
caller_frame_ = caller_frame;
#endif // GTEST_HAS_ABSL
}
#ifdef GTEST_HAS_DEATH_TEST
#ifdef GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
// A helper class that creates the premature-exit file in its
// constructor and deletes the file in its destructor.
class ScopedPrematureExitFile {
@@ -5137,9 +5171,12 @@ class ScopedPrematureExitFile {
// create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this.
FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w");
fwrite("0", 1, 1, pfile);
fclose(pfile);
if (FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w")) {
fwrite("0", 1, 1, pfile);
fclose(pfile);
} else {
premature_exit_filepath_.clear();
}
}
}
@@ -5157,12 +5194,12 @@ class ScopedPrematureExitFile {
}
private:
const std::string premature_exit_filepath_;
std::string premature_exit_filepath_;
ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;
};
#endif // GTEST_HAS_DEATH_TEST
#endif // GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
} // namespace internal
@@ -5382,13 +5419,13 @@ void UnitTest::UponLeavingGTest() {
// Sets the TestSuite object for the test that's currently running.
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->set_current_test_suite(a_current_test_suite);
}
// Sets the TestInfo object for the test that's currently running.
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->set_current_test_info(a_current_test_info);
}
@@ -5420,14 +5457,14 @@ Environment* UnitTest::AddEnvironment(Environment* env) {
// this to report their results. The user code should use the
// assertion macros instead of calling this directly.
void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
const char* file_name, int line_number,
const std::string& message,
const std::string_view file_name,
int line_number, const std::string& message,
const std::string& os_stack_trace)
GTEST_LOCK_EXCLUDED_(mutex_) {
Message msg;
msg << message;
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
if (!impl_->gtest_trace_stack().empty()) {
msg << "\n" << GTEST_NAME_ << " trace:";
@@ -5507,7 +5544,7 @@ void UnitTest::RecordProperty(const std::string& key,
// We don't protect this under mutex_, as we only support calling it
// from the main thread.
int UnitTest::Run() {
#ifdef GTEST_HAS_DEATH_TEST
#ifdef GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
const bool in_death_test_child_process =
!GTEST_FLAG_GET(internal_run_death_test).empty();
@@ -5538,7 +5575,7 @@ int UnitTest::Run() {
: internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
#else
const bool in_death_test_child_process = false;
#endif // GTEST_HAS_DEATH_TEST
#endif // GTEST_INTERNAL_HAS_PREMATURE_EXIT_FILE
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
// used for the duration of the program.
@@ -5610,7 +5647,7 @@ const char* UnitTest::original_working_dir() const {
// or NULL if no test is running.
const TestSuite* UnitTest::current_test_suite() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
return impl_->current_test_suite();
}
@@ -5618,7 +5655,7 @@ const TestSuite* UnitTest::current_test_suite() const
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
const TestCase* UnitTest::current_test_case() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
return impl_->current_test_suite();
}
#endif
@@ -5627,7 +5664,7 @@ const TestCase* UnitTest::current_test_case() const
// or NULL if no test is running.
const TestInfo* UnitTest::current_test_info() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
return impl_->current_test_info();
}
@@ -5651,13 +5688,13 @@ UnitTest::~UnitTest() { delete impl_; }
// Google Test trace stack.
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->gtest_trace_stack().push_back(trace);
}
// Pops a trace from the per-thread Google Test trace stack.
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->gtest_trace_stack().pop_back();
}
@@ -5960,8 +5997,7 @@ bool UnitTestImpl::RunAllTests() {
#endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
#endif // GTEST_HAS_DEATH_TEST
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
in_subprocess_for_death_test);
const bool should_shard = ShouldShard(in_subprocess_for_death_test);
// Compares the full test names with the filter to decide which
// tests to run.
@@ -6079,6 +6115,20 @@ bool UnitTestImpl::RunAllTests() {
TearDownEnvironment);
repeater->OnEnvironmentsTearDownEnd(*parent_);
}
} else if (GTEST_FLAG_GET(fail_if_no_test_selected)) {
// If there were no tests to run, bail if we were requested to be
// strict.
constexpr char kNoTestsSelectedMessage[] =
"No tests ran. Check that tests exist and are not disabled or "
"filtered out.\n\n"
"For sharded runs, this error indicates an empty shard. This can "
"happen if you have more shards than tests, or if --gtest_filter "
"leaves a shard with no tests.\n\n"
"To permit empty shards (e.g., when debugging with a filter), "
"specify \n"
"--gtest_fail_if_no_test_selected=false.";
ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage);
return false;
}
elapsed_time_ = timer.Elapsed();
@@ -6159,45 +6209,44 @@ void WriteToShardStatusFileIfNeeded() {
}
#endif // GTEST_HAS_FILE_SYSTEM
// Checks whether sharding is enabled by examining the relevant
// environment variable values. If the variables are present,
// but inconsistent (i.e., shard_index >= total_shards), prints
// an error and exits. If in_subprocess_for_death_test, sharding is
// disabled because it must only be applied to the original test
// process. Otherwise, we could filter out death tests we intended to execute.
bool ShouldShard(const char* total_shards_env, const char* shard_index_env,
bool in_subprocess_for_death_test) {
// Checks whether sharding is enabled by examining the relevant command line
// arguments. If the arguments are present, but inconsistent
// (i.e., shard_index >= total_shards), prints an error and exits.
// If in_subprocess_for_death_test, sharding is disabled because it must only
// be applied to the original test process. Otherwise, we could filter out death
// tests we intended to execute.
bool ShouldShard(bool in_subprocess_for_death_test) {
if (in_subprocess_for_death_test) {
return false;
}
const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1);
const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1);
const int32_t total_shards = GTEST_FLAG_GET(total_shards);
const int32_t shard_index = GTEST_FLAG_GET(shard_index);
if (total_shards == -1 && shard_index == -1) {
return false;
} else if (total_shards == -1 && shard_index != -1) {
const Message msg = Message() << "Invalid environment variables: you have "
<< kTestShardIndex << " = " << shard_index
<< ", but have left " << kTestTotalShards
<< " unset.\n";
const Message msg = Message()
<< "Invalid sharding: you have " << kTestShardIndex
<< " = " << shard_index << ", but have left "
<< kTestTotalShards << " unset.\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) {
const Message msg = Message()
<< "Invalid environment variables: you have "
<< kTestTotalShards << " = " << total_shards
<< ", but have left " << kTestShardIndex << " unset.\n";
<< "Invalid sharding: you have " << kTestTotalShards
<< " = " << total_shards << ", but have left "
<< kTestShardIndex << " unset.\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) {
const Message msg =
Message() << "Invalid environment variables: we require 0 <= "
<< kTestShardIndex << " < " << kTestTotalShards
<< ", but you have " << kTestShardIndex << "=" << shard_index
<< ", " << kTestTotalShards << "=" << total_shards << ".\n";
Message() << "Invalid sharding: we require 0 <= " << kTestShardIndex
<< " < " << kTestTotalShards << ", but you have "
<< kTestShardIndex << "=" << shard_index << ", "
<< kTestTotalShards << "=" << total_shards << ".\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
@@ -6240,11 +6289,10 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
// . Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL
? Int32FromEnvOrDie(kTestTotalShards, -1)
? GTEST_FLAG_GET(total_shards)
: -1;
const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL
? Int32FromEnvOrDie(kTestShardIndex, -1)
: -1;
const int32_t shard_index =
shard_tests == HONOR_SHARDING_PROTOCOL ? GTEST_FLAG_GET(shard_index) : -1;
const PositiveAndNegativeUnitTestFilter gtest_flag_filter(
GTEST_FLAG_GET(filter));
@@ -6686,6 +6734,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_
@@ -6698,6 +6752,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 "
@@ -6714,6 +6771,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"
@@ -6726,6 +6786,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 "
@@ -6763,6 +6826,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_selected);
GTEST_INTERNAL_PARSE_FLAG(filter);
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
GTEST_INTERNAL_PARSE_FLAG(list_tests);
@@ -6772,6 +6836,8 @@ static bool ParseGoogleTestFlag(const char* const arg) {
GTEST_INTERNAL_PARSE_FLAG(print_utf8);
GTEST_INTERNAL_PARSE_FLAG(random_seed);
GTEST_INTERNAL_PARSE_FLAG(repeat);
GTEST_INTERNAL_PARSE_FLAG(shard_index);
GTEST_INTERNAL_PARSE_FLAG(total_shards);
GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);
GTEST_INTERNAL_PARSE_FLAG(shuffle);
GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);
@@ -6864,7 +6930,7 @@ void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
std::vector<char*> positional_args;
std::vector<absl::UnrecognizedFlag> unrecognized_flags;
absl::ParseAbseilFlagsOnly(*argc, argv, positional_args, unrecognized_flags);
absl::flat_hash_set<absl::string_view> unrecognized;
absl::flat_hash_set<std::string_view> unrecognized;
for (const auto& flag : unrecognized_flags) {
unrecognized.insert(flag.flag_name);
}