mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
3rdparty: Update googletest to v1.17.0
This commit is contained in:
parent
be213695a0
commit
7dd4ab947b
8
3rdparty/googletest/CONTRIBUTING.md
vendored
8
3rdparty/googletest/CONTRIBUTING.md
vendored
@ -47,11 +47,11 @@ PR is acceptable as an alternative.
|
||||
## The Google Test and Google Mock Communities
|
||||
|
||||
The Google Test community exists primarily through the
|
||||
[discussion group](http://groups.google.com/group/googletestframework) and the
|
||||
[discussion group](https://groups.google.com/group/googletestframework) and the
|
||||
GitHub repository. Likewise, the Google Mock community exists primarily through
|
||||
their own [discussion group](http://groups.google.com/group/googlemock). You are
|
||||
definitely encouraged to contribute to the discussion and you can also help us
|
||||
to keep the effectiveness of the group high by following and promoting the
|
||||
their own [discussion group](https://groups.google.com/group/googlemock). You
|
||||
are definitely encouraged to contribute to the discussion and you can also help
|
||||
us to keep the effectiveness of the group high by following and promoting the
|
||||
guidelines listed here.
|
||||
|
||||
### Please Be Friendly
|
||||
|
||||
15
3rdparty/googletest/README.md
vendored
15
3rdparty/googletest/README.md
vendored
@ -2,27 +2,18 @@
|
||||
|
||||
### Announcements
|
||||
|
||||
#### Live at Head
|
||||
|
||||
GoogleTest now follows the
|
||||
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
|
||||
We recommend
|
||||
[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
|
||||
We do publish occasional semantic versions, tagged with
|
||||
`v${major}.${minor}.${patch}` (e.g. `v1.16.0`).
|
||||
|
||||
#### Documentation Updates
|
||||
|
||||
Our documentation is now live on GitHub Pages at
|
||||
https://google.github.io/googletest/. We recommend browsing the documentation on
|
||||
GitHub Pages rather than directly in the repository.
|
||||
|
||||
#### Release 1.16.0
|
||||
#### Release 1.17.0
|
||||
|
||||
[Release 1.16.0](https://github.com/google/googletest/releases/tag/v1.16.0) is
|
||||
[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is
|
||||
now available.
|
||||
|
||||
The 1.16.x branch requires at least C++14.
|
||||
The 1.17.x branch [requires at least C++17]((https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
|
||||
|
||||
#### Continuous Integration
|
||||
|
||||
|
||||
@ -835,6 +835,10 @@ class Action<R(Args...)> {
|
||||
Result operator()(const InArgs&...) const {
|
||||
return function_impl();
|
||||
}
|
||||
template <typename... InArgs>
|
||||
Result operator()(const InArgs&...) {
|
||||
return function_impl();
|
||||
}
|
||||
|
||||
FunctionImpl function_impl;
|
||||
};
|
||||
@ -1451,6 +1455,30 @@ struct WithArgsAction {
|
||||
return OA{std::move(inner_action)};
|
||||
}
|
||||
|
||||
// As above, but in the case where we want to create a OnceAction from a const
|
||||
// WithArgsAction. This is fine as long as the inner action doesn't need to
|
||||
// move any of its state to create a OnceAction.
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const InnerAction&,
|
||||
OnceAction<R(internal::TupleElement<
|
||||
I, std::tuple<Args...>>...)>>::value,
|
||||
int>::type = 0>
|
||||
operator OnceAction<R(Args...)>() const& { // NOLINT
|
||||
struct OA {
|
||||
OnceAction<InnerSignature<R, Args...>> inner_action;
|
||||
|
||||
R operator()(Args&&... args) && {
|
||||
return std::move(inner_action)
|
||||
.Call(std::get<I>(
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))...);
|
||||
}
|
||||
};
|
||||
|
||||
return OA{inner_action};
|
||||
}
|
||||
|
||||
template <
|
||||
typename R, typename... Args,
|
||||
typename std::enable_if<
|
||||
@ -1703,9 +1731,8 @@ template <size_t k>
|
||||
struct ReturnArgAction {
|
||||
template <typename... Args,
|
||||
typename = typename std::enable_if<(k < sizeof...(Args))>::type>
|
||||
auto operator()(Args&&... args) const
|
||||
-> decltype(std::get<k>(
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))) {
|
||||
auto operator()(Args&&... args) const -> decltype(std::get<k>(
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))) {
|
||||
return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));
|
||||
}
|
||||
};
|
||||
@ -1720,6 +1747,16 @@ struct SaveArgAction {
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgByMoveAction {
|
||||
Ptr pointer;
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args) const {
|
||||
*pointer = std::move(std::get<k>(std::tie(args...)));
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t k, typename Ptr>
|
||||
struct SaveArgPointeeAction {
|
||||
Ptr pointer;
|
||||
@ -2070,6 +2107,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgByMove<k>(pointer) moves the k-th (0-based) argument of the
|
||||
// mock function into *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
|
||||
return {pointer};
|
||||
}
|
||||
|
||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||
template <size_t k, typename Ptr>
|
||||
@ -2213,9 +2257,9 @@ template <typename F, typename Impl>
|
||||
}
|
||||
|
||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
||||
, GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \
|
||||
, [[maybe_unused]] const arg##i##_type& arg##i
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||
[[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||
|
||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
||||
@ -2280,8 +2324,8 @@ template <typename F, typename Impl>
|
||||
std::shared_ptr<const gmock_Impl> impl_; \
|
||||
}; \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
|
||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
||||
@ -2316,7 +2360,7 @@ template <typename F, typename Impl>
|
||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||
}; \
|
||||
}; \
|
||||
inline name##Action name() GTEST_MUST_USE_RESULT_; \
|
||||
[[nodiscard]] inline name##Action name(); \
|
||||
inline name##Action name() { return name##Action(); } \
|
||||
template <typename function_type, typename return_type, typename args_type, \
|
||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||
|
||||
@ -257,6 +257,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
@ -1311,6 +1312,15 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
|
||||
|
||||
bool MatchAndExplain(const T& x,
|
||||
MatchResultListener* listener) const override {
|
||||
if (!listener->IsInterested()) {
|
||||
// Fast path to avoid unnecessary formatting.
|
||||
for (const Matcher<T>& matcher : matchers_) {
|
||||
if (!matcher.Matches(x)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// This method uses matcher's explanation when explaining the result.
|
||||
// However, if matcher doesn't provide one, this method uses matcher's
|
||||
// description.
|
||||
@ -1430,6 +1440,15 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
|
||||
|
||||
bool MatchAndExplain(const T& x,
|
||||
MatchResultListener* listener) const override {
|
||||
if (!listener->IsInterested()) {
|
||||
// Fast path to avoid unnecessary formatting of match explanations.
|
||||
for (const Matcher<T>& matcher : matchers_) {
|
||||
if (matcher.Matches(x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// This method uses matcher's explanation when explaining the result.
|
||||
// However, if matcher doesn't provide one, this method uses matcher's
|
||||
// description.
|
||||
@ -2097,11 +2116,11 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
|
||||
template <typename Class, typename FieldType>
|
||||
class FieldMatcher {
|
||||
public:
|
||||
FieldMatcher(FieldType Class::*field,
|
||||
FieldMatcher(FieldType Class::* field,
|
||||
const Matcher<const FieldType&>& matcher)
|
||||
: field_(field), matcher_(matcher), whose_field_("whose given field ") {}
|
||||
|
||||
FieldMatcher(const std::string& field_name, FieldType Class::*field,
|
||||
FieldMatcher(const std::string& field_name, FieldType Class::* field,
|
||||
const Matcher<const FieldType&>& matcher)
|
||||
: field_(field),
|
||||
matcher_(matcher),
|
||||
@ -2145,7 +2164,7 @@ class FieldMatcher {
|
||||
return MatchAndExplainImpl(std::false_type(), *p, listener);
|
||||
}
|
||||
|
||||
const FieldType Class::*field_;
|
||||
const FieldType Class::* field_;
|
||||
const Matcher<const FieldType&> matcher_;
|
||||
|
||||
// Contains either "whose given field " if the name of the field is unknown
|
||||
@ -2855,6 +2874,54 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
|
||||
}
|
||||
};
|
||||
|
||||
// Implements DistanceFrom(target, get_distance, distance_matcher) for the given
|
||||
// argument types:
|
||||
// * V is the type of the value to be matched.
|
||||
// * T is the type of the target value.
|
||||
// * Distance is the type of the distance between V and T.
|
||||
// * GetDistance is the type of the functor for computing the distance between
|
||||
// V and T.
|
||||
template <typename V, typename T, typename Distance, typename GetDistance>
|
||||
class DistanceFromMatcherImpl : public MatcherInterface<V> {
|
||||
public:
|
||||
// Arguments:
|
||||
// * target: the target value.
|
||||
// * get_distance: the functor for computing the distance between the value
|
||||
// being matched and target.
|
||||
// * distance_matcher: the matcher for checking the distance.
|
||||
DistanceFromMatcherImpl(T target, GetDistance get_distance,
|
||||
Matcher<const Distance&> distance_matcher)
|
||||
: target_(std::move(target)),
|
||||
get_distance_(std::move(get_distance)),
|
||||
distance_matcher_(std::move(distance_matcher)) {}
|
||||
|
||||
// Describes what this matcher does.
|
||||
void DescribeTo(::std::ostream* os) const override {
|
||||
distance_matcher_.DescribeTo(os);
|
||||
*os << " away from " << PrintToString(target_);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(::std::ostream* os) const override {
|
||||
distance_matcher_.DescribeNegationTo(os);
|
||||
*os << " away from " << PrintToString(target_);
|
||||
}
|
||||
|
||||
bool MatchAndExplain(V value, MatchResultListener* listener) const override {
|
||||
const auto distance = get_distance_(value, target_);
|
||||
const bool match = distance_matcher_.Matches(distance);
|
||||
if (!match && listener->IsInterested()) {
|
||||
*listener << "which is " << PrintToString(distance) << " away from "
|
||||
<< PrintToString(target_);
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
private:
|
||||
const T target_;
|
||||
const GetDistance get_distance_;
|
||||
const Matcher<const Distance&> distance_matcher_;
|
||||
};
|
||||
|
||||
// Implements Each(element_matcher) for the given argument type Container.
|
||||
// Symmetric to ContainsMatcherImpl.
|
||||
template <typename Container>
|
||||
@ -2990,6 +3057,52 @@ auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT
|
||||
}
|
||||
} // namespace pair_getters
|
||||
|
||||
// Default functor for computing the distance between two values.
|
||||
struct DefaultGetDistance {
|
||||
template <typename T, typename U>
|
||||
auto operator()(const T& lhs, const U& rhs) const {
|
||||
using std::abs;
|
||||
// Allow finding abs() in the type's namespace via ADL.
|
||||
return abs(lhs - rhs);
|
||||
}
|
||||
};
|
||||
|
||||
// Implements polymorphic DistanceFrom(target, get_distance, distance_matcher)
|
||||
// matcher. Template arguments:
|
||||
// * T is the type of the target value.
|
||||
// * GetDistance is the type of the functor for computing the distance between
|
||||
// the value being matched and the target.
|
||||
// * DistanceMatcher is the type of the matcher for checking the distance.
|
||||
template <typename T, typename GetDistance, typename DistanceMatcher>
|
||||
class DistanceFromMatcher {
|
||||
public:
|
||||
// Arguments:
|
||||
// * target: the target value.
|
||||
// * get_distance: the functor for computing the distance between the value
|
||||
// being matched and target.
|
||||
// * distance_matcher: the matcher for checking the distance.
|
||||
DistanceFromMatcher(T target, GetDistance get_distance,
|
||||
DistanceMatcher distance_matcher)
|
||||
: target_(std::move(target)),
|
||||
get_distance_(std::move(get_distance)),
|
||||
distance_matcher_(std::move(distance_matcher)) {}
|
||||
|
||||
DistanceFromMatcher(const DistanceFromMatcher& other) = default;
|
||||
|
||||
// Implicitly converts to a monomorphic matcher of the given type.
|
||||
template <typename V>
|
||||
operator Matcher<V>() const { // NOLINT
|
||||
using Distance = decltype(get_distance_(std::declval<V>(), target_));
|
||||
return Matcher<V>(new DistanceFromMatcherImpl<V, T, Distance, GetDistance>(
|
||||
target_, get_distance_, distance_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
const T target_;
|
||||
const GetDistance get_distance_;
|
||||
const DistanceMatcher distance_matcher_;
|
||||
};
|
||||
|
||||
// Implements Key(inner_matcher) for the given argument pair type.
|
||||
// Key(inner_matcher) matches an std::pair whose 'first' field matches
|
||||
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
|
||||
@ -3197,8 +3310,8 @@ class PairMatcher {
|
||||
};
|
||||
|
||||
template <typename T, size_t... I>
|
||||
auto UnpackStructImpl(const T& t, std::index_sequence<I...>,
|
||||
int) -> decltype(std::tie(get<I>(t)...)) {
|
||||
auto UnpackStructImpl(const T& t, std::index_sequence<I...>, int)
|
||||
-> decltype(std::tie(get<I>(t)...)) {
|
||||
static_assert(std::tuple_size<T>::value == sizeof...(I),
|
||||
"Number of arguments doesn't match the number of fields.");
|
||||
return std::tie(get<I>(t)...);
|
||||
@ -3305,6 +3418,21 @@ auto UnpackStructImpl(const T& u, std::make_index_sequence<20>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = u;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t);
|
||||
}
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& in, std::make_index_sequence<21>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u] =
|
||||
in;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
|
||||
u);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto UnpackStructImpl(const T& in, std::make_index_sequence<22>, char) {
|
||||
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||
v] = in;
|
||||
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
|
||||
v);
|
||||
}
|
||||
#endif // defined(__cpp_structured_bindings)
|
||||
|
||||
template <size_t I, typename T>
|
||||
@ -3480,7 +3608,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
StlContainerReference stl_container = View::ConstReference(container);
|
||||
auto it = stl_container.begin();
|
||||
size_t exam_pos = 0;
|
||||
bool mismatch_found = false; // Have we found a mismatched element yet?
|
||||
bool unmatched_found = false;
|
||||
|
||||
// Go through the elements and matchers in pairs, until we reach
|
||||
// the end of either the elements or the matchers, or until we find a
|
||||
@ -3496,11 +3624,23 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
mismatch_found = true;
|
||||
unmatched_found = true;
|
||||
// We cannot store the iterator for the unmatched element to be used
|
||||
// later, as some users use ElementsAre() with a "container" whose
|
||||
// iterator is not copy-constructible or copy-assignable.
|
||||
//
|
||||
// We cannot store a pointer to the element either, as some container's
|
||||
// iterators return a temporary.
|
||||
//
|
||||
// We cannot store the element itself either, as the element may not be
|
||||
// copyable.
|
||||
//
|
||||
// Therefore, we just remember the index of the unmatched element,
|
||||
// and use it later to print the unmatched element.
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If mismatch_found is true, 'exam_pos' is the index of the mismatch.
|
||||
// If unmatched_found is true, exam_pos is the index of the mismatch.
|
||||
|
||||
// Find how many elements the actual container has. We avoid
|
||||
// calling size() s.t. this code works for stream-like "containers"
|
||||
@ -3521,10 +3661,27 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mismatch_found) {
|
||||
if (unmatched_found) {
|
||||
// The element count matches, but the exam_pos-th element doesn't match.
|
||||
if (listener_interested) {
|
||||
*listener << "whose element #" << exam_pos << " doesn't match";
|
||||
// Find the unmatched element.
|
||||
auto unmatched_it = stl_container.begin();
|
||||
// We cannot call std::advance() on the iterator, as some users use
|
||||
// ElementsAre() with a "container" whose iterator is incompatible with
|
||||
// std::advance() (e.g. it may not have the difference_type member
|
||||
// type).
|
||||
for (size_t i = 0; i != exam_pos; ++i) {
|
||||
++unmatched_it;
|
||||
}
|
||||
|
||||
// If the array is long or the elements' print-out is large, it may be
|
||||
// hard for the user to find the mismatched element and its
|
||||
// corresponding matcher description. Therefore we print the index, the
|
||||
// value of the mismatched element, and the corresponding matcher
|
||||
// description to ease debugging.
|
||||
*listener << "whose element #" << exam_pos << " ("
|
||||
<< PrintToString(*unmatched_it) << ") ";
|
||||
matchers_[exam_pos].DescribeNegationTo(listener->stream());
|
||||
PrintIfNotEmpty(explanations[exam_pos], listener->stream());
|
||||
}
|
||||
return false;
|
||||
@ -3930,15 +4087,15 @@ GTEST_API_ std::string FormatMatcherDescription(
|
||||
// Overloads to support `OptionalMatcher` being used with a type that either
|
||||
// supports implicit conversion to bool or a `has_value()` method.
|
||||
template <typename Optional>
|
||||
auto IsOptionalEngaged(const Optional& optional,
|
||||
Rank1) -> decltype(!!optional) {
|
||||
auto IsOptionalEngaged(const Optional& optional, Rank1)
|
||||
-> decltype(!!optional) {
|
||||
// The use of double-negation here is to preserve historical behavior where
|
||||
// the matcher used `operator!` rather than directly using `operator bool`.
|
||||
return !static_cast<bool>(!optional);
|
||||
}
|
||||
template <typename Optional>
|
||||
auto IsOptionalEngaged(const Optional& optional,
|
||||
Rank0) -> decltype(!optional.has_value()) {
|
||||
auto IsOptionalEngaged(const Optional& optional, Rank0)
|
||||
-> decltype(!optional.has_value()) {
|
||||
return optional.has_value();
|
||||
}
|
||||
|
||||
@ -3979,6 +4136,10 @@ class OptionalMatcher {
|
||||
return false;
|
||||
}
|
||||
const ValueType& value = *optional;
|
||||
if (!listener->IsInterested()) {
|
||||
// Fast path to avoid unnecessary generation of match explanation.
|
||||
return value_matcher_.Matches(value);
|
||||
}
|
||||
StringMatchResultListener value_listener;
|
||||
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
|
||||
*listener << "whose value " << PrintToString(value)
|
||||
@ -4365,6 +4526,42 @@ inline internal::FloatingEqMatcher<double> DoubleNear(double rhs,
|
||||
return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);
|
||||
}
|
||||
|
||||
// The DistanceFrom(target, get_distance, m) and DistanceFrom(target, m)
|
||||
// matchers work on arbitrary types that have the "distance" concept. What they
|
||||
// do:
|
||||
//
|
||||
// 1. compute the distance between the value and the target using
|
||||
// get_distance(value, target) if get_distance is provided; otherwise compute
|
||||
// the distance as abs(value - target).
|
||||
// 2. match the distance against the user-provided matcher m; if the match
|
||||
// succeeds, the DistanceFrom() match succeeds.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// // 0.5's distance from 0.6 should be <= 0.2.
|
||||
// EXPECT_THAT(0.5, DistanceFrom(0.6, Le(0.2)));
|
||||
//
|
||||
// Vector2D v1(3.0, 4.0), v2(3.2, 6.0);
|
||||
// // v1's distance from v2, as computed by EuclideanDistance(v1, v2),
|
||||
// // should be >= 1.0.
|
||||
// EXPECT_THAT(v1, DistanceFrom(v2, EuclideanDistance, Ge(1.0)));
|
||||
|
||||
template <typename T, typename GetDistance, typename DistanceMatcher>
|
||||
inline internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>
|
||||
DistanceFrom(T target, GetDistance get_distance,
|
||||
DistanceMatcher distance_matcher) {
|
||||
return internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>(
|
||||
std::move(target), std::move(get_distance), std::move(distance_matcher));
|
||||
}
|
||||
|
||||
template <typename T, typename DistanceMatcher>
|
||||
inline internal::DistanceFromMatcher<T, internal::DefaultGetDistance,
|
||||
DistanceMatcher>
|
||||
DistanceFrom(T target, DistanceMatcher distance_matcher) {
|
||||
return DistanceFrom(std::move(target), internal::DefaultGetDistance(),
|
||||
std::move(distance_matcher));
|
||||
}
|
||||
|
||||
// Creates a matcher that matches any double argument approximately equal to
|
||||
// rhs, up to the specified max absolute error bound, including NaN values when
|
||||
// rhs is NaN. The max absolute error bound must be non-negative.
|
||||
@ -4430,7 +4627,7 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
|
||||
// matches a Foo object x if and only if x.number >= 5.
|
||||
template <typename Class, typename FieldType, typename FieldMatcher>
|
||||
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
||||
FieldType Class::*field, const FieldMatcher& matcher) {
|
||||
FieldType Class::* field, const FieldMatcher& matcher) {
|
||||
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
|
||||
field, MatcherCast<const FieldType&>(matcher)));
|
||||
// The call to MatcherCast() is required for supporting inner
|
||||
@ -4443,7 +4640,7 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
||||
// messages.
|
||||
template <typename Class, typename FieldType, typename FieldMatcher>
|
||||
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
||||
const std::string& field_name, FieldType Class::*field,
|
||||
const std::string& field_name, FieldType Class::* field,
|
||||
const FieldMatcher& matcher) {
|
||||
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
|
||||
field_name, field, MatcherCast<const FieldType&>(matcher)));
|
||||
@ -4453,6 +4650,10 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
||||
// matches 'matcher'. For example,
|
||||
// Property(&Foo::str, StartsWith("hi"))
|
||||
// matches a Foo object x if and only if x.str() starts with "hi".
|
||||
//
|
||||
// Warning: Don't use `Property()` against member functions that you do not
|
||||
// own, because taking addresses of functions is fragile and generally not part
|
||||
// of the contract of the function.
|
||||
template <typename Class, typename PropertyType, typename PropertyMatcher>
|
||||
inline PolymorphicMatcher<internal::PropertyMatcher<
|
||||
Class, PropertyType, PropertyType (Class::*)() const>>
|
||||
@ -5551,8 +5752,7 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
template <typename arg_type> \
|
||||
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener* \
|
||||
result_listener) const
|
||||
[[maybe_unused]] ::testing::MatchResultListener* result_listener) const
|
||||
|
||||
#define MATCHER_P(name, p0, description) \
|
||||
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))
|
||||
@ -5637,8 +5837,8 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
||||
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>:: \
|
||||
gmock_Impl<arg_type>::MatchAndExplain( \
|
||||
const arg_type& arg, \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing:: \
|
||||
MatchResultListener* result_listener) const
|
||||
[[maybe_unused]] ::testing::MatchResultListener* result_listener) \
|
||||
const
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
|
||||
GMOCK_PP_TAIL( \
|
||||
|
||||
@ -521,9 +521,8 @@
|
||||
GMOCK_INTERNAL_DECL_##value_params) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||
= default; \
|
||||
, \
|
||||
: impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
, : impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params \
|
||||
@ -551,10 +550,10 @@
|
||||
}; \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
GMOCK_ACTION_CLASS_( \
|
||||
[[nodiscard]] GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params); \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
inline GMOCK_ACTION_CLASS_( \
|
||||
|
||||
@ -467,11 +467,6 @@ struct Function<R(Args...)> {
|
||||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||
};
|
||||
|
||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
#endif
|
||||
|
||||
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
||||
// when std::tuple_element is used.
|
||||
// See: https://github.com/google/googletest/issues/3931
|
||||
|
||||
6
3rdparty/googletest/googletest/README.md
vendored
6
3rdparty/googletest/googletest/README.md
vendored
@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
|
||||
with
|
||||
|
||||
```
|
||||
git clone https://github.com/google/googletest.git -b v1.16.0
|
||||
git clone https://github.com/google/googletest.git -b v1.17.0
|
||||
cd googletest # Main directory of the cloned repository.
|
||||
mkdir build # Create a directory to hold the build output.
|
||||
cd build
|
||||
@ -124,9 +124,9 @@ match the project in which it is included.
|
||||
|
||||
#### C++ Standard Version
|
||||
|
||||
An environment that supports C++14 is required in order to successfully build
|
||||
An environment that supports C++17 is required in order to successfully build
|
||||
GoogleTest. One way to ensure this is to specify the standard in the top-level
|
||||
project, for example by using the `set(CMAKE_CXX_STANDARD 14)` command along
|
||||
project, for example by using the `set(CMAKE_CXX_STANDARD 17)` command along
|
||||
with `set(CMAKE_CXX_STANDARD_REQUIRED ON)`. If this is not feasible, for example
|
||||
in a C project using GoogleTest for validation, then it can be specified by
|
||||
adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option.
|
||||
|
||||
@ -129,6 +129,13 @@ namespace testing {
|
||||
//
|
||||
// Expected: Foo() is even
|
||||
// Actual: it's 5
|
||||
//
|
||||
|
||||
// Returned AssertionResult objects may not be ignored.
|
||||
// Note: Disabled for SWIG as it doesn't parse attributes correctly.
|
||||
#if !defined(SWIG)
|
||||
class [[nodiscard]] AssertionResult;
|
||||
#endif // !SWIG
|
||||
|
||||
class GTEST_API_ AssertionResult {
|
||||
public:
|
||||
|
||||
@ -174,6 +174,7 @@ TEST_P(DerivedTest, DoesBlah) {
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
@ -413,7 +414,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
// Synopsis:
|
||||
// ConvertGenerator<T>(gen)
|
||||
// - returns a generator producing the same elements as generated by gen, but
|
||||
// each element is static_cast to type T before being returned
|
||||
// each T-typed element is static_cast to a type deduced from the interface
|
||||
// that accepts this generator, and then returned
|
||||
//
|
||||
// It is useful when using the Combine() function to get the generated
|
||||
// parameters in a custom type instead of std::tuple
|
||||
@ -441,10 +443,65 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE))));
|
||||
//
|
||||
template <typename T>
|
||||
internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
internal::ParamGenerator<T> gen) {
|
||||
return internal::ParamConverterGenerator<T>(gen);
|
||||
template <typename RequestedT>
|
||||
internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
|
||||
internal::ParamGenerator<RequestedT> gen) {
|
||||
return internal::ParamConverterGenerator<RequestedT>(std::move(gen));
|
||||
}
|
||||
|
||||
// As above, but takes a callable as a second argument. The callable converts
|
||||
// the generated parameter to the test fixture's parameter type. This allows you
|
||||
// to use a parameter type that does not have a converting constructor from the
|
||||
// generated type.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test suite AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// struct ParamType {
|
||||
// std::string animal;
|
||||
// Color color;
|
||||
// };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<ParamType> {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(
|
||||
// AnimalVariations, AnimalTest,
|
||||
// ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)),
|
||||
// [](std::tuple<std::string, Color> t) {
|
||||
// return ParamType{.animal = std::get<0>(t),
|
||||
// .color = std::get<1>(t)};
|
||||
// }));
|
||||
//
|
||||
template <typename T, int&... ExplicitArgumentBarrier, typename Gen,
|
||||
typename Func,
|
||||
typename StdFunction = decltype(std::function(std::declval<Func>()))>
|
||||
internal::ParamConverterGenerator<T, StdFunction> ConvertGenerator(Gen&& gen,
|
||||
Func&& f) {
|
||||
return internal::ParamConverterGenerator<T, StdFunction>(
|
||||
std::forward<Gen>(gen), std::forward<Func>(f));
|
||||
}
|
||||
|
||||
// As above, but infers the T from the supplied std::function instead of
|
||||
// having the caller specify it.
|
||||
template <int&... ExplicitArgumentBarrier, typename Gen, typename Func,
|
||||
typename StdFunction = decltype(std::function(std::declval<Func>()))>
|
||||
auto ConvertGenerator(Gen&& gen, Func&& f) {
|
||||
constexpr bool is_single_arg_std_function =
|
||||
internal::IsSingleArgStdFunction<StdFunction>::value;
|
||||
if constexpr (is_single_arg_std_function) {
|
||||
return ConvertGenerator<
|
||||
typename internal::FuncSingleParamType<StdFunction>::type>(
|
||||
std::forward<Gen>(gen), std::forward<Func>(f));
|
||||
} else {
|
||||
static_assert(is_single_arg_std_function,
|
||||
"The call signature must contain a single argument.");
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_P(test_suite_name, test_name) \
|
||||
@ -469,7 +526,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
||||
return 0; \
|
||||
} \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \
|
||||
[[maybe_unused]] static int gtest_registering_dummy_; \
|
||||
}; \
|
||||
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
@ -493,39 +550,38 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
#define GTEST_GET_FIRST_(first, ...) first
|
||||
#define GTEST_GET_SECOND_(first, second, ...) second
|
||||
|
||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||
if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))); \
|
||||
auto t = std::make_tuple(__VA_ARGS__); \
|
||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||
"Too Many Args!"); \
|
||||
} \
|
||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))))(info); \
|
||||
} \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \
|
||||
gtest_##prefix##test_suite_name##_dummy_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
GTEST_STRINGIFY_(test_suite_name), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestSuiteInstantiation( \
|
||||
GTEST_STRINGIFY_(prefix), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
||||
__FILE__, __LINE__)
|
||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||
if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))); \
|
||||
auto t = std::make_tuple(__VA_ARGS__); \
|
||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||
"Too Many Args!"); \
|
||||
} \
|
||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))))(info); \
|
||||
} \
|
||||
[[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
GTEST_STRINGIFY_(test_suite_name), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestSuiteInstantiation( \
|
||||
GTEST_STRINGIFY_(prefix), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
|
||||
__LINE__)
|
||||
|
||||
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
||||
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
|
||||
|
||||
@ -194,34 +194,33 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
||||
GTEST_NAME_GENERATOR_(CaseName)
|
||||
|
||||
#define TYPED_TEST(CaseName, TestName) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||
"test-name must not be empty"); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
||||
gtest_##CaseName##_##TestName##_registered_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_( \
|
||||
CaseName, TestName)>, \
|
||||
GTEST_TYPE_PARAMS_( \
|
||||
CaseName)>::Register("", \
|
||||
::testing::internal::CodeLocation( \
|
||||
__FILE__, __LINE__), \
|
||||
GTEST_STRINGIFY_(CaseName), \
|
||||
GTEST_STRINGIFY_(TestName), 0, \
|
||||
::testing::internal::GenerateNames< \
|
||||
GTEST_NAME_GENERATOR_(CaseName), \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
#define TYPED_TEST(CaseName, TestName) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||
"test-name must not be empty"); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
[[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)>, \
|
||||
GTEST_TYPE_PARAMS_( \
|
||||
CaseName)>::Register("", \
|
||||
::testing::internal::CodeLocation( \
|
||||
__FILE__, __LINE__), \
|
||||
GTEST_STRINGIFY_(CaseName), \
|
||||
GTEST_STRINGIFY_(TestName), 0, \
|
||||
::testing::internal::GenerateNames< \
|
||||
GTEST_NAME_GENERATOR_(CaseName), \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
@ -268,23 +267,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
||||
gtest_##TestName##_defined_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Note: this won't work correctly if the trailing arguments are macros.
|
||||
@ -292,8 +290,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||
} \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName) = \
|
||||
[[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||
SuiteName) = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
@ -305,24 +303,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
REGISTER_TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||
"test-suit-prefix must not be empty"); \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
||||
gtest_##Prefix##_##SuiteName = \
|
||||
::testing::internal::TypeParameterizedTestSuite< \
|
||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||
Register( \
|
||||
GTEST_STRINGIFY_(Prefix), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||
GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||
::testing::internal::GenerateNames< \
|
||||
::testing::internal::NameGeneratorSelector< \
|
||||
__VA_ARGS__>::type, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>())
|
||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||
"test-suit-prefix must not be empty"); \
|
||||
[[maybe_unused]] static bool gtest_##Prefix##_##SuiteName = \
|
||||
::testing::internal::TypeParameterizedTestSuite< \
|
||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||
Register(GTEST_STRINGIFY_(Prefix), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||
GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||
::testing::internal::GenerateNames< \
|
||||
::testing::internal::NameGeneratorSelector< \
|
||||
__VA_ARGS__>::type, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>())
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
@ -1123,7 +1123,7 @@ class GTEST_API_ UnitTest {
|
||||
// This method can only be called from the main thread.
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
int Run() GTEST_MUST_USE_RESULT_;
|
||||
[[nodiscard]] int Run();
|
||||
|
||||
// Returns the working directory when the first TEST() or TEST_F()
|
||||
// was executed. The UnitTest object owns the string.
|
||||
@ -2329,7 +2329,7 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
|
||||
//
|
||||
// This function was formerly a macro; thus, it is in the global
|
||||
// namespace and has an all-caps name.
|
||||
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
|
||||
[[nodiscard]] int RUN_ALL_TESTS();
|
||||
|
||||
inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }
|
||||
|
||||
|
||||
@ -290,17 +290,17 @@ class FloatingPoint {
|
||||
// around may change its bits, although the new value is guaranteed
|
||||
// to be also a NAN. Therefore, don't expect this constructor to
|
||||
// preserve the bits in x when x is a NAN.
|
||||
explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
|
||||
explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
|
||||
|
||||
// Static methods
|
||||
|
||||
// Reinterprets a bit pattern as a floating-point number.
|
||||
//
|
||||
// This function is needed to test the AlmostEquals() method.
|
||||
static RawType ReinterpretBits(const Bits bits) {
|
||||
FloatingPoint fp(0);
|
||||
fp.u_.bits_ = bits;
|
||||
return fp.u_.value_;
|
||||
static RawType ReinterpretBits(Bits bits) {
|
||||
RawType fp;
|
||||
memcpy(&fp, &bits, sizeof(fp));
|
||||
return fp;
|
||||
}
|
||||
|
||||
// Returns the floating-point number that represent positive infinity.
|
||||
@ -309,16 +309,16 @@ class FloatingPoint {
|
||||
// Non-static methods
|
||||
|
||||
// Returns the bits that represents this number.
|
||||
const Bits& bits() const { return u_.bits_; }
|
||||
const Bits& bits() const { return bits_; }
|
||||
|
||||
// Returns the exponent bits of this number.
|
||||
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
|
||||
Bits exponent_bits() const { return kExponentBitMask & bits_; }
|
||||
|
||||
// Returns the fraction bits of this number.
|
||||
Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
|
||||
Bits fraction_bits() const { return kFractionBitMask & bits_; }
|
||||
|
||||
// Returns the sign bit of this number.
|
||||
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
|
||||
Bits sign_bit() const { return kSignBitMask & bits_; }
|
||||
|
||||
// Returns true if and only if this is NAN (not a number).
|
||||
bool is_nan() const {
|
||||
@ -332,23 +332,16 @@ class FloatingPoint {
|
||||
//
|
||||
// - returns false if either number is (or both are) NAN.
|
||||
// - treats really large numbers as almost equal to infinity.
|
||||
// - thinks +0.0 and -0.0 are 0 DLP's apart.
|
||||
// - thinks +0.0 and -0.0 are 0 ULP's apart.
|
||||
bool AlmostEquals(const FloatingPoint& rhs) const {
|
||||
// The IEEE standard says that any comparison operation involving
|
||||
// a NAN must return false.
|
||||
if (is_nan() || rhs.is_nan()) return false;
|
||||
|
||||
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
|
||||
kMaxUlps;
|
||||
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
|
||||
}
|
||||
|
||||
private:
|
||||
// The data type used to store the actual floating-point number.
|
||||
union FloatingPointUnion {
|
||||
RawType value_; // The raw floating-point number.
|
||||
Bits bits_; // The bits that represent the number.
|
||||
};
|
||||
|
||||
// Converts an integer from the sign-and-magnitude representation to
|
||||
// the biased representation. More precisely, let N be 2 to the
|
||||
// power of (kBitCount - 1), an integer x is represented by the
|
||||
@ -364,7 +357,7 @@ class FloatingPoint {
|
||||
//
|
||||
// Read https://en.wikipedia.org/wiki/Signed_number_representations
|
||||
// for more details on signed number representations.
|
||||
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
||||
static Bits SignAndMagnitudeToBiased(Bits sam) {
|
||||
if (kSignBitMask & sam) {
|
||||
// sam represents a negative number.
|
||||
return ~sam + 1;
|
||||
@ -376,14 +369,13 @@ class FloatingPoint {
|
||||
|
||||
// Given two numbers in the sign-and-magnitude representation,
|
||||
// returns the distance between them as an unsigned number.
|
||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
|
||||
const Bits& sam2) {
|
||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
|
||||
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
||||
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
||||
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
||||
}
|
||||
|
||||
FloatingPointUnion u_;
|
||||
Bits bits_; // The bits that represent the number.
|
||||
};
|
||||
|
||||
// Typedefs the instances of the FloatingPoint template class that we
|
||||
@ -894,11 +886,6 @@ class HasDebugStringAndShortDebugString {
|
||||
HasDebugStringType::value && HasShortDebugStringType::value;
|
||||
};
|
||||
|
||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
||||
template <typename T>
|
||||
constexpr bool HasDebugStringAndShortDebugString<T>::value;
|
||||
#endif
|
||||
|
||||
// When the compiler sees expression IsContainerTest<C>(0), if C is an
|
||||
// STL-style container class, the first overload of IsContainerTest
|
||||
// will be viable (since both C::iterator* and C::const_iterator* are
|
||||
@ -1241,30 +1228,40 @@ class FlatTuple
|
||||
|
||||
// Utility functions to be called with static_assert to induce deprecation
|
||||
// warnings.
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
||||
"INSTANTIATE_TEST_SUITE_P")
|
||||
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
|
||||
"INSTANTIATE_TEST_SUITE_P")]]
|
||||
constexpr bool InstantiateTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"TYPED_TEST_CASE_P is deprecated, please use "
|
||||
"TYPED_TEST_SUITE_P")
|
||||
constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
|
||||
"TYPED_TEST_SUITE_P")]]
|
||||
constexpr bool TypedTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"TYPED_TEST_CASE is deprecated, please use "
|
||||
"TYPED_TEST_SUITE")
|
||||
constexpr bool TypedTestCaseIsDeprecated() { return true; }
|
||||
"TYPED_TEST_SUITE")]]
|
||||
constexpr bool TypedTestCaseIsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
||||
"REGISTER_TYPED_TEST_SUITE_P")
|
||||
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
|
||||
"REGISTER_TYPED_TEST_SUITE_P")]]
|
||||
constexpr bool RegisterTypedTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GTEST_INTERNAL_DEPRECATED(
|
||||
[[deprecated(
|
||||
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
||||
"INSTANTIATE_TYPED_TEST_SUITE_P")
|
||||
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
|
||||
"INSTANTIATE_TYPED_TEST_SUITE_P")]]
|
||||
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
@ -1501,8 +1498,7 @@ class NeverThrown {
|
||||
\
|
||||
private: \
|
||||
void TestBody() override; \
|
||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \
|
||||
test_info_; \
|
||||
[[maybe_unused]] static ::testing::TestInfo* const test_info_; \
|
||||
}; \
|
||||
\
|
||||
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@ -529,8 +530,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||
// prefix). test_base_name is the name of an individual test without
|
||||
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||
// test suite base name and DoBar is test base name.
|
||||
void AddTestPattern(const char*,
|
||||
const char* test_base_name,
|
||||
void AddTestPattern(const char*, const char* test_base_name,
|
||||
TestMetaFactoryBase<ParamType>* meta_factory,
|
||||
CodeLocation code_location) {
|
||||
tests_.emplace_back(
|
||||
@ -952,11 +952,11 @@ class CartesianProductHolder {
|
||||
std::tuple<Gen...> generators_;
|
||||
};
|
||||
|
||||
template <typename From, typename To>
|
||||
template <typename From, typename To, typename Func>
|
||||
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
public:
|
||||
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
|
||||
: generator_(std::move(gen)) {}
|
||||
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
|
||||
: generator_(std::move(gen)), converter_(std::move(converter)) {}
|
||||
|
||||
ParamIteratorInterface<To>* Begin() const override {
|
||||
return new Iterator(this, generator_.begin(), generator_.end());
|
||||
@ -965,13 +965,21 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
return new Iterator(this, generator_.end(), generator_.end());
|
||||
}
|
||||
|
||||
// Returns the std::function wrapping the user-supplied converter callable. It
|
||||
// is used by the iterator (see class Iterator below) to convert the object
|
||||
// (of type FROM) returned by the ParamGenerator to an object of a type that
|
||||
// can be static_cast to type TO.
|
||||
const Func& TypeConverter() const { return converter_; }
|
||||
|
||||
private:
|
||||
class Iterator : public ParamIteratorInterface<To> {
|
||||
public:
|
||||
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
|
||||
Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
|
||||
ParamIterator<From> end)
|
||||
: base_(base), it_(it), end_(end) {
|
||||
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
|
||||
if (it_ != end_)
|
||||
value_ =
|
||||
std::make_shared<To>(static_cast<To>(base->TypeConverter()(*it_)));
|
||||
}
|
||||
~Iterator() override = default;
|
||||
|
||||
@ -980,7 +988,9 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
}
|
||||
void Advance() override {
|
||||
++it_;
|
||||
if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
|
||||
if (it_ != end_)
|
||||
value_ =
|
||||
std::make_shared<To>(static_cast<To>(base_->TypeConverter()(*it_)));
|
||||
}
|
||||
ParamIteratorInterface<To>* Clone() const override {
|
||||
return new Iterator(*this);
|
||||
@ -1000,30 +1010,54 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||
private:
|
||||
Iterator(const Iterator& other) = default;
|
||||
|
||||
const ParamGeneratorInterface<To>* const base_;
|
||||
const ParamGeneratorConverter* const base_;
|
||||
ParamIterator<From> it_;
|
||||
ParamIterator<From> end_;
|
||||
std::shared_ptr<To> value_;
|
||||
}; // class ParamGeneratorConverter::Iterator
|
||||
|
||||
ParamGenerator<From> generator_;
|
||||
Func converter_;
|
||||
}; // class ParamGeneratorConverter
|
||||
|
||||
template <class Gen>
|
||||
template <class GeneratedT,
|
||||
typename StdFunction =
|
||||
std::function<const GeneratedT&(const GeneratedT&)>>
|
||||
class ParamConverterGenerator {
|
||||
public:
|
||||
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
|
||||
: generator_(std::move(g)) {}
|
||||
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
|
||||
: generator_(std::move(g)), converter_(Identity) {}
|
||||
|
||||
ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
|
||||
: generator_(std::move(g)), converter_(std::move(converter)) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { // NOLINT
|
||||
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
|
||||
return ParamGenerator<T>(
|
||||
new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
|
||||
converter_));
|
||||
}
|
||||
|
||||
private:
|
||||
ParamGenerator<Gen> generator_;
|
||||
static const GeneratedT& Identity(const GeneratedT& v) { return v; }
|
||||
|
||||
ParamGenerator<GeneratedT> generator_;
|
||||
StdFunction converter_;
|
||||
};
|
||||
|
||||
// Template to determine the param type of a single-param std::function.
|
||||
template <typename T>
|
||||
struct FuncSingleParamType;
|
||||
template <typename R, typename P>
|
||||
struct FuncSingleParamType<std::function<R(P)>> {
|
||||
using type = std::remove_cv_t<std::remove_reference_t<P>>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsSingleArgStdFunction : public std::false_type {};
|
||||
template <typename R, typename P>
|
||||
struct IsSingleArgStdFunction<std::function<R(P)>> : public std::true_type {};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
|
||||
@ -194,7 +194,6 @@
|
||||
//
|
||||
// Macros for basic C++ coding:
|
||||
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
||||
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
|
||||
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
|
||||
// suppressed (constant conditional).
|
||||
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
||||
@ -260,11 +259,6 @@
|
||||
// BoolFromGTestEnv() - parses a bool environment variable.
|
||||
// Int32FromGTestEnv() - parses an int32_t environment variable.
|
||||
// StringFromGTestEnv() - parses a string environment variable.
|
||||
//
|
||||
// Deprecation warnings:
|
||||
// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as
|
||||
// deprecated; calling a marked function
|
||||
// should generate a compiler warning
|
||||
|
||||
// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can
|
||||
// potentially be used as an #include guard.
|
||||
@ -275,8 +269,8 @@
|
||||
#endif
|
||||
|
||||
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L
|
||||
#error C++ versions less than C++14 are not supported.
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
|
||||
#error C++ versions less than C++17 are not supported.
|
||||
#endif
|
||||
|
||||
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
|
||||
@ -288,10 +282,14 @@
|
||||
|
||||
// Detect C++ feature test macros as gracefully as possible.
|
||||
// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
|
||||
#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \
|
||||
(!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))
|
||||
#include <version> // C++20 and later
|
||||
#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))
|
||||
//
|
||||
// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
|
||||
// <version> instead, even though <version> is not available in C++17 mode prior
|
||||
// to GCC9.
|
||||
#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
|
||||
GTEST_INTERNAL_HAS_INCLUDE(<version>)
|
||||
#include <version> // C++20 or <version> support.
|
||||
#else
|
||||
#include <ciso646> // Pre-C++20
|
||||
#endif
|
||||
|
||||
@ -772,25 +770,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#define GTEST_HAVE_FEATURE_(x) 0
|
||||
#endif
|
||||
|
||||
// Use this annotation after a variable or parameter declaration to tell the
|
||||
// compiler the variable/parameter may be used.
|
||||
// Example:
|
||||
//
|
||||
// GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar();
|
||||
//
|
||||
// This can be removed once we only support only C++17 or newer and
|
||||
// [[maybe_unused]] is available on all supported platforms.
|
||||
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused)
|
||||
#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
|
||||
#elif GTEST_HAVE_ATTRIBUTE_(unused)
|
||||
// This is inferior to [[maybe_unused]] as it can produce a
|
||||
// -Wused-but-marked-unused warning on optionally used symbols, but it is all we
|
||||
// have.
|
||||
#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
// Use this annotation before a function that takes a printf format string.
|
||||
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
||||
// MinGW has two different printf implementations. Ensure the format macro
|
||||
@ -805,17 +784,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
||||
#endif
|
||||
|
||||
// Tell the compiler to warn about unused return values for functions declared
|
||||
// with this macro. The macro should be used on function declarations
|
||||
// following the argument list:
|
||||
//
|
||||
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
|
||||
#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)
|
||||
#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
|
||||
#else
|
||||
#define GTEST_MUST_USE_RESULT_
|
||||
#endif
|
||||
|
||||
// MS C++ compiler emits warning when a conditional expression is compile time
|
||||
// constant. In some contexts this warning is false positive and needs to be
|
||||
// suppressed. Use the following two macros in such cases:
|
||||
@ -2367,26 +2335,6 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#if !defined(GTEST_INTERNAL_DEPRECATED)
|
||||
|
||||
// Internal Macro to mark an API deprecated, for googletest usage only
|
||||
// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or
|
||||
// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of
|
||||
// a deprecated entity will trigger a warning when compiled with
|
||||
// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).
|
||||
// For msvc /W3 option will need to be used
|
||||
// Note that for 'other' compilers this macro evaluates to nothing to prevent
|
||||
// compilations errors.
|
||||
#if defined(_MSC_VER)
|
||||
#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))
|
||||
#elif defined(__GNUC__)
|
||||
#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
#else
|
||||
#define GTEST_INTERNAL_DEPRECATED(message)
|
||||
#endif
|
||||
|
||||
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
||||
// is built with absl support.
|
||||
@ -2527,12 +2475,6 @@ using Variant = ::std::variant<T...>;
|
||||
#define GTEST_INTERNAL_HAS_VARIANT 0
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_constexpr) && !defined(__cpp_inline_variables)) || \
|
||||
(defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L)
|
||||
#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_lib_three_way_comparison) || \
|
||||
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
||||
|
||||
@ -826,6 +826,10 @@ class GTEST_API_ UnitTestImpl {
|
||||
bool catch_exceptions() const { return catch_exceptions_; }
|
||||
|
||||
private:
|
||||
// Returns true if a warning should be issued if no tests match the test
|
||||
// filter flag.
|
||||
bool ShouldWarnIfNoTestsMatchFilter() const;
|
||||
|
||||
struct CompareTestSuitesByPointer {
|
||||
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
|
||||
return lhs->name_ < rhs->name_;
|
||||
|
||||
86
3rdparty/googletest/googletest/src/gtest.cc
vendored
86
3rdparty/googletest/googletest/src/gtest.cc
vendored
@ -192,12 +192,17 @@ static const char kDefaultOutputFormat[] = "xml";
|
||||
// The default output file.
|
||||
static const char kDefaultOutputFile[] = "test_detail";
|
||||
|
||||
// These environment variables are set by Bazel.
|
||||
// https://bazel.build/reference/test-encyclopedia#initial-conditions
|
||||
//
|
||||
// The environment variable name for the test shard index.
|
||||
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
||||
// The environment variable name for the total number of test shards.
|
||||
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
||||
// The environment variable name for the test shard status file.
|
||||
static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
|
||||
// The environment variable name for the test output warnings file.
|
||||
static const char kTestWarningsOutputFile[] = "TEST_WARNINGS_OUTPUT_FILE";
|
||||
|
||||
namespace internal {
|
||||
|
||||
@ -258,6 +263,12 @@ GTEST_DEFINE_bool_(
|
||||
testing::GetDefaultFailFast()),
|
||||
"True if and only if a test failure should stop further test execution.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
fail_if_no_test_linked,
|
||||
testing::internal::BoolFromGTestEnv("fail_if_no_test_linked", false),
|
||||
"True if and only if the test should fail if no test case (including "
|
||||
"disabled test cases) is linked.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
also_run_disabled_tests,
|
||||
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||
@ -5869,6 +5880,23 @@ TestSuite* UnitTestImpl::GetTestSuite(
|
||||
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
|
||||
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
||||
|
||||
// If the environment variable TEST_WARNINGS_OUTPUT_FILE was provided, appends
|
||||
// `str` to the file, creating the file if necessary.
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
static void AppendToTestWarningsOutputFile(const std::string& str) {
|
||||
const char* const filename = posix::GetEnv(kTestWarningsOutputFile);
|
||||
if (filename == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto* const file = posix::FOpen(filename, "a");
|
||||
if (file == nullptr) {
|
||||
return;
|
||||
}
|
||||
GTEST_CHECK_(fwrite(str.data(), 1, str.size(), file) == str.size());
|
||||
GTEST_CHECK_(posix::FClose(file) == 0);
|
||||
}
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
|
||||
// Runs all tests in this UnitTest object, prints the result, and
|
||||
// returns true if all tests are successful. If any exception is
|
||||
// thrown during a test, the test is considered to be failed, but the
|
||||
@ -5890,6 +5918,28 @@ bool UnitTestImpl::RunAllTests() {
|
||||
// user didn't call InitGoogleTest.
|
||||
PostFlagParsingInit();
|
||||
|
||||
// Handle the case where the program has no tests linked.
|
||||
// Sometimes this is a programmer mistake, but sometimes it is intended.
|
||||
if (total_test_count() == 0) {
|
||||
constexpr char kNoTestLinkedMessage[] =
|
||||
"This test program does NOT link in any test case.";
|
||||
constexpr char kNoTestLinkedFatal[] =
|
||||
"This is INVALID. Please make sure to link in at least one test case.";
|
||||
constexpr char kNoTestLinkedWarning[] =
|
||||
"Please make sure this is intended.";
|
||||
const bool fail_if_no_test_linked = GTEST_FLAG_GET(fail_if_no_test_linked);
|
||||
ColoredPrintf(
|
||||
GTestColor::kRed, "%s %s\n", kNoTestLinkedMessage,
|
||||
fail_if_no_test_linked ? kNoTestLinkedFatal : kNoTestLinkedWarning);
|
||||
if (fail_if_no_test_linked) {
|
||||
return false;
|
||||
}
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
AppendToTestWarningsOutputFile(std::string(kNoTestLinkedMessage) + ' ' +
|
||||
kNoTestLinkedWarning + '\n');
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
}
|
||||
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
// Even if sharding is not on, test runners may want to use the
|
||||
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
||||
@ -6063,6 +6113,17 @@ bool UnitTestImpl::RunAllTests() {
|
||||
environments_.clear();
|
||||
}
|
||||
|
||||
// Try to warn the user if no tests matched the test filter.
|
||||
if (ShouldWarnIfNoTestsMatchFilter()) {
|
||||
const std::string filter_warning =
|
||||
std::string("filter \"") + GTEST_FLAG_GET(filter) +
|
||||
"\" did not match any test; no tests were run\n";
|
||||
ColoredPrintf(GTestColor::kRed, "WARNING: %s", filter_warning.c_str());
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
AppendToTestWarningsOutputFile(filter_warning);
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
}
|
||||
|
||||
if (!gtest_is_initialized_before_run_all_tests) {
|
||||
ColoredPrintf(
|
||||
GTestColor::kRed,
|
||||
@ -6231,6 +6292,30 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
||||
return num_selected_tests;
|
||||
}
|
||||
|
||||
// Returns true if a warning should be issued if no tests match the test filter
|
||||
// flag. We can't simply count the number of tests that ran because, for
|
||||
// instance, test sharding and death tests might mean no tests are expected to
|
||||
// run in this process, but will run in another process.
|
||||
bool UnitTestImpl::ShouldWarnIfNoTestsMatchFilter() const {
|
||||
if (total_test_count() == 0) {
|
||||
// No tests were linked in to program.
|
||||
// This case is handled by a different warning.
|
||||
return false;
|
||||
}
|
||||
const PositiveAndNegativeUnitTestFilter gtest_flag_filter(
|
||||
GTEST_FLAG_GET(filter));
|
||||
for (auto* test_suite : test_suites_) {
|
||||
const std::string& test_suite_name = test_suite->name_;
|
||||
for (TestInfo* test_info : test_suite->test_info_list()) {
|
||||
const std::string& test_name = test_info->name_;
|
||||
if (gtest_flag_filter.MatchesTest(test_suite_name, test_name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prints the given C-string on a single line by replacing all '\n'
|
||||
// characters with string "\\n". If the output takes more than
|
||||
// max_length characters, only prints the first max_length characters
|
||||
@ -6677,6 +6762,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
|
||||
GTEST_INTERNAL_PARSE_FLAG(death_test_style);
|
||||
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(filter);
|
||||
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
||||
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user