mirror of
https://github.com/stenzek/duckstation.git
synced 2026-10-11 22:49:58 +00:00
dep/googletest: Update to v1.18.0
Note: std::any support is disabled because it depends on RTTI support in MSVC, which we have disabled.
This commit is contained in:
@@ -5,34 +5,62 @@
|
||||
|
||||
Ajay Joshi <[email protected]>
|
||||
Balázs Dán <[email protected]>
|
||||
Benoit Sigoure <[email protected]>
|
||||
Bharat Mediratta <[email protected]>
|
||||
Bogdan Piloca <[email protected]>
|
||||
Chandler Carruth <[email protected]>
|
||||
Chris Prince <[email protected]>
|
||||
Chris Taylor <[email protected]>
|
||||
Dan Egnor <[email protected]>
|
||||
Dave MacLachlan <[email protected]>
|
||||
David Anderson <[email protected]>
|
||||
Dean Sturtevant
|
||||
Eric Roman <[email protected]>
|
||||
Gene Volovich <[email protected]>
|
||||
Hady Zalek <[email protected]>
|
||||
Hal Burch <[email protected]>
|
||||
Jeffrey Yasskin <[email protected]>
|
||||
Jim Keller <[email protected]>
|
||||
Joe Walnes <[email protected]>
|
||||
Jon Wray <[email protected]>
|
||||
Jói Sigurðsson <[email protected]>
|
||||
Keir Mierle <[email protected]>
|
||||
Keith Ray <[email protected]>
|
||||
Kenton Varda <[email protected]>
|
||||
Kostya Serebryany <[email protected]>
|
||||
Krystian Kuzniarek <[email protected]>
|
||||
Lev Makhlis
|
||||
Manuel Klimek <[email protected]>
|
||||
Mario Tanev <[email protected]>
|
||||
Mark Paskin
|
||||
Markus Heule <[email protected]>
|
||||
Martijn Vels <[email protected]>
|
||||
Matthew Simmons <[email protected]>
|
||||
Mika Raento <[email protected]>
|
||||
Mike Bland <[email protected]>
|
||||
Miklós Fazekas <[email protected]>
|
||||
Neal Norwitz <[email protected]>
|
||||
Nermin Ozkiranartli <[email protected]>
|
||||
Owen Carlsen <[email protected]>
|
||||
Paneendra Ba <[email protected]>
|
||||
Pasi Valminen <[email protected]>
|
||||
Patrick Hanna <[email protected]>
|
||||
Patrick Riley <[email protected]>
|
||||
Paul Menage <[email protected]>
|
||||
Peter Kaminski <[email protected]>
|
||||
Piotr Kaminski <[email protected]>
|
||||
Preston Jackson <[email protected]>
|
||||
Rainer Klaffenboeck <[email protected]>
|
||||
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]>
|
||||
Tracy Bialik <[email protected]>
|
||||
Vadim Berman <[email protected]>
|
||||
Vlad Losev <[email protected]>
|
||||
Wolfgang Klier <[email protected]>
|
||||
Zhanyong Wan <[email protected]>
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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<<;
|
||||
|
||||
@@ -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,15 @@ 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> {};
|
||||
|
||||
#if 0
|
||||
// DUCKSTATION-CHANGE: Disabled because it requires RTTI on Windows/MSVC.
|
||||
// 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 +928,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 +938,61 @@ 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 << ')';
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
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 +1041,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 +1052,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 +1075,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 +1114,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 +1130,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 +1146,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 +1161,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 +1179,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 +1228,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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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".
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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 << "]]>]]><![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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user