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 and Google Mock Communities
|
||||||
|
|
||||||
The Google Test community exists primarily through the
|
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
|
GitHub repository. Likewise, the Google Mock community exists primarily through
|
||||||
their own [discussion group](http://groups.google.com/group/googlemock). You are
|
their own [discussion group](https://groups.google.com/group/googlemock). You
|
||||||
definitely encouraged to contribute to the discussion and you can also help us
|
are definitely encouraged to contribute to the discussion and you can also help
|
||||||
to keep the effectiveness of the group high by following and promoting the
|
us to keep the effectiveness of the group high by following and promoting the
|
||||||
guidelines listed here.
|
guidelines listed here.
|
||||||
|
|
||||||
### Please Be Friendly
|
### Please Be Friendly
|
||||||
|
|||||||
15
3rdparty/googletest/README.md
vendored
15
3rdparty/googletest/README.md
vendored
@ -2,27 +2,18 @@
|
|||||||
|
|
||||||
### Announcements
|
### 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
|
#### Documentation Updates
|
||||||
|
|
||||||
Our documentation is now live on GitHub Pages at
|
Our documentation is now live on GitHub Pages at
|
||||||
https://google.github.io/googletest/. We recommend browsing the documentation on
|
https://google.github.io/googletest/. We recommend browsing the documentation on
|
||||||
GitHub Pages rather than directly in the repository.
|
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.
|
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
|
#### Continuous Integration
|
||||||
|
|
||||||
|
|||||||
@ -835,6 +835,10 @@ class Action<R(Args...)> {
|
|||||||
Result operator()(const InArgs&...) const {
|
Result operator()(const InArgs&...) const {
|
||||||
return function_impl();
|
return function_impl();
|
||||||
}
|
}
|
||||||
|
template <typename... InArgs>
|
||||||
|
Result operator()(const InArgs&...) {
|
||||||
|
return function_impl();
|
||||||
|
}
|
||||||
|
|
||||||
FunctionImpl function_impl;
|
FunctionImpl function_impl;
|
||||||
};
|
};
|
||||||
@ -1451,6 +1455,30 @@ struct WithArgsAction {
|
|||||||
return OA{std::move(inner_action)};
|
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 <
|
template <
|
||||||
typename R, typename... Args,
|
typename R, typename... Args,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
@ -1703,9 +1731,8 @@ template <size_t k>
|
|||||||
struct ReturnArgAction {
|
struct ReturnArgAction {
|
||||||
template <typename... Args,
|
template <typename... Args,
|
||||||
typename = typename std::enable_if<(k < sizeof...(Args))>::type>
|
typename = typename std::enable_if<(k < sizeof...(Args))>::type>
|
||||||
auto operator()(Args&&... args) const
|
auto operator()(Args&&... args) const -> decltype(std::get<k>(
|
||||||
-> decltype(std::get<k>(
|
std::forward_as_tuple(std::forward<Args>(args)...))) {
|
||||||
std::forward_as_tuple(std::forward<Args>(args)...))) {
|
|
||||||
return 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>
|
template <size_t k, typename Ptr>
|
||||||
struct SaveArgPointeeAction {
|
struct SaveArgPointeeAction {
|
||||||
Ptr pointer;
|
Ptr pointer;
|
||||||
@ -2070,6 +2107,13 @@ internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
|
|||||||
return {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
|
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||||
template <size_t k, typename Ptr>
|
template <size_t k, typename Ptr>
|
||||||
@ -2213,9 +2257,9 @@ template <typename F, typename Impl>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
|
||||||
, GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i
|
, [[maybe_unused]] const arg##i##_type& arg##i
|
||||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \
|
[[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
|
||||||
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
GMOCK_INTERNAL_ARG_UNUSED, , 10)
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
|
#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_; \
|
std::shared_ptr<const gmock_Impl> impl_; \
|
||||||
}; \
|
}; \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
[[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \
|
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
|
||||||
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
|
||||||
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
|
||||||
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
|
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; \
|
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(); } \
|
inline name##Action name() { return name##Action(); } \
|
||||||
template <typename function_type, typename return_type, typename args_type, \
|
template <typename function_type, typename return_type, typename args_type, \
|
||||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||||
|
|||||||
@ -257,6 +257,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstddef>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
@ -1311,6 +1312,15 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
|
|||||||
|
|
||||||
bool MatchAndExplain(const T& x,
|
bool MatchAndExplain(const T& x,
|
||||||
MatchResultListener* listener) const override {
|
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.
|
// This method uses matcher's explanation when explaining the result.
|
||||||
// However, if matcher doesn't provide one, this method uses matcher's
|
// However, if matcher doesn't provide one, this method uses matcher's
|
||||||
// description.
|
// description.
|
||||||
@ -1430,6 +1440,15 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
|
|||||||
|
|
||||||
bool MatchAndExplain(const T& x,
|
bool MatchAndExplain(const T& x,
|
||||||
MatchResultListener* listener) const override {
|
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.
|
// This method uses matcher's explanation when explaining the result.
|
||||||
// However, if matcher doesn't provide one, this method uses matcher's
|
// However, if matcher doesn't provide one, this method uses matcher's
|
||||||
// description.
|
// description.
|
||||||
@ -2097,11 +2116,11 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
|
|||||||
template <typename Class, typename FieldType>
|
template <typename Class, typename FieldType>
|
||||||
class FieldMatcher {
|
class FieldMatcher {
|
||||||
public:
|
public:
|
||||||
FieldMatcher(FieldType Class::*field,
|
FieldMatcher(FieldType Class::* field,
|
||||||
const Matcher<const FieldType&>& matcher)
|
const Matcher<const FieldType&>& matcher)
|
||||||
: field_(field), matcher_(matcher), whose_field_("whose given field ") {}
|
: 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)
|
const Matcher<const FieldType&>& matcher)
|
||||||
: field_(field),
|
: field_(field),
|
||||||
matcher_(matcher),
|
matcher_(matcher),
|
||||||
@ -2145,7 +2164,7 @@ class FieldMatcher {
|
|||||||
return MatchAndExplainImpl(std::false_type(), *p, listener);
|
return MatchAndExplainImpl(std::false_type(), *p, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FieldType Class::*field_;
|
const FieldType Class::* field_;
|
||||||
const Matcher<const FieldType&> matcher_;
|
const Matcher<const FieldType&> matcher_;
|
||||||
|
|
||||||
// Contains either "whose given field " if the name of the field is unknown
|
// 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.
|
// Implements Each(element_matcher) for the given argument type Container.
|
||||||
// Symmetric to ContainsMatcherImpl.
|
// Symmetric to ContainsMatcherImpl.
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
@ -2990,6 +3057,52 @@ auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT
|
|||||||
}
|
}
|
||||||
} // namespace pair_getters
|
} // 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.
|
// Implements Key(inner_matcher) for the given argument pair type.
|
||||||
// Key(inner_matcher) matches an std::pair whose 'first' field matches
|
// 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
|
// 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>
|
template <typename T, size_t... I>
|
||||||
auto UnpackStructImpl(const T& t, std::index_sequence<I...>,
|
auto UnpackStructImpl(const T& t, std::index_sequence<I...>, int)
|
||||||
int) -> decltype(std::tie(get<I>(t)...)) {
|
-> decltype(std::tie(get<I>(t)...)) {
|
||||||
static_assert(std::tuple_size<T>::value == sizeof...(I),
|
static_assert(std::tuple_size<T>::value == sizeof...(I),
|
||||||
"Number of arguments doesn't match the number of fields.");
|
"Number of arguments doesn't match the number of fields.");
|
||||||
return std::tie(get<I>(t)...);
|
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;
|
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);
|
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)
|
#endif // defined(__cpp_structured_bindings)
|
||||||
|
|
||||||
template <size_t I, typename T>
|
template <size_t I, typename T>
|
||||||
@ -3480,7 +3608,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
|||||||
StlContainerReference stl_container = View::ConstReference(container);
|
StlContainerReference stl_container = View::ConstReference(container);
|
||||||
auto it = stl_container.begin();
|
auto it = stl_container.begin();
|
||||||
size_t exam_pos = 0;
|
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
|
// 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
|
// 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) {
|
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;
|
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
|
// Find how many elements the actual container has. We avoid
|
||||||
// calling size() s.t. this code works for stream-like "containers"
|
// calling size() s.t. this code works for stream-like "containers"
|
||||||
@ -3521,10 +3661,27 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mismatch_found) {
|
if (unmatched_found) {
|
||||||
// The element count matches, but the exam_pos-th element doesn't match.
|
// The element count matches, but the exam_pos-th element doesn't match.
|
||||||
if (listener_interested) {
|
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());
|
PrintIfNotEmpty(explanations[exam_pos], listener->stream());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -3930,15 +4087,15 @@ GTEST_API_ std::string FormatMatcherDescription(
|
|||||||
// Overloads to support `OptionalMatcher` being used with a type that either
|
// Overloads to support `OptionalMatcher` being used with a type that either
|
||||||
// supports implicit conversion to bool or a `has_value()` method.
|
// supports implicit conversion to bool or a `has_value()` method.
|
||||||
template <typename Optional>
|
template <typename Optional>
|
||||||
auto IsOptionalEngaged(const Optional& optional,
|
auto IsOptionalEngaged(const Optional& optional, Rank1)
|
||||||
Rank1) -> decltype(!!optional) {
|
-> decltype(!!optional) {
|
||||||
// The use of double-negation here is to preserve historical behavior where
|
// The use of double-negation here is to preserve historical behavior where
|
||||||
// the matcher used `operator!` rather than directly using `operator bool`.
|
// the matcher used `operator!` rather than directly using `operator bool`.
|
||||||
return !static_cast<bool>(!optional);
|
return !static_cast<bool>(!optional);
|
||||||
}
|
}
|
||||||
template <typename Optional>
|
template <typename Optional>
|
||||||
auto IsOptionalEngaged(const Optional& optional,
|
auto IsOptionalEngaged(const Optional& optional, Rank0)
|
||||||
Rank0) -> decltype(!optional.has_value()) {
|
-> decltype(!optional.has_value()) {
|
||||||
return optional.has_value();
|
return optional.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3979,6 +4136,10 @@ class OptionalMatcher {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const ValueType& value = *optional;
|
const ValueType& value = *optional;
|
||||||
|
if (!listener->IsInterested()) {
|
||||||
|
// Fast path to avoid unnecessary generation of match explanation.
|
||||||
|
return value_matcher_.Matches(value);
|
||||||
|
}
|
||||||
StringMatchResultListener value_listener;
|
StringMatchResultListener value_listener;
|
||||||
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
|
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
|
||||||
*listener << "whose value " << PrintToString(value)
|
*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);
|
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
|
// 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, up to the specified max absolute error bound, including NaN values when
|
||||||
// rhs is NaN. The max absolute error bound must be non-negative.
|
// 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.
|
// matches a Foo object x if and only if x.number >= 5.
|
||||||
template <typename Class, typename FieldType, typename FieldMatcher>
|
template <typename Class, typename FieldType, typename FieldMatcher>
|
||||||
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
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>(
|
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
|
||||||
field, MatcherCast<const FieldType&>(matcher)));
|
field, MatcherCast<const FieldType&>(matcher)));
|
||||||
// The call to MatcherCast() is required for supporting inner
|
// The call to MatcherCast() is required for supporting inner
|
||||||
@ -4443,7 +4640,7 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
|||||||
// messages.
|
// messages.
|
||||||
template <typename Class, typename FieldType, typename FieldMatcher>
|
template <typename Class, typename FieldType, typename FieldMatcher>
|
||||||
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
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) {
|
const FieldMatcher& matcher) {
|
||||||
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
|
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
|
||||||
field_name, field, MatcherCast<const FieldType&>(matcher)));
|
field_name, field, MatcherCast<const FieldType&>(matcher)));
|
||||||
@ -4453,6 +4650,10 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
|
|||||||
// matches 'matcher'. For example,
|
// matches 'matcher'. For example,
|
||||||
// Property(&Foo::str, StartsWith("hi"))
|
// Property(&Foo::str, StartsWith("hi"))
|
||||||
// matches a Foo object x if and only if x.str() starts with "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>
|
template <typename Class, typename PropertyType, typename PropertyMatcher>
|
||||||
inline PolymorphicMatcher<internal::PropertyMatcher<
|
inline PolymorphicMatcher<internal::PropertyMatcher<
|
||||||
Class, PropertyType, PropertyType (Class::*)() const>>
|
Class, PropertyType, PropertyType (Class::*)() const>>
|
||||||
@ -5551,8 +5752,7 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
|
|||||||
template <typename arg_type> \
|
template <typename arg_type> \
|
||||||
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
|
||||||
const arg_type& arg, \
|
const arg_type& arg, \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener* \
|
[[maybe_unused]] ::testing::MatchResultListener* result_listener) const
|
||||||
result_listener) const
|
|
||||||
|
|
||||||
#define MATCHER_P(name, p0, description) \
|
#define MATCHER_P(name, p0, description) \
|
||||||
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))
|
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)>:: \
|
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>:: \
|
||||||
gmock_Impl<arg_type>::MatchAndExplain( \
|
gmock_Impl<arg_type>::MatchAndExplain( \
|
||||||
const arg_type& arg, \
|
const arg_type& arg, \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing:: \
|
[[maybe_unused]] ::testing::MatchResultListener* result_listener) \
|
||||||
MatchResultListener* result_listener) const
|
const
|
||||||
|
|
||||||
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
|
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
|
||||||
GMOCK_PP_TAIL( \
|
GMOCK_PP_TAIL( \
|
||||||
|
|||||||
@ -521,9 +521,8 @@
|
|||||||
GMOCK_INTERNAL_DECL_##value_params) \
|
GMOCK_INTERNAL_DECL_##value_params) \
|
||||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||||
= default; \
|
= default; \
|
||||||
, \
|
, : impl_(std::make_shared<gmock_Impl>( \
|
||||||
: impl_(std::make_shared<gmock_Impl>( \
|
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
|
||||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||||
##value_params \
|
##value_params \
|
||||||
@ -551,10 +550,10 @@
|
|||||||
}; \
|
}; \
|
||||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
GMOCK_ACTION_CLASS_( \
|
[[nodiscard]] GMOCK_ACTION_CLASS_( \
|
||||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||||
GMOCK_INTERNAL_LIST_TYPE_##value_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 \
|
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||||
inline GMOCK_ACTION_CLASS_( \
|
inline GMOCK_ACTION_CLASS_( \
|
||||||
|
|||||||
@ -467,11 +467,6 @@ struct Function<R(Args...)> {
|
|||||||
using MakeResultIgnoredValue = IgnoredValue(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'
|
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
||||||
// when std::tuple_element is used.
|
// when std::tuple_element is used.
|
||||||
// See: https://github.com/google/googletest/issues/3931
|
// 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
|
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.
|
cd googletest # Main directory of the cloned repository.
|
||||||
mkdir build # Create a directory to hold the build output.
|
mkdir build # Create a directory to hold the build output.
|
||||||
cd build
|
cd build
|
||||||
@ -124,9 +124,9 @@ match the project in which it is included.
|
|||||||
|
|
||||||
#### C++ Standard Version
|
#### 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
|
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
|
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
|
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.
|
adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option.
|
||||||
|
|||||||
@ -129,6 +129,13 @@ namespace testing {
|
|||||||
//
|
//
|
||||||
// Expected: Foo() is even
|
// Expected: Foo() is even
|
||||||
// Actual: it's 5
|
// 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 {
|
class GTEST_API_ AssertionResult {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -174,6 +174,7 @@ TEST_P(DerivedTest, DoesBlah) {
|
|||||||
|
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -413,7 +414,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|||||||
// Synopsis:
|
// Synopsis:
|
||||||
// ConvertGenerator<T>(gen)
|
// ConvertGenerator<T>(gen)
|
||||||
// - returns a generator producing the same elements as generated by gen, but
|
// - 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
|
// It is useful when using the Combine() function to get the generated
|
||||||
// parameters in a custom type instead of std::tuple
|
// parameters in a custom type instead of std::tuple
|
||||||
@ -441,10 +443,65 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|||||||
// Combine(Values("cat", "dog"),
|
// Combine(Values("cat", "dog"),
|
||||||
// Values(BLACK, WHITE))));
|
// Values(BLACK, WHITE))));
|
||||||
//
|
//
|
||||||
template <typename T>
|
template <typename RequestedT>
|
||||||
internal::ParamConverterGenerator<T> ConvertGenerator(
|
internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
|
||||||
internal::ParamGenerator<T> gen) {
|
internal::ParamGenerator<RequestedT> gen) {
|
||||||
return internal::ParamConverterGenerator<T>(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) \
|
#define TEST_P(test_suite_name, test_name) \
|
||||||
@ -469,7 +526,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
|||||||
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
||||||
return 0; \
|
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, \
|
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
test_name)::gtest_registering_dummy_ = \
|
test_name)::gtest_registering_dummy_ = \
|
||||||
@ -493,39 +550,38 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
|
|||||||
#define GTEST_GET_FIRST_(first, ...) first
|
#define GTEST_GET_FIRST_(first, ...) first
|
||||||
#define GTEST_GET_SECOND_(first, second, ...) second
|
#define GTEST_GET_SECOND_(first, second, ...) second
|
||||||
|
|
||||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||||
} \
|
} \
|
||||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||||
if (::testing::internal::AlwaysFalse()) { \
|
if (::testing::internal::AlwaysFalse()) { \
|
||||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||||
__VA_ARGS__, \
|
__VA_ARGS__, \
|
||||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||||
DUMMY_PARAM_))); \
|
DUMMY_PARAM_))); \
|
||||||
auto t = std::make_tuple(__VA_ARGS__); \
|
auto t = std::make_tuple(__VA_ARGS__); \
|
||||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||||
"Too Many Args!"); \
|
"Too Many Args!"); \
|
||||||
} \
|
} \
|
||||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||||
__VA_ARGS__, \
|
__VA_ARGS__, \
|
||||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||||
DUMMY_PARAM_))))(info); \
|
DUMMY_PARAM_))))(info); \
|
||||||
} \
|
} \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \
|
[[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
|
||||||
gtest_##prefix##test_suite_name##_dummy_ = \
|
::testing::UnitTest::GetInstance() \
|
||||||
::testing::UnitTest::GetInstance() \
|
->parameterized_test_registry() \
|
||||||
->parameterized_test_registry() \
|
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
GTEST_STRINGIFY_(test_suite_name), \
|
||||||
GTEST_STRINGIFY_(test_suite_name), \
|
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
->AddTestSuiteInstantiation( \
|
||||||
->AddTestSuiteInstantiation( \
|
GTEST_STRINGIFY_(prefix), \
|
||||||
GTEST_STRINGIFY_(prefix), \
|
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
>est_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
|
||||||
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
__LINE__)
|
||||||
__FILE__, __LINE__)
|
|
||||||
|
|
||||||
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
||||||
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
|
#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 \
|
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
||||||
GTEST_NAME_GENERATOR_(CaseName)
|
GTEST_NAME_GENERATOR_(CaseName)
|
||||||
|
|
||||||
#define TYPED_TEST(CaseName, TestName) \
|
#define TYPED_TEST(CaseName, TestName) \
|
||||||
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||||
"test-name must not be empty"); \
|
"test-name must not be empty"); \
|
||||||
template <typename gtest_TypeParam_> \
|
template <typename gtest_TypeParam_> \
|
||||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||||
: public CaseName<gtest_TypeParam_> { \
|
: public CaseName<gtest_TypeParam_> { \
|
||||||
private: \
|
private: \
|
||||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||||
typedef gtest_TypeParam_ TypeParam; \
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
}; \
|
}; \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
[[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \
|
||||||
gtest_##CaseName##_##TestName##_registered_ = \
|
::testing::internal::TypeParameterizedTest< \
|
||||||
::testing::internal::TypeParameterizedTest< \
|
CaseName, \
|
||||||
CaseName, \
|
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_( \
|
TestName)>, \
|
||||||
CaseName, TestName)>, \
|
GTEST_TYPE_PARAMS_( \
|
||||||
GTEST_TYPE_PARAMS_( \
|
CaseName)>::Register("", \
|
||||||
CaseName)>::Register("", \
|
::testing::internal::CodeLocation( \
|
||||||
::testing::internal::CodeLocation( \
|
__FILE__, __LINE__), \
|
||||||
__FILE__, __LINE__), \
|
GTEST_STRINGIFY_(CaseName), \
|
||||||
GTEST_STRINGIFY_(CaseName), \
|
GTEST_STRINGIFY_(TestName), 0, \
|
||||||
GTEST_STRINGIFY_(TestName), 0, \
|
::testing::internal::GenerateNames< \
|
||||||
::testing::internal::GenerateNames< \
|
GTEST_NAME_GENERATOR_(CaseName), \
|
||||||
GTEST_NAME_GENERATOR_(CaseName), \
|
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||||
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
template <typename gtest_TypeParam_> \
|
||||||
template <typename gtest_TypeParam_> \
|
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||||
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
|
||||||
TestName)<gtest_TypeParam_>::TestBody()
|
TestName)<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
// Legacy API is deprecated but still available
|
// Legacy API is deprecated but still available
|
||||||
@ -268,23 +267,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|||||||
TYPED_TEST_SUITE_P
|
TYPED_TEST_SUITE_P
|
||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
template <typename gtest_TypeParam_> \
|
template <typename gtest_TypeParam_> \
|
||||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||||
private: \
|
private: \
|
||||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||||
typedef gtest_TypeParam_ TypeParam; \
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
}; \
|
}; \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
|
||||||
gtest_##TestName##_defined_ = \
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
GTEST_STRINGIFY_(TestName)); \
|
||||||
GTEST_STRINGIFY_(TestName)); \
|
} \
|
||||||
} \
|
template <typename gtest_TypeParam_> \
|
||||||
template <typename gtest_TypeParam_> \
|
void GTEST_SUITE_NAMESPACE_( \
|
||||||
void GTEST_SUITE_NAMESPACE_( \
|
|
||||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
// Note: this won't work correctly if the trailing arguments are macros.
|
// 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) { \
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||||
} \
|
} \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const \
|
[[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName) = \
|
SuiteName) = \
|
||||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||||
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
||||||
|
|
||||||
@ -305,24 +303,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|||||||
REGISTER_TYPED_TEST_SUITE_P
|
REGISTER_TYPED_TEST_SUITE_P
|
||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||||
"test-suit-prefix must not be empty"); \
|
"test-suit-prefix must not be empty"); \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
|
[[maybe_unused]] static bool gtest_##Prefix##_##SuiteName = \
|
||||||
gtest_##Prefix##_##SuiteName = \
|
::testing::internal::TypeParameterizedTestSuite< \
|
||||||
::testing::internal::TypeParameterizedTestSuite< \
|
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
Register(GTEST_STRINGIFY_(Prefix), \
|
||||||
Register( \
|
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||||
GTEST_STRINGIFY_(Prefix), \
|
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
GTEST_STRINGIFY_(SuiteName), \
|
||||||
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||||
GTEST_STRINGIFY_(SuiteName), \
|
::testing::internal::GenerateNames< \
|
||||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
::testing::internal::NameGeneratorSelector< \
|
||||||
::testing::internal::GenerateNames< \
|
__VA_ARGS__>::type, \
|
||||||
::testing::internal::NameGeneratorSelector< \
|
::testing::internal::GenerateTypeList<Types>::type>())
|
||||||
__VA_ARGS__>::type, \
|
|
||||||
::testing::internal::GenerateTypeList<Types>::type>())
|
|
||||||
|
|
||||||
// Legacy API is deprecated but still available
|
// Legacy API is deprecated but still available
|
||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|||||||
@ -1123,7 +1123,7 @@ class GTEST_API_ UnitTest {
|
|||||||
// This method can only be called from the main thread.
|
// This method can only be called from the main thread.
|
||||||
//
|
//
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
// 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()
|
// Returns the working directory when the first TEST() or TEST_F()
|
||||||
// was executed. The UnitTest object owns the string.
|
// 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
|
// This function was formerly a macro; thus, it is in the global
|
||||||
// namespace and has an all-caps name.
|
// 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(); }
|
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
|
// around may change its bits, although the new value is guaranteed
|
||||||
// to be also a NAN. Therefore, don't expect this constructor to
|
// to be also a NAN. Therefore, don't expect this constructor to
|
||||||
// preserve the bits in x when x is a NAN.
|
// 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
|
// Static methods
|
||||||
|
|
||||||
// Reinterprets a bit pattern as a floating-point number.
|
// Reinterprets a bit pattern as a floating-point number.
|
||||||
//
|
//
|
||||||
// This function is needed to test the AlmostEquals() method.
|
// This function is needed to test the AlmostEquals() method.
|
||||||
static RawType ReinterpretBits(const Bits bits) {
|
static RawType ReinterpretBits(Bits bits) {
|
||||||
FloatingPoint fp(0);
|
RawType fp;
|
||||||
fp.u_.bits_ = bits;
|
memcpy(&fp, &bits, sizeof(fp));
|
||||||
return fp.u_.value_;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the floating-point number that represent positive infinity.
|
// Returns the floating-point number that represent positive infinity.
|
||||||
@ -309,16 +309,16 @@ class FloatingPoint {
|
|||||||
// Non-static methods
|
// Non-static methods
|
||||||
|
|
||||||
// Returns the bits that represents this number.
|
// 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.
|
// 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.
|
// 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.
|
// 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).
|
// Returns true if and only if this is NAN (not a number).
|
||||||
bool is_nan() const {
|
bool is_nan() const {
|
||||||
@ -332,23 +332,16 @@ class FloatingPoint {
|
|||||||
//
|
//
|
||||||
// - returns false if either number is (or both are) NAN.
|
// - returns false if either number is (or both are) NAN.
|
||||||
// - treats really large numbers as almost equal to infinity.
|
// - 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 {
|
bool AlmostEquals(const FloatingPoint& rhs) const {
|
||||||
// The IEEE standard says that any comparison operation involving
|
// The IEEE standard says that any comparison operation involving
|
||||||
// a NAN must return false.
|
// a NAN must return false.
|
||||||
if (is_nan() || rhs.is_nan()) return false;
|
if (is_nan() || rhs.is_nan()) return false;
|
||||||
|
|
||||||
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
|
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
|
||||||
kMaxUlps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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
|
// Converts an integer from the sign-and-magnitude representation to
|
||||||
// the biased representation. More precisely, let N be 2 to the
|
// the biased representation. More precisely, let N be 2 to the
|
||||||
// power of (kBitCount - 1), an integer x is represented by 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
|
// Read https://en.wikipedia.org/wiki/Signed_number_representations
|
||||||
// for more details on signed number representations.
|
// for more details on signed number representations.
|
||||||
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
static Bits SignAndMagnitudeToBiased(Bits sam) {
|
||||||
if (kSignBitMask & sam) {
|
if (kSignBitMask & sam) {
|
||||||
// sam represents a negative number.
|
// sam represents a negative number.
|
||||||
return ~sam + 1;
|
return ~sam + 1;
|
||||||
@ -376,14 +369,13 @@ class FloatingPoint {
|
|||||||
|
|
||||||
// Given two numbers in the sign-and-magnitude representation,
|
// Given two numbers in the sign-and-magnitude representation,
|
||||||
// returns the distance between them as an unsigned number.
|
// returns the distance between them as an unsigned number.
|
||||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
|
static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
|
||||||
const Bits& sam2) {
|
|
||||||
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
||||||
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
||||||
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
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
|
// Typedefs the instances of the FloatingPoint template class that we
|
||||||
@ -894,11 +886,6 @@ class HasDebugStringAndShortDebugString {
|
|||||||
HasDebugStringType::value && HasShortDebugStringType::value;
|
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
|
// When the compiler sees expression IsContainerTest<C>(0), if C is an
|
||||||
// STL-style container class, the first overload of IsContainerTest
|
// STL-style container class, the first overload of IsContainerTest
|
||||||
// will be viable (since both C::iterator* and C::const_iterator* are
|
// 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
|
// Utility functions to be called with static_assert to induce deprecation
|
||||||
// warnings.
|
// warnings.
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
||||||
"INSTANTIATE_TEST_SUITE_P")
|
"INSTANTIATE_TEST_SUITE_P")]]
|
||||||
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
|
constexpr bool InstantiateTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"TYPED_TEST_CASE_P is deprecated, please use "
|
"TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
"TYPED_TEST_SUITE_P")
|
"TYPED_TEST_SUITE_P")]]
|
||||||
constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
|
constexpr bool TypedTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"TYPED_TEST_CASE is deprecated, please use "
|
"TYPED_TEST_CASE is deprecated, please use "
|
||||||
"TYPED_TEST_SUITE")
|
"TYPED_TEST_SUITE")]]
|
||||||
constexpr bool TypedTestCaseIsDeprecated() { return true; }
|
constexpr bool TypedTestCaseIsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
"REGISTER_TYPED_TEST_SUITE_P")
|
"REGISTER_TYPED_TEST_SUITE_P")]]
|
||||||
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
|
constexpr bool RegisterTypedTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GTEST_INTERNAL_DEPRECATED(
|
[[deprecated(
|
||||||
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
"INSTANTIATE_TYPED_TEST_SUITE_P")
|
"INSTANTIATE_TYPED_TEST_SUITE_P")]]
|
||||||
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
|
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
@ -1501,8 +1498,7 @@ class NeverThrown {
|
|||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
void TestBody() override; \
|
void TestBody() override; \
|
||||||
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \
|
[[maybe_unused]] static ::testing::TestInfo* const test_info_; \
|
||||||
test_info_; \
|
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -529,8 +530,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// prefix). test_base_name is the name of an individual test without
|
// prefix). test_base_name is the name of an individual test without
|
||||||
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||||
// test suite base name and DoBar is test base name.
|
// test suite base name and DoBar is test base name.
|
||||||
void AddTestPattern(const char*,
|
void AddTestPattern(const char*, const char* test_base_name,
|
||||||
const char* test_base_name,
|
|
||||||
TestMetaFactoryBase<ParamType>* meta_factory,
|
TestMetaFactoryBase<ParamType>* meta_factory,
|
||||||
CodeLocation code_location) {
|
CodeLocation code_location) {
|
||||||
tests_.emplace_back(
|
tests_.emplace_back(
|
||||||
@ -952,11 +952,11 @@ class CartesianProductHolder {
|
|||||||
std::tuple<Gen...> generators_;
|
std::tuple<Gen...> generators_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename From, typename To>
|
template <typename From, typename To, typename Func>
|
||||||
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
||||||
public:
|
public:
|
||||||
ParamGeneratorConverter(ParamGenerator<From> gen) // NOLINT
|
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
|
||||||
: generator_(std::move(gen)) {}
|
: generator_(std::move(gen)), converter_(std::move(converter)) {}
|
||||||
|
|
||||||
ParamIteratorInterface<To>* Begin() const override {
|
ParamIteratorInterface<To>* Begin() const override {
|
||||||
return new Iterator(this, generator_.begin(), generator_.end());
|
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());
|
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:
|
private:
|
||||||
class Iterator : public ParamIteratorInterface<To> {
|
class Iterator : public ParamIteratorInterface<To> {
|
||||||
public:
|
public:
|
||||||
Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
|
Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
|
||||||
ParamIterator<From> end)
|
ParamIterator<From> end)
|
||||||
: base_(base), it_(it), end_(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;
|
~Iterator() override = default;
|
||||||
|
|
||||||
@ -980,7 +988,9 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
|||||||
}
|
}
|
||||||
void Advance() override {
|
void Advance() override {
|
||||||
++it_;
|
++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 {
|
ParamIteratorInterface<To>* Clone() const override {
|
||||||
return new Iterator(*this);
|
return new Iterator(*this);
|
||||||
@ -1000,30 +1010,54 @@ class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
|
|||||||
private:
|
private:
|
||||||
Iterator(const Iterator& other) = default;
|
Iterator(const Iterator& other) = default;
|
||||||
|
|
||||||
const ParamGeneratorInterface<To>* const base_;
|
const ParamGeneratorConverter* const base_;
|
||||||
ParamIterator<From> it_;
|
ParamIterator<From> it_;
|
||||||
ParamIterator<From> end_;
|
ParamIterator<From> end_;
|
||||||
std::shared_ptr<To> value_;
|
std::shared_ptr<To> value_;
|
||||||
}; // class ParamGeneratorConverter::Iterator
|
}; // class ParamGeneratorConverter::Iterator
|
||||||
|
|
||||||
ParamGenerator<From> generator_;
|
ParamGenerator<From> generator_;
|
||||||
|
Func converter_;
|
||||||
}; // class ParamGeneratorConverter
|
}; // class ParamGeneratorConverter
|
||||||
|
|
||||||
template <class Gen>
|
template <class GeneratedT,
|
||||||
|
typename StdFunction =
|
||||||
|
std::function<const GeneratedT&(const GeneratedT&)>>
|
||||||
class ParamConverterGenerator {
|
class ParamConverterGenerator {
|
||||||
public:
|
public:
|
||||||
ParamConverterGenerator(ParamGenerator<Gen> g) // NOLINT
|
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
|
||||||
: generator_(std::move(g)) {}
|
: generator_(std::move(g)), converter_(Identity) {}
|
||||||
|
|
||||||
|
ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
|
||||||
|
: generator_(std::move(g)), converter_(std::move(converter)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const { // NOLINT
|
operator ParamGenerator<T>() const { // NOLINT
|
||||||
return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
|
return ParamGenerator<T>(
|
||||||
|
new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
|
||||||
|
converter_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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 internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
|||||||
@ -194,7 +194,6 @@
|
|||||||
//
|
//
|
||||||
// Macros for basic C++ coding:
|
// Macros for basic C++ coding:
|
||||||
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
// 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
|
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
|
||||||
// suppressed (constant conditional).
|
// suppressed (constant conditional).
|
||||||
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
||||||
@ -260,11 +259,6 @@
|
|||||||
// BoolFromGTestEnv() - parses a bool environment variable.
|
// BoolFromGTestEnv() - parses a bool environment variable.
|
||||||
// Int32FromGTestEnv() - parses an int32_t environment variable.
|
// Int32FromGTestEnv() - parses an int32_t environment variable.
|
||||||
// StringFromGTestEnv() - parses a string 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
|
// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can
|
||||||
// potentially be used as an #include guard.
|
// potentially be used as an #include guard.
|
||||||
@ -275,8 +269,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L
|
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
|
||||||
#error C++ versions less than C++14 are not supported.
|
#error C++ versions less than C++17 are not supported.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
|
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
|
||||||
@ -288,10 +282,14 @@
|
|||||||
|
|
||||||
// Detect C++ feature test macros as gracefully as possible.
|
// 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.
|
// 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>))
|
// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
|
||||||
#include <version> // C++20 and later
|
// <version> instead, even though <version> is not available in C++17 mode prior
|
||||||
#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))
|
// 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
|
#include <ciso646> // Pre-C++20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -772,25 +770,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|||||||
#define GTEST_HAVE_FEATURE_(x) 0
|
#define GTEST_HAVE_FEATURE_(x) 0
|
||||||
#endif
|
#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.
|
// Use this annotation before a function that takes a printf format string.
|
||||||
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)
|
||||||
// MinGW has two different printf implementations. Ensure the format macro
|
// 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)
|
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
||||||
#endif
|
#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
|
// 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
|
// constant. In some contexts this warning is false positive and needs to be
|
||||||
// suppressed. Use the following two macros in such cases:
|
// 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 internal
|
||||||
} // namespace testing
|
} // 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
|
#ifdef GTEST_HAS_ABSL
|
||||||
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
// Always use absl::any for UniversalPrinter<> specializations if googletest
|
||||||
// is built with absl support.
|
// is built with absl support.
|
||||||
@ -2527,12 +2475,6 @@ using Variant = ::std::variant<T...>;
|
|||||||
#define GTEST_INTERNAL_HAS_VARIANT 0
|
#define GTEST_INTERNAL_HAS_VARIANT 0
|
||||||
#endif
|
#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) || \
|
#if (defined(__cpp_lib_three_way_comparison) || \
|
||||||
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
(GTEST_INTERNAL_HAS_INCLUDE(<compare>) && \
|
||||||
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L))
|
||||||
|
|||||||
@ -826,6 +826,10 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
bool catch_exceptions() const { return catch_exceptions_; }
|
bool catch_exceptions() const { return catch_exceptions_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Returns true if a warning should be issued if no tests match the test
|
||||||
|
// filter flag.
|
||||||
|
bool ShouldWarnIfNoTestsMatchFilter() const;
|
||||||
|
|
||||||
struct CompareTestSuitesByPointer {
|
struct CompareTestSuitesByPointer {
|
||||||
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
|
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
|
||||||
return lhs->name_ < rhs->name_;
|
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.
|
// The default output file.
|
||||||
static const char kDefaultOutputFile[] = "test_detail";
|
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.
|
// The environment variable name for the test shard index.
|
||||||
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
||||||
// The environment variable name for the total number of test shards.
|
// The environment variable name for the total number of test shards.
|
||||||
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
||||||
// The environment variable name for the test shard status file.
|
// The environment variable name for the test shard status file.
|
||||||
static const char kTestShardStatusFile[] = "GTEST_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 {
|
namespace internal {
|
||||||
|
|
||||||
@ -258,6 +263,12 @@ GTEST_DEFINE_bool_(
|
|||||||
testing::GetDefaultFailFast()),
|
testing::GetDefaultFailFast()),
|
||||||
"True if and only if a test failure should stop further test execution.");
|
"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_(
|
GTEST_DEFINE_bool_(
|
||||||
also_run_disabled_tests,
|
also_run_disabled_tests,
|
||||||
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||||
@ -5869,6 +5880,23 @@ TestSuite* UnitTestImpl::GetTestSuite(
|
|||||||
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
|
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
|
||||||
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
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
|
// Runs all tests in this UnitTest object, prints the result, and
|
||||||
// returns true if all tests are successful. If any exception is
|
// returns true if all tests are successful. If any exception is
|
||||||
// thrown during a test, the test is considered to be failed, but the
|
// 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.
|
// user didn't call InitGoogleTest.
|
||||||
PostFlagParsingInit();
|
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
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Even if sharding is not on, test runners may want to use the
|
// 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
|
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
||||||
@ -6063,6 +6113,17 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
environments_.clear();
|
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) {
|
if (!gtest_is_initialized_before_run_all_tests) {
|
||||||
ColoredPrintf(
|
ColoredPrintf(
|
||||||
GTestColor::kRed,
|
GTestColor::kRed,
|
||||||
@ -6231,6 +6292,30 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|||||||
return num_selected_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'
|
// Prints the given C-string on a single line by replacing all '\n'
|
||||||
// characters with string "\\n". If the output takes more than
|
// characters with string "\\n". If the output takes more than
|
||||||
// max_length characters, only prints the first max_length characters
|
// 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_style);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
||||||
|
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(filter);
|
GTEST_INTERNAL_PARSE_FLAG(filter);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
||||||
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user