update gtest on windx64
This commit is contained in:
@@ -42,15 +42,19 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11 // Defined by gtest-port.h via gmock-port.h.
|
#ifdef _MSC_VER
|
||||||
#include <functional>
|
# pragma warning(push)
|
||||||
#include <type_traits>
|
# pragma warning(disable:4100)
|
||||||
#endif // GTEST_LANG_CXX11
|
#endif
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
@@ -65,9 +69,6 @@ namespace testing {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <typename F1, typename F2>
|
|
||||||
class ActionAdaptor;
|
|
||||||
|
|
||||||
// BuiltInDefaultValueGetter<T, true>::Get() returns a
|
// BuiltInDefaultValueGetter<T, true>::Get() returns a
|
||||||
// default-constructed T value. BuiltInDefaultValueGetter<T,
|
// default-constructed T value. BuiltInDefaultValueGetter<T,
|
||||||
// false>::Get() crashes with an error.
|
// false>::Get() crashes with an error.
|
||||||
@@ -98,8 +99,8 @@ struct BuiltInDefaultValueGetter<T, false> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class BuiltInDefaultValue {
|
class BuiltInDefaultValue {
|
||||||
public:
|
public:
|
||||||
#if GTEST_LANG_CXX11
|
// This function returns true if and only if type T has a built-in default
|
||||||
// This function returns true iff type T has a built-in default value.
|
// value.
|
||||||
static bool Exists() {
|
static bool Exists() {
|
||||||
return ::std::is_default_constructible<T>::value;
|
return ::std::is_default_constructible<T>::value;
|
||||||
}
|
}
|
||||||
@@ -108,18 +109,6 @@ class BuiltInDefaultValue {
|
|||||||
return BuiltInDefaultValueGetter<
|
return BuiltInDefaultValueGetter<
|
||||||
T, ::std::is_default_constructible<T>::value>::Get();
|
T, ::std::is_default_constructible<T>::value>::Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // GTEST_LANG_CXX11
|
|
||||||
// This function returns true iff type T has a built-in default value.
|
|
||||||
static bool Exists() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static T Get() {
|
|
||||||
return BuiltInDefaultValueGetter<T, false>::Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This partial specialization says that we use the same built-in
|
// This partial specialization says that we use the same built-in
|
||||||
@@ -137,7 +126,7 @@ template <typename T>
|
|||||||
class BuiltInDefaultValue<T*> {
|
class BuiltInDefaultValue<T*> {
|
||||||
public:
|
public:
|
||||||
static bool Exists() { return true; }
|
static bool Exists() { return true; }
|
||||||
static T* Get() { return NULL; }
|
static T* Get() { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following specializations define the default values for
|
// The following specializations define the default values for
|
||||||
@@ -151,9 +140,6 @@ class BuiltInDefaultValue<T*> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT
|
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT
|
||||||
#if GTEST_HAS_GLOBAL_STRING
|
|
||||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, "");
|
|
||||||
#endif // GTEST_HAS_GLOBAL_STRING
|
|
||||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
|
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
|
||||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
|
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
|
||||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
|
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
|
||||||
@@ -220,11 +206,11 @@ class DefaultValue {
|
|||||||
// Unsets the default value for type T.
|
// Unsets the default value for type T.
|
||||||
static void Clear() {
|
static void Clear() {
|
||||||
delete producer_;
|
delete producer_;
|
||||||
producer_ = NULL;
|
producer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff the user has set the default value for type T.
|
// Returns true if and only if the user has set the default value for type T.
|
||||||
static bool IsSet() { return producer_ != NULL; }
|
static bool IsSet() { return producer_ != nullptr; }
|
||||||
|
|
||||||
// Returns true if T has a default return value set by the user or there
|
// Returns true if T has a default return value set by the user or there
|
||||||
// exists a built-in default value.
|
// exists a built-in default value.
|
||||||
@@ -236,8 +222,8 @@ class DefaultValue {
|
|||||||
// otherwise returns the built-in default value. Requires that Exists()
|
// otherwise returns the built-in default value. Requires that Exists()
|
||||||
// is true, which ensures that the return value is well-defined.
|
// is true, which ensures that the return value is well-defined.
|
||||||
static T Get() {
|
static T Get() {
|
||||||
return producer_ == NULL ?
|
return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()
|
||||||
internal::BuiltInDefaultValue<T>::Get() : producer_->Produce();
|
: producer_->Produce();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -250,7 +236,7 @@ class DefaultValue {
|
|||||||
class FixedValueProducer : public ValueProducer {
|
class FixedValueProducer : public ValueProducer {
|
||||||
public:
|
public:
|
||||||
explicit FixedValueProducer(T value) : value_(value) {}
|
explicit FixedValueProducer(T value) : value_(value) {}
|
||||||
virtual T Produce() { return value_; }
|
T Produce() override { return value_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const T value_;
|
const T value_;
|
||||||
@@ -261,7 +247,7 @@ class DefaultValue {
|
|||||||
public:
|
public:
|
||||||
explicit FactoryValueProducer(FactoryFunction factory)
|
explicit FactoryValueProducer(FactoryFunction factory)
|
||||||
: factory_(factory) {}
|
: factory_(factory) {}
|
||||||
virtual T Produce() { return factory_(); }
|
T Produce() override { return factory_(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const FactoryFunction factory_;
|
const FactoryFunction factory_;
|
||||||
@@ -282,12 +268,10 @@ class DefaultValue<T&> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unsets the default value for type T&.
|
// Unsets the default value for type T&.
|
||||||
static void Clear() {
|
static void Clear() { address_ = nullptr; }
|
||||||
address_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true iff the user has set the default value for type T&.
|
// Returns true if and only if the user has set the default value for type T&.
|
||||||
static bool IsSet() { return address_ != NULL; }
|
static bool IsSet() { return address_ != nullptr; }
|
||||||
|
|
||||||
// Returns true if T has a default return value set by the user or there
|
// Returns true if T has a default return value set by the user or there
|
||||||
// exists a built-in default value.
|
// exists a built-in default value.
|
||||||
@@ -299,8 +283,8 @@ class DefaultValue<T&> {
|
|||||||
// otherwise returns the built-in default value if there is one;
|
// otherwise returns the built-in default value if there is one;
|
||||||
// otherwise aborts the process.
|
// otherwise aborts the process.
|
||||||
static T& Get() {
|
static T& Get() {
|
||||||
return address_ == NULL ?
|
return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()
|
||||||
internal::BuiltInDefaultValue<T&>::Get() : *address_;
|
: *address_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -318,11 +302,11 @@ class DefaultValue<void> {
|
|||||||
|
|
||||||
// Points to the user-set default value for type T.
|
// Points to the user-set default value for type T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = NULL;
|
typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;
|
||||||
|
|
||||||
// Points to the user-set default value for type T&.
|
// Points to the user-set default value for type T&.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* DefaultValue<T&>::address_ = NULL;
|
T* DefaultValue<T&>::address_ = nullptr;
|
||||||
|
|
||||||
// Implement this interface to define an action for function type F.
|
// Implement this interface to define an action for function type F.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
@@ -347,14 +331,25 @@ class ActionInterface {
|
|||||||
// An Action<F> is a copyable and IMMUTABLE (except by assignment)
|
// An Action<F> is a copyable and IMMUTABLE (except by assignment)
|
||||||
// object that represents an action to be taken when a mock function
|
// object that represents an action to be taken when a mock function
|
||||||
// of type F is called. The implementation of Action<T> is just a
|
// of type F is called. The implementation of Action<T> is just a
|
||||||
// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
|
// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action!
|
||||||
// Don't inherit from Action!
|
|
||||||
//
|
|
||||||
// You can view an object implementing ActionInterface<F> as a
|
// You can view an object implementing ActionInterface<F> as a
|
||||||
// concrete action (including its current state), and an Action<F>
|
// concrete action (including its current state), and an Action<F>
|
||||||
// object as a handle to it.
|
// object as a handle to it.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class Action {
|
class Action {
|
||||||
|
// Adapter class to allow constructing Action from a legacy ActionInterface.
|
||||||
|
// New code should create Actions from functors instead.
|
||||||
|
struct ActionAdapter {
|
||||||
|
// Adapter must be copyable to satisfy std::function requirements.
|
||||||
|
::std::shared_ptr<ActionInterface<F>> impl_;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
typename internal::Function<F>::Result operator()(Args&&... args) {
|
||||||
|
return impl_->Perform(
|
||||||
|
::std::forward_as_tuple(::std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename internal::Function<F>::Result Result;
|
typedef typename internal::Function<F>::Result Result;
|
||||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
@@ -363,7 +358,6 @@ class Action {
|
|||||||
// STL containers.
|
// STL containers.
|
||||||
Action() {}
|
Action() {}
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
// Construct an Action from a specified callable.
|
// Construct an Action from a specified callable.
|
||||||
// This cannot take std::function directly, because then Action would not be
|
// This cannot take std::function directly, because then Action would not be
|
||||||
// directly constructible from lambda (it would require two conversions).
|
// directly constructible from lambda (it would require two conversions).
|
||||||
@@ -371,26 +365,19 @@ class Action {
|
|||||||
typename = typename ::std::enable_if<
|
typename = typename ::std::enable_if<
|
||||||
::std::is_constructible<::std::function<F>, G>::value>::type>
|
::std::is_constructible<::std::function<F>, G>::value>::type>
|
||||||
Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT
|
Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT
|
||||||
#endif
|
|
||||||
|
|
||||||
// Constructs an Action from its implementation.
|
// Constructs an Action from its implementation.
|
||||||
explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
|
explicit Action(ActionInterface<F>* impl)
|
||||||
|
: fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}
|
||||||
|
|
||||||
// This constructor allows us to turn an Action<Func> object into an
|
// This constructor allows us to turn an Action<Func> object into an
|
||||||
// Action<F>, as long as F's arguments can be implicitly converted
|
// Action<F>, as long as F's arguments can be implicitly converted
|
||||||
// to Func's and Func's return type can be implicitly converted to
|
// to Func's and Func's return type can be implicitly converted to F's.
|
||||||
// F's.
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
explicit Action(const Action<Func>& action);
|
explicit Action(const Action<Func>& action) : fun_(action.fun_) {}
|
||||||
|
|
||||||
// Returns true iff this is the DoDefault() action.
|
// Returns true if and only if this is the DoDefault() action.
|
||||||
bool IsDoDefault() const {
|
bool IsDoDefault() const { return fun_ == nullptr; }
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
return impl_ == nullptr && fun_ == nullptr;
|
|
||||||
#else
|
|
||||||
return impl_ == NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Performs the action. Note that this method is const even though
|
// Performs the action. Note that this method is const even though
|
||||||
// the corresponding method in ActionInterface is not. The reason
|
// the corresponding method in ActionInterface is not. The reason
|
||||||
@@ -402,31 +389,15 @@ class Action {
|
|||||||
if (IsDoDefault()) {
|
if (IsDoDefault()) {
|
||||||
internal::IllegalDoDefault(__FILE__, __LINE__);
|
internal::IllegalDoDefault(__FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
#if GTEST_LANG_CXX11
|
return internal::Apply(fun_, ::std::move(args));
|
||||||
if (fun_ != nullptr) {
|
|
||||||
return internal::Apply(fun_, ::std::move(args));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return impl_->Perform(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename F1, typename F2>
|
|
||||||
friend class internal::ActionAdaptor;
|
|
||||||
|
|
||||||
template <typename G>
|
template <typename G>
|
||||||
friend class Action;
|
friend class Action;
|
||||||
|
|
||||||
// In C++11, Action can be implemented either as a generic functor (through
|
// fun_ is an empty function if and only if this is the DoDefault() action.
|
||||||
// std::function), or legacy ActionInterface. In C++98, only ActionInterface
|
|
||||||
// is available. The invariants are as follows:
|
|
||||||
// * in C++98, impl_ is null iff this is the default action
|
|
||||||
// * in C++11, at most one of fun_ & impl_ may be nonnull; both are null iff
|
|
||||||
// this is the default action
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
::std::function<F> fun_;
|
::std::function<F> fun_;
|
||||||
#endif
|
|
||||||
internal::linked_ptr<ActionInterface<F> > impl_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The PolymorphicAction class template makes it easy to implement a
|
// The PolymorphicAction class template makes it easy to implement a
|
||||||
@@ -441,7 +412,7 @@ class Action {
|
|||||||
// template <typename Result, typename ArgumentTuple>
|
// template <typename Result, typename ArgumentTuple>
|
||||||
// Result Perform(const ArgumentTuple& args) const {
|
// Result Perform(const ArgumentTuple& args) const {
|
||||||
// // Processes the arguments and returns a result, using
|
// // Processes the arguments and returns a result, using
|
||||||
// // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
|
// // std::get<N>(args) to get the N-th (0-based) argument in the tuple.
|
||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// };
|
// };
|
||||||
@@ -469,7 +440,7 @@ class PolymorphicAction {
|
|||||||
|
|
||||||
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple& args) {
|
Result Perform(const ArgumentTuple& args) override {
|
||||||
return impl_.template Perform<Result>(args);
|
return impl_.template Perform<Result>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,31 +476,11 @@ inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
|
|
||||||
// and F1 are compatible.
|
|
||||||
template <typename F1, typename F2>
|
|
||||||
class ActionAdaptor : public ActionInterface<F1> {
|
|
||||||
public:
|
|
||||||
typedef typename internal::Function<F1>::Result Result;
|
|
||||||
typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
|
|
||||||
|
|
||||||
explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
|
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple& args) {
|
|
||||||
return impl_->Perform(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const internal::linked_ptr<ActionInterface<F2> > impl_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(ActionAdaptor);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper struct to specialize ReturnAction to execute a move instead of a copy
|
// Helper struct to specialize ReturnAction to execute a move instead of a copy
|
||||||
// on return. Useful for move-only types, but could be used on any type.
|
// on return. Useful for move-only types, but could be used on any type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ByMoveWrapper {
|
struct ByMoveWrapper {
|
||||||
explicit ByMoveWrapper(T value) : payload(internal::move(value)) {}
|
explicit ByMoveWrapper(T value) : payload(std::move(value)) {}
|
||||||
T payload;
|
T payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -566,12 +517,12 @@ class ReturnAction {
|
|||||||
// Constructs a ReturnAction object from the value to be returned.
|
// Constructs a ReturnAction object from the value to be returned.
|
||||||
// 'value' is passed by value instead of by const reference in order
|
// 'value' is passed by value instead of by const reference in order
|
||||||
// to allow Return("string literal") to compile.
|
// to allow Return("string literal") to compile.
|
||||||
explicit ReturnAction(R value) : value_(new R(internal::move(value))) {}
|
explicit ReturnAction(R value) : value_(new R(std::move(value))) {}
|
||||||
|
|
||||||
// This template type conversion operator allows Return(x) to be
|
// This template type conversion operator allows Return(x) to be
|
||||||
// used in ANY function that returns x's type.
|
// used in ANY function that returns x's type.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
operator Action<F>() const {
|
operator Action<F>() const { // NOLINT
|
||||||
// Assert statement belongs here because this is the best place to verify
|
// Assert statement belongs here because this is the best place to verify
|
||||||
// conditions on F. It produces the clearest error messages
|
// conditions on F. It produces the clearest error messages
|
||||||
// in most compilers.
|
// in most compilers.
|
||||||
@@ -582,8 +533,10 @@ class ReturnAction {
|
|||||||
// in the Impl class. But both definitions must be the same.
|
// in the Impl class. But both definitions must be the same.
|
||||||
typedef typename Function<F>::Result Result;
|
typedef typename Function<F>::Result Result;
|
||||||
GTEST_COMPILE_ASSERT_(
|
GTEST_COMPILE_ASSERT_(
|
||||||
!is_reference<Result>::value,
|
!std::is_reference<Result>::value,
|
||||||
use_ReturnRef_instead_of_Return_to_return_a_reference);
|
use_ReturnRef_instead_of_Return_to_return_a_reference);
|
||||||
|
static_assert(!std::is_void<Result>::value,
|
||||||
|
"Can't use Return() on an action expected to return `void`.");
|
||||||
return Action<F>(new Impl<R, F>(value_));
|
return Action<F>(new Impl<R, F>(value_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,14 +555,14 @@ class ReturnAction {
|
|||||||
// Result to call. ImplicitCast_ forces the compiler to convert R to
|
// Result to call. ImplicitCast_ forces the compiler to convert R to
|
||||||
// Result without considering explicit constructors, thus resolving the
|
// Result without considering explicit constructors, thus resolving the
|
||||||
// ambiguity. value_ is then initialized using its copy constructor.
|
// ambiguity. value_ is then initialized using its copy constructor.
|
||||||
explicit Impl(const linked_ptr<R>& value)
|
explicit Impl(const std::shared_ptr<R>& value)
|
||||||
: value_before_cast_(*value),
|
: value_before_cast_(*value),
|
||||||
value_(ImplicitCast_<Result>(value_before_cast_)) {}
|
value_(ImplicitCast_<Result>(value_before_cast_)) {}
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple&) { return value_; }
|
Result Perform(const ArgumentTuple&) override { return value_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GTEST_COMPILE_ASSERT_(!is_reference<Result>::value,
|
GTEST_COMPILE_ASSERT_(!std::is_reference<Result>::value,
|
||||||
Result_cannot_be_a_reference_type);
|
Result_cannot_be_a_reference_type);
|
||||||
// We save the value before casting just in case it is being cast to a
|
// We save the value before casting just in case it is being cast to a
|
||||||
// wrapper type.
|
// wrapper type.
|
||||||
@@ -627,24 +580,24 @@ class ReturnAction {
|
|||||||
typedef typename Function<F>::Result Result;
|
typedef typename Function<F>::Result Result;
|
||||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
explicit Impl(const linked_ptr<R>& wrapper)
|
explicit Impl(const std::shared_ptr<R>& wrapper)
|
||||||
: performed_(false), wrapper_(wrapper) {}
|
: performed_(false), wrapper_(wrapper) {}
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple&) {
|
Result Perform(const ArgumentTuple&) override {
|
||||||
GTEST_CHECK_(!performed_)
|
GTEST_CHECK_(!performed_)
|
||||||
<< "A ByMove() action should only be performed once.";
|
<< "A ByMove() action should only be performed once.";
|
||||||
performed_ = true;
|
performed_ = true;
|
||||||
return internal::move(wrapper_->payload);
|
return std::move(wrapper_->payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool performed_;
|
bool performed_;
|
||||||
const linked_ptr<R> wrapper_;
|
const std::shared_ptr<R> wrapper_;
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(Impl);
|
GTEST_DISALLOW_ASSIGN_(Impl);
|
||||||
};
|
};
|
||||||
|
|
||||||
const linked_ptr<R> value_;
|
const std::shared_ptr<R> value_;
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(ReturnAction);
|
GTEST_DISALLOW_ASSIGN_(ReturnAction);
|
||||||
};
|
};
|
||||||
@@ -657,13 +610,7 @@ class ReturnNullAction {
|
|||||||
// pointer type on compile time.
|
// pointer type on compile time.
|
||||||
template <typename Result, typename ArgumentTuple>
|
template <typename Result, typename ArgumentTuple>
|
||||||
static Result Perform(const ArgumentTuple&) {
|
static Result Perform(const ArgumentTuple&) {
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
|
||||||
GTEST_COMPILE_ASSERT_(internal::is_pointer<Result>::value,
|
|
||||||
ReturnNull_can_be_used_to_return_a_pointer_only);
|
|
||||||
return NULL;
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -673,7 +620,7 @@ class ReturnVoidAction {
|
|||||||
// Allows Return() to be used in any void-returning function.
|
// Allows Return() to be used in any void-returning function.
|
||||||
template <typename Result, typename ArgumentTuple>
|
template <typename Result, typename ArgumentTuple>
|
||||||
static void Perform(const ArgumentTuple&) {
|
static void Perform(const ArgumentTuple&) {
|
||||||
CompileAssertTypesEqual<void, Result>();
|
static_assert(std::is_void<Result>::value, "Result should be void.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -694,7 +641,7 @@ class ReturnRefAction {
|
|||||||
// Asserts that the function return type is a reference. This
|
// Asserts that the function return type is a reference. This
|
||||||
// catches the user error of using ReturnRef(x) when Return(x)
|
// catches the user error of using ReturnRef(x) when Return(x)
|
||||||
// should be used, and generates some helpful error message.
|
// should be used, and generates some helpful error message.
|
||||||
GTEST_COMPILE_ASSERT_(internal::is_reference<Result>::value,
|
GTEST_COMPILE_ASSERT_(std::is_reference<Result>::value,
|
||||||
use_Return_instead_of_ReturnRef_to_return_a_value);
|
use_Return_instead_of_ReturnRef_to_return_a_value);
|
||||||
return Action<F>(new Impl<F>(ref_));
|
return Action<F>(new Impl<F>(ref_));
|
||||||
}
|
}
|
||||||
@@ -709,9 +656,7 @@ class ReturnRefAction {
|
|||||||
|
|
||||||
explicit Impl(T& ref) : ref_(ref) {} // NOLINT
|
explicit Impl(T& ref) : ref_(ref) {} // NOLINT
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple&) {
|
Result Perform(const ArgumentTuple&) override { return ref_; }
|
||||||
return ref_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T& ref_;
|
T& ref_;
|
||||||
@@ -743,7 +688,7 @@ class ReturnRefOfCopyAction {
|
|||||||
// catches the user error of using ReturnRefOfCopy(x) when Return(x)
|
// catches the user error of using ReturnRefOfCopy(x) when Return(x)
|
||||||
// should be used, and generates some helpful error message.
|
// should be used, and generates some helpful error message.
|
||||||
GTEST_COMPILE_ASSERT_(
|
GTEST_COMPILE_ASSERT_(
|
||||||
internal::is_reference<Result>::value,
|
std::is_reference<Result>::value,
|
||||||
use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
|
use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
|
||||||
return Action<F>(new Impl<F>(value_));
|
return Action<F>(new Impl<F>(value_));
|
||||||
}
|
}
|
||||||
@@ -758,9 +703,7 @@ class ReturnRefOfCopyAction {
|
|||||||
|
|
||||||
explicit Impl(const T& value) : value_(value) {} // NOLINT
|
explicit Impl(const T& value) : value_(value) {} // NOLINT
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple&) {
|
Result Perform(const ArgumentTuple&) override { return value_; }
|
||||||
return value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T value_;
|
T value_;
|
||||||
@@ -827,114 +770,58 @@ class SetErrnoAndReturnAction {
|
|||||||
#endif // !GTEST_OS_WINDOWS_MOBILE
|
#endif // !GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
// Implements the SetArgumentPointee<N>(x) action for any function
|
// Implements the SetArgumentPointee<N>(x) action for any function
|
||||||
// whose N-th argument (0-based) is a pointer to x's type. The
|
// whose N-th argument (0-based) is a pointer to x's type.
|
||||||
// template parameter kIsProto is true iff type A is ProtocolMessage,
|
template <size_t N, typename A, typename = void>
|
||||||
// proto2::Message, or a sub-class of those.
|
struct SetArgumentPointeeAction {
|
||||||
template <size_t N, typename A, bool kIsProto>
|
A value;
|
||||||
class SetArgumentPointeeAction {
|
|
||||||
public:
|
|
||||||
// Constructs an action that sets the variable pointed to by the
|
|
||||||
// N-th function argument to 'value'.
|
|
||||||
explicit SetArgumentPointeeAction(const A& value) : value_(value) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
template <typename... Args>
|
||||||
void Perform(const ArgumentTuple& args) const {
|
void operator()(const Args&... args) const {
|
||||||
CompileAssertTypesEqual<void, Result>();
|
*::std::get<N>(std::tie(args...)) = value;
|
||||||
*::testing::get<N>(args) = value_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
const A value_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t N, typename Proto>
|
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||||
class SetArgumentPointeeAction<N, Proto, true> {
|
template <class Class, typename MethodPtr>
|
||||||
public:
|
struct InvokeMethodAction {
|
||||||
// Constructs an action that sets the variable pointed to by the
|
Class* const obj_ptr;
|
||||||
// N-th function argument to 'proto'. Both ProtocolMessage and
|
const MethodPtr method_ptr;
|
||||||
// proto2::Message have the CopyFrom() method, so the same
|
|
||||||
// implementation works for both.
|
template <typename... Args>
|
||||||
explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) {
|
auto operator()(Args&&... args) const
|
||||||
proto_->CopyFrom(proto);
|
-> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {
|
||||||
|
return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
void Perform(const ArgumentTuple& args) const {
|
|
||||||
CompileAssertTypesEqual<void, Result>();
|
|
||||||
::testing::get<N>(args)->CopyFrom(*proto_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const internal::linked_ptr<Proto> proto_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements the InvokeWithoutArgs(f) action. The template argument
|
// Implements the InvokeWithoutArgs(f) action. The template argument
|
||||||
// FunctionImpl is the implementation type of f, which can be either a
|
// FunctionImpl is the implementation type of f, which can be either a
|
||||||
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
||||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
// Action<F> as long as f's type is compatible with F.
|
||||||
// assigned to a tr1::function<F>).
|
|
||||||
template <typename FunctionImpl>
|
template <typename FunctionImpl>
|
||||||
class InvokeWithoutArgsAction {
|
struct InvokeWithoutArgsAction {
|
||||||
public:
|
FunctionImpl function_impl;
|
||||||
// The c'tor makes a copy of function_impl (either a function
|
|
||||||
// pointer or a functor).
|
|
||||||
explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
|
|
||||||
: function_impl_(function_impl) {}
|
|
||||||
|
|
||||||
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
||||||
// compatible with f.
|
// compatible with f.
|
||||||
template <typename Result, typename ArgumentTuple>
|
template <typename... Args>
|
||||||
Result Perform(const ArgumentTuple&) { return function_impl_(); }
|
auto operator()(const Args&...) -> decltype(function_impl()) {
|
||||||
|
return function_impl();
|
||||||
private:
|
}
|
||||||
FunctionImpl function_impl_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
||||||
template <class Class, typename MethodPtr>
|
template <class Class, typename MethodPtr>
|
||||||
class InvokeMethodWithoutArgsAction {
|
struct InvokeMethodWithoutArgsAction {
|
||||||
public:
|
Class* const obj_ptr;
|
||||||
InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
|
const MethodPtr method_ptr;
|
||||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
using ReturnType = typename std::result_of<MethodPtr(Class*)>::type;
|
||||||
Result Perform(const ArgumentTuple&) const {
|
|
||||||
return (obj_ptr_->*method_ptr_)();
|
template <typename... Args>
|
||||||
|
ReturnType operator()(const Args&...) const {
|
||||||
|
return (obj_ptr->*method_ptr)();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
Class* const obj_ptr_;
|
|
||||||
const MethodPtr method_ptr_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements the InvokeWithoutArgs(callback) action.
|
|
||||||
template <typename CallbackType>
|
|
||||||
class InvokeCallbackWithoutArgsAction {
|
|
||||||
public:
|
|
||||||
// The c'tor takes ownership of the callback.
|
|
||||||
explicit InvokeCallbackWithoutArgsAction(CallbackType* callback)
|
|
||||||
: callback_(callback) {
|
|
||||||
callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
|
|
||||||
}
|
|
||||||
|
|
||||||
// This type conversion operator template allows Invoke(callback) to
|
|
||||||
// be used wherever the callback's return type can be implicitly
|
|
||||||
// converted to that of the mock function.
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple&) const { return callback_->Run(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const internal::linked_ptr<CallbackType> callback_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implements the IgnoreResult(action) action.
|
// Implements the IgnoreResult(action) action.
|
||||||
@@ -956,7 +843,7 @@ class IgnoreResultAction {
|
|||||||
typedef typename internal::Function<F>::Result Result;
|
typedef typename internal::Function<F>::Result Result;
|
||||||
|
|
||||||
// Asserts at compile time that F returns void.
|
// Asserts at compile time that F returns void.
|
||||||
CompileAssertTypesEqual<void, Result>();
|
static_assert(std::is_void<Result>::value, "Result type should be void.");
|
||||||
|
|
||||||
return Action<F>(new Impl<F>(action_));
|
return Action<F>(new Impl<F>(action_));
|
||||||
}
|
}
|
||||||
@@ -970,7 +857,7 @@ class IgnoreResultAction {
|
|||||||
|
|
||||||
explicit Impl(const A& action) : action_(action) {}
|
explicit Impl(const A& action) : action_(action) {}
|
||||||
|
|
||||||
virtual void Perform(const ArgumentTuple& args) {
|
void Perform(const ArgumentTuple& args) override {
|
||||||
// Performs the action and ignores its result.
|
// Performs the action and ignores its result.
|
||||||
action_.Perform(args);
|
action_.Perform(args);
|
||||||
}
|
}
|
||||||
@@ -991,76 +878,51 @@ class IgnoreResultAction {
|
|||||||
GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
|
GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ReferenceWrapper<T> object represents a reference to type T,
|
template <typename InnerAction, size_t... I>
|
||||||
// which can be either const or not. It can be explicitly converted
|
struct WithArgsAction {
|
||||||
// from, and implicitly converted to, a T&. Unlike a reference,
|
InnerAction action;
|
||||||
// ReferenceWrapper<T> can be copied and can survive template type
|
|
||||||
// inference. This is used to support by-reference arguments in the
|
|
||||||
// InvokeArgument<N>(...) action. The idea was from "reference
|
|
||||||
// wrappers" in tr1, which we don't have in our source tree yet.
|
|
||||||
template <typename T>
|
|
||||||
class ReferenceWrapper {
|
|
||||||
public:
|
|
||||||
// Constructs a ReferenceWrapper<T> object from a T&.
|
|
||||||
explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
|
|
||||||
|
|
||||||
// Allows a ReferenceWrapper<T> object to be implicitly converted to
|
// The inner action could be anything convertible to Action<X>.
|
||||||
// a T&.
|
// We use the conversion operator to detect the signature of the inner Action.
|
||||||
operator T&() const { return *pointer_; }
|
template <typename R, typename... Args>
|
||||||
private:
|
operator Action<R(Args...)>() const { // NOLINT
|
||||||
T* pointer_;
|
Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)>
|
||||||
|
converted(action);
|
||||||
|
|
||||||
|
return [converted](Args... args) -> R {
|
||||||
|
return converted.Perform(std::forward_as_tuple(
|
||||||
|
std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allows the expression ByRef(x) to be printed as a reference to x.
|
template <typename... Actions>
|
||||||
template <typename T>
|
struct DoAllAction {
|
||||||
void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
|
private:
|
||||||
T& value = ref;
|
template <typename... Args, size_t... I>
|
||||||
UniversalPrinter<T&>::Print(value, os);
|
std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
|
||||||
}
|
return {std::get<I>(actions)...};
|
||||||
|
|
||||||
// Does two actions sequentially. Used for implementing the DoAll(a1,
|
|
||||||
// a2, ...) action.
|
|
||||||
template <typename Action1, typename Action2>
|
|
||||||
class DoBothAction {
|
|
||||||
public:
|
|
||||||
DoBothAction(Action1 action1, Action2 action2)
|
|
||||||
: action1_(action1), action2_(action2) {}
|
|
||||||
|
|
||||||
// This template type conversion operator allows DoAll(a1, ..., a_n)
|
|
||||||
// to be used in ANY function of compatible type.
|
|
||||||
template <typename F>
|
|
||||||
operator Action<F>() const {
|
|
||||||
return Action<F>(new Impl<F>(action1_, action2_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
public:
|
||||||
// Implements the DoAll(...) action for a particular function type F.
|
std::tuple<Actions...> actions;
|
||||||
template <typename F>
|
|
||||||
class Impl : public ActionInterface<F> {
|
|
||||||
public:
|
|
||||||
typedef typename Function<F>::Result Result;
|
|
||||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
|
||||||
typedef typename Function<F>::MakeResultVoid VoidResult;
|
|
||||||
|
|
||||||
Impl(const Action<VoidResult>& action1, const Action<F>& action2)
|
template <typename R, typename... Args>
|
||||||
: action1_(action1), action2_(action2) {}
|
operator Action<R(Args...)>() const { // NOLINT
|
||||||
|
struct Op {
|
||||||
virtual Result Perform(const ArgumentTuple& args) {
|
std::vector<Action<void(Args...)>> converted;
|
||||||
action1_.Perform(args);
|
Action<R(Args...)> last;
|
||||||
return action2_.Perform(args);
|
R operator()(Args... args) const {
|
||||||
}
|
auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
|
||||||
|
for (auto& a : converted) {
|
||||||
private:
|
a.Perform(tuple_args);
|
||||||
const Action<VoidResult> action1_;
|
}
|
||||||
const Action<F> action2_;
|
return last.Perform(tuple_args);
|
||||||
|
}
|
||||||
GTEST_DISALLOW_ASSIGN_(Impl);
|
};
|
||||||
};
|
return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()),
|
||||||
|
std::get<sizeof...(Actions) - 1>(actions)};
|
||||||
Action1 action1_;
|
}
|
||||||
Action2 action2_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(DoBothAction);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
@@ -1097,19 +959,43 @@ class DoBothAction {
|
|||||||
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||||
typedef internal::IgnoredValue Unused;
|
typedef internal::IgnoredValue Unused;
|
||||||
|
|
||||||
// This constructor allows us to turn an Action<From> object into an
|
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||||
// Action<To>, as long as To's arguments can be implicitly converted
|
// each invocation.
|
||||||
// to From's and From's return type cann be implicitly converted to
|
template <typename... Action>
|
||||||
// To's.
|
internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
|
||||||
template <typename To>
|
Action&&... action) {
|
||||||
template <typename From>
|
return {std::forward_as_tuple(std::forward<Action>(action)...)};
|
||||||
Action<To>::Action(const Action<From>& from)
|
}
|
||||||
:
|
|
||||||
#if GTEST_LANG_CXX11
|
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||||
fun_(from.fun_),
|
// (0-based) argument of the mock function to an_action and performs
|
||||||
#endif
|
// it. It adapts an action accepting one argument to one that accepts
|
||||||
impl_(from.impl_ == NULL ? NULL
|
// multiple arguments. For convenience, we also provide
|
||||||
: new internal::ActionAdaptor<To, From>(from)) {
|
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||||
|
template <size_t k, typename InnerAction>
|
||||||
|
internal::WithArgsAction<typename std::decay<InnerAction>::type, k>
|
||||||
|
WithArg(InnerAction&& action) {
|
||||||
|
return {std::forward<InnerAction>(action)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||||
|
// the selected arguments of the mock function to an_action and
|
||||||
|
// performs it. It serves as an adaptor between actions with
|
||||||
|
// different argument lists.
|
||||||
|
template <size_t k, size_t... ks, typename InnerAction>
|
||||||
|
internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>
|
||||||
|
WithArgs(InnerAction&& action) {
|
||||||
|
return {std::forward<InnerAction>(action)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||||
|
// non-empty argument list to perform inner_action, which takes no
|
||||||
|
// argument. In other words, it adapts an action accepting no
|
||||||
|
// argument to one that accepts (and ignores) arguments.
|
||||||
|
template <typename InnerAction>
|
||||||
|
internal::WithArgsAction<typename std::decay<InnerAction>::type>
|
||||||
|
WithoutArgs(InnerAction&& action) {
|
||||||
|
return {std::forward<InnerAction>(action)};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that returns 'value'. 'value' is passed by value
|
// Creates an action that returns 'value'. 'value' is passed by value
|
||||||
@@ -1117,7 +1003,7 @@ Action<To>::Action(const Action<From>& from)
|
|||||||
// will trigger a compiler error about using array as initializer.
|
// will trigger a compiler error about using array as initializer.
|
||||||
template <typename R>
|
template <typename R>
|
||||||
internal::ReturnAction<R> Return(R value) {
|
internal::ReturnAction<R> Return(R value) {
|
||||||
return internal::ReturnAction<R>(internal::move(value));
|
return internal::ReturnAction<R>(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that returns NULL.
|
// Creates an action that returns NULL.
|
||||||
@@ -1150,7 +1036,7 @@ inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {
|
|||||||
// invariant.
|
// invariant.
|
||||||
template <typename R>
|
template <typename R>
|
||||||
internal::ByMoveWrapper<R> ByMove(R x) {
|
internal::ByMoveWrapper<R> ByMove(R x) {
|
||||||
return internal::ByMoveWrapper<R>(internal::move(x));
|
return internal::ByMoveWrapper<R>(std::move(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that does the default action for the give mock function.
|
// Creates an action that does the default action for the give mock function.
|
||||||
@@ -1161,43 +1047,14 @@ inline internal::DoDefaultAction DoDefault() {
|
|||||||
// Creates an action that sets the variable pointed by the N-th
|
// Creates an action that sets the variable pointed by the N-th
|
||||||
// (0-based) function argument to 'value'.
|
// (0-based) function argument to 'value'.
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
PolymorphicAction<
|
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T x) {
|
||||||
internal::SetArgumentPointeeAction<
|
return {std::move(x)};
|
||||||
N, T, internal::IsAProtocolMessage<T>::value> >
|
|
||||||
SetArgPointee(const T& x) {
|
|
||||||
return MakePolymorphicAction(internal::SetArgumentPointeeAction<
|
|
||||||
N, T, internal::IsAProtocolMessage<T>::value>(x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN)
|
|
||||||
// This overload allows SetArgPointee() to accept a string literal.
|
|
||||||
// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish
|
|
||||||
// this overload from the templated version and emit a compile error.
|
|
||||||
template <size_t N>
|
|
||||||
PolymorphicAction<
|
|
||||||
internal::SetArgumentPointeeAction<N, const char*, false> >
|
|
||||||
SetArgPointee(const char* p) {
|
|
||||||
return MakePolymorphicAction(internal::SetArgumentPointeeAction<
|
|
||||||
N, const char*, false>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N>
|
|
||||||
PolymorphicAction<
|
|
||||||
internal::SetArgumentPointeeAction<N, const wchar_t*, false> >
|
|
||||||
SetArgPointee(const wchar_t* p) {
|
|
||||||
return MakePolymorphicAction(internal::SetArgumentPointeeAction<
|
|
||||||
N, const wchar_t*, false>(p));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The following version is DEPRECATED.
|
// The following version is DEPRECATED.
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
PolymorphicAction<
|
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T x) {
|
||||||
internal::SetArgumentPointeeAction<
|
return {std::move(x)};
|
||||||
N, T, internal::IsAProtocolMessage<T>::value> >
|
|
||||||
SetArgumentPointee(const T& x) {
|
|
||||||
return MakePolymorphicAction(internal::SetArgumentPointeeAction<
|
|
||||||
N, T, internal::IsAProtocolMessage<T>::value>(x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that sets a pointer referent to a given value.
|
// Creates an action that sets a pointer referent to a given value.
|
||||||
@@ -1218,24 +1075,38 @@ SetErrnoAndReturn(int errval, T result) {
|
|||||||
|
|
||||||
#endif // !GTEST_OS_WINDOWS_MOBILE
|
#endif // !GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
// Various overloads for InvokeWithoutArgs().
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
|
// Legacy function.
|
||||||
|
// Actions can now be implicitly constructed from callables. No need to create
|
||||||
|
// wrapper objects.
|
||||||
|
// This function exists for backwards compatibility.
|
||||||
|
template <typename FunctionImpl>
|
||||||
|
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
|
||||||
|
return std::forward<FunctionImpl>(function_impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an action that invokes the given method on the given object
|
||||||
|
// with the mock function's arguments.
|
||||||
|
template <class Class, typename MethodPtr>
|
||||||
|
internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
|
||||||
|
MethodPtr method_ptr) {
|
||||||
|
return {obj_ptr, method_ptr};
|
||||||
|
}
|
||||||
|
|
||||||
// Creates an action that invokes 'function_impl' with no argument.
|
// Creates an action that invokes 'function_impl' with no argument.
|
||||||
template <typename FunctionImpl>
|
template <typename FunctionImpl>
|
||||||
PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
|
internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
|
||||||
InvokeWithoutArgs(FunctionImpl function_impl) {
|
InvokeWithoutArgs(FunctionImpl function_impl) {
|
||||||
return MakePolymorphicAction(
|
return {std::move(function_impl)};
|
||||||
internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that invokes the given method on the given object
|
// Creates an action that invokes the given method on the given object
|
||||||
// with no argument.
|
// with no argument.
|
||||||
template <class Class, typename MethodPtr>
|
template <class Class, typename MethodPtr>
|
||||||
PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
|
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(
|
||||||
InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
|
Class* obj_ptr, MethodPtr method_ptr) {
|
||||||
return MakePolymorphicAction(
|
return {obj_ptr, method_ptr};
|
||||||
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
|
|
||||||
obj_ptr, method_ptr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an action that performs an_action and throws away its
|
// Creates an action that performs an_action and throws away its
|
||||||
@@ -1253,11 +1124,19 @@ inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
|
|||||||
// where Base is a base class of Derived, just write:
|
// where Base is a base class of Derived, just write:
|
||||||
//
|
//
|
||||||
// ByRef<const Base>(derived)
|
// ByRef<const Base>(derived)
|
||||||
|
//
|
||||||
|
// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper.
|
||||||
|
// However, it may still be used for consistency with ByMove().
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
|
inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT
|
||||||
return internal::ReferenceWrapper<T>(l_value);
|
return ::std::reference_wrapper<T>(l_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <memory>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
@@ -69,10 +70,12 @@ class CardinalityInterface {
|
|||||||
virtual int ConservativeLowerBound() const { return 0; }
|
virtual int ConservativeLowerBound() const { return 0; }
|
||||||
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||||
|
|
||||||
// Returns true iff call_count calls will satisfy this cardinality.
|
// Returns true if and only if call_count calls will satisfy this
|
||||||
|
// cardinality.
|
||||||
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||||
|
|
||||||
// Returns true iff call_count calls will saturate this cardinality.
|
// Returns true if and only if call_count calls will saturate this
|
||||||
|
// cardinality.
|
||||||
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||||
|
|
||||||
// Describes self to an ostream.
|
// Describes self to an ostream.
|
||||||
@@ -81,9 +84,8 @@ class CardinalityInterface {
|
|||||||
|
|
||||||
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||||
// object that specifies how many times a mock function is expected to
|
// object that specifies how many times a mock function is expected to
|
||||||
// be called. The implementation of Cardinality is just a linked_ptr
|
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||||
// to const CardinalityInterface, so copying is fairly cheap.
|
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||||
// Don't inherit from Cardinality!
|
|
||||||
class GTEST_API_ Cardinality {
|
class GTEST_API_ Cardinality {
|
||||||
public:
|
public:
|
||||||
// Constructs a null cardinality. Needed for storing Cardinality
|
// Constructs a null cardinality. Needed for storing Cardinality
|
||||||
@@ -98,17 +100,19 @@ class GTEST_API_ Cardinality {
|
|||||||
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||||
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||||
|
|
||||||
// Returns true iff call_count calls will satisfy this cardinality.
|
// Returns true if and only if call_count calls will satisfy this
|
||||||
|
// cardinality.
|
||||||
bool IsSatisfiedByCallCount(int call_count) const {
|
bool IsSatisfiedByCallCount(int call_count) const {
|
||||||
return impl_->IsSatisfiedByCallCount(call_count);
|
return impl_->IsSatisfiedByCallCount(call_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff call_count calls will saturate this cardinality.
|
// Returns true if and only if call_count calls will saturate this
|
||||||
|
// cardinality.
|
||||||
bool IsSaturatedByCallCount(int call_count) const {
|
bool IsSaturatedByCallCount(int call_count) const {
|
||||||
return impl_->IsSaturatedByCallCount(call_count);
|
return impl_->IsSaturatedByCallCount(call_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff call_count calls will over-saturate this
|
// Returns true if and only if call_count calls will over-saturate this
|
||||||
// cardinality, i.e. exceed the maximum number of allowed calls.
|
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||||
bool IsOverSaturatedByCallCount(int call_count) const {
|
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||||
return impl_->IsSaturatedByCallCount(call_count) &&
|
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||||
@@ -123,7 +127,7 @@ class GTEST_API_ Cardinality {
|
|||||||
::std::ostream* os);
|
::std::ostream* os);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::linked_ptr<const CardinalityInterface> impl_;
|
std::shared_ptr<const CardinalityInterface> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Creates a cardinality that allows at least n calls.
|
// Creates a cardinality that allows at least n calls.
|
||||||
|
|||||||
253
winx64/include/gmock/gmock-function-mocker.h
Normal file
253
winx64/include/gmock/gmock-function-mocker.h
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements MOCK_METHOD.
|
||||||
|
|
||||||
|
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||||
|
|
||||||
|
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||||
|
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
|
||||||
|
|
||||||
|
#include "gmock/gmock-generated-function-mockers.h" // NOLINT
|
||||||
|
#include "gmock/internal/gmock-pp.h"
|
||||||
|
|
||||||
|
#define MOCK_METHOD(...) \
|
||||||
|
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
|
||||||
|
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \
|
||||||
|
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
|
||||||
|
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
||||||
|
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
||||||
|
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
||||||
|
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||||
|
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
||||||
|
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||||
|
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||||
|
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
||||||
|
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
||||||
|
GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \
|
||||||
|
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
|
||||||
|
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \
|
||||||
|
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \
|
||||||
|
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_WRONG_ARITY(...) \
|
||||||
|
static_assert( \
|
||||||
|
false, \
|
||||||
|
"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \
|
||||||
|
"_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \
|
||||||
|
"enclosed in parentheses. If _Ret is a type with unprotected commas, " \
|
||||||
|
"it must also be enclosed in parentheses.")
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \
|
||||||
|
static_assert( \
|
||||||
|
GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \
|
||||||
|
GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.")
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \
|
||||||
|
static_assert( \
|
||||||
|
std::is_function<__VA_ARGS__>::value, \
|
||||||
|
"Signature must be a function type, maybe return type contains " \
|
||||||
|
"unprotected comma."); \
|
||||||
|
static_assert( \
|
||||||
|
::testing::tuple_size<typename ::testing::internal::Function< \
|
||||||
|
__VA_ARGS__>::ArgumentTuple>::value == _N, \
|
||||||
|
"This method does not take " GMOCK_PP_STRINGIZE( \
|
||||||
|
_N) " arguments. Parenthesize all types with unproctected commas.")
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||||
|
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
|
||||||
|
_Override, _Final, _Noexcept, \
|
||||||
|
_CallType, _Signature) \
|
||||||
|
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
|
||||||
|
_Signature)>::Result \
|
||||||
|
GMOCK_INTERNAL_EXPAND(_CallType) \
|
||||||
|
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
|
||||||
|
GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \
|
||||||
|
GMOCK_PP_IF(_Override, override, ) \
|
||||||
|
GMOCK_PP_IF(_Final, final, ) { \
|
||||||
|
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||||
|
.SetOwnerAndName(this, #_MethodName); \
|
||||||
|
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||||
|
.Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
|
||||||
|
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
|
||||||
|
GMOCK_PP_IF(_Constness, const, ) { \
|
||||||
|
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||||
|
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
|
||||||
|
const ::testing::internal::WithoutMatchers&, \
|
||||||
|
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
|
||||||
|
GMOCK_PP_REMOVE_PARENS(_Signature)>*) \
|
||||||
|
const GMOCK_PP_IF(_Noexcept, noexcept, ) { \
|
||||||
|
return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \
|
||||||
|
GMOCK_PP_IF(_Constness, const, ))(this) \
|
||||||
|
->gmock_##_MethodName(GMOCK_PP_REPEAT( \
|
||||||
|
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
|
||||||
|
GMOCK_MOCKER_(_N, _Constness, _MethodName)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
|
||||||
|
|
||||||
|
// Five Valid modifiers.
|
||||||
|
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
|
||||||
|
GMOCK_PP_HAS_COMMA( \
|
||||||
|
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \
|
||||||
|
GMOCK_PP_HAS_COMMA( \
|
||||||
|
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
|
||||||
|
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||||
|
static_assert( \
|
||||||
|
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
|
||||||
|
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
|
||||||
|
GMOCK_PP_STRINGIZE( \
|
||||||
|
_elem) " cannot be recognized as a valid specification modifier.");
|
||||||
|
|
||||||
|
// Modifiers implementation.
|
||||||
|
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_DETECT_CONST_I_const ,
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
|
||||||
|
|
||||||
|
// TODO(iserna): Maybe noexcept should accept an argument here as well.
|
||||||
|
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
|
||||||
|
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
|
||||||
|
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
|
||||||
|
(_elem)
|
||||||
|
|
||||||
|
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
|
||||||
|
// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
|
||||||
|
// maybe they can be simplified somehow.
|
||||||
|
#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
|
||||||
|
GMOCK_INTERNAL_IS_CALLTYPE_I( \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
|
||||||
|
#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
|
||||||
|
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
|
||||||
|
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
|
||||||
|
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
|
||||||
|
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
|
||||||
|
GMOCK_PP_IDENTITY) \
|
||||||
|
(_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
|
||||||
|
GMOCK_PP_COMMA_IF(_i) \
|
||||||
|
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
|
||||||
|
GMOCK_PP_IDENTITY) \
|
||||||
|
(_elem)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
|
||||||
|
GMOCK_PP_COMMA_IF(_i) \
|
||||||
|
GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
|
||||||
|
GMOCK_PP_REMOVE_PARENS(_Signature)) \
|
||||||
|
gmock_a##_i
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
|
||||||
|
GMOCK_PP_COMMA_IF(_i) \
|
||||||
|
::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
|
||||||
|
GMOCK_PP_REMOVE_PARENS(_Signature))>( \
|
||||||
|
gmock_a##_i)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
|
||||||
|
GMOCK_PP_COMMA_IF(_i) \
|
||||||
|
GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \
|
||||||
|
GMOCK_PP_REMOVE_PARENS(_Signature)) \
|
||||||
|
gmock_a##_i
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
|
||||||
|
GMOCK_PP_COMMA_IF(_i) \
|
||||||
|
gmock_a##_i
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
|
||||||
|
GMOCK_PP_COMMA_IF(_i) \
|
||||||
|
::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
|
||||||
|
GMOCK_PP_REMOVE_PARENS(_Signature))>()
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
|
||||||
|
GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
|
||||||
|
|
||||||
|
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -43,173 +43,15 @@ $$}} This meta comment fixes auto-indentation in editors.
|
|||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "gmock/gmock-actions.h"
|
#include "gmock/gmock-actions.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
|
|
||||||
// function, method, or callback with the unpacked values, where F is
|
|
||||||
// a function type that takes N arguments.
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
class InvokeHelper;
|
|
||||||
|
|
||||||
|
|
||||||
$var max_callback_arity = 5
|
|
||||||
$range i 0..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var types = [[$for j [[, typename A$j]]]]
|
|
||||||
$var as = [[$for j, [[A$j]]]]
|
|
||||||
$var args = [[$if i==0 [[]] $else [[ args]]]]
|
|
||||||
$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
|
|
||||||
template <typename R$types>
|
|
||||||
class InvokeHelper<R, ::testing::tuple<$as> > {
|
|
||||||
public:
|
|
||||||
template <typename Function>
|
|
||||||
static R Invoke(Function function, const ::testing::tuple<$as>&$args) {
|
|
||||||
return function($gets);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Class, typename MethodPtr>
|
|
||||||
static R InvokeMethod(Class* obj_ptr,
|
|
||||||
MethodPtr method_ptr,
|
|
||||||
const ::testing::tuple<$as>&$args) {
|
|
||||||
return (obj_ptr->*method_ptr)($gets);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$if i <= max_callback_arity [[
|
|
||||||
template <typename CallbackType>
|
|
||||||
static R InvokeCallback(CallbackType* callback,
|
|
||||||
const ::testing::tuple<$as>&$args) {
|
|
||||||
return callback->Run($gets);
|
|
||||||
}
|
|
||||||
]] $else [[
|
|
||||||
// There is no InvokeCallback() for $i-tuples
|
|
||||||
]]
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
// Implements the Invoke(callback) action.
|
|
||||||
template <typename CallbackType>
|
|
||||||
class InvokeCallbackAction {
|
|
||||||
public:
|
|
||||||
// The c'tor takes ownership of the callback.
|
|
||||||
explicit InvokeCallbackAction(CallbackType* callback)
|
|
||||||
: callback_(callback) {
|
|
||||||
callback->CheckIsRepeatable(); // Makes sure the callback is permanent.
|
|
||||||
}
|
|
||||||
|
|
||||||
// This type conversion operator template allows Invoke(callback) to
|
|
||||||
// be used wherever the callback's type is compatible with that of
|
|
||||||
// the mock function, i.e. if the mock function's arguments can be
|
|
||||||
// implicitly converted to the callback's arguments and the
|
|
||||||
// callback's result can be implicitly converted to the mock
|
|
||||||
// function's result.
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple& args) const {
|
|
||||||
return InvokeHelper<Result, ArgumentTuple>::InvokeCallback(
|
|
||||||
callback_.get(), args);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
const linked_ptr<CallbackType> callback_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// An INTERNAL macro for extracting the type of a tuple field. It's
|
|
||||||
// subject to change without notice - DO NOT USE IN USER CODE!
|
|
||||||
#define GMOCK_FIELD_(Tuple, N) \
|
|
||||||
typename ::testing::tuple_element<N, Tuple>::type
|
|
||||||
|
|
||||||
$range i 1..n
|
|
||||||
|
|
||||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
|
|
||||||
// type of an n-ary function whose i-th (1-based) argument type is the
|
|
||||||
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
|
|
||||||
// type, and whose return type is Result. For example,
|
|
||||||
// SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type
|
|
||||||
// is int(bool, long).
|
|
||||||
//
|
|
||||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
|
|
||||||
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
|
|
||||||
// For example,
|
|
||||||
// SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select(
|
|
||||||
// ::testing::make_tuple(true, 'a', 2.5))
|
|
||||||
// returns tuple (2.5, true).
|
|
||||||
//
|
|
||||||
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
|
|
||||||
// in the range [0, $n]. Duplicates are allowed and they don't have
|
|
||||||
// to be in an ascending or descending order.
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
|
|
||||||
class SelectArgs {
|
|
||||||
public:
|
|
||||||
typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
|
|
||||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
|
||||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
|
||||||
return SelectedArgs($for i, [[get<k$i>(args)]]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$for i [[
|
|
||||||
$range j 1..n
|
|
||||||
$range j1 1..i-1
|
|
||||||
template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
|
|
||||||
class SelectArgs<Result, ArgumentTuple,
|
|
||||||
$for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
|
|
||||||
public:
|
|
||||||
typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
|
|
||||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
|
||||||
static SelectedArgs Select(const ArgumentTuple& [[]]
|
|
||||||
$if i == 1 [[/* args */]] $else [[args]]) {
|
|
||||||
return SelectedArgs($for j1, [[get<k$j1>(args)]]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
#undef GMOCK_FIELD_
|
|
||||||
|
|
||||||
$var ks = [[$for i, [[k$i]]]]
|
|
||||||
|
|
||||||
// Implements the WithArgs action.
|
|
||||||
template <typename InnerAction, $for i, [[int k$i = -1]]>
|
|
||||||
class WithArgsAction {
|
|
||||||
public:
|
|
||||||
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
|
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename F>
|
|
||||||
class Impl : public ActionInterface<F> {
|
|
||||||
public:
|
|
||||||
typedef typename Function<F>::Result Result;
|
|
||||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
|
||||||
|
|
||||||
explicit Impl(const InnerAction& action) : action_(action) {}
|
|
||||||
|
|
||||||
virtual Result Perform(const ArgumentTuple& args) {
|
|
||||||
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef typename SelectArgs<Result, ArgumentTuple,
|
|
||||||
$ks>::type InnerFunctionType;
|
|
||||||
|
|
||||||
Action<InnerFunctionType> action_;
|
|
||||||
};
|
|
||||||
|
|
||||||
const InnerAction action_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A macro from the ACTION* family (defined later in this file)
|
// A macro from the ACTION* family (defined later in this file)
|
||||||
// defines an action that can be used in a mock function. Typically,
|
// defines an action that can be used in a mock function. Typically,
|
||||||
// these actions only care about a subset of the arguments of the mock
|
// these actions only care about a subset of the arguments of the mock
|
||||||
@@ -240,12 +82,12 @@ $range j 0..i-1
|
|||||||
]]]]
|
]]]]
|
||||||
$range j 0..i-1
|
$range j 0..i-1
|
||||||
$var As = [[$for j, [[A$j]]]]
|
$var As = [[$for j, [[A$j]]]]
|
||||||
$var as = [[$for j, [[get<$j>(args)]]]]
|
$var as = [[$for j, [[std::get<$j>(args)]]]]
|
||||||
$range k 1..n-i
|
$range k 1..n-i
|
||||||
$var eas = [[$for k, [[ExcessiveArg()]]]]
|
$var eas = [[$for k, [[ExcessiveArg()]]]]
|
||||||
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
|
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
|
||||||
$template
|
$template
|
||||||
static Result Perform(Impl* impl, const ::testing::tuple<$As>& args) {
|
static Result Perform(Impl* impl, const ::std::tuple<$As>& args) {
|
||||||
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
|
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,53 +95,6 @@ $template
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// Various overloads for Invoke().
|
|
||||||
|
|
||||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
|
||||||
// the selected arguments of the mock function to an_action and
|
|
||||||
// performs it. It serves as an adaptor between actions with
|
|
||||||
// different argument lists. C++ doesn't support default arguments for
|
|
||||||
// function templates, so we have to overload it.
|
|
||||||
|
|
||||||
$range i 1..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
template <$for j [[int k$j, ]]typename InnerAction>
|
|
||||||
inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
|
|
||||||
WithArgs(const InnerAction& action) {
|
|
||||||
return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
|
||||||
// each invocation.
|
|
||||||
$range i 2..n
|
|
||||||
$for i [[
|
|
||||||
$range j 2..i
|
|
||||||
$var types = [[$for j, [[typename Action$j]]]]
|
|
||||||
$var Aas = [[$for j [[, Action$j a$j]]]]
|
|
||||||
|
|
||||||
template <typename Action1, $types>
|
|
||||||
$range k 1..i-1
|
|
||||||
|
|
||||||
inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
|
|
||||||
|
|
||||||
DoAll(Action1 a1$Aas) {
|
|
||||||
$if i==2 [[
|
|
||||||
|
|
||||||
return internal::DoBothAction<Action1, Action2>(a1, a2);
|
|
||||||
]] $else [[
|
|
||||||
$range j2 2..i
|
|
||||||
|
|
||||||
return DoAll(a1, DoAll($for j2, [[a$j2]]));
|
|
||||||
]]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
// The ACTION* family of macros can be used in a namespace scope to
|
// The ACTION* family of macros can be used in a namespace scope to
|
||||||
@@ -387,16 +182,15 @@ $range j2 2..i
|
|||||||
//
|
//
|
||||||
// CAVEAT:
|
// CAVEAT:
|
||||||
//
|
//
|
||||||
// ACTION*() can only be used in a namespace scope. The reason is
|
// ACTION*() can only be used in a namespace scope as templates cannot be
|
||||||
// that C++ doesn't yet allow function-local types to be used to
|
// declared inside of a local class.
|
||||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
// Users can, however, define any local functors (e.g. a lambda) that
|
||||||
// Once that's done, we'll consider supporting using ACTION*() inside
|
// can be used as actions.
|
||||||
// a function.
|
|
||||||
//
|
//
|
||||||
// MORE INFORMATION:
|
// MORE INFORMATION:
|
||||||
//
|
//
|
||||||
// To learn more about using these macros, please search for 'ACTION'
|
// To learn more about using these macros, please search for 'ACTION' on
|
||||||
// on https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
|
// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
|
||||||
|
|
||||||
$range i 0..n
|
$range i 0..n
|
||||||
$range k 0..n-1
|
$range k 0..n-1
|
||||||
@@ -405,7 +199,7 @@ $range k 0..n-1
|
|||||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
|
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
|
||||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_
|
const args_type& args GTEST_ATTRIBUTE_UNUSED_
|
||||||
$for k [[, \
|
$for k [[, \
|
||||||
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
|
const arg$k[[]]_type& arg$k GTEST_ATTRIBUTE_UNUSED_]]
|
||||||
|
|
||||||
|
|
||||||
// Sometimes you want to give an action explicit template parameters
|
// Sometimes you want to give an action explicit template parameters
|
||||||
@@ -432,7 +226,7 @@ $for k [[, \
|
|||||||
// ACTION_TEMPLATE(DuplicateArg,
|
// ACTION_TEMPLATE(DuplicateArg,
|
||||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||||
// AND_1_VALUE_PARAMS(output)) {
|
// AND_1_VALUE_PARAMS(output)) {
|
||||||
// *output = T(::testing::get<k>(args));
|
// *output = T(::std::get<k>(args));
|
||||||
// }
|
// }
|
||||||
// ...
|
// ...
|
||||||
// int n;
|
// int n;
|
||||||
@@ -525,7 +319,7 @@ _VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
|
|||||||
$for i [[
|
$for i [[
|
||||||
$range j 0..i-1
|
$range j 0..i-1
|
||||||
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
|
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
|
||||||
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::testing::internal::move(gmock_p$j))]]
|
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]]
|
||||||
|
|
||||||
|
|
||||||
]]
|
]]
|
||||||
@@ -607,7 +401,7 @@ $range k 0..n-1
|
|||||||
}\
|
}\
|
||||||
template <$for k, [[typename arg$k[[]]_type]]>\
|
template <$for k, [[typename arg$k[[]]_type]]>\
|
||||||
return_type gmock_PerformImpl(const args_type& args[[]]
|
return_type gmock_PerformImpl(const args_type& args[[]]
|
||||||
$for k [[, arg$k[[]]_type arg$k]]) const;\
|
$for k [[, const arg$k[[]]_type& arg$k]]) const;\
|
||||||
GMOCK_INTERNAL_DEFN_##value_params\
|
GMOCK_INTERNAL_DEFN_##value_params\
|
||||||
private:\
|
private:\
|
||||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||||
@@ -658,7 +452,7 @@ $var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
|
|||||||
$range j 0..i-1
|
$range j 0..i-1
|
||||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::forward<p$j##_type>(gmock_p$j))]]]]]]
|
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::forward<p$j##_type>(gmock_p$j))]]]]]]
|
||||||
$var param_field_decls = [[$for j
|
$var param_field_decls = [[$for j
|
||||||
[[
|
[[
|
||||||
|
|
||||||
@@ -672,7 +466,7 @@ $var param_field_decls2 = [[$for j
|
|||||||
$var params = [[$for j, [[p$j]]]]
|
$var params = [[$for j, [[p$j]]]]
|
||||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||||
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
|
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
|
||||||
$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
|
$var arg_types_and_names = [[$for k, [[const arg$k[[]]_type& arg$k]]]]
|
||||||
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
|
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
|
||||||
$else [[ACTION_P$i]]]]
|
$else [[ACTION_P$i]]]]
|
||||||
|
|
||||||
@@ -796,7 +590,7 @@ ACTION_TEMPLATE(InvokeArgument,
|
|||||||
using internal::invoke_argument::InvokeArgumentAdl;
|
using internal::invoke_argument::InvokeArgumentAdl;
|
||||||
return InvokeArgumentAdl<return_type>(
|
return InvokeArgumentAdl<return_type>(
|
||||||
internal::invoke_argument::AdlTag(),
|
internal::invoke_argument::AdlTag(),
|
||||||
::testing::get<k>(args)$for j [[, p$j]]);
|
::std::get<k>(args)$for j [[, p$j]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
]]
|
]]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -42,59 +42,16 @@ $var n = 10 $$ The maximum arity we support.
|
|||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "gmock/gmock-spec-builders.h"
|
#include "gmock/gmock-spec-builders.h"
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
#if GTEST_HAS_STD_FUNCTION_
|
|
||||||
# include <functional>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
class FunctionMockerBase;
|
|
||||||
|
|
||||||
// Note: class FunctionMocker really belongs to the ::testing
|
|
||||||
// namespace. However if we define it in ::testing, MSVC will
|
|
||||||
// complain when classes in ::testing::internal declare it as a
|
|
||||||
// friend class template. To workaround this compiler bug, we define
|
|
||||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
|
||||||
template <typename F>
|
|
||||||
class FunctionMocker;
|
|
||||||
|
|
||||||
|
|
||||||
$range i 0..n
|
$range i 0..n
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
|
||||||
$var As = [[$for j, [[A$j]]]]
|
|
||||||
$var as = [[$for j, [[internal::forward<A$j>(a$j)]]]]
|
|
||||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
|
||||||
$var ms = [[$for j, [[m$j]]]]
|
|
||||||
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
|
|
||||||
template <typename R$typename_As>
|
|
||||||
class FunctionMocker<R($As)> : public
|
|
||||||
internal::FunctionMockerBase<R($As)> {
|
|
||||||
public:
|
|
||||||
typedef R F($As);
|
|
||||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
|
||||||
|
|
||||||
MockSpec<F> With($matchers) {
|
|
||||||
return MockSpec<F>(this, ::testing::make_tuple($ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
R Invoke($Aas) {
|
|
||||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
|
||||||
// by the C++ standard [14.6.4] here, as the base class type is
|
|
||||||
// dependent on the template argument (and thus shouldn't be
|
|
||||||
// looked into when resolving InvokeWith).
|
|
||||||
return this->InvokeWith(ArgumentTuple($as));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
// Removes the given pointer; this is a helper for the expectation setter method
|
// Removes the given pointer; this is a helper for the expectation setter method
|
||||||
// for parameterless matchers.
|
// for parameterless matchers.
|
||||||
//
|
//
|
||||||
@@ -167,7 +124,7 @@ using internal::FunctionMocker;
|
|||||||
// The type of argument N of the given function type.
|
// The type of argument N of the given function type.
|
||||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
#define GMOCK_ARG_(tn, N, ...) \
|
#define GMOCK_ARG_(tn, N, ...) \
|
||||||
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
|
tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type
|
||||||
|
|
||||||
// The matcher type for argument N of the given function type.
|
// The matcher type for argument N of the given function type.
|
||||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
@@ -184,7 +141,7 @@ $for i [[
|
|||||||
$range j 1..i
|
$range j 1..i
|
||||||
$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||||
$var as = [[$for j, \
|
$var as = [[$for j, \
|
||||||
[[::testing::internal::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]]
|
[[::std::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]]
|
||||||
$var matcher_arg_as = [[$for j, \
|
$var matcher_arg_as = [[$for j, \
|
||||||
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||||
$var matcher_as = [[$for j, [[gmock_a$j]]]]
|
$var matcher_as = [[$for j, [[gmock_a$j]]]]
|
||||||
@@ -192,11 +149,9 @@ $var anything_matchers = [[$for j, \
|
|||||||
[[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
|
[[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
|
||||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
|
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
|
||||||
|
static_assert($i == ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, "MOCK_METHOD<N> must match argument count.");\
|
||||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
$arg_as) constness { \
|
$arg_as) constness { \
|
||||||
GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
|
|
||||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
|
|
||||||
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
|
|
||||||
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
|
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
|
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
|
||||||
} \
|
} \
|
||||||
@@ -267,82 +222,6 @@ $for i [[
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
// A MockFunction<F> class has one mock method whose type is F. It is
|
|
||||||
// useful when you just want your test code to emit some messages and
|
|
||||||
// have Google Mock verify the right messages are sent (and perhaps at
|
|
||||||
// the right times). For example, if you are exercising code:
|
|
||||||
//
|
|
||||||
// Foo(1);
|
|
||||||
// Foo(2);
|
|
||||||
// Foo(3);
|
|
||||||
//
|
|
||||||
// and want to verify that Foo(1) and Foo(3) both invoke
|
|
||||||
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
|
||||||
//
|
|
||||||
// TEST(FooTest, InvokesBarCorrectly) {
|
|
||||||
// MyMock mock;
|
|
||||||
// MockFunction<void(string check_point_name)> check;
|
|
||||||
// {
|
|
||||||
// InSequence s;
|
|
||||||
//
|
|
||||||
// EXPECT_CALL(mock, Bar("a"));
|
|
||||||
// EXPECT_CALL(check, Call("1"));
|
|
||||||
// EXPECT_CALL(check, Call("2"));
|
|
||||||
// EXPECT_CALL(mock, Bar("a"));
|
|
||||||
// }
|
|
||||||
// Foo(1);
|
|
||||||
// check.Call("1");
|
|
||||||
// Foo(2);
|
|
||||||
// check.Call("2");
|
|
||||||
// Foo(3);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The expectation spec says that the first Bar("a") must happen
|
|
||||||
// before check point "1", the second Bar("a") must happen after check
|
|
||||||
// point "2", and nothing should happen between the two check
|
|
||||||
// points. The explicit check points make it easy to tell which
|
|
||||||
// Bar("a") is called by which call to Foo().
|
|
||||||
//
|
|
||||||
// MockFunction<F> can also be used to exercise code that accepts
|
|
||||||
// std::function<F> callbacks. To do so, use AsStdFunction() method
|
|
||||||
// to create std::function proxy forwarding to original object's Call.
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// TEST(FooTest, RunsCallbackWithBarArgument) {
|
|
||||||
// MockFunction<int(string)> callback;
|
|
||||||
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
|
|
||||||
// Foo(callback.AsStdFunction());
|
|
||||||
// }
|
|
||||||
template <typename F>
|
|
||||||
class MockFunction;
|
|
||||||
|
|
||||||
|
|
||||||
$for i [[
|
|
||||||
$range j 0..i-1
|
|
||||||
$var ArgTypes = [[$for j, [[A$j]]]]
|
|
||||||
$var ArgValues = [[$for j, [[::std::move(a$j)]]]]
|
|
||||||
$var ArgDecls = [[$for j, [[A$j a$j]]]]
|
|
||||||
template <typename R$for j [[, typename A$j]]>
|
|
||||||
class MockFunction<R($ArgTypes)> {
|
|
||||||
public:
|
|
||||||
MockFunction() {}
|
|
||||||
|
|
||||||
MOCK_METHOD$i[[]]_T(Call, R($ArgTypes));
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_FUNCTION_
|
|
||||||
::std::function<R($ArgTypes)> AsStdFunction() {
|
|
||||||
return [this]($ArgDecls) -> R {
|
|
||||||
return this->Call($ArgValues);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif // GTEST_HAS_STD_FUNCTION_
|
|
||||||
|
|
||||||
private:
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -45,340 +45,10 @@ $$ }} This line fixes auto-indentation of the following code in Emacs.
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "gmock/gmock-matchers.h"
|
#include "gmock/gmock-matchers.h"
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
$range i 0..n-1
|
|
||||||
|
|
||||||
// The type of the i-th (0-based) field of Tuple.
|
|
||||||
#define GMOCK_FIELD_TYPE_(Tuple, i) \
|
|
||||||
typename ::testing::tuple_element<i, Tuple>::type
|
|
||||||
|
|
||||||
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
|
|
||||||
// tuple of type Tuple. It has two members:
|
|
||||||
//
|
|
||||||
// type: a tuple type whose i-th field is the ki-th field of Tuple.
|
|
||||||
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
|
|
||||||
//
|
|
||||||
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
|
|
||||||
//
|
|
||||||
// type is tuple<int, bool>, and
|
|
||||||
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
|
|
||||||
|
|
||||||
template <class Tuple$for i [[, int k$i = -1]]>
|
|
||||||
class TupleFields;
|
|
||||||
|
|
||||||
// This generic version is used when there are $n selectors.
|
|
||||||
template <class Tuple$for i [[, int k$i]]>
|
|
||||||
class TupleFields {
|
|
||||||
public:
|
|
||||||
typedef ::testing::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
|
|
||||||
static type GetSelectedFields(const Tuple& t) {
|
|
||||||
return type($for i, [[get<k$i>(t)]]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The following specialization is used for 0 ~ $(n-1) selectors.
|
|
||||||
|
|
||||||
$for i [[
|
|
||||||
$$ }}}
|
|
||||||
$range j 0..i-1
|
|
||||||
$range k 0..n-1
|
|
||||||
|
|
||||||
template <class Tuple$for j [[, int k$j]]>
|
|
||||||
class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
|
|
||||||
public:
|
|
||||||
typedef ::testing::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
|
|
||||||
static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) {
|
|
||||||
return type($for j, [[get<k$j>(t)]]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
#undef GMOCK_FIELD_TYPE_
|
|
||||||
|
|
||||||
// Implements the Args() matcher.
|
|
||||||
|
|
||||||
$var ks = [[$for i, [[k$i]]]]
|
|
||||||
template <class ArgsTuple$for i [[, int k$i = -1]]>
|
|
||||||
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
|
||||||
public:
|
|
||||||
// ArgsTuple may have top-level const or reference modifiers.
|
|
||||||
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
|
|
||||||
typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
|
|
||||||
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
|
|
||||||
|
|
||||||
template <typename InnerMatcher>
|
|
||||||
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
|
||||||
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
|
||||||
|
|
||||||
virtual bool MatchAndExplain(ArgsTuple args,
|
|
||||||
MatchResultListener* listener) const {
|
|
||||||
const SelectedArgs& selected_args = GetSelectedArgs(args);
|
|
||||||
if (!listener->IsInterested())
|
|
||||||
return inner_matcher_.Matches(selected_args);
|
|
||||||
|
|
||||||
PrintIndices(listener->stream());
|
|
||||||
*listener << "are " << PrintToString(selected_args);
|
|
||||||
|
|
||||||
StringMatchResultListener inner_listener;
|
|
||||||
const bool match = inner_matcher_.MatchAndExplain(selected_args,
|
|
||||||
&inner_listener);
|
|
||||||
PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void DescribeTo(::std::ostream* os) const {
|
|
||||||
*os << "are a tuple ";
|
|
||||||
PrintIndices(os);
|
|
||||||
inner_matcher_.DescribeTo(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
|
||||||
*os << "are a tuple ";
|
|
||||||
PrintIndices(os);
|
|
||||||
inner_matcher_.DescribeNegationTo(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
|
||||||
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prints the indices of the selected fields.
|
|
||||||
static void PrintIndices(::std::ostream* os) {
|
|
||||||
*os << "whose fields (";
|
|
||||||
const int indices[$n] = { $ks };
|
|
||||||
for (int i = 0; i < $n; i++) {
|
|
||||||
if (indices[i] < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i >= 1)
|
|
||||||
*os << ", ";
|
|
||||||
|
|
||||||
*os << "#" << indices[i];
|
|
||||||
}
|
|
||||||
*os << ") ";
|
|
||||||
}
|
|
||||||
|
|
||||||
const MonomorphicInnerMatcher inner_matcher_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class InnerMatcher$for i [[, int k$i = -1]]>
|
|
||||||
class ArgsMatcher {
|
|
||||||
public:
|
|
||||||
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
|
|
||||||
: inner_matcher_(inner_matcher) {}
|
|
||||||
|
|
||||||
template <typename ArgsTuple>
|
|
||||||
operator Matcher<ArgsTuple>() const {
|
|
||||||
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const InnerMatcher inner_matcher_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A set of metafunctions for computing the result type of AllOf.
|
|
||||||
// AllOf(m1, ..., mN) returns
|
|
||||||
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
|
||||||
|
|
||||||
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
|
|
||||||
// to simplify the implementation.
|
|
||||||
template <typename M1>
|
|
||||||
struct AllOfResult1 {
|
|
||||||
typedef M1 type;
|
|
||||||
};
|
|
||||||
|
|
||||||
$range i 1..n
|
|
||||||
|
|
||||||
$range i 2..n
|
|
||||||
$for i [[
|
|
||||||
$range j 2..i
|
|
||||||
$var m = i/2
|
|
||||||
$range k 1..m
|
|
||||||
$range t m+1..i
|
|
||||||
|
|
||||||
template <typename M1$for j [[, typename M$j]]>
|
|
||||||
struct AllOfResult$i {
|
|
||||||
typedef BothOfMatcher<
|
|
||||||
typename AllOfResult$m<$for k, [[M$k]]>::type,
|
|
||||||
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
|
|
||||||
> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// A set of metafunctions for computing the result type of AnyOf.
|
|
||||||
// AnyOf(m1, ..., mN) returns
|
|
||||||
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
|
||||||
|
|
||||||
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
|
|
||||||
// to simplify the implementation.
|
|
||||||
template <typename M1>
|
|
||||||
struct AnyOfResult1 {
|
|
||||||
typedef M1 type;
|
|
||||||
};
|
|
||||||
|
|
||||||
$range i 1..n
|
|
||||||
|
|
||||||
$range i 2..n
|
|
||||||
$for i [[
|
|
||||||
$range j 2..i
|
|
||||||
$var m = i/2
|
|
||||||
$range k 1..m
|
|
||||||
$range t m+1..i
|
|
||||||
|
|
||||||
template <typename M1$for j [[, typename M$j]]>
|
|
||||||
struct AnyOfResult$i {
|
|
||||||
typedef EitherOfMatcher<
|
|
||||||
typename AnyOfResult$m<$for k, [[M$k]]>::type,
|
|
||||||
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
|
|
||||||
> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
|
|
||||||
// fields of it matches a_matcher. C++ doesn't support default
|
|
||||||
// arguments for function templates, so we have to overload it.
|
|
||||||
|
|
||||||
$range i 0..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
template <$for j [[int k$j, ]]typename InnerMatcher>
|
|
||||||
inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
|
|
||||||
Args(const InnerMatcher& matcher) {
|
|
||||||
return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
|
|
||||||
// n elements, where the i-th element in the container must
|
|
||||||
// match the i-th argument in the list. Each argument of
|
|
||||||
// ElementsAre() can be either a value or a matcher. We support up to
|
|
||||||
// $n arguments.
|
|
||||||
//
|
|
||||||
// The use of DecayArray in the implementation allows ElementsAre()
|
|
||||||
// to accept string literals, whose type is const char[N], but we
|
|
||||||
// want to treat them as const char*.
|
|
||||||
//
|
|
||||||
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
|
||||||
// must not be used with containers whose elements's order is
|
|
||||||
// undefined (e.g. hash_map).
|
|
||||||
|
|
||||||
$range i 0..n
|
|
||||||
$for i [[
|
|
||||||
|
|
||||||
$range j 1..i
|
|
||||||
|
|
||||||
$if i>0 [[
|
|
||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
|
||||||
]]
|
|
||||||
|
|
||||||
inline internal::ElementsAreMatcher<
|
|
||||||
::testing::tuple<
|
|
||||||
$for j, [[
|
|
||||||
|
|
||||||
typename internal::DecayArray<T$j[[]]>::type]]> >
|
|
||||||
ElementsAre($for j, [[const T$j& e$j]]) {
|
|
||||||
typedef ::testing::tuple<
|
|
||||||
$for j, [[
|
|
||||||
|
|
||||||
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
|
||||||
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
|
|
||||||
// that matches n elements in any order. We support up to n=$n arguments.
|
|
||||||
//
|
|
||||||
// If you have >$n elements, consider UnorderedElementsAreArray() or
|
|
||||||
// UnorderedPointwise() instead.
|
|
||||||
|
|
||||||
$range i 0..n
|
|
||||||
$for i [[
|
|
||||||
|
|
||||||
$range j 1..i
|
|
||||||
|
|
||||||
$if i>0 [[
|
|
||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
|
||||||
]]
|
|
||||||
|
|
||||||
inline internal::UnorderedElementsAreMatcher<
|
|
||||||
::testing::tuple<
|
|
||||||
$for j, [[
|
|
||||||
|
|
||||||
typename internal::DecayArray<T$j[[]]>::type]]> >
|
|
||||||
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
|
|
||||||
typedef ::testing::tuple<
|
|
||||||
$for j, [[
|
|
||||||
|
|
||||||
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
|
||||||
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
|
|
||||||
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
|
|
||||||
|
|
||||||
$range i 2..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var m = i/2
|
|
||||||
$range k 1..m
|
|
||||||
$range t m+1..i
|
|
||||||
|
|
||||||
template <$for j, [[typename M$j]]>
|
|
||||||
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
|
|
||||||
AllOf($for j, [[M$j m$j]]) {
|
|
||||||
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
|
|
||||||
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
|
|
||||||
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
|
|
||||||
// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
|
|
||||||
|
|
||||||
$range i 2..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var m = i/2
|
|
||||||
$range k 1..m
|
|
||||||
$range t m+1..i
|
|
||||||
|
|
||||||
template <$for j, [[typename M$j]]>
|
|
||||||
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
|
|
||||||
AnyOf($for j, [[M$j m$j]]) {
|
|
||||||
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
|
|
||||||
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
|
|
||||||
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
} // namespace testing
|
|
||||||
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
|
|
||||||
$$ // show up in the generated code.
|
|
||||||
|
|
||||||
|
|
||||||
// The MATCHER* family of macros can be used in a namespace scope to
|
// The MATCHER* family of macros can be used in a namespace scope to
|
||||||
// define custom matchers easily.
|
// define custom matchers easily.
|
||||||
//
|
//
|
||||||
@@ -582,18 +252,15 @@ $$ // show up in the generated code.
|
|||||||
// overloading matchers based on parameter types (as opposed to just
|
// overloading matchers based on parameter types (as opposed to just
|
||||||
// based on the number of parameters).
|
// based on the number of parameters).
|
||||||
//
|
//
|
||||||
// MATCHER*() can only be used in a namespace scope. The reason is
|
// MATCHER*() can only be used in a namespace scope as templates cannot be
|
||||||
// that C++ doesn't yet allow function-local types to be used to
|
// declared inside of a local class.
|
||||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
|
||||||
// Once that's done, we'll consider supporting using MATCHER*() inside
|
|
||||||
// a function.
|
|
||||||
//
|
//
|
||||||
// More Information
|
// More Information
|
||||||
// ================
|
// ================
|
||||||
//
|
//
|
||||||
// To learn more about using these macros, please search for 'MATCHER'
|
// To learn more about using these macros, please search for 'MATCHER'
|
||||||
// on
|
// on
|
||||||
// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
|
// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
|
||||||
|
|
||||||
$range i 0..n
|
$range i 0..n
|
||||||
$for i
|
$for i
|
||||||
@@ -610,8 +277,8 @@ $var template = [[$if i==0 [[]] $else [[
|
|||||||
]]]]
|
]]]]
|
||||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||||
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||||
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]]
|
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]]
|
||||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::testing::internal::move(gmock_p$j))]]]]]]
|
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(::std::move(gmock_p$j))]]]]]]
|
||||||
$var params = [[$for j, [[p$j]]]]
|
$var params = [[$for j, [[p$j]]]]
|
||||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||||
@@ -647,12 +314,13 @@ $var param_field_decls2 = [[$for j
|
|||||||
private:\
|
private:\
|
||||||
::std::string FormatDescription(bool negation) const {\
|
::std::string FormatDescription(bool negation) const {\
|
||||||
::std::string gmock_description = (description);\
|
::std::string gmock_description = (description);\
|
||||||
if (!gmock_description.empty())\
|
if (!gmock_description.empty()) {\
|
||||||
return gmock_description;\
|
return gmock_description;\
|
||||||
|
}\
|
||||||
return ::testing::internal::FormatMatcherDescription(\
|
return ::testing::internal::FormatMatcherDescription(\
|
||||||
negation, #name, \
|
negation, #name, \
|
||||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
|
::std::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
|
||||||
}\
|
}\
|
||||||
};\
|
};\
|
||||||
template <typename arg_type>\
|
template <typename arg_type>\
|
||||||
|
|||||||
@@ -1,459 +0,0 @@
|
|||||||
// This file was GENERATED by command:
|
|
||||||
// pump.py gmock-generated-nice-strict.h.pump
|
|
||||||
// DO NOT EDIT BY HAND!!!
|
|
||||||
|
|
||||||
// Copyright 2008, Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
|
||||||
//
|
|
||||||
// Given a mock class MockFoo that is created using Google Mock,
|
|
||||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
|
||||||
// uninteresting calls (i.e. calls to mock methods that have no
|
|
||||||
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
|
||||||
// that prints a warning when an uninteresting call occurs, and
|
|
||||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
|
||||||
// uninteresting calls as errors.
|
|
||||||
//
|
|
||||||
// Currently a mock is naggy by default, so MockFoo and
|
|
||||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
|
||||||
// switch the default behavior of mocks to be nice, as that in general
|
|
||||||
// leads to more maintainable tests. When that happens, MockFoo will
|
|
||||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
|
||||||
// NiceMock<MockFoo>.
|
|
||||||
//
|
|
||||||
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
|
||||||
// their respective base class. Therefore you can write
|
|
||||||
// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
|
|
||||||
// has a constructor that accepts (int, const char*), for example.
|
|
||||||
//
|
|
||||||
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
|
||||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
|
||||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
|
||||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
|
||||||
// or "strict" modifier may not affect it, depending on the compiler.
|
|
||||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
|
||||||
// supported.
|
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
|
||||||
|
|
||||||
#include "gmock/gmock-spec-builders.h"
|
|
||||||
#include "gmock/internal/gmock-port.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
template <class MockClass>
|
|
||||||
class NiceMock : public MockClass {
|
|
||||||
public:
|
|
||||||
NiceMock() : MockClass() {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
// Ideally, we would inherit base class's constructors through a using
|
|
||||||
// declaration, which would preserve their visibility. However, many existing
|
|
||||||
// tests rely on the fact that current implementation reexports protected
|
|
||||||
// constructors as public. These tests would need to be cleaned up first.
|
|
||||||
|
|
||||||
// Single argument constructor is special-cased so that it can be
|
|
||||||
// made explicit.
|
|
||||||
template <typename A>
|
|
||||||
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename... An>
|
|
||||||
NiceMock(A1&& arg1, A2&& arg2, An&&... args)
|
|
||||||
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
|
||||||
std::forward<An>(args)...) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// C++98 doesn't have variadic templates, so we have to define one
|
|
||||||
// for each arity.
|
|
||||||
template <typename A1>
|
|
||||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
template <typename A1, typename A2>
|
|
||||||
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3,
|
|
||||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
|
||||||
a6, a7) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
|
||||||
a2, a3, a4, a5, a6, a7, a8) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
|
||||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
|
||||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
|
||||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
|
||||||
::testing::Mock::AllowUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
|
|
||||||
~NiceMock() {
|
|
||||||
::testing::Mock::UnregisterCallReaction(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class MockClass>
|
|
||||||
class NaggyMock : public MockClass {
|
|
||||||
public:
|
|
||||||
NaggyMock() : MockClass() {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
// Ideally, we would inherit base class's constructors through a using
|
|
||||||
// declaration, which would preserve their visibility. However, many existing
|
|
||||||
// tests rely on the fact that current implementation reexports protected
|
|
||||||
// constructors as public. These tests would need to be cleaned up first.
|
|
||||||
|
|
||||||
// Single argument constructor is special-cased so that it can be
|
|
||||||
// made explicit.
|
|
||||||
template <typename A>
|
|
||||||
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename... An>
|
|
||||||
NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
|
|
||||||
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
|
||||||
std::forward<An>(args)...) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// C++98 doesn't have variadic templates, so we have to define one
|
|
||||||
// for each arity.
|
|
||||||
template <typename A1>
|
|
||||||
explicit NaggyMock(const A1& a1) : MockClass(a1) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
template <typename A1, typename A2>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3,
|
|
||||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
|
||||||
a6, a7) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
|
||||||
a2, a3, a4, a5, a6, a7, a8) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
|
||||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
|
||||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
|
||||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
|
||||||
::testing::Mock::WarnUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
|
|
||||||
~NaggyMock() {
|
|
||||||
::testing::Mock::UnregisterCallReaction(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class MockClass>
|
|
||||||
class StrictMock : public MockClass {
|
|
||||||
public:
|
|
||||||
StrictMock() : MockClass() {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
// Ideally, we would inherit base class's constructors through a using
|
|
||||||
// declaration, which would preserve their visibility. However, many existing
|
|
||||||
// tests rely on the fact that current implementation reexports protected
|
|
||||||
// constructors as public. These tests would need to be cleaned up first.
|
|
||||||
|
|
||||||
// Single argument constructor is special-cased so that it can be
|
|
||||||
// made explicit.
|
|
||||||
template <typename A>
|
|
||||||
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename... An>
|
|
||||||
StrictMock(A1&& arg1, A2&& arg2, An&&... args)
|
|
||||||
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
|
||||||
std::forward<An>(args)...) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// C++98 doesn't have variadic templates, so we have to define one
|
|
||||||
// for each arity.
|
|
||||||
template <typename A1>
|
|
||||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
template <typename A1, typename A2>
|
|
||||||
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3,
|
|
||||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
|
||||||
a6, a7) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
|
||||||
a2, a3, a4, a5, a6, a7, a8) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
|
||||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
|
||||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
|
||||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
|
||||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
|
||||||
::testing::Mock::FailUninterestingCalls(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
|
|
||||||
~StrictMock() {
|
|
||||||
::testing::Mock::UnregisterCallReaction(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
|
||||||
};
|
|
||||||
|
|
||||||
// The following specializations catch some (relatively more common)
|
|
||||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
|
||||||
// all possible errors.
|
|
||||||
|
|
||||||
// These specializations are declared but not defined, as NiceMock,
|
|
||||||
// NaggyMock, and StrictMock cannot be nested.
|
|
||||||
|
|
||||||
template <typename MockClass>
|
|
||||||
class NiceMock<NiceMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NiceMock<NaggyMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NiceMock<StrictMock<MockClass> >;
|
|
||||||
|
|
||||||
template <typename MockClass>
|
|
||||||
class NaggyMock<NiceMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NaggyMock<NaggyMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class NaggyMock<StrictMock<MockClass> >;
|
|
||||||
|
|
||||||
template <typename MockClass>
|
|
||||||
class StrictMock<NiceMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class StrictMock<NaggyMock<MockClass> >;
|
|
||||||
template <typename MockClass>
|
|
||||||
class StrictMock<StrictMock<MockClass> >;
|
|
||||||
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -38,59 +38,13 @@
|
|||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "gmock/gmock-generated-actions.h"
|
#include "gmock/gmock-generated-actions.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Implements the Invoke(f) action. The template argument
|
|
||||||
// FunctionImpl is the implementation type of f, which can be either a
|
|
||||||
// function pointer or a functor. Invoke(f) can be used as an
|
|
||||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
|
||||||
// assigned to a tr1::function<F>).
|
|
||||||
template <typename FunctionImpl>
|
|
||||||
class InvokeAction {
|
|
||||||
public:
|
|
||||||
// The c'tor makes a copy of function_impl (either a function
|
|
||||||
// pointer or a functor).
|
|
||||||
explicit InvokeAction(FunctionImpl function_impl)
|
|
||||||
: function_impl_(function_impl) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple& args) {
|
|
||||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FunctionImpl function_impl_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
|
||||||
template <class Class, typename MethodPtr>
|
|
||||||
class InvokeMethodAction {
|
|
||||||
public:
|
|
||||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
|
||||||
: method_ptr_(method_ptr), obj_ptr_(obj_ptr) {}
|
|
||||||
|
|
||||||
template <typename Result, typename ArgumentTuple>
|
|
||||||
Result Perform(const ArgumentTuple& args) const {
|
|
||||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
|
||||||
obj_ptr_, method_ptr_, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The order of these members matters. Reversing the order can trigger
|
|
||||||
// warning C4121 in MSVC (see
|
|
||||||
// http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm ).
|
|
||||||
const MethodPtr method_ptr_;
|
|
||||||
Class* const obj_ptr_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// An internal replacement for std::copy which mimics its behavior. This is
|
// An internal replacement for std::copy which mimics its behavior. This is
|
||||||
// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
|
// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
|
||||||
// However Visual Studio 2010 and later do not honor #pragmas which disable that
|
// However Visual Studio 2010 and later do not honor #pragmas which disable that
|
||||||
@@ -109,45 +63,6 @@ inline OutputIterator CopyElements(InputIterator first,
|
|||||||
|
|
||||||
// Various overloads for Invoke().
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
// Creates an action that invokes 'function_impl' with the mock
|
|
||||||
// function's arguments.
|
|
||||||
template <typename FunctionImpl>
|
|
||||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
|
||||||
FunctionImpl function_impl) {
|
|
||||||
return MakePolymorphicAction(
|
|
||||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates an action that invokes the given method on the given object
|
|
||||||
// with the mock function's arguments.
|
|
||||||
template <class Class, typename MethodPtr>
|
|
||||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
|
||||||
Class* obj_ptr, MethodPtr method_ptr) {
|
|
||||||
return MakePolymorphicAction(
|
|
||||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
|
||||||
// non-empty argument list to perform inner_action, which takes no
|
|
||||||
// argument. In other words, it adapts an action accepting no
|
|
||||||
// argument to one that accepts (and ignores) arguments.
|
|
||||||
template <typename InnerAction>
|
|
||||||
inline internal::WithArgsAction<InnerAction>
|
|
||||||
WithoutArgs(const InnerAction& action) {
|
|
||||||
return internal::WithArgsAction<InnerAction>(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
|
||||||
// (0-based) argument of the mock function to an_action and performs
|
|
||||||
// it. It adapts an action accepting one argument to one that accepts
|
|
||||||
// multiple arguments. For convenience, we also provide
|
|
||||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
|
||||||
template <int k, typename InnerAction>
|
|
||||||
inline internal::WithArgsAction<InnerAction, k>
|
|
||||||
WithArg(const InnerAction& action) {
|
|
||||||
return internal::WithArgsAction<InnerAction, k>(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||||
// the macro definition, as the warnings are generated when the macro
|
// the macro definition, as the warnings are generated when the macro
|
||||||
@@ -162,7 +77,7 @@ WithArg(const InnerAction& action) {
|
|||||||
ACTION_TEMPLATE(ReturnArg,
|
ACTION_TEMPLATE(ReturnArg,
|
||||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
AND_0_VALUE_PARAMS()) {
|
AND_0_VALUE_PARAMS()) {
|
||||||
return ::testing::get<k>(args);
|
return ::std::get<k>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||||
@@ -170,7 +85,7 @@ ACTION_TEMPLATE(ReturnArg,
|
|||||||
ACTION_TEMPLATE(SaveArg,
|
ACTION_TEMPLATE(SaveArg,
|
||||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
AND_1_VALUE_PARAMS(pointer)) {
|
AND_1_VALUE_PARAMS(pointer)) {
|
||||||
*pointer = ::testing::get<k>(args);
|
*pointer = ::std::get<k>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||||
@@ -178,7 +93,7 @@ ACTION_TEMPLATE(SaveArg,
|
|||||||
ACTION_TEMPLATE(SaveArgPointee,
|
ACTION_TEMPLATE(SaveArgPointee,
|
||||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
AND_1_VALUE_PARAMS(pointer)) {
|
AND_1_VALUE_PARAMS(pointer)) {
|
||||||
*pointer = *::testing::get<k>(args);
|
*pointer = *::std::get<k>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||||
@@ -186,13 +101,13 @@ ACTION_TEMPLATE(SaveArgPointee,
|
|||||||
ACTION_TEMPLATE(SetArgReferee,
|
ACTION_TEMPLATE(SetArgReferee,
|
||||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
AND_1_VALUE_PARAMS(value)) {
|
AND_1_VALUE_PARAMS(value)) {
|
||||||
typedef typename ::testing::tuple_element<k, args_type>::type argk_type;
|
typedef typename ::std::tuple_element<k, args_type>::type argk_type;
|
||||||
// Ensures that argument #k is a reference. If you get a compiler
|
// Ensures that argument #k is a reference. If you get a compiler
|
||||||
// error on the next line, you are using SetArgReferee<k>(value) in
|
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||||
// a mock function whose k-th (0-based) argument is not a reference.
|
// a mock function whose k-th (0-based) argument is not a reference.
|
||||||
GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
GTEST_COMPILE_ASSERT_(std::is_reference<argk_type>::value,
|
||||||
SetArgReferee_must_be_used_with_a_reference_argument);
|
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||||
::testing::get<k>(args) = value;
|
::std::get<k>(args) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action SetArrayArgument<k>(first, last) copies the elements in
|
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||||
@@ -205,9 +120,9 @@ ACTION_TEMPLATE(SetArrayArgument,
|
|||||||
AND_2_VALUE_PARAMS(first, last)) {
|
AND_2_VALUE_PARAMS(first, last)) {
|
||||||
// Visual Studio deprecates ::std::copy, so we use our own copy in that case.
|
// Visual Studio deprecates ::std::copy, so we use our own copy in that case.
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
internal::CopyElements(first, last, ::testing::get<k>(args));
|
internal::CopyElements(first, last, ::std::get<k>(args));
|
||||||
#else
|
#else
|
||||||
::std::copy(first, last, ::testing::get<k>(args));
|
::std::copy(first, last, ::std::get<k>(args));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +131,7 @@ ACTION_TEMPLATE(SetArrayArgument,
|
|||||||
ACTION_TEMPLATE(DeleteArg,
|
ACTION_TEMPLATE(DeleteArg,
|
||||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
AND_0_VALUE_PARAMS()) {
|
AND_0_VALUE_PARAMS()) {
|
||||||
delete ::testing::get<k>(args);
|
delete ::std::get<k>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This action returns the value pointed to by 'pointer'.
|
// This action returns the value pointed to by 'pointer'.
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
$$ -*- mode: c++; -*-
|
|
||||||
$$ This is a Pump source file. Please use Pump to convert
|
|
||||||
$$ it to gmock-generated-nice-strict.h.
|
|
||||||
$$
|
|
||||||
$var n = 10 $$ The maximum arity we support.
|
|
||||||
// Copyright 2008, Google Inc.
|
// Copyright 2008, Google Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -65,34 +60,22 @@ $var n = 10 $$ The maximum arity we support.
|
|||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
// GOOGLETEST_CM0002 DO NOT DELETE
|
||||||
|
|
||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
|
|
||||||
#include "gmock/gmock-spec-builders.h"
|
#include "gmock/gmock-spec-builders.h"
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
$range kind 0..2
|
|
||||||
$for kind [[
|
|
||||||
|
|
||||||
$var clazz=[[$if kind==0 [[NiceMock]]
|
|
||||||
$elif kind==1 [[NaggyMock]]
|
|
||||||
$else [[StrictMock]]]]
|
|
||||||
|
|
||||||
$var method=[[$if kind==0 [[AllowUninterestingCalls]]
|
|
||||||
$elif kind==1 [[WarnUninterestingCalls]]
|
|
||||||
$else [[FailUninterestingCalls]]]]
|
|
||||||
|
|
||||||
template <class MockClass>
|
template <class MockClass>
|
||||||
class $clazz : public MockClass {
|
class NiceMock : public MockClass {
|
||||||
public:
|
public:
|
||||||
$clazz() : MockClass() {
|
NiceMock() : MockClass() {
|
||||||
::testing::Mock::$method(
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
// Ideally, we would inherit base class's constructors through a using
|
// Ideally, we would inherit base class's constructors through a using
|
||||||
// declaration, which would preserve their visibility. However, many existing
|
// declaration, which would preserve their visibility. However, many existing
|
||||||
// tests rely on the fact that current implementation reexports protected
|
// tests rely on the fact that current implementation reexports protected
|
||||||
@@ -101,50 +84,103 @@ class $clazz : public MockClass {
|
|||||||
// Single argument constructor is special-cased so that it can be
|
// Single argument constructor is special-cased so that it can be
|
||||||
// made explicit.
|
// made explicit.
|
||||||
template <typename A>
|
template <typename A>
|
||||||
explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) {
|
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||||
::testing::Mock::$method(
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename A1, typename A2, typename... An>
|
template <typename A1, typename A2, typename... An>
|
||||||
$clazz(A1&& arg1, A2&& arg2, An&&... args)
|
NiceMock(A1&& arg1, A2&& arg2, An&&... args)
|
||||||
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
||||||
std::forward<An>(args)...) {
|
std::forward<An>(args)...) {
|
||||||
::testing::Mock::$method(
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// C++98 doesn't have variadic templates, so we have to define one
|
|
||||||
// for each arity.
|
|
||||||
template <typename A1>
|
|
||||||
explicit $clazz(const A1& a1) : MockClass(a1) {
|
|
||||||
::testing::Mock::$method(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
$range i 2..n
|
~NiceMock() { // NOLINT
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
template <$for j, [[typename A$j]]>
|
|
||||||
$clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
|
||||||
::testing::Mock::$method(
|
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
|
|
||||||
~$clazz() {
|
|
||||||
::testing::Mock::UnregisterCallReaction(
|
::testing::Mock::UnregisterCallReaction(
|
||||||
internal::ImplicitCast_<MockClass*>(this));
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
|
||||||
};
|
};
|
||||||
|
|
||||||
]]
|
template <class MockClass>
|
||||||
|
class NaggyMock : public MockClass {
|
||||||
|
public:
|
||||||
|
NaggyMock() : MockClass() {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideally, we would inherit base class's constructors through a using
|
||||||
|
// declaration, which would preserve their visibility. However, many existing
|
||||||
|
// tests rely on the fact that current implementation reexports protected
|
||||||
|
// constructors as public. These tests would need to be cleaned up first.
|
||||||
|
|
||||||
|
// Single argument constructor is special-cased so that it can be
|
||||||
|
// made explicit.
|
||||||
|
template <typename A>
|
||||||
|
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename... An>
|
||||||
|
NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
|
||||||
|
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
||||||
|
std::forward<An>(args)...) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
~NaggyMock() { // NOLINT
|
||||||
|
::testing::Mock::UnregisterCallReaction(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class MockClass>
|
||||||
|
class StrictMock : public MockClass {
|
||||||
|
public:
|
||||||
|
StrictMock() : MockClass() {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideally, we would inherit base class's constructors through a using
|
||||||
|
// declaration, which would preserve their visibility. However, many existing
|
||||||
|
// tests rely on the fact that current implementation reexports protected
|
||||||
|
// constructors as public. These tests would need to be cleaned up first.
|
||||||
|
|
||||||
|
// Single argument constructor is special-cased so that it can be
|
||||||
|
// made explicit.
|
||||||
|
template <typename A>
|
||||||
|
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename... An>
|
||||||
|
StrictMock(A1&& arg1, A2&& arg2, An&&... args)
|
||||||
|
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
|
||||||
|
std::forward<An>(args)...) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
~StrictMock() { // NOLINT
|
||||||
|
::testing::Mock::UnregisterCallReaction(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
||||||
|
};
|
||||||
|
|
||||||
// The following specializations catch some (relatively more common)
|
// The following specializations catch some (relatively more common)
|
||||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||||
@@ -176,4 +212,4 @@ class StrictMock<StrictMock<MockClass> >;
|
|||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||||
@@ -61,10 +61,14 @@
|
|||||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "gmock/gmock-actions.h"
|
#include "gmock/gmock-actions.h"
|
||||||
#include "gmock/gmock-cardinalities.h"
|
#include "gmock/gmock-cardinalities.h"
|
||||||
@@ -104,9 +108,6 @@ template <typename F> class TypedExpectation;
|
|||||||
// Helper class for testing the Expectation class template.
|
// Helper class for testing the Expectation class template.
|
||||||
class ExpectationTester;
|
class ExpectationTester;
|
||||||
|
|
||||||
// Base class for function mockers.
|
|
||||||
template <typename F> class FunctionMockerBase;
|
|
||||||
|
|
||||||
// Protects the mock object registry (in class Mock), all function
|
// Protects the mock object registry (in class Mock), all function
|
||||||
// mockers, and all expectations.
|
// mockers, and all expectations.
|
||||||
//
|
//
|
||||||
@@ -123,9 +124,9 @@ GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
|
|||||||
// Untyped base class for ActionResultHolder<R>.
|
// Untyped base class for ActionResultHolder<R>.
|
||||||
class UntypedActionResultHolderBase;
|
class UntypedActionResultHolderBase;
|
||||||
|
|
||||||
// Abstract base class of FunctionMockerBase. This is the
|
// Abstract base class of FunctionMocker. This is the
|
||||||
// type-agnostic part of the function mocker interface. Its pure
|
// type-agnostic part of the function mocker interface. Its pure
|
||||||
// virtual methods are implemented by FunctionMockerBase.
|
// virtual methods are implemented by FunctionMocker.
|
||||||
class GTEST_API_ UntypedFunctionMockerBase {
|
class GTEST_API_ UntypedFunctionMockerBase {
|
||||||
public:
|
public:
|
||||||
UntypedFunctionMockerBase();
|
UntypedFunctionMockerBase();
|
||||||
@@ -187,7 +188,6 @@ class GTEST_API_ UntypedFunctionMockerBase {
|
|||||||
// this information in the global mock registry. Will be called
|
// this information in the global mock registry. Will be called
|
||||||
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
||||||
// method.
|
// method.
|
||||||
// FIXME: rename to SetAndRegisterOwner().
|
|
||||||
void RegisterOwner(const void* mock_obj)
|
void RegisterOwner(const void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
|
||||||
|
|
||||||
@@ -218,8 +218,7 @@ class GTEST_API_ UntypedFunctionMockerBase {
|
|||||||
protected:
|
protected:
|
||||||
typedef std::vector<const void*> UntypedOnCallSpecs;
|
typedef std::vector<const void*> UntypedOnCallSpecs;
|
||||||
|
|
||||||
typedef std::vector<internal::linked_ptr<ExpectationBase> >
|
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
|
||||||
UntypedExpectations;
|
|
||||||
|
|
||||||
// Returns an Expectation object that references and co-owns exp,
|
// Returns an Expectation object that references and co-owns exp,
|
||||||
// which must be an expectation on this mock function.
|
// which must be an expectation on this mock function.
|
||||||
@@ -304,11 +303,9 @@ class OnCallSpec : public UntypedOnCallSpecBase {
|
|||||||
: UntypedOnCallSpecBase(a_file, a_line),
|
: UntypedOnCallSpecBase(a_file, a_line),
|
||||||
matchers_(matchers),
|
matchers_(matchers),
|
||||||
// By default, extra_matcher_ should match anything. However,
|
// By default, extra_matcher_ should match anything. However,
|
||||||
// we cannot initialize it with _ as that triggers a compiler
|
// we cannot initialize it with _ as that causes ambiguity between
|
||||||
// bug in Symbian's C++ compiler (cannot decide between two
|
// Matcher's copy and move constructor for some argument types.
|
||||||
// overloaded constructors of Matcher<const ArgumentTuple&>).
|
extra_matcher_(A<const ArgumentTuple&>()) {}
|
||||||
extra_matcher_(A<const ArgumentTuple&>()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements the .With() clause.
|
// Implements the .With() clause.
|
||||||
OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {
|
OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {
|
||||||
@@ -335,7 +332,7 @@ class OnCallSpec : public UntypedOnCallSpecBase {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff the given arguments match the matchers.
|
// Returns true if and only if the given arguments match the matchers.
|
||||||
bool Matches(const ArgumentTuple& args) const {
|
bool Matches(const ArgumentTuple& args) const {
|
||||||
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
|
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
|
||||||
}
|
}
|
||||||
@@ -393,18 +390,28 @@ class GTEST_API_ Mock {
|
|||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
||||||
|
|
||||||
// Verifies all expectations on the given mock object and clears its
|
// Verifies all expectations on the given mock object and clears its
|
||||||
// default actions and expectations. Returns true iff the
|
// default actions and expectations. Returns true if and only if the
|
||||||
// verification was successful.
|
// verification was successful.
|
||||||
static bool VerifyAndClear(void* mock_obj)
|
static bool VerifyAndClear(void* mock_obj)
|
||||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
||||||
|
|
||||||
|
// Returns whether the mock was created as a naggy mock (default)
|
||||||
|
static bool IsNaggy(void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
||||||
|
// Returns whether the mock was created as a nice mock
|
||||||
|
static bool IsNice(void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
||||||
|
// Returns whether the mock was created as a strict mock
|
||||||
|
static bool IsStrict(void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class internal::UntypedFunctionMockerBase;
|
friend class internal::UntypedFunctionMockerBase;
|
||||||
|
|
||||||
// Needed for a function mocker to register itself (so that we know
|
// Needed for a function mocker to register itself (so that we know
|
||||||
// how to clear a mock object).
|
// how to clear a mock object).
|
||||||
template <typename F>
|
template <typename F>
|
||||||
friend class internal::FunctionMockerBase;
|
friend class internal::FunctionMocker;
|
||||||
|
|
||||||
template <typename M>
|
template <typename M>
|
||||||
friend class NiceMock;
|
friend class NiceMock;
|
||||||
@@ -467,7 +474,7 @@ class GTEST_API_ Mock {
|
|||||||
// Unregisters a mock method; removes the owning mock object from
|
// Unregisters a mock method; removes the owning mock object from
|
||||||
// the registry when the last mock method associated with it has
|
// the registry when the last mock method associated with it has
|
||||||
// been unregistered. This is called only in the destructor of
|
// been unregistered. This is called only in the destructor of
|
||||||
// FunctionMockerBase.
|
// FunctionMocker.
|
||||||
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
|
||||||
}; // class Mock
|
}; // class Mock
|
||||||
@@ -487,12 +494,7 @@ class GTEST_API_ Mock {
|
|||||||
// - Constness is shallow: a const Expectation object itself cannot
|
// - Constness is shallow: a const Expectation object itself cannot
|
||||||
// be modified, but the mutable methods of the ExpectationBase
|
// be modified, but the mutable methods of the ExpectationBase
|
||||||
// object it references can be called via expectation_base().
|
// object it references can be called via expectation_base().
|
||||||
// - The constructors and destructor are defined out-of-line because
|
|
||||||
// the Symbian WINSCW compiler wants to otherwise instantiate them
|
|
||||||
// when it sees this class definition, at which point it doesn't have
|
|
||||||
// ExpectationBase available yet, leading to incorrect destruction
|
|
||||||
// in the linked_ptr (or compilation errors if using a checking
|
|
||||||
// linked_ptr).
|
|
||||||
class GTEST_API_ Expectation {
|
class GTEST_API_ Expectation {
|
||||||
public:
|
public:
|
||||||
// Constructs a null object that doesn't reference any expectation.
|
// Constructs a null object that doesn't reference any expectation.
|
||||||
@@ -514,7 +516,8 @@ class GTEST_API_ Expectation {
|
|||||||
// The compiler-generated copy ctor and operator= work exactly as
|
// The compiler-generated copy ctor and operator= work exactly as
|
||||||
// intended, so we don't need to define our own.
|
// intended, so we don't need to define our own.
|
||||||
|
|
||||||
// Returns true iff rhs references the same expectation as this object does.
|
// Returns true if and only if rhs references the same expectation as this
|
||||||
|
// object does.
|
||||||
bool operator==(const Expectation& rhs) const {
|
bool operator==(const Expectation& rhs) const {
|
||||||
return expectation_base_ == rhs.expectation_base_;
|
return expectation_base_ == rhs.expectation_base_;
|
||||||
}
|
}
|
||||||
@@ -528,7 +531,7 @@ class GTEST_API_ Expectation {
|
|||||||
friend class ::testing::internal::UntypedFunctionMockerBase;
|
friend class ::testing::internal::UntypedFunctionMockerBase;
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
friend class ::testing::internal::FunctionMockerBase;
|
friend class ::testing::internal::FunctionMocker;
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
friend class ::testing::internal::TypedExpectation;
|
friend class ::testing::internal::TypedExpectation;
|
||||||
@@ -544,16 +547,15 @@ class GTEST_API_ Expectation {
|
|||||||
typedef ::std::set<Expectation, Less> Set;
|
typedef ::std::set<Expectation, Less> Set;
|
||||||
|
|
||||||
Expectation(
|
Expectation(
|
||||||
const internal::linked_ptr<internal::ExpectationBase>& expectation_base);
|
const std::shared_ptr<internal::ExpectationBase>& expectation_base);
|
||||||
|
|
||||||
// Returns the expectation this object references.
|
// Returns the expectation this object references.
|
||||||
const internal::linked_ptr<internal::ExpectationBase>&
|
const std::shared_ptr<internal::ExpectationBase>& expectation_base() const {
|
||||||
expectation_base() const {
|
|
||||||
return expectation_base_;
|
return expectation_base_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A linked_ptr that co-owns the expectation this handle references.
|
// A shared_ptr that co-owns the expectation this handle references.
|
||||||
internal::linked_ptr<internal::ExpectationBase> expectation_base_;
|
std::shared_ptr<internal::ExpectationBase> expectation_base_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A set of expectation handles. Useful in the .After() clause of
|
// A set of expectation handles. Useful in the .After() clause of
|
||||||
@@ -597,8 +599,8 @@ class ExpectationSet {
|
|||||||
// The compiler-generator ctor and operator= works exactly as
|
// The compiler-generator ctor and operator= works exactly as
|
||||||
// intended, so we don't need to define our own.
|
// intended, so we don't need to define our own.
|
||||||
|
|
||||||
// Returns true iff rhs contains the same set of Expectation objects
|
// Returns true if and only if rhs contains the same set of Expectation
|
||||||
// as this does.
|
// objects as this does.
|
||||||
bool operator==(const ExpectationSet& rhs) const {
|
bool operator==(const ExpectationSet& rhs) const {
|
||||||
return expectations_ == rhs.expectations_;
|
return expectations_ == rhs.expectations_;
|
||||||
}
|
}
|
||||||
@@ -635,11 +637,8 @@ class GTEST_API_ Sequence {
|
|||||||
void AddExpectation(const Expectation& expectation) const;
|
void AddExpectation(const Expectation& expectation) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The last expectation in this sequence. We use a linked_ptr here
|
// The last expectation in this sequence.
|
||||||
// because Sequence objects are copyable and we want the copies to
|
std::shared_ptr<Expectation> last_expectation_;
|
||||||
// be aliases. The linked_ptr allows the copies to co-own and share
|
|
||||||
// the same Expectation object.
|
|
||||||
internal::linked_ptr<Expectation> last_expectation_;
|
|
||||||
}; // class Sequence
|
}; // class Sequence
|
||||||
|
|
||||||
// An object of this type causes all EXPECT_CALL() statements
|
// An object of this type causes all EXPECT_CALL() statements
|
||||||
@@ -762,8 +761,8 @@ class GTEST_API_ ExpectationBase {
|
|||||||
// by the subclasses to implement the .Times() clause.
|
// by the subclasses to implement the .Times() clause.
|
||||||
void SpecifyCardinality(const Cardinality& cardinality);
|
void SpecifyCardinality(const Cardinality& cardinality);
|
||||||
|
|
||||||
// Returns true iff the user specified the cardinality explicitly
|
// Returns true if and only if the user specified the cardinality
|
||||||
// using a .Times().
|
// explicitly using a .Times().
|
||||||
bool cardinality_specified() const { return cardinality_specified_; }
|
bool cardinality_specified() const { return cardinality_specified_; }
|
||||||
|
|
||||||
// Sets the cardinality of this expectation spec.
|
// Sets the cardinality of this expectation spec.
|
||||||
@@ -779,7 +778,7 @@ class GTEST_API_ ExpectationBase {
|
|||||||
void RetireAllPreRequisites()
|
void RetireAllPreRequisites()
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
|
||||||
|
|
||||||
// Returns true iff this expectation is retired.
|
// Returns true if and only if this expectation is retired.
|
||||||
bool is_retired() const
|
bool is_retired() const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
@@ -793,28 +792,29 @@ class GTEST_API_ ExpectationBase {
|
|||||||
retired_ = true;
|
retired_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff this expectation is satisfied.
|
// Returns true if and only if this expectation is satisfied.
|
||||||
bool IsSatisfied() const
|
bool IsSatisfied() const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
return cardinality().IsSatisfiedByCallCount(call_count_);
|
return cardinality().IsSatisfiedByCallCount(call_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff this expectation is saturated.
|
// Returns true if and only if this expectation is saturated.
|
||||||
bool IsSaturated() const
|
bool IsSaturated() const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
return cardinality().IsSaturatedByCallCount(call_count_);
|
return cardinality().IsSaturatedByCallCount(call_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff this expectation is over-saturated.
|
// Returns true if and only if this expectation is over-saturated.
|
||||||
bool IsOverSaturated() const
|
bool IsOverSaturated() const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
return cardinality().IsOverSaturatedByCallCount(call_count_);
|
return cardinality().IsOverSaturatedByCallCount(call_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff all pre-requisites of this expectation are satisfied.
|
// Returns true if and only if all pre-requisites of this expectation are
|
||||||
|
// satisfied.
|
||||||
bool AllPrerequisitesAreSatisfied() const
|
bool AllPrerequisitesAreSatisfied() const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
|
||||||
|
|
||||||
@@ -857,12 +857,12 @@ class GTEST_API_ ExpectationBase {
|
|||||||
const char* file_; // The file that contains the expectation.
|
const char* file_; // The file that contains the expectation.
|
||||||
int line_; // The line number of the expectation.
|
int line_; // The line number of the expectation.
|
||||||
const std::string source_text_; // The EXPECT_CALL(...) source text.
|
const std::string source_text_; // The EXPECT_CALL(...) source text.
|
||||||
// True iff the cardinality is specified explicitly.
|
// True if and only if the cardinality is specified explicitly.
|
||||||
bool cardinality_specified_;
|
bool cardinality_specified_;
|
||||||
Cardinality cardinality_; // The cardinality of the expectation.
|
Cardinality cardinality_; // The cardinality of the expectation.
|
||||||
// The immediate pre-requisites (i.e. expectations that must be
|
// The immediate pre-requisites (i.e. expectations that must be
|
||||||
// satisfied before this expectation can be matched) of this
|
// satisfied before this expectation can be matched) of this
|
||||||
// expectation. We use linked_ptr in the set because we want an
|
// expectation. We use std::shared_ptr in the set because we want an
|
||||||
// Expectation object to be co-owned by its FunctionMocker and its
|
// Expectation object to be co-owned by its FunctionMocker and its
|
||||||
// successors. This allows multiple mock objects to be deleted at
|
// successors. This allows multiple mock objects to be deleted at
|
||||||
// different times.
|
// different times.
|
||||||
@@ -871,7 +871,7 @@ class GTEST_API_ ExpectationBase {
|
|||||||
// This group of fields are the current state of the expectation,
|
// This group of fields are the current state of the expectation,
|
||||||
// and can change as the mock function is called.
|
// and can change as the mock function is called.
|
||||||
int call_count_; // How many times this expectation has been invoked.
|
int call_count_; // How many times this expectation has been invoked.
|
||||||
bool retired_; // True iff this expectation has retired.
|
bool retired_; // True if and only if this expectation has retired.
|
||||||
UntypedActions untyped_actions_;
|
UntypedActions untyped_actions_;
|
||||||
bool extra_matcher_specified_;
|
bool extra_matcher_specified_;
|
||||||
bool repeated_action_specified_; // True if a WillRepeatedly() was specified.
|
bool repeated_action_specified_; // True if a WillRepeatedly() was specified.
|
||||||
@@ -891,20 +891,19 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
|
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
|
||||||
typedef typename Function<F>::Result Result;
|
typedef typename Function<F>::Result Result;
|
||||||
|
|
||||||
TypedExpectation(FunctionMockerBase<F>* owner, const char* a_file, int a_line,
|
TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,
|
||||||
const std::string& a_source_text,
|
const std::string& a_source_text,
|
||||||
const ArgumentMatcherTuple& m)
|
const ArgumentMatcherTuple& m)
|
||||||
: ExpectationBase(a_file, a_line, a_source_text),
|
: ExpectationBase(a_file, a_line, a_source_text),
|
||||||
owner_(owner),
|
owner_(owner),
|
||||||
matchers_(m),
|
matchers_(m),
|
||||||
// By default, extra_matcher_ should match anything. However,
|
// By default, extra_matcher_ should match anything. However,
|
||||||
// we cannot initialize it with _ as that triggers a compiler
|
// we cannot initialize it with _ as that causes ambiguity between
|
||||||
// bug in Symbian's C++ compiler (cannot decide between two
|
// Matcher's copy and move constructor for some argument types.
|
||||||
// overloaded constructors of Matcher<const ArgumentTuple&>).
|
|
||||||
extra_matcher_(A<const ArgumentTuple&>()),
|
extra_matcher_(A<const ArgumentTuple&>()),
|
||||||
repeated_action_(DoDefault()) {}
|
repeated_action_(DoDefault()) {}
|
||||||
|
|
||||||
virtual ~TypedExpectation() {
|
~TypedExpectation() override {
|
||||||
// Check the validity of the action count if it hasn't been done
|
// Check the validity of the action count if it hasn't been done
|
||||||
// yet (for example, if the expectation was never used).
|
// yet (for example, if the expectation was never used).
|
||||||
CheckActionCountIfNotDone();
|
CheckActionCountIfNotDone();
|
||||||
@@ -1070,7 +1069,7 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
|
|
||||||
// If this mock method has an extra matcher (i.e. .With(matcher)),
|
// If this mock method has an extra matcher (i.e. .With(matcher)),
|
||||||
// describes it to the ostream.
|
// describes it to the ostream.
|
||||||
virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) {
|
void MaybeDescribeExtraMatcherTo(::std::ostream* os) override {
|
||||||
if (extra_matcher_specified_) {
|
if (extra_matcher_specified_) {
|
||||||
*os << " Expected args: ";
|
*os << " Expected args: ";
|
||||||
extra_matcher_.DescribeTo(os);
|
extra_matcher_.DescribeTo(os);
|
||||||
@@ -1080,26 +1079,25 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
friend class FunctionMockerBase;
|
friend class FunctionMocker;
|
||||||
|
|
||||||
// Returns an Expectation object that references and co-owns this
|
// Returns an Expectation object that references and co-owns this
|
||||||
// expectation.
|
// expectation.
|
||||||
virtual Expectation GetHandle() {
|
Expectation GetHandle() override { return owner_->GetHandleOf(this); }
|
||||||
return owner_->GetHandleOf(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following methods will be called only after the EXPECT_CALL()
|
// The following methods will be called only after the EXPECT_CALL()
|
||||||
// statement finishes and when the current thread holds
|
// statement finishes and when the current thread holds
|
||||||
// g_gmock_mutex.
|
// g_gmock_mutex.
|
||||||
|
|
||||||
// Returns true iff this expectation matches the given arguments.
|
// Returns true if and only if this expectation matches the given arguments.
|
||||||
bool Matches(const ArgumentTuple& args) const
|
bool Matches(const ArgumentTuple& args) const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
|
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff this expectation should handle the given arguments.
|
// Returns true if and only if this expectation should handle the given
|
||||||
|
// arguments.
|
||||||
bool ShouldHandleArguments(const ArgumentTuple& args) const
|
bool ShouldHandleArguments(const ArgumentTuple& args) const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
@@ -1159,10 +1157,9 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the action that should be taken for the current invocation.
|
// Returns the action that should be taken for the current invocation.
|
||||||
const Action<F>& GetCurrentAction(
|
const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,
|
||||||
const FunctionMockerBase<F>* mocker,
|
const ArgumentTuple& args) const
|
||||||
const ArgumentTuple& args) const
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
const int count = call_count();
|
const int count = call_count();
|
||||||
Assert(count >= 1, __FILE__, __LINE__,
|
Assert(count >= 1, __FILE__, __LINE__,
|
||||||
@@ -1184,9 +1181,10 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
Log(kWarning, ss.str(), 1);
|
Log(kWarning, ss.str(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count <= action_count ?
|
return count <= action_count
|
||||||
*static_cast<const Action<F>*>(untyped_actions_[count - 1]) :
|
? *static_cast<const Action<F>*>(
|
||||||
repeated_action();
|
untyped_actions_[static_cast<size_t>(count - 1)])
|
||||||
|
: repeated_action();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given the arguments of a mock function call, if the call will
|
// Given the arguments of a mock function call, if the call will
|
||||||
@@ -1196,12 +1194,11 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
// Mock does it to 'why'. This method is not const as it calls
|
// Mock does it to 'why'. This method is not const as it calls
|
||||||
// IncrementCallCount(). A return value of NULL means the default
|
// IncrementCallCount(). A return value of NULL means the default
|
||||||
// action.
|
// action.
|
||||||
const Action<F>* GetActionForArguments(
|
const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,
|
||||||
const FunctionMockerBase<F>* mocker,
|
const ArgumentTuple& args,
|
||||||
const ArgumentTuple& args,
|
::std::ostream* what,
|
||||||
::std::ostream* what,
|
::std::ostream* why)
|
||||||
::std::ostream* why)
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
if (IsSaturated()) {
|
if (IsSaturated()) {
|
||||||
// We have an excessive call.
|
// We have an excessive call.
|
||||||
@@ -1210,10 +1207,7 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
mocker->DescribeDefaultActionTo(args, what);
|
mocker->DescribeDefaultActionTo(args, what);
|
||||||
DescribeCallCountTo(why);
|
DescribeCallCountTo(why);
|
||||||
|
|
||||||
// FIXME: allow the user to control whether
|
return nullptr;
|
||||||
// unexpected calls should fail immediately or continue using a
|
|
||||||
// flag --gmock_unexpected_calls_are_fatal.
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IncrementCallCount();
|
IncrementCallCount();
|
||||||
@@ -1230,7 +1224,7 @@ class TypedExpectation : public ExpectationBase {
|
|||||||
|
|
||||||
// All the fields below won't change once the EXPECT_CALL()
|
// All the fields below won't change once the EXPECT_CALL()
|
||||||
// statement finishes.
|
// statement finishes.
|
||||||
FunctionMockerBase<F>* const owner_;
|
FunctionMocker<F>* const owner_;
|
||||||
ArgumentMatcherTuple matchers_;
|
ArgumentMatcherTuple matchers_;
|
||||||
Matcher<const ArgumentTuple&> extra_matcher_;
|
Matcher<const ArgumentTuple&> extra_matcher_;
|
||||||
Action<F> repeated_action_;
|
Action<F> repeated_action_;
|
||||||
@@ -1262,7 +1256,7 @@ class MockSpec {
|
|||||||
|
|
||||||
// Constructs a MockSpec object, given the function mocker object
|
// Constructs a MockSpec object, given the function mocker object
|
||||||
// that the spec is associated with.
|
// that the spec is associated with.
|
||||||
MockSpec(internal::FunctionMockerBase<F>* function_mocker,
|
MockSpec(internal::FunctionMocker<F>* function_mocker,
|
||||||
const ArgumentMatcherTuple& matchers)
|
const ArgumentMatcherTuple& matchers)
|
||||||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||||
|
|
||||||
@@ -1298,7 +1292,7 @@ class MockSpec {
|
|||||||
friend class internal::FunctionMocker;
|
friend class internal::FunctionMocker;
|
||||||
|
|
||||||
// The function mocker that owns this spec.
|
// The function mocker that owns this spec.
|
||||||
internal::FunctionMockerBase<F>* const function_mocker_;
|
internal::FunctionMocker<F>* const function_mocker_;
|
||||||
// The argument matchers specified in the spec.
|
// The argument matchers specified in the spec.
|
||||||
ArgumentMatcherTuple matchers_;
|
ArgumentMatcherTuple matchers_;
|
||||||
|
|
||||||
@@ -1319,18 +1313,18 @@ class ReferenceOrValueWrapper {
|
|||||||
public:
|
public:
|
||||||
// Constructs a wrapper from the given value/reference.
|
// Constructs a wrapper from the given value/reference.
|
||||||
explicit ReferenceOrValueWrapper(T value)
|
explicit ReferenceOrValueWrapper(T value)
|
||||||
: value_(::testing::internal::move(value)) {
|
: value_(std::move(value)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwraps and returns the underlying value/reference, exactly as
|
// Unwraps and returns the underlying value/reference, exactly as
|
||||||
// originally passed. The behavior of calling this more than once on
|
// originally passed. The behavior of calling this more than once on
|
||||||
// the same object is unspecified.
|
// the same object is unspecified.
|
||||||
T Unwrap() { return ::testing::internal::move(value_); }
|
T Unwrap() { return std::move(value_); }
|
||||||
|
|
||||||
// Provides nondestructive access to the underlying value/reference.
|
// Provides nondestructive access to the underlying value/reference.
|
||||||
// Always returns a const reference (more precisely,
|
// Always returns a const reference (more precisely,
|
||||||
// const RemoveReference<T>&). The behavior of calling this after
|
// const std::add_lvalue_reference<T>::type). The behavior of calling this
|
||||||
// calling Unwrap on the same object is unspecified.
|
// after calling Unwrap on the same object is unspecified.
|
||||||
const T& Peek() const {
|
const T& Peek() const {
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
@@ -1389,7 +1383,7 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prints the held value as an action's result to os.
|
// Prints the held value as an action's result to os.
|
||||||
virtual void PrintAsActionResult(::std::ostream* os) const {
|
void PrintAsActionResult(::std::ostream* os) const override {
|
||||||
*os << "\n Returns: ";
|
*os << "\n Returns: ";
|
||||||
// T may be a reference type, so we don't use UniversalPrint().
|
// T may be a reference type, so we don't use UniversalPrint().
|
||||||
UniversalPrinter<T>::Print(result_.Peek(), os);
|
UniversalPrinter<T>::Print(result_.Peek(), os);
|
||||||
@@ -1399,28 +1393,27 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
|
|||||||
// result in a new-ed ActionResultHolder.
|
// result in a new-ed ActionResultHolder.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
static ActionResultHolder* PerformDefaultAction(
|
static ActionResultHolder* PerformDefaultAction(
|
||||||
const FunctionMockerBase<F>* func_mocker,
|
const FunctionMocker<F>* func_mocker,
|
||||||
typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
|
typename Function<F>::ArgumentTuple&& args,
|
||||||
const std::string& call_description) {
|
const std::string& call_description) {
|
||||||
return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
|
return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
|
||||||
internal::move(args), call_description)));
|
std::move(args), call_description)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs the given action and returns the result in a new-ed
|
// Performs the given action and returns the result in a new-ed
|
||||||
// ActionResultHolder.
|
// ActionResultHolder.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
static ActionResultHolder* PerformAction(
|
static ActionResultHolder* PerformAction(
|
||||||
const Action<F>& action,
|
const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
|
||||||
typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
|
|
||||||
return new ActionResultHolder(
|
return new ActionResultHolder(
|
||||||
Wrapper(action.Perform(internal::move(args))));
|
Wrapper(action.Perform(std::move(args))));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef ReferenceOrValueWrapper<T> Wrapper;
|
typedef ReferenceOrValueWrapper<T> Wrapper;
|
||||||
|
|
||||||
explicit ActionResultHolder(Wrapper result)
|
explicit ActionResultHolder(Wrapper result)
|
||||||
: result_(::testing::internal::move(result)) {
|
: result_(std::move(result)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Wrapper result_;
|
Wrapper result_;
|
||||||
@@ -1434,16 +1427,16 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
|
|||||||
public:
|
public:
|
||||||
void Unwrap() { }
|
void Unwrap() { }
|
||||||
|
|
||||||
virtual void PrintAsActionResult(::std::ostream* /* os */) const {}
|
void PrintAsActionResult(::std::ostream* /* os */) const override {}
|
||||||
|
|
||||||
// Performs the given mock function's default action and returns ownership
|
// Performs the given mock function's default action and returns ownership
|
||||||
// of an empty ActionResultHolder*.
|
// of an empty ActionResultHolder*.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
static ActionResultHolder* PerformDefaultAction(
|
static ActionResultHolder* PerformDefaultAction(
|
||||||
const FunctionMockerBase<F>* func_mocker,
|
const FunctionMocker<F>* func_mocker,
|
||||||
typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
|
typename Function<F>::ArgumentTuple&& args,
|
||||||
const std::string& call_description) {
|
const std::string& call_description) {
|
||||||
func_mocker->PerformDefaultAction(internal::move(args), call_description);
|
func_mocker->PerformDefaultAction(std::move(args), call_description);
|
||||||
return new ActionResultHolder;
|
return new ActionResultHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1451,9 +1444,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
|
|||||||
// ActionResultHolder*.
|
// ActionResultHolder*.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
static ActionResultHolder* PerformAction(
|
static ActionResultHolder* PerformAction(
|
||||||
const Action<F>& action,
|
const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
|
||||||
typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
|
action.Perform(std::move(args));
|
||||||
action.Perform(internal::move(args));
|
|
||||||
return new ActionResultHolder;
|
return new ActionResultHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1462,23 +1454,39 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The base of the function mocker class for the given function type.
|
|
||||||
// We put the methods in this class instead of its child to avoid code
|
|
||||||
// bloat.
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class FunctionMockerBase : public UntypedFunctionMockerBase {
|
class FunctionMocker;
|
||||||
public:
|
|
||||||
typedef typename Function<F>::Result Result;
|
|
||||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
|
||||||
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
|
|
||||||
|
|
||||||
FunctionMockerBase() {}
|
template <typename R, typename... Args>
|
||||||
|
class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
|
||||||
|
using F = R(Args...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Result = R;
|
||||||
|
using ArgumentTuple = std::tuple<Args...>;
|
||||||
|
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||||
|
|
||||||
|
FunctionMocker() {}
|
||||||
|
|
||||||
|
// There is no generally useful and implementable semantics of
|
||||||
|
// copying a mock object, so copying a mock is usually a user error.
|
||||||
|
// Thus we disallow copying function mockers. If the user really
|
||||||
|
// wants to copy a mock object, they should implement their own copy
|
||||||
|
// operation, for example:
|
||||||
|
//
|
||||||
|
// class MockFoo : public Foo {
|
||||||
|
// public:
|
||||||
|
// // Defines a copy constructor explicitly.
|
||||||
|
// MockFoo(const MockFoo& src) {}
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
FunctionMocker(const FunctionMocker&) = delete;
|
||||||
|
FunctionMocker& operator=(const FunctionMocker&) = delete;
|
||||||
|
|
||||||
// The destructor verifies that all expectations on this mock
|
// The destructor verifies that all expectations on this mock
|
||||||
// function have been satisfied. If not, it will report Google Test
|
// function have been satisfied. If not, it will report Google Test
|
||||||
// non-fatal failures for the violations.
|
// non-fatal failures for the violations.
|
||||||
virtual ~FunctionMockerBase()
|
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(&g_gmock_mutex);
|
||||||
VerifyAndClearExpectationsLocked();
|
VerifyAndClearExpectationsLocked();
|
||||||
Mock::UnregisterLocked(this);
|
Mock::UnregisterLocked(this);
|
||||||
@@ -1498,7 +1506,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs the default action of this mock function on the given
|
// Performs the default action of this mock function on the given
|
||||||
@@ -1508,13 +1516,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
// mutable state of this object, and thus can be called concurrently
|
// mutable state of this object, and thus can be called concurrently
|
||||||
// without locking.
|
// without locking.
|
||||||
// L = *
|
// L = *
|
||||||
Result PerformDefaultAction(
|
Result PerformDefaultAction(ArgumentTuple&& args,
|
||||||
typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
|
const std::string& call_description) const {
|
||||||
const std::string& call_description) const {
|
|
||||||
const OnCallSpec<F>* const spec =
|
const OnCallSpec<F>* const spec =
|
||||||
this->FindOnCallSpec(args);
|
this->FindOnCallSpec(args);
|
||||||
if (spec != NULL) {
|
if (spec != nullptr) {
|
||||||
return spec->GetAction().Perform(internal::move(args));
|
return spec->GetAction().Perform(std::move(args));
|
||||||
}
|
}
|
||||||
const std::string message =
|
const std::string message =
|
||||||
call_description +
|
call_description +
|
||||||
@@ -1535,11 +1542,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
// the error message to describe the call in the case the default
|
// the error message to describe the call in the case the default
|
||||||
// action fails. The caller is responsible for deleting the result.
|
// action fails. The caller is responsible for deleting the result.
|
||||||
// L = *
|
// L = *
|
||||||
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
|
UntypedActionResultHolderBase* UntypedPerformDefaultAction(
|
||||||
void* untyped_args, // must point to an ArgumentTuple
|
void* untyped_args, // must point to an ArgumentTuple
|
||||||
const std::string& call_description) const {
|
const std::string& call_description) const override {
|
||||||
ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
|
ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
|
||||||
return ResultHolder::PerformDefaultAction(this, internal::move(*args),
|
return ResultHolder::PerformDefaultAction(this, std::move(*args),
|
||||||
call_description);
|
call_description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1547,18 +1554,18 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
// the action's result. The caller is responsible for deleting the
|
// the action's result. The caller is responsible for deleting the
|
||||||
// result.
|
// result.
|
||||||
// L = *
|
// L = *
|
||||||
virtual UntypedActionResultHolderBase* UntypedPerformAction(
|
UntypedActionResultHolderBase* UntypedPerformAction(
|
||||||
const void* untyped_action, void* untyped_args) const {
|
const void* untyped_action, void* untyped_args) const override {
|
||||||
// Make a copy of the action before performing it, in case the
|
// Make a copy of the action before performing it, in case the
|
||||||
// action deletes the mock object (and thus deletes itself).
|
// action deletes the mock object (and thus deletes itself).
|
||||||
const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
|
const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
|
||||||
ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
|
ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
|
||||||
return ResultHolder::PerformAction(action, internal::move(*args));
|
return ResultHolder::PerformAction(action, std::move(*args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
|
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
|
||||||
// clears the ON_CALL()s set on this mock function.
|
// clears the ON_CALL()s set on this mock function.
|
||||||
virtual void ClearDefaultActionsLocked()
|
void ClearDefaultActionsLocked() override
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
|
|
||||||
@@ -1584,26 +1591,26 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
g_gmock_mutex.Lock();
|
g_gmock_mutex.Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the result of invoking this mock function with the given
|
||||||
|
// arguments. This function can be safely called from multiple
|
||||||
|
// threads concurrently.
|
||||||
|
Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
|
ArgumentTuple tuple(std::forward<Args>(args)...);
|
||||||
|
std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>(
|
||||||
|
this->UntypedInvokeWith(static_cast<void*>(&tuple))));
|
||||||
|
return holder->Unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
MockSpec<F> With(Matcher<Args>... m) {
|
||||||
|
return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
friend class MockSpec;
|
friend class MockSpec;
|
||||||
|
|
||||||
typedef ActionResultHolder<Result> ResultHolder;
|
typedef ActionResultHolder<Result> ResultHolder;
|
||||||
|
|
||||||
// Returns the result of invoking this mock function with the given
|
|
||||||
// arguments. This function can be safely called from multiple
|
|
||||||
// threads concurrently.
|
|
||||||
Result InvokeWith(
|
|
||||||
typename RvalueRef<typename Function<F>::ArgumentTuple>::type args)
|
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
|
||||||
// const_cast is required since in C++98 we still pass ArgumentTuple around
|
|
||||||
// by const& instead of rvalue reference.
|
|
||||||
void* untyped_args = const_cast<void*>(static_cast<const void*>(&args));
|
|
||||||
scoped_ptr<ResultHolder> holder(
|
|
||||||
DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args)));
|
|
||||||
return holder->Unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds and returns a default action spec for this mock function.
|
// Adds and returns a default action spec for this mock function.
|
||||||
OnCallSpec<F>& AddNewOnCallSpec(
|
OnCallSpec<F>& AddNewOnCallSpec(
|
||||||
const char* file, int line,
|
const char* file, int line,
|
||||||
@@ -1623,14 +1630,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
|
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
|
||||||
TypedExpectation<F>* const expectation =
|
TypedExpectation<F>* const expectation =
|
||||||
new TypedExpectation<F>(this, file, line, source_text, m);
|
new TypedExpectation<F>(this, file, line, source_text, m);
|
||||||
const linked_ptr<ExpectationBase> untyped_expectation(expectation);
|
const std::shared_ptr<ExpectationBase> untyped_expectation(expectation);
|
||||||
// See the definition of untyped_expectations_ for why access to
|
// See the definition of untyped_expectations_ for why access to
|
||||||
// it is unprotected here.
|
// it is unprotected here.
|
||||||
untyped_expectations_.push_back(untyped_expectation);
|
untyped_expectations_.push_back(untyped_expectation);
|
||||||
|
|
||||||
// Adds this expectation into the implicit sequence if there is one.
|
// Adds this expectation into the implicit sequence if there is one.
|
||||||
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
|
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
|
||||||
if (implicit_sequence != NULL) {
|
if (implicit_sequence != nullptr) {
|
||||||
implicit_sequence->AddExpectation(Expectation(untyped_expectation));
|
implicit_sequence->AddExpectation(Expectation(untyped_expectation));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1649,10 +1656,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
::std::ostream* os) const {
|
::std::ostream* os) const {
|
||||||
const OnCallSpec<F>* const spec = FindOnCallSpec(args);
|
const OnCallSpec<F>* const spec = FindOnCallSpec(args);
|
||||||
|
|
||||||
if (spec == NULL) {
|
if (spec == nullptr) {
|
||||||
*os << (internal::type_equals<Result, void>::value ?
|
*os << (std::is_void<Result>::value ? "returning directly.\n"
|
||||||
"returning directly.\n" :
|
: "returning default value.\n");
|
||||||
"returning default value.\n");
|
|
||||||
} else {
|
} else {
|
||||||
*os << "taking default action specified at:\n"
|
*os << "taking default action specified at:\n"
|
||||||
<< FormatFileLocation(spec->file(), spec->line()) << "\n";
|
<< FormatFileLocation(spec->file(), spec->line()) << "\n";
|
||||||
@@ -1662,10 +1668,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
// Writes a message that the call is uninteresting (i.e. neither
|
// Writes a message that the call is uninteresting (i.e. neither
|
||||||
// explicitly expected nor explicitly unexpected) to the given
|
// explicitly expected nor explicitly unexpected) to the given
|
||||||
// ostream.
|
// ostream.
|
||||||
virtual void UntypedDescribeUninterestingCall(
|
void UntypedDescribeUninterestingCall(const void* untyped_args,
|
||||||
const void* untyped_args,
|
::std::ostream* os) const override
|
||||||
::std::ostream* os) const
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
|
||||||
const ArgumentTuple& args =
|
const ArgumentTuple& args =
|
||||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||||
*os << "Uninteresting mock function call - ";
|
*os << "Uninteresting mock function call - ";
|
||||||
@@ -1690,18 +1695,17 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
// section. The reason is that we have no control on what the
|
// section. The reason is that we have no control on what the
|
||||||
// action does (it can invoke an arbitrary user function or even a
|
// action does (it can invoke an arbitrary user function or even a
|
||||||
// mock function) and excessive locking could cause a dead lock.
|
// mock function) and excessive locking could cause a dead lock.
|
||||||
virtual const ExpectationBase* UntypedFindMatchingExpectation(
|
const ExpectationBase* UntypedFindMatchingExpectation(
|
||||||
const void* untyped_args,
|
const void* untyped_args, const void** untyped_action, bool* is_excessive,
|
||||||
const void** untyped_action, bool* is_excessive,
|
::std::ostream* what, ::std::ostream* why) override
|
||||||
::std::ostream* what, ::std::ostream* why)
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
|
||||||
const ArgumentTuple& args =
|
const ArgumentTuple& args =
|
||||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||||
MutexLock l(&g_gmock_mutex);
|
MutexLock l(&g_gmock_mutex);
|
||||||
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
|
||||||
if (exp == NULL) { // A match wasn't found.
|
if (exp == nullptr) { // A match wasn't found.
|
||||||
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
this->FormatUnexpectedCallMessageLocked(args, what, why);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This line must be done before calling GetActionForArguments(),
|
// This line must be done before calling GetActionForArguments(),
|
||||||
@@ -1709,15 +1713,15 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
// its saturation status.
|
// its saturation status.
|
||||||
*is_excessive = exp->IsSaturated();
|
*is_excessive = exp->IsSaturated();
|
||||||
const Action<F>* action = exp->GetActionForArguments(this, args, what, why);
|
const Action<F>* action = exp->GetActionForArguments(this, args, what, why);
|
||||||
if (action != NULL && action->IsDoDefault())
|
if (action != nullptr && action->IsDoDefault())
|
||||||
action = NULL; // Normalize "do default" to NULL.
|
action = nullptr; // Normalize "do default" to NULL.
|
||||||
*untyped_action = action;
|
*untyped_action = action;
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints the given function arguments to the ostream.
|
// Prints the given function arguments to the ostream.
|
||||||
virtual void UntypedPrintArgs(const void* untyped_args,
|
void UntypedPrintArgs(const void* untyped_args,
|
||||||
::std::ostream* os) const {
|
::std::ostream* os) const override {
|
||||||
const ArgumentTuple& args =
|
const ArgumentTuple& args =
|
||||||
*static_cast<const ArgumentTuple*>(untyped_args);
|
*static_cast<const ArgumentTuple*>(untyped_args);
|
||||||
UniversalPrint(args, os);
|
UniversalPrint(args, os);
|
||||||
@@ -1740,7 +1744,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a message that the arguments don't match any expectation.
|
// Returns a message that the arguments don't match any expectation.
|
||||||
@@ -1762,12 +1766,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
::std::ostream* why) const
|
::std::ostream* why) const
|
||||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
g_gmock_mutex.AssertHeld();
|
g_gmock_mutex.AssertHeld();
|
||||||
const int count = static_cast<int>(untyped_expectations_.size());
|
const size_t count = untyped_expectations_.size();
|
||||||
*why << "Google Mock tried the following " << count << " "
|
*why << "Google Mock tried the following " << count << " "
|
||||||
<< (count == 1 ? "expectation, but it didn't match" :
|
<< (count == 1 ? "expectation, but it didn't match" :
|
||||||
"expectations, but none matched")
|
"expectations, but none matched")
|
||||||
<< ":\n";
|
<< ":\n";
|
||||||
for (int i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
TypedExpectation<F>* const expectation =
|
TypedExpectation<F>* const expectation =
|
||||||
static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());
|
static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());
|
||||||
*why << "\n";
|
*why << "\n";
|
||||||
@@ -1780,36 +1784,98 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
|||||||
expectation->DescribeCallCountTo(why);
|
expectation->DescribeCallCountTo(why);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}; // class FunctionMocker
|
||||||
// There is no generally useful and implementable semantics of
|
|
||||||
// copying a mock object, so copying a mock is usually a user error.
|
|
||||||
// Thus we disallow copying function mockers. If the user really
|
|
||||||
// wants to copy a mock object, they should implement their own copy
|
|
||||||
// operation, for example:
|
|
||||||
//
|
|
||||||
// class MockFoo : public Foo {
|
|
||||||
// public:
|
|
||||||
// // Defines a copy constructor explicitly.
|
|
||||||
// MockFoo(const MockFoo& src) {}
|
|
||||||
// ...
|
|
||||||
// };
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase);
|
|
||||||
}; // class FunctionMockerBase
|
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
|
||||||
|
|
||||||
// Implements methods of FunctionMockerBase.
|
|
||||||
|
|
||||||
// Verifies that all expectations on this mock function have been
|
|
||||||
// satisfied. Reports one or more Google Test non-fatal failures and
|
|
||||||
// returns false if not.
|
|
||||||
|
|
||||||
// Reports an uninteresting call (whose description is in msg) in the
|
// Reports an uninteresting call (whose description is in msg) in the
|
||||||
// manner specified by 'reaction'.
|
// manner specified by 'reaction'.
|
||||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
|
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
// A MockFunction<F> class has one mock method whose type is F. It is
|
||||||
|
// useful when you just want your test code to emit some messages and
|
||||||
|
// have Google Mock verify the right messages are sent (and perhaps at
|
||||||
|
// the right times). For example, if you are exercising code:
|
||||||
|
//
|
||||||
|
// Foo(1);
|
||||||
|
// Foo(2);
|
||||||
|
// Foo(3);
|
||||||
|
//
|
||||||
|
// and want to verify that Foo(1) and Foo(3) both invoke
|
||||||
|
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
||||||
|
//
|
||||||
|
// TEST(FooTest, InvokesBarCorrectly) {
|
||||||
|
// MyMock mock;
|
||||||
|
// MockFunction<void(string check_point_name)> check;
|
||||||
|
// {
|
||||||
|
// InSequence s;
|
||||||
|
//
|
||||||
|
// EXPECT_CALL(mock, Bar("a"));
|
||||||
|
// EXPECT_CALL(check, Call("1"));
|
||||||
|
// EXPECT_CALL(check, Call("2"));
|
||||||
|
// EXPECT_CALL(mock, Bar("a"));
|
||||||
|
// }
|
||||||
|
// Foo(1);
|
||||||
|
// check.Call("1");
|
||||||
|
// Foo(2);
|
||||||
|
// check.Call("2");
|
||||||
|
// Foo(3);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The expectation spec says that the first Bar("a") must happen
|
||||||
|
// before check point "1", the second Bar("a") must happen after check
|
||||||
|
// point "2", and nothing should happen between the two check
|
||||||
|
// points. The explicit check points make it easy to tell which
|
||||||
|
// Bar("a") is called by which call to Foo().
|
||||||
|
//
|
||||||
|
// MockFunction<F> can also be used to exercise code that accepts
|
||||||
|
// std::function<F> callbacks. To do so, use AsStdFunction() method
|
||||||
|
// to create std::function proxy forwarding to original object's Call.
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// TEST(FooTest, RunsCallbackWithBarArgument) {
|
||||||
|
// MockFunction<int(string)> callback;
|
||||||
|
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
|
||||||
|
// Foo(callback.AsStdFunction());
|
||||||
|
// }
|
||||||
|
template <typename F>
|
||||||
|
class MockFunction;
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
class MockFunction<R(Args...)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
MockFunction(const MockFunction&) = delete;
|
||||||
|
MockFunction& operator=(const MockFunction&) = delete;
|
||||||
|
|
||||||
|
std::function<R(Args...)> AsStdFunction() {
|
||||||
|
return [this](Args... args) -> R {
|
||||||
|
return this->Call(std::forward<Args>(args)...);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation detail: the expansion of the MOCK_METHOD macro.
|
||||||
|
R Call(Args... args) {
|
||||||
|
mock_.SetOwnerAndName(this, "Call");
|
||||||
|
return mock_.Invoke(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
|
||||||
|
mock_.RegisterOwner(this);
|
||||||
|
return mock_.With(std::move(m)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
|
||||||
|
R (*)(Args...)) {
|
||||||
|
return this->gmock_Call(::testing::A<Args>()...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
internal::FunctionMocker<R(Args...)> mock_;
|
||||||
|
};
|
||||||
|
|
||||||
// The style guide prohibits "using" statements in a namespace scope
|
// The style guide prohibits "using" statements in a namespace scope
|
||||||
// inside a header file. However, the MockSpec class template is
|
// inside a header file. However, the MockSpec class template is
|
||||||
// meant to be defined in the ::testing namespace. The following line
|
// meant to be defined in the ::testing namespace. The following line
|
||||||
@@ -1905,8 +1971,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|||||||
// second argument is an internal type derived from the method signature. The
|
// second argument is an internal type derived from the method signature. The
|
||||||
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
// failure to disambiguate two overloads of this method in the ON_CALL statement
|
||||||
// is how we block callers from setting expectations on overloaded methods.
|
// is how we block callers from setting expectations on overloaded methods.
|
||||||
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
|
||||||
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), NULL) \
|
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
|
||||||
|
nullptr) \
|
||||||
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
.Setter(__FILE__, __LINE__, #mock_expr, #call)
|
||||||
|
|
||||||
#define ON_CALL(obj, call) \
|
#define ON_CALL(obj, call) \
|
||||||
|
|||||||
@@ -39,14 +39,14 @@
|
|||||||
|
|
||||||
// This file implements the following syntax:
|
// This file implements the following syntax:
|
||||||
//
|
//
|
||||||
// ON_CALL(mock_object.Method(...))
|
// ON_CALL(mock_object, Method(...))
|
||||||
// .With(...) ?
|
// .With(...) ?
|
||||||
// .WillByDefault(...);
|
// .WillByDefault(...);
|
||||||
//
|
//
|
||||||
// where With() is optional and WillByDefault() must appear exactly
|
// where With() is optional and WillByDefault() must appear exactly
|
||||||
// once.
|
// once.
|
||||||
//
|
//
|
||||||
// EXPECT_CALL(mock_object.Method(...))
|
// EXPECT_CALL(mock_object, Method(...))
|
||||||
// .With(...) ?
|
// .With(...) ?
|
||||||
// .Times(...) ?
|
// .Times(...) ?
|
||||||
// .InSequence(...) *
|
// .InSequence(...) *
|
||||||
@@ -58,13 +58,14 @@
|
|||||||
|
|
||||||
#include "gmock/gmock-actions.h"
|
#include "gmock/gmock-actions.h"
|
||||||
#include "gmock/gmock-cardinalities.h"
|
#include "gmock/gmock-cardinalities.h"
|
||||||
|
#include "gmock/gmock-function-mocker.h"
|
||||||
#include "gmock/gmock-generated-actions.h"
|
#include "gmock/gmock-generated-actions.h"
|
||||||
#include "gmock/gmock-generated-function-mockers.h"
|
#include "gmock/gmock-generated-function-mockers.h"
|
||||||
#include "gmock/gmock-generated-matchers.h"
|
#include "gmock/gmock-generated-matchers.h"
|
||||||
#include "gmock/gmock-generated-nice-strict.h"
|
|
||||||
#include "gmock/gmock-matchers.h"
|
#include "gmock/gmock-matchers.h"
|
||||||
#include "gmock/gmock-more-actions.h"
|
#include "gmock/gmock-more-actions.h"
|
||||||
#include "gmock/gmock-more-matchers.h"
|
#include "gmock/gmock-more-matchers.h"
|
||||||
|
#include "gmock/gmock-nice-strict.h"
|
||||||
#include "gmock/internal/gmock-internal-utils.h"
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@@ -91,6 +92,10 @@ GTEST_API_ void InitGoogleMock(int* argc, char** argv);
|
|||||||
// UNICODE mode.
|
// UNICODE mode.
|
||||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
||||||
|
|
||||||
|
// This overloaded version can be used on Arduino/embedded platforms where
|
||||||
|
// there is no argc/argv.
|
||||||
|
GTEST_API_ void InitGoogleMock();
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||||
|
|||||||
@@ -1,287 +0,0 @@
|
|||||||
// This file was GENERATED by command:
|
|
||||||
// pump.py gmock-generated-internal-utils.h.pump
|
|
||||||
// DO NOT EDIT BY HAND!!!
|
|
||||||
|
|
||||||
// Copyright 2007, Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
// Google Mock - a framework for writing C++ mock classes.
|
|
||||||
//
|
|
||||||
// This file contains template meta-programming utility classes needed
|
|
||||||
// for implementing Google Mock.
|
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
|
||||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
|
||||||
|
|
||||||
#include "gmock/internal/gmock-port.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Matcher;
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
|
||||||
// This is used in implementing the IgnoreResult(a) action.
|
|
||||||
class IgnoredValue {
|
|
||||||
public:
|
|
||||||
// This constructor template allows any value to be implicitly
|
|
||||||
// converted to IgnoredValue. The object has no data member and
|
|
||||||
// doesn't try to remember anything about the argument. We
|
|
||||||
// deliberately omit the 'explicit' keyword in order to allow the
|
|
||||||
// conversion to be implicit.
|
|
||||||
template <typename T>
|
|
||||||
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
|
||||||
};
|
|
||||||
|
|
||||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
|
||||||
// for the corresponding field in tuple type T.
|
|
||||||
template <typename Tuple>
|
|
||||||
struct MatcherTuple;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct MatcherTuple< ::testing::tuple<> > {
|
|
||||||
typedef ::testing::tuple< > type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1> > type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2> > type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
|
||||||
Matcher<A5> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
|
||||||
Matcher<A5>, Matcher<A6> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
|
||||||
Matcher<A5>, Matcher<A6>, Matcher<A7> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
|
||||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
|
||||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
|
|
||||||
Matcher<A9> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
|
||||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
|
||||||
struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
|
||||||
A10> > {
|
|
||||||
typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
|
||||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>,
|
|
||||||
Matcher<A9>, Matcher<A10> >
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Template struct Function<F>, where F must be a function type, contains
|
|
||||||
// the following typedefs:
|
|
||||||
//
|
|
||||||
// Result: the function's return type.
|
|
||||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
|
||||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
|
||||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
|
||||||
// parameters of F.
|
|
||||||
// MakeResultVoid: the function type obtained by substituting void
|
|
||||||
// for the return type of F.
|
|
||||||
// MakeResultIgnoredValue:
|
|
||||||
// the function type obtained by substituting Something
|
|
||||||
// for the return type of F.
|
|
||||||
template <typename F>
|
|
||||||
struct Function;
|
|
||||||
|
|
||||||
template <typename R>
|
|
||||||
struct Function<R()> {
|
|
||||||
typedef R Result;
|
|
||||||
typedef ::testing::tuple<> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid();
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue();
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1>
|
|
||||||
struct Function<R(A1)>
|
|
||||||
: Function<R()> {
|
|
||||||
typedef A1 Argument1;
|
|
||||||
typedef ::testing::tuple<A1> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2>
|
|
||||||
struct Function<R(A1, A2)>
|
|
||||||
: Function<R(A1)> {
|
|
||||||
typedef A2 Argument2;
|
|
||||||
typedef ::testing::tuple<A1, A2> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3>
|
|
||||||
struct Function<R(A1, A2, A3)>
|
|
||||||
: Function<R(A1, A2)> {
|
|
||||||
typedef A3 Argument3;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
|
||||||
struct Function<R(A1, A2, A3, A4)>
|
|
||||||
: Function<R(A1, A2, A3)> {
|
|
||||||
typedef A4 Argument4;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
|
||||||
typename A5>
|
|
||||||
struct Function<R(A1, A2, A3, A4, A5)>
|
|
||||||
: Function<R(A1, A2, A3, A4)> {
|
|
||||||
typedef A5 Argument5;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
|
||||||
typename A5, typename A6>
|
|
||||||
struct Function<R(A1, A2, A3, A4, A5, A6)>
|
|
||||||
: Function<R(A1, A2, A3, A4, A5)> {
|
|
||||||
typedef A6 Argument6;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
|
||||||
typename A5, typename A6, typename A7>
|
|
||||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
|
|
||||||
: Function<R(A1, A2, A3, A4, A5, A6)> {
|
|
||||||
typedef A7 Argument7;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
|
||||||
typename A5, typename A6, typename A7, typename A8>
|
|
||||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
|
|
||||||
: Function<R(A1, A2, A3, A4, A5, A6, A7)> {
|
|
||||||
typedef A8 Argument8;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
|
||||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
|
||||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
|
|
||||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
|
||||||
typedef A9 Argument9;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
|
||||||
A9);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
|
||||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
|
||||||
typename A10>
|
|
||||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
|
|
||||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
|
||||||
typedef A10 Argument10;
|
|
||||||
typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
|
||||||
A10> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
|
||||||
A9, A10);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
$$ -*- mode: c++; -*-
|
|
||||||
$$ This is a Pump source file. Please use Pump to convert it to
|
|
||||||
$$ gmock-generated-function-mockers.h.
|
|
||||||
$$
|
|
||||||
$var n = 10 $$ The maximum arity we support.
|
|
||||||
// Copyright 2007, Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
// Google Mock - a framework for writing C++ mock classes.
|
|
||||||
//
|
|
||||||
// This file contains template meta-programming utility classes needed
|
|
||||||
// for implementing Google Mock.
|
|
||||||
|
|
||||||
// GOOGLETEST_CM0002 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
|
||||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
|
||||||
|
|
||||||
#include "gmock/internal/gmock-port.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Matcher;
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
|
||||||
// This is used in implementing the IgnoreResult(a) action.
|
|
||||||
class IgnoredValue {
|
|
||||||
public:
|
|
||||||
// This constructor template allows any value to be implicitly
|
|
||||||
// converted to IgnoredValue. The object has no data member and
|
|
||||||
// doesn't try to remember anything about the argument. We
|
|
||||||
// deliberately omit the 'explicit' keyword in order to allow the
|
|
||||||
// conversion to be implicit.
|
|
||||||
template <typename T>
|
|
||||||
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
|
||||||
};
|
|
||||||
|
|
||||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
|
||||||
// for the corresponding field in tuple type T.
|
|
||||||
template <typename Tuple>
|
|
||||||
struct MatcherTuple;
|
|
||||||
|
|
||||||
|
|
||||||
$range i 0..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
|
||||||
$var As = [[$for j, [[A$j]]]]
|
|
||||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
|
||||||
template <$typename_As>
|
|
||||||
struct MatcherTuple< ::testing::tuple<$As> > {
|
|
||||||
typedef ::testing::tuple<$matcher_As > type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
// Template struct Function<F>, where F must be a function type, contains
|
|
||||||
// the following typedefs:
|
|
||||||
//
|
|
||||||
// Result: the function's return type.
|
|
||||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
|
||||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
|
||||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
|
||||||
// parameters of F.
|
|
||||||
// MakeResultVoid: the function type obtained by substituting void
|
|
||||||
// for the return type of F.
|
|
||||||
// MakeResultIgnoredValue:
|
|
||||||
// the function type obtained by substituting Something
|
|
||||||
// for the return type of F.
|
|
||||||
template <typename F>
|
|
||||||
struct Function;
|
|
||||||
|
|
||||||
template <typename R>
|
|
||||||
struct Function<R()> {
|
|
||||||
typedef R Result;
|
|
||||||
typedef ::testing::tuple<> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid();
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$range i 1..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
|
||||||
$var As = [[$for j, [[A$j]]]]
|
|
||||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
|
||||||
$range k 1..i-1
|
|
||||||
$var prev_As = [[$for k, [[A$k]]]]
|
|
||||||
template <typename R$typename_As>
|
|
||||||
struct Function<R($As)>
|
|
||||||
: Function<R($prev_As)> {
|
|
||||||
typedef A$i Argument$i;
|
|
||||||
typedef ::testing::tuple<$As> ArgumentTuple;
|
|
||||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
|
||||||
typedef void MakeResultVoid($As);
|
|
||||||
typedef IgnoredValue MakeResultIgnoredValue($As);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
|
||||||
@@ -42,11 +42,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "gmock/internal/gmock-generated-internal-utils.h"
|
#include <type_traits>
|
||||||
#include "gmock/internal/gmock-port.h"
|
#include "gmock/internal/gmock-port.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
class Matcher;
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Silence MSVC C4100 (unreferenced formal parameter) and
|
// Silence MSVC C4100 (unreferenced formal parameter) and
|
||||||
@@ -92,46 +96,16 @@ inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
|||||||
template <typename Element>
|
template <typename Element>
|
||||||
inline Element* GetRawPointer(Element* p) { return p; }
|
inline Element* GetRawPointer(Element* p) { return p; }
|
||||||
|
|
||||||
// This comparator allows linked_ptr to be stored in sets.
|
|
||||||
template <typename T>
|
|
||||||
struct LinkedPtrLessThan {
|
|
||||||
bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
|
|
||||||
const ::testing::internal::linked_ptr<T>& rhs) const {
|
|
||||||
return lhs.get() < rhs.get();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Symbian compilation can be done with wchar_t being either a native
|
|
||||||
// type or a typedef. Using Google Mock with OpenC without wchar_t
|
|
||||||
// should require the definition of _STLP_NO_WCHAR_T.
|
|
||||||
//
|
|
||||||
// MSVC treats wchar_t as a native type usually, but treats it as the
|
// MSVC treats wchar_t as a native type usually, but treats it as the
|
||||||
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||||
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||||
// is a native type.
|
// is a native type.
|
||||||
#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
|
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
|
||||||
(defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
|
|
||||||
// wchar_t is a typedef.
|
// wchar_t is a typedef.
|
||||||
#else
|
#else
|
||||||
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
|
|
||||||
// Using them is a bad practice and not portable. So DON'T use them.
|
|
||||||
//
|
|
||||||
// Still, Google Mock is designed to work even if the user uses signed
|
|
||||||
// wchar_t or unsigned wchar_t (obviously, assuming the compiler
|
|
||||||
// supports them).
|
|
||||||
//
|
|
||||||
// To gcc,
|
|
||||||
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#if !defined(__WCHAR_UNSIGNED__)
|
|
||||||
// signed/unsigned wchar_t are valid types.
|
|
||||||
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// In what follows, we use the term "kind" to indicate whether a type
|
// In what follows, we use the term "kind" to indicate whether a type
|
||||||
// is bool, an integer type (excluding bool), a floating-point type,
|
// is bool, an integer type (excluding bool), a floating-point type,
|
||||||
// or none of them. This categorization is useful for determining
|
// or none of them. This categorization is useful for determining
|
||||||
@@ -183,11 +157,11 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
|||||||
static_cast< ::testing::internal::TypeKind>( \
|
static_cast< ::testing::internal::TypeKind>( \
|
||||||
::testing::internal::KindOf<type>::value)
|
::testing::internal::KindOf<type>::value)
|
||||||
|
|
||||||
// Evaluates to true iff integer type T is signed.
|
// Evaluates to true if and only if integer type T is signed.
|
||||||
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
|
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
|
||||||
|
|
||||||
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||||
// is true iff arithmetic type From can be losslessly converted to
|
// is true if and only if arithmetic type From can be losslessly converted to
|
||||||
// arithmetic type To.
|
// arithmetic type To.
|
||||||
//
|
//
|
||||||
// It's the user's responsibility to ensure that both From and To are
|
// It's the user's responsibility to ensure that both From and To are
|
||||||
@@ -196,30 +170,30 @@ GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
|||||||
// From, and kToKind is the kind of To; the value is
|
// From, and kToKind is the kind of To; the value is
|
||||||
// implementation-defined when the above pre-condition is violated.
|
// implementation-defined when the above pre-condition is violated.
|
||||||
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl : public false_type {};
|
struct LosslessArithmeticConvertibleImpl : public std::false_type {};
|
||||||
|
|
||||||
// Converting bool to bool is lossless.
|
// Converting bool to bool is lossless.
|
||||||
template <>
|
template <>
|
||||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
|
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
|
||||||
: public true_type {}; // NOLINT
|
: public std::true_type {};
|
||||||
|
|
||||||
// Converting bool to any integer type is lossless.
|
// Converting bool to any integer type is lossless.
|
||||||
template <typename To>
|
template <typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
|
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
|
||||||
: public true_type {}; // NOLINT
|
: public std::true_type {};
|
||||||
|
|
||||||
// Converting bool to any floating-point type is lossless.
|
// Converting bool to any floating-point type is lossless.
|
||||||
template <typename To>
|
template <typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
|
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
|
||||||
: public true_type {}; // NOLINT
|
: public std::true_type {};
|
||||||
|
|
||||||
// Converting an integer to bool is lossy.
|
// Converting an integer to bool is lossy.
|
||||||
template <typename From>
|
template <typename From>
|
||||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
|
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
|
||||||
: public false_type {}; // NOLINT
|
: public std::false_type {};
|
||||||
|
|
||||||
// Converting an integer to another non-bool integer is lossless iff
|
// Converting an integer to another non-bool integer is lossless
|
||||||
// the target type's range encloses the source type's range.
|
// if and only if the target type's range encloses the source type's range.
|
||||||
template <typename From, typename To>
|
template <typename From, typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
||||||
: public bool_constant<
|
: public bool_constant<
|
||||||
@@ -237,27 +211,27 @@ struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
|||||||
// the format of a floating-point number is implementation-defined.
|
// the format of a floating-point number is implementation-defined.
|
||||||
template <typename From, typename To>
|
template <typename From, typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
|
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
|
||||||
: public false_type {}; // NOLINT
|
: public std::false_type {};
|
||||||
|
|
||||||
// Converting a floating-point to bool is lossy.
|
// Converting a floating-point to bool is lossy.
|
||||||
template <typename From>
|
template <typename From>
|
||||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
|
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
|
||||||
: public false_type {}; // NOLINT
|
: public std::false_type {};
|
||||||
|
|
||||||
// Converting a floating-point to an integer is lossy.
|
// Converting a floating-point to an integer is lossy.
|
||||||
template <typename From, typename To>
|
template <typename From, typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
|
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
|
||||||
: public false_type {}; // NOLINT
|
: public std::false_type {};
|
||||||
|
|
||||||
// Converting a floating-point to another floating-point is lossless
|
// Converting a floating-point to another floating-point is lossless
|
||||||
// iff the target type is at least as big as the source type.
|
// if and only if the target type is at least as big as the source type.
|
||||||
template <typename From, typename To>
|
template <typename From, typename To>
|
||||||
struct LosslessArithmeticConvertibleImpl<
|
struct LosslessArithmeticConvertibleImpl<
|
||||||
kFloatingPoint, From, kFloatingPoint, To>
|
kFloatingPoint, From, kFloatingPoint, To>
|
||||||
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
|
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
|
||||||
|
|
||||||
// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
|
// LosslessArithmeticConvertible<From, To>::value is true if and only if
|
||||||
// type From can be losslessly converted to arithmetic type To.
|
// arithmetic type From can be losslessly converted to arithmetic type To.
|
||||||
//
|
//
|
||||||
// It's the user's responsibility to ensure that both From and To are
|
// It's the user's responsibility to ensure that both From and To are
|
||||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||||
@@ -331,11 +305,11 @@ const char kWarningVerbosity[] = "warning";
|
|||||||
// No logs are printed.
|
// No logs are printed.
|
||||||
const char kErrorVerbosity[] = "error";
|
const char kErrorVerbosity[] = "error";
|
||||||
|
|
||||||
// Returns true iff a log with the given severity is visible according
|
// Returns true if and only if a log with the given severity is visible
|
||||||
// to the --gmock_verbose flag.
|
// according to the --gmock_verbose flag.
|
||||||
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||||
|
|
||||||
// Prints the given message to stdout iff 'severity' >= the level
|
// Prints the given message to stdout if and only if 'severity' >= the level
|
||||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||||
// 0, also prints the stack trace excluding the top
|
// 0, also prints the stack trace excluding the top
|
||||||
// stack_frames_to_skip frames. In opt mode, any positive
|
// stack_frames_to_skip frames. In opt mode, any positive
|
||||||
@@ -360,35 +334,8 @@ class WithoutMatchers {
|
|||||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||||
|
|
||||||
// FIXME: group all type utilities together.
|
|
||||||
|
|
||||||
// Type traits.
|
// Type traits.
|
||||||
|
|
||||||
// is_reference<T>::value is non-zero iff T is a reference type.
|
|
||||||
template <typename T> struct is_reference : public false_type {};
|
|
||||||
template <typename T> struct is_reference<T&> : public true_type {};
|
|
||||||
|
|
||||||
// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
|
|
||||||
template <typename T1, typename T2> struct type_equals : public false_type {};
|
|
||||||
template <typename T> struct type_equals<T, T> : public true_type {};
|
|
||||||
|
|
||||||
// remove_reference<T>::type removes the reference from type T, if any.
|
|
||||||
template <typename T> struct remove_reference { typedef T type; }; // NOLINT
|
|
||||||
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
|
|
||||||
|
|
||||||
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
|
|
||||||
// other types. Useful for saving a copy of a function argument.
|
|
||||||
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
|
|
||||||
template <typename T, size_t N> struct DecayArray<T[N]> {
|
|
||||||
typedef const T* type;
|
|
||||||
};
|
|
||||||
// Sometimes people use arrays whose size is not available at the use site
|
|
||||||
// (e.g. extern const char kNamePrefix[]). This specialization covers that
|
|
||||||
// case.
|
|
||||||
template <typename T> struct DecayArray<T[]> {
|
|
||||||
typedef const T* type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Disable MSVC warnings for infinite recursion, since in this case the
|
// Disable MSVC warnings for infinite recursion, since in this case the
|
||||||
// the recursion is unreachable.
|
// the recursion is unreachable.
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -437,9 +384,8 @@ class StlContainerView {
|
|||||||
typedef const type& const_reference;
|
typedef const type& const_reference;
|
||||||
|
|
||||||
static const_reference ConstReference(const RawContainer& container) {
|
static const_reference ConstReference(const RawContainer& container) {
|
||||||
// Ensures that RawContainer is not a const type.
|
static_assert(!std::is_const<RawContainer>::value,
|
||||||
testing::StaticAssertTypeEq<RawContainer,
|
"RawContainer type must not be const");
|
||||||
GTEST_REMOVE_CONST_(RawContainer)>();
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
static type Copy(const RawContainer& container) { return container; }
|
static type Copy(const RawContainer& container) { return container; }
|
||||||
@@ -449,7 +395,7 @@ class StlContainerView {
|
|||||||
template <typename Element, size_t N>
|
template <typename Element, size_t N>
|
||||||
class StlContainerView<Element[N]> {
|
class StlContainerView<Element[N]> {
|
||||||
public:
|
public:
|
||||||
typedef GTEST_REMOVE_CONST_(Element) RawElement;
|
typedef typename std::remove_const<Element>::type RawElement;
|
||||||
typedef internal::NativeArray<RawElement> type;
|
typedef internal::NativeArray<RawElement> type;
|
||||||
// NativeArray<T> can represent a native array either by value or by
|
// NativeArray<T> can represent a native array either by value or by
|
||||||
// reference (selected by a constructor argument), so 'const type'
|
// reference (selected by a constructor argument), so 'const type'
|
||||||
@@ -459,53 +405,32 @@ class StlContainerView<Element[N]> {
|
|||||||
typedef const type const_reference;
|
typedef const type const_reference;
|
||||||
|
|
||||||
static const_reference ConstReference(const Element (&array)[N]) {
|
static const_reference ConstReference(const Element (&array)[N]) {
|
||||||
// Ensures that Element is not a const type.
|
static_assert(std::is_same<Element, RawElement>::value,
|
||||||
testing::StaticAssertTypeEq<Element, RawElement>();
|
"Element type must not be const");
|
||||||
#if GTEST_OS_SYMBIAN
|
|
||||||
// The Nokia Symbian compiler confuses itself in template instantiation
|
|
||||||
// for this call without the cast to Element*:
|
|
||||||
// function call '[testing::internal::NativeArray<char *>].NativeArray(
|
|
||||||
// {lval} const char *[4], long, testing::internal::RelationToSource)'
|
|
||||||
// does not match
|
|
||||||
// 'testing::internal::NativeArray<char *>::NativeArray(
|
|
||||||
// char *const *, unsigned int, testing::internal::RelationToSource)'
|
|
||||||
// (instantiating: 'testing::internal::ContainsMatcherImpl
|
|
||||||
// <const char * (&)[4]>::Matches(const char * (&)[4]) const')
|
|
||||||
// (instantiating: 'testing::internal::StlContainerView<char *[4]>::
|
|
||||||
// ConstReference(const char * (&)[4])')
|
|
||||||
// (and though the N parameter type is mismatched in the above explicit
|
|
||||||
// conversion of it doesn't help - only the conversion of the array).
|
|
||||||
return type(const_cast<Element*>(&array[0]), N,
|
|
||||||
RelationToSourceReference());
|
|
||||||
#else
|
|
||||||
return type(array, N, RelationToSourceReference());
|
return type(array, N, RelationToSourceReference());
|
||||||
#endif // GTEST_OS_SYMBIAN
|
|
||||||
}
|
}
|
||||||
static type Copy(const Element (&array)[N]) {
|
static type Copy(const Element (&array)[N]) {
|
||||||
#if GTEST_OS_SYMBIAN
|
|
||||||
return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy());
|
|
||||||
#else
|
|
||||||
return type(array, N, RelationToSourceCopy());
|
return type(array, N, RelationToSourceCopy());
|
||||||
#endif // GTEST_OS_SYMBIAN
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This specialization is used when RawContainer is a native array
|
// This specialization is used when RawContainer is a native array
|
||||||
// represented as a (pointer, size) tuple.
|
// represented as a (pointer, size) tuple.
|
||||||
template <typename ElementPointer, typename Size>
|
template <typename ElementPointer, typename Size>
|
||||||
class StlContainerView< ::testing::tuple<ElementPointer, Size> > {
|
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||||
public:
|
public:
|
||||||
typedef GTEST_REMOVE_CONST_(
|
typedef typename std::remove_const<
|
||||||
typename internal::PointeeOf<ElementPointer>::type) RawElement;
|
typename internal::PointeeOf<ElementPointer>::type>::type RawElement;
|
||||||
typedef internal::NativeArray<RawElement> type;
|
typedef internal::NativeArray<RawElement> type;
|
||||||
typedef const type const_reference;
|
typedef const type const_reference;
|
||||||
|
|
||||||
static const_reference ConstReference(
|
static const_reference ConstReference(
|
||||||
const ::testing::tuple<ElementPointer, Size>& array) {
|
const ::std::tuple<ElementPointer, Size>& array) {
|
||||||
return type(get<0>(array), get<1>(array), RelationToSourceReference());
|
return type(std::get<0>(array), std::get<1>(array),
|
||||||
|
RelationToSourceReference());
|
||||||
}
|
}
|
||||||
static type Copy(const ::testing::tuple<ElementPointer, Size>& array) {
|
static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
|
||||||
return type(get<0>(array), get<1>(array), RelationToSourceCopy());
|
return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -527,29 +452,12 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
|
|||||||
typedef std::pair<K, V> type;
|
typedef std::pair<K, V> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
|
|
||||||
// std::integral_constant<bool, kValue>.
|
|
||||||
template <bool kValue>
|
|
||||||
struct BooleanConstant {};
|
|
||||||
|
|
||||||
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
|
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
|
||||||
// reduce code size.
|
// reduce code size.
|
||||||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
// Helper types for Apply() below.
|
|
||||||
template <size_t... Is> struct int_pack { typedef int_pack type; };
|
|
||||||
|
|
||||||
template <class Pack, size_t I> struct append;
|
|
||||||
template <size_t... Is, size_t I>
|
|
||||||
struct append<int_pack<Is...>, I> : int_pack<Is..., I> {};
|
|
||||||
|
|
||||||
template <size_t C>
|
|
||||||
struct make_int_pack : append<typename make_int_pack<C - 1>::type, C - 1> {};
|
|
||||||
template <> struct make_int_pack<0> : int_pack<> {};
|
|
||||||
|
|
||||||
template <typename F, typename Tuple, size_t... Idx>
|
template <typename F, typename Tuple, size_t... Idx>
|
||||||
auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype(
|
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
|
||||||
std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
|
std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||||
}
|
}
|
||||||
@@ -558,12 +466,42 @@ auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype(
|
|||||||
template <typename F, typename Tuple>
|
template <typename F, typename Tuple>
|
||||||
auto Apply(F&& f, Tuple&& args)
|
auto Apply(F&& f, Tuple&& args)
|
||||||
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
-> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||||
make_int_pack<std::tuple_size<Tuple>::value>())) {
|
MakeIndexSequence<std::tuple_size<Tuple>::value>())) {
|
||||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||||
make_int_pack<std::tuple_size<Tuple>::value>());
|
MakeIndexSequence<std::tuple_size<Tuple>::value>());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// Template struct Function<F>, where F must be a function type, contains
|
||||||
|
// the following typedefs:
|
||||||
|
//
|
||||||
|
// Result: the function's return type.
|
||||||
|
// Arg<N>: the type of the N-th argument, where N starts with 0.
|
||||||
|
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||||
|
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||||
|
// parameters of F.
|
||||||
|
// MakeResultVoid: the function type obtained by substituting void
|
||||||
|
// for the return type of F.
|
||||||
|
// MakeResultIgnoredValue:
|
||||||
|
// the function type obtained by substituting Something
|
||||||
|
// for the return type of F.
|
||||||
|
template <typename T>
|
||||||
|
struct Function;
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
struct Function<R(Args...)> {
|
||||||
|
using Result = R;
|
||||||
|
static constexpr size_t ArgumentCount = sizeof...(Args);
|
||||||
|
template <size_t I>
|
||||||
|
using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
|
||||||
|
Args...>;
|
||||||
|
using ArgumentTuple = std::tuple<Args...>;
|
||||||
|
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||||
|
using MakeResultVoid = void(Args...);
|
||||||
|
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(pop)
|
# pragma warning(pop)
|
||||||
|
|||||||
@@ -52,14 +52,13 @@
|
|||||||
// here, as Google Mock depends on Google Test. Only add a utility
|
// here, as Google Mock depends on Google Test. Only add a utility
|
||||||
// here if it's truly specific to Google Mock.
|
// here if it's truly specific to Google Mock.
|
||||||
|
|
||||||
#include "gtest/internal/gtest-linked_ptr.h"
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gmock/internal/custom/gmock-port.h"
|
#include "gmock/internal/custom/gmock-port.h"
|
||||||
|
|
||||||
// For MS Visual C++, check the compiler version. At least VS 2003 is
|
// For MS Visual C++, check the compiler version. At least VS 2015 is
|
||||||
// required to compile Google Mock.
|
// required to compile Google Mock.
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1310
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
|
# error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Macro for referencing flags. This is public as we want the user to
|
// Macro for referencing flags. This is public as we want the user to
|
||||||
|
|||||||
317
winx64/include/gmock/internal/gmock-pp.h
Normal file
317
winx64/include/gmock/internal/gmock-pp.h
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
|
||||||
|
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
|
||||||
|
|
||||||
|
#undef GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
#if defined(__clang__)
|
||||||
|
#define GMOCK_PP_INTERNAL_USE_MSVC 0
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
// TODO(iserna): Also verify tradional versus comformant preprocessor.
|
||||||
|
static_assert(
|
||||||
|
_MSC_VER >= 1900,
|
||||||
|
"MSVC version not supported. There is support for MSVC 14.0 and above.");
|
||||||
|
#define GMOCK_PP_INTERNAL_USE_MSVC 1
|
||||||
|
#else
|
||||||
|
#define GMOCK_PP_INTERNAL_USE_MSVC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Expands and concatenates the arguments. Constructed macros reevaluate.
|
||||||
|
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
|
||||||
|
|
||||||
|
// Expands and stringifies the only argument.
|
||||||
|
#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
|
||||||
|
|
||||||
|
// Returns empty. Given a variadic number of arguments.
|
||||||
|
#define GMOCK_PP_EMPTY(...)
|
||||||
|
|
||||||
|
// Returns a comma. Given a variadic number of arguments.
|
||||||
|
#define GMOCK_PP_COMMA(...) ,
|
||||||
|
|
||||||
|
// Returns the only argument.
|
||||||
|
#define GMOCK_PP_IDENTITY(_1) _1
|
||||||
|
|
||||||
|
// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
|
||||||
|
// CAT-like directive to force correct evaluation. Each macro has its own.
|
||||||
|
#if GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
|
||||||
|
// Evaluates to the number of arguments after expansion.
|
||||||
|
//
|
||||||
|
// #define PAIR x, y
|
||||||
|
//
|
||||||
|
// GMOCK_PP_NARG() => 1
|
||||||
|
// GMOCK_PP_NARG(x) => 1
|
||||||
|
// GMOCK_PP_NARG(x, y) => 2
|
||||||
|
// GMOCK_PP_NARG(PAIR) => 2
|
||||||
|
//
|
||||||
|
// Requires: the number of arguments after expansion is at most 15.
|
||||||
|
#define GMOCK_PP_NARG(...) \
|
||||||
|
GMOCK_PP_INTERNAL_NARG_CAT( \
|
||||||
|
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
|
||||||
|
8, 7, 6, 5, 4, 3, 2, 1), )
|
||||||
|
|
||||||
|
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
|
||||||
|
// returns 0. Requires no more than 15 unprotected commas.
|
||||||
|
#define GMOCK_PP_HAS_COMMA(...) \
|
||||||
|
GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \
|
||||||
|
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||||
|
1, 1, 1, 1, 1, 0), )
|
||||||
|
// Returns the first argument.
|
||||||
|
#define GMOCK_PP_HEAD(...) \
|
||||||
|
GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
|
||||||
|
|
||||||
|
// Returns the tail. A variadic list of all arguments minus the first. Requires
|
||||||
|
// at least one argument.
|
||||||
|
#define GMOCK_PP_TAIL(...) \
|
||||||
|
GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
|
||||||
|
|
||||||
|
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
|
||||||
|
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
|
||||||
|
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
|
||||||
|
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
|
||||||
|
|
||||||
|
#else // GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
|
||||||
|
#define GMOCK_PP_NARG(...) \
|
||||||
|
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
|
||||||
|
7, 6, 5, 4, 3, 2, 1)
|
||||||
|
#define GMOCK_PP_HAS_COMMA(...) \
|
||||||
|
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||||
|
1, 1, 1, 1, 0)
|
||||||
|
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
|
||||||
|
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
|
||||||
|
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
|
||||||
|
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif // GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
|
||||||
|
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
|
||||||
|
// evaluates to `0`.
|
||||||
|
//
|
||||||
|
// Requires: * the number of arguments after expansion is at most 15.
|
||||||
|
// * If the argument is a macro, it must be able to be called with one
|
||||||
|
// argument.
|
||||||
|
//
|
||||||
|
// Implementation details:
|
||||||
|
//
|
||||||
|
// There is one case when it generates a compile error: if the argument is macro
|
||||||
|
// that cannot be called with one argument.
|
||||||
|
//
|
||||||
|
// #define M(a, b) // it doesn't matter what it expands to
|
||||||
|
//
|
||||||
|
// // Expected: expands to `0`.
|
||||||
|
// // Actual: compile error.
|
||||||
|
// GMOCK_PP_IS_EMPTY(M)
|
||||||
|
//
|
||||||
|
// There are 4 cases tested:
|
||||||
|
//
|
||||||
|
// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.
|
||||||
|
// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.
|
||||||
|
// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.
|
||||||
|
// Expected 0
|
||||||
|
// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in
|
||||||
|
// parenthesis, or is a macro that ()-evaluates to comma. Expected 1.
|
||||||
|
//
|
||||||
|
// We trigger detection on '0001', i.e. on empty.
|
||||||
|
#define GMOCK_PP_IS_EMPTY(...) \
|
||||||
|
GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \
|
||||||
|
GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))
|
||||||
|
|
||||||
|
// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.
|
||||||
|
#define GMOCK_PP_IF(_Cond, _Then, _Else) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
|
||||||
|
|
||||||
|
// Evaluates to the number of arguments after expansion. Identifies 'empty' as
|
||||||
|
// 0.
|
||||||
|
//
|
||||||
|
// #define PAIR x, y
|
||||||
|
//
|
||||||
|
// GMOCK_PP_NARG0() => 0
|
||||||
|
// GMOCK_PP_NARG0(x) => 1
|
||||||
|
// GMOCK_PP_NARG0(x, y) => 2
|
||||||
|
// GMOCK_PP_NARG0(PAIR) => 2
|
||||||
|
//
|
||||||
|
// Requires: * the number of arguments after expansion is at most 15.
|
||||||
|
// * If the argument is a macro, it must be able to be called with one
|
||||||
|
// argument.
|
||||||
|
#define GMOCK_PP_NARG0(...) \
|
||||||
|
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))
|
||||||
|
|
||||||
|
// Expands to 1 if the first argument starts with something in parentheses,
|
||||||
|
// otherwise to 0.
|
||||||
|
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
|
||||||
|
GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \
|
||||||
|
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
|
||||||
|
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
|
||||||
|
|
||||||
|
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
|
||||||
|
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
|
||||||
|
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
|
||||||
|
GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)
|
||||||
|
|
||||||
|
// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.
|
||||||
|
#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
|
||||||
|
|
||||||
|
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
|
||||||
|
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
|
||||||
|
// Requires: * |_Macro| can be called with 3 arguments.
|
||||||
|
// * |_Tuple| expansion has no more than 15 elements.
|
||||||
|
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
|
||||||
|
(0, _Macro, _Data, _Tuple)
|
||||||
|
|
||||||
|
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
|
||||||
|
// Empty if _K = 0.
|
||||||
|
// Requires: * |_Macro| can be called with 3 arguments.
|
||||||
|
// * |_K| literal between 0 and 15
|
||||||
|
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
|
||||||
|
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
|
||||||
|
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
|
||||||
|
|
||||||
|
// Increments the argument, requires the argument to be between 0 and 15.
|
||||||
|
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
|
||||||
|
|
||||||
|
// Returns comma if _i != 0. Requires _i to be between 0 and 15.
|
||||||
|
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
|
||||||
|
|
||||||
|
// Internal details follow. Do not use any of these symbols outside of this
|
||||||
|
// file or we will break your code.
|
||||||
|
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
|
||||||
|
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
|
||||||
|
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
|
||||||
|
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
|
||||||
|
_10, _11, _12, _13, _14, _15, _16, \
|
||||||
|
...) \
|
||||||
|
_16
|
||||||
|
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
|
||||||
|
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
|
||||||
|
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
|
||||||
|
_1, _2, _3, _4))
|
||||||
|
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
|
||||||
|
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
|
||||||
|
#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
|
||||||
|
#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
|
||||||
|
|
||||||
|
#if GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
|
||||||
|
#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
|
||||||
|
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
|
||||||
|
GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
|
||||||
|
#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
|
||||||
|
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
|
||||||
|
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
|
||||||
|
#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
|
||||||
|
#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
|
||||||
|
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
|
||||||
|
#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
|
||||||
|
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
|
||||||
|
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
|
||||||
|
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
|
||||||
|
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
|
||||||
|
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
|
||||||
|
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
|
||||||
|
#else // GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
|
||||||
|
#endif // GMOCK_PP_INTERNAL_USE_MSVC
|
||||||
|
|
||||||
|
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
|
||||||
|
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
|
||||||
|
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \
|
||||||
|
0,
|
||||||
|
#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_0 1
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_1 2
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_2 3
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_3 4
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_4 5
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_5 6
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_6 7
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_7 8
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_8 9
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_9 10
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_10 11
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_11 12
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_12 13
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_13 14
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_14 15
|
||||||
|
#define GMOCK_PP_INTERNAL_INC_15 16
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_0
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
|
||||||
|
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
|
||||||
|
_Macro(_i, _Data, _element)
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||||
|
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||||
|
(GMOCK_PP_TAIL _Tuple))
|
||||||
|
|
||||||
|
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||||
@@ -161,7 +161,6 @@ GTEST_API_ bool InDeathTestChild();
|
|||||||
// is rarely a problem as people usually don't put the test binary
|
// is rarely a problem as people usually don't put the test binary
|
||||||
// directory in PATH.
|
// directory in PATH.
|
||||||
//
|
//
|
||||||
// FIXME: make thread-safe death tests search the PATH.
|
|
||||||
|
|
||||||
// Asserts that a given statement causes the program to exit, with an
|
// Asserts that a given statement causes the program to exit, with an
|
||||||
// integer exit status that satisfies predicate, and emitting error output
|
// integer exit status that satisfies predicate, and emitting error output
|
||||||
@@ -170,7 +169,7 @@ GTEST_API_ bool InDeathTestChild();
|
|||||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
|
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
|
||||||
|
|
||||||
// Like ASSERT_EXIT, but continues on to successive tests in the
|
// Like ASSERT_EXIT, but continues on to successive tests in the
|
||||||
// test case, if any:
|
// test suite, if any:
|
||||||
# define EXPECT_EXIT(statement, predicate, regex) \
|
# define EXPECT_EXIT(statement, predicate, regex) \
|
||||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
|
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
|
||||||
|
|
||||||
@@ -181,7 +180,7 @@ GTEST_API_ bool InDeathTestChild();
|
|||||||
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||||
|
|
||||||
// Like ASSERT_DEATH, but continues on to successive tests in the
|
// Like ASSERT_DEATH, but continues on to successive tests in the
|
||||||
// test case, if any:
|
// test suite, if any:
|
||||||
# define EXPECT_DEATH(statement, regex) \
|
# define EXPECT_DEATH(statement, regex) \
|
||||||
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||||
|
|
||||||
@@ -228,7 +227,7 @@ class GTEST_API_ KilledBySignal {
|
|||||||
// return 12;
|
// return 12;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
|
// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
|
||||||
// int sideeffect = 0;
|
// int sideeffect = 0;
|
||||||
// // Only asserts in dbg.
|
// // Only asserts in dbg.
|
||||||
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||||
@@ -277,20 +276,20 @@ class GTEST_API_ KilledBySignal {
|
|||||||
// This macro is used for implementing macros such as
|
// This macro is used for implementing macros such as
|
||||||
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||||
// death tests are not supported. Those macros must compile on such systems
|
// death tests are not supported. Those macros must compile on such systems
|
||||||
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
|
// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters
|
||||||
// systems that support death tests. This allows one to write such a macro
|
// on systems that support death tests. This allows one to write such a macro on
|
||||||
// on a system that does not support death tests and be sure that it will
|
// a system that does not support death tests and be sure that it will compile
|
||||||
// compile on a death-test supporting system. It is exposed publicly so that
|
// on a death-test supporting system. It is exposed publicly so that systems
|
||||||
// systems that have death-tests with stricter requirements than
|
// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST
|
||||||
// GTEST_HAS_DEATH_TEST can write their own equivalent of
|
// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and
|
||||||
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED.
|
// ASSERT_DEATH_IF_SUPPORTED.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// statement - A statement that a macro such as EXPECT_DEATH would test
|
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||||
// for program termination. This macro has to make sure this
|
// for program termination. This macro has to make sure this
|
||||||
// statement is compiled but not executed, to ensure that
|
// statement is compiled but not executed, to ensure that
|
||||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||||
// parameter iff EXPECT_DEATH compiles with it.
|
// parameter if and only if EXPECT_DEATH compiles with it.
|
||||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||||
// the output of statement. This parameter has to be
|
// the output of statement. This parameter has to be
|
||||||
// compiled but not evaluated by this macro, to ensure that
|
// compiled but not evaluated by this macro, to ensure that
|
||||||
|
|||||||
750
winx64/include/gtest/gtest-matchers.h
Normal file
750
winx64/include/gtest/gtest-matchers.h
Normal file
@@ -0,0 +1,750 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||||
|
//
|
||||||
|
// This file implements just enough of the matcher interface to allow
|
||||||
|
// EXPECT_DEATH and friends to accept a matcher argument.
|
||||||
|
|
||||||
|
// IWYU pragma: private, include "testing/base/public/gunit.h"
|
||||||
|
// IWYU pragma: friend third_party/googletest/googlemock/.*
|
||||||
|
// IWYU pragma: friend third_party/googletest/googletest/.*
|
||||||
|
|
||||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||||
|
#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "gtest/gtest-printers.h"
|
||||||
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
// MSVC warning C5046 is new as of VS2017 version 15.8.
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1915
|
||||||
|
#define GTEST_MAYBE_5046_ 5046
|
||||||
|
#else
|
||||||
|
#define GTEST_MAYBE_5046_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
||||||
|
4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
|
||||||
|
clients of class B */
|
||||||
|
/* Symbol involving type with internal linkage not defined */)
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// To implement a matcher Foo for type T, define:
|
||||||
|
// 1. a class FooMatcherImpl that implements the
|
||||||
|
// MatcherInterface<T> interface, and
|
||||||
|
// 2. a factory function that creates a Matcher<T> object from a
|
||||||
|
// FooMatcherImpl*.
|
||||||
|
//
|
||||||
|
// The two-level delegation design makes it possible to allow a user
|
||||||
|
// to write "v" instead of "Eq(v)" where a Matcher is expected, which
|
||||||
|
// is impossible if we pass matchers by pointers. It also eases
|
||||||
|
// ownership management as Matcher objects can now be copied like
|
||||||
|
// plain values.
|
||||||
|
|
||||||
|
// MatchResultListener is an abstract class. Its << operator can be
|
||||||
|
// used by a matcher to explain why a value matches or doesn't match.
|
||||||
|
//
|
||||||
|
class MatchResultListener {
|
||||||
|
public:
|
||||||
|
// Creates a listener object with the given underlying ostream. The
|
||||||
|
// listener does not own the ostream, and does not dereference it
|
||||||
|
// in the constructor or destructor.
|
||||||
|
explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
|
||||||
|
virtual ~MatchResultListener() = 0; // Makes this class abstract.
|
||||||
|
|
||||||
|
// Streams x to the underlying ostream; does nothing if the ostream
|
||||||
|
// is NULL.
|
||||||
|
template <typename T>
|
||||||
|
MatchResultListener& operator<<(const T& x) {
|
||||||
|
if (stream_ != nullptr) *stream_ << x;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the underlying ostream.
|
||||||
|
::std::ostream* stream() { return stream_; }
|
||||||
|
|
||||||
|
// Returns true if and only if the listener is interested in an explanation
|
||||||
|
// of the match result. A matcher's MatchAndExplain() method can use
|
||||||
|
// this information to avoid generating the explanation when no one
|
||||||
|
// intends to hear it.
|
||||||
|
bool IsInterested() const { return stream_ != nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
::std::ostream* const stream_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline MatchResultListener::~MatchResultListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// An instance of a subclass of this knows how to describe itself as a
|
||||||
|
// matcher.
|
||||||
|
class MatcherDescriberInterface {
|
||||||
|
public:
|
||||||
|
virtual ~MatcherDescriberInterface() {}
|
||||||
|
|
||||||
|
// Describes this matcher to an ostream. The function should print
|
||||||
|
// a verb phrase that describes the property a value matching this
|
||||||
|
// matcher should have. The subject of the verb phrase is the value
|
||||||
|
// being matched. For example, the DescribeTo() method of the Gt(7)
|
||||||
|
// matcher prints "is greater than 7".
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||||
|
|
||||||
|
// Describes the negation of this matcher to an ostream. For
|
||||||
|
// example, if the description of this matcher is "is greater than
|
||||||
|
// 7", the negated description could be "is not greater than 7".
|
||||||
|
// You are not required to override this when implementing
|
||||||
|
// MatcherInterface, but it is highly advised so that your matcher
|
||||||
|
// can produce good error messages.
|
||||||
|
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "not (";
|
||||||
|
DescribeTo(os);
|
||||||
|
*os << ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The implementation of a matcher.
|
||||||
|
template <typename T>
|
||||||
|
class MatcherInterface : public MatcherDescriberInterface {
|
||||||
|
public:
|
||||||
|
// Returns true if and only if the matcher matches x; also explains the
|
||||||
|
// match result to 'listener' if necessary (see the next paragraph), in
|
||||||
|
// the form of a non-restrictive relative clause ("which ...",
|
||||||
|
// "whose ...", etc) that describes x. For example, the
|
||||||
|
// MatchAndExplain() method of the Pointee(...) matcher should
|
||||||
|
// generate an explanation like "which points to ...".
|
||||||
|
//
|
||||||
|
// Implementations of MatchAndExplain() should add an explanation of
|
||||||
|
// the match result *if and only if* they can provide additional
|
||||||
|
// information that's not already present (or not obvious) in the
|
||||||
|
// print-out of x and the matcher's description. Whether the match
|
||||||
|
// succeeds is not a factor in deciding whether an explanation is
|
||||||
|
// needed, as sometimes the caller needs to print a failure message
|
||||||
|
// when the match succeeds (e.g. when the matcher is used inside
|
||||||
|
// Not()).
|
||||||
|
//
|
||||||
|
// For example, a "has at least 10 elements" matcher should explain
|
||||||
|
// what the actual element count is, regardless of the match result,
|
||||||
|
// as it is useful information to the reader; on the other hand, an
|
||||||
|
// "is empty" matcher probably only needs to explain what the actual
|
||||||
|
// size is when the match fails, as it's redundant to say that the
|
||||||
|
// size is 0 when the value is already known to be empty.
|
||||||
|
//
|
||||||
|
// You should override this method when defining a new matcher.
|
||||||
|
//
|
||||||
|
// It's the responsibility of the caller (Google Test) to guarantee
|
||||||
|
// that 'listener' is not NULL. This helps to simplify a matcher's
|
||||||
|
// implementation when it doesn't care about the performance, as it
|
||||||
|
// can talk to 'listener' without checking its validity first.
|
||||||
|
// However, in order to implement dummy listeners efficiently,
|
||||||
|
// listener->stream() may be NULL.
|
||||||
|
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
|
||||||
|
|
||||||
|
// Inherits these methods from MatcherDescriberInterface:
|
||||||
|
// virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||||
|
// virtual void DescribeNegationTo(::std::ostream* os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
|
||||||
|
template <typename T>
|
||||||
|
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
|
||||||
|
public:
|
||||||
|
explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
|
||||||
|
: impl_(impl) {}
|
||||||
|
~MatcherInterfaceAdapter() override { delete impl_; }
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); }
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
|
impl_->DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MatchAndExplain(const T& x,
|
||||||
|
MatchResultListener* listener) const override {
|
||||||
|
return impl_->MatchAndExplain(x, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const MatcherInterface<T>* const impl_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnyEq {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a == b; }
|
||||||
|
};
|
||||||
|
struct AnyNe {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a != b; }
|
||||||
|
};
|
||||||
|
struct AnyLt {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a < b; }
|
||||||
|
};
|
||||||
|
struct AnyGt {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a > b; }
|
||||||
|
};
|
||||||
|
struct AnyLe {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a <= b; }
|
||||||
|
};
|
||||||
|
struct AnyGe {
|
||||||
|
template <typename A, typename B>
|
||||||
|
bool operator()(const A& a, const B& b) const { return a >= b; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// A match result listener that ignores the explanation.
|
||||||
|
class DummyMatchResultListener : public MatchResultListener {
|
||||||
|
public:
|
||||||
|
DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
// A match result listener that forwards the explanation to a given
|
||||||
|
// ostream. The difference between this and MatchResultListener is
|
||||||
|
// that the former is concrete.
|
||||||
|
class StreamMatchResultListener : public MatchResultListener {
|
||||||
|
public:
|
||||||
|
explicit StreamMatchResultListener(::std::ostream* os)
|
||||||
|
: MatchResultListener(os) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
// An internal class for implementing Matcher<T>, which will derive
|
||||||
|
// from it. We put functionalities common to all Matcher<T>
|
||||||
|
// specializations here to avoid code duplication.
|
||||||
|
template <typename T>
|
||||||
|
class MatcherBase {
|
||||||
|
public:
|
||||||
|
// Returns true if and only if the matcher matches x; also explains the
|
||||||
|
// match result to 'listener'.
|
||||||
|
bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
|
||||||
|
return impl_->MatchAndExplain(x, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if and only if this matcher matches x.
|
||||||
|
bool Matches(const T& x) const {
|
||||||
|
DummyMatchResultListener dummy;
|
||||||
|
return MatchAndExplain(x, &dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes this matcher to an ostream.
|
||||||
|
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||||
|
|
||||||
|
// Describes the negation of this matcher to an ostream.
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
impl_->DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explains why x matches, or doesn't match, the matcher.
|
||||||
|
void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
|
||||||
|
StreamMatchResultListener listener(os);
|
||||||
|
MatchAndExplain(x, &listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the describer for this matcher object; retains ownership
|
||||||
|
// of the describer, which is only guaranteed to be alive when
|
||||||
|
// this matcher object is alive.
|
||||||
|
const MatcherDescriberInterface* GetDescriber() const {
|
||||||
|
return impl_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MatcherBase() {}
|
||||||
|
|
||||||
|
// Constructs a matcher from its implementation.
|
||||||
|
explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
explicit MatcherBase(
|
||||||
|
const MatcherInterface<U>* impl,
|
||||||
|
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
|
||||||
|
nullptr)
|
||||||
|
: impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
|
||||||
|
|
||||||
|
MatcherBase(const MatcherBase&) = default;
|
||||||
|
MatcherBase& operator=(const MatcherBase&) = default;
|
||||||
|
MatcherBase(MatcherBase&&) = default;
|
||||||
|
MatcherBase& operator=(MatcherBase&&) = default;
|
||||||
|
|
||||||
|
virtual ~MatcherBase() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const MatcherInterface<const T&>> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
|
||||||
|
// object that can check whether a value of type T matches. The
|
||||||
|
// implementation of Matcher<T> is just a std::shared_ptr to const
|
||||||
|
// MatcherInterface<T>. Don't inherit from Matcher!
|
||||||
|
template <typename T>
|
||||||
|
class Matcher : public internal::MatcherBase<T> {
|
||||||
|
public:
|
||||||
|
// Constructs a null matcher. Needed for storing Matcher objects in STL
|
||||||
|
// containers. A default-constructed matcher is not yet initialized. You
|
||||||
|
// cannot use it until a valid value has been assigned to it.
|
||||||
|
explicit Matcher() {} // NOLINT
|
||||||
|
|
||||||
|
// Constructs a matcher from its implementation.
|
||||||
|
explicit Matcher(const MatcherInterface<const T&>* impl)
|
||||||
|
: internal::MatcherBase<T>(impl) {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
explicit Matcher(
|
||||||
|
const MatcherInterface<U>* impl,
|
||||||
|
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
|
||||||
|
nullptr)
|
||||||
|
: internal::MatcherBase<T>(impl) {}
|
||||||
|
|
||||||
|
// Implicit constructor here allows people to write
|
||||||
|
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
||||||
|
Matcher(T value); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following two specializations allow the user to write str
|
||||||
|
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
||||||
|
// matcher is expected.
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<const std::string&>
|
||||||
|
: public internal::MatcherBase<const std::string&> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||||
|
: internal::MatcherBase<const std::string&>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a std::string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<std::string>
|
||||||
|
: public internal::MatcherBase<std::string> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||||
|
: internal::MatcherBase<std::string>(impl) {}
|
||||||
|
explicit Matcher(const MatcherInterface<std::string>* impl)
|
||||||
|
: internal::MatcherBase<std::string>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
#if GTEST_HAS_ABSL
|
||||||
|
// The following two specializations allow the user to write str
|
||||||
|
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
|
||||||
|
// matcher is expected.
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<const absl::string_view&>
|
||||||
|
: public internal::MatcherBase<const absl::string_view&> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
|
||||||
|
: internal::MatcherBase<const absl::string_view&>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a std::string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to pass absl::string_views directly.
|
||||||
|
Matcher(absl::string_view s); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class GTEST_API_ Matcher<absl::string_view>
|
||||||
|
: public internal::MatcherBase<absl::string_view> {
|
||||||
|
public:
|
||||||
|
Matcher() {}
|
||||||
|
|
||||||
|
explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
|
||||||
|
: internal::MatcherBase<absl::string_view>(impl) {}
|
||||||
|
explicit Matcher(const MatcherInterface<absl::string_view>* impl)
|
||||||
|
: internal::MatcherBase<absl::string_view>(impl) {}
|
||||||
|
|
||||||
|
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||||
|
// str is a std::string object.
|
||||||
|
Matcher(const std::string& s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||||
|
Matcher(const char* s); // NOLINT
|
||||||
|
|
||||||
|
// Allows the user to pass absl::string_views directly.
|
||||||
|
Matcher(absl::string_view s); // NOLINT
|
||||||
|
};
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
// Prints a matcher in a human-readable format.
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
|
||||||
|
matcher.DescribeTo(&os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The PolymorphicMatcher class template makes it easy to implement a
|
||||||
|
// polymorphic matcher (i.e. a matcher that can match values of more
|
||||||
|
// than one type, e.g. Eq(n) and NotNull()).
|
||||||
|
//
|
||||||
|
// To define a polymorphic matcher, a user should provide an Impl
|
||||||
|
// class that has a DescribeTo() method and a DescribeNegationTo()
|
||||||
|
// method, and define a member function (or member function template)
|
||||||
|
//
|
||||||
|
// bool MatchAndExplain(const Value& value,
|
||||||
|
// MatchResultListener* listener) const;
|
||||||
|
//
|
||||||
|
// See the definition of NotNull() for a complete example.
|
||||||
|
template <class Impl>
|
||||||
|
class PolymorphicMatcher {
|
||||||
|
public:
|
||||||
|
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
|
||||||
|
|
||||||
|
// Returns a mutable reference to the underlying matcher
|
||||||
|
// implementation object.
|
||||||
|
Impl& mutable_impl() { return impl_; }
|
||||||
|
|
||||||
|
// Returns an immutable reference to the underlying matcher
|
||||||
|
// implementation object.
|
||||||
|
const Impl& impl() const { return impl_; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
operator Matcher<T>() const {
|
||||||
|
return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
class MonomorphicImpl : public MatcherInterface<T> {
|
||||||
|
public:
|
||||||
|
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
||||||
|
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); }
|
||||||
|
|
||||||
|
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
impl_.DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
|
||||||
|
return impl_.MatchAndExplain(x, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Impl impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Impl impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates a matcher from its implementation.
|
||||||
|
// DEPRECATED: Especially in the generic code, prefer:
|
||||||
|
// Matcher<T>(new MyMatcherImpl<const T&>(...));
|
||||||
|
//
|
||||||
|
// MakeMatcher may create a Matcher that accepts its argument by value, which
|
||||||
|
// leads to unnecessary copies & lack of support for non-copyable types.
|
||||||
|
template <typename T>
|
||||||
|
inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
|
||||||
|
return Matcher<T>(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher from its implementation. This is
|
||||||
|
// easier to use than the PolymorphicMatcher<Impl> constructor as it
|
||||||
|
// doesn't require you to explicitly write the template argument, e.g.
|
||||||
|
//
|
||||||
|
// MakePolymorphicMatcher(foo);
|
||||||
|
// vs
|
||||||
|
// PolymorphicMatcher<TypeOfFoo>(foo);
|
||||||
|
template <class Impl>
|
||||||
|
inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
|
||||||
|
return PolymorphicMatcher<Impl>(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
// Implements a matcher that compares a given value with a
|
||||||
|
// pre-supplied value using one of the ==, <=, <, etc, operators. The
|
||||||
|
// two values being compared don't have to have the same type.
|
||||||
|
//
|
||||||
|
// The matcher defined here is polymorphic (for example, Eq(5) can be
|
||||||
|
// used to match an int, a short, a double, etc). Therefore we use
|
||||||
|
// a template type conversion operator in the implementation.
|
||||||
|
//
|
||||||
|
// The following template definition assumes that the Rhs parameter is
|
||||||
|
// a "bare" type (i.e. neither 'const T' nor 'T&').
|
||||||
|
template <typename D, typename Rhs, typename Op>
|
||||||
|
class ComparisonBase {
|
||||||
|
public:
|
||||||
|
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
||||||
|
template <typename Lhs>
|
||||||
|
operator Matcher<Lhs>() const {
|
||||||
|
return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static const T& Unwrap(const T& v) { return v; }
|
||||||
|
template <typename T>
|
||||||
|
static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
|
||||||
|
|
||||||
|
template <typename Lhs, typename = Rhs>
|
||||||
|
class Impl : public MatcherInterface<Lhs> {
|
||||||
|
public:
|
||||||
|
explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
|
||||||
|
bool MatchAndExplain(Lhs lhs,
|
||||||
|
MatchResultListener* /* listener */) const override {
|
||||||
|
return Op()(lhs, Unwrap(rhs_));
|
||||||
|
}
|
||||||
|
void DescribeTo(::std::ostream* os) const override {
|
||||||
|
*os << D::Desc() << " ";
|
||||||
|
UniversalPrint(Unwrap(rhs_), os);
|
||||||
|
}
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const override {
|
||||||
|
*os << D::NegatedDesc() << " ";
|
||||||
|
UniversalPrint(Unwrap(rhs_), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Rhs rhs_;
|
||||||
|
};
|
||||||
|
Rhs rhs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Rhs>
|
||||||
|
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
|
||||||
|
public:
|
||||||
|
explicit EqMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
|
||||||
|
static const char* Desc() { return "is equal to"; }
|
||||||
|
static const char* NegatedDesc() { return "isn't equal to"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
|
||||||
|
public:
|
||||||
|
explicit NeMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
|
||||||
|
static const char* Desc() { return "isn't equal to"; }
|
||||||
|
static const char* NegatedDesc() { return "is equal to"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
|
||||||
|
public:
|
||||||
|
explicit LtMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
|
||||||
|
static const char* Desc() { return "is <"; }
|
||||||
|
static const char* NegatedDesc() { return "isn't <"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
|
||||||
|
public:
|
||||||
|
explicit GtMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
|
||||||
|
static const char* Desc() { return "is >"; }
|
||||||
|
static const char* NegatedDesc() { return "isn't >"; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
|
||||||
|
public:
|
||||||
|
explicit LeMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
|
||||||
|
static const char* Desc() { return "is <="; }
|
||||||
|
static const char* NegatedDesc() { return "isn't <="; }
|
||||||
|
};
|
||||||
|
template <typename Rhs>
|
||||||
|
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
|
||||||
|
public:
|
||||||
|
explicit GeMatcher(const Rhs& rhs)
|
||||||
|
: ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
|
||||||
|
static const char* Desc() { return "is >="; }
|
||||||
|
static const char* NegatedDesc() { return "isn't >="; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implements polymorphic matchers MatchesRegex(regex) and
|
||||||
|
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
||||||
|
// T can be converted to a string.
|
||||||
|
class MatchesRegexMatcher {
|
||||||
|
public:
|
||||||
|
MatchesRegexMatcher(const RE* regex, bool full_match)
|
||||||
|
: regex_(regex), full_match_(full_match) {}
|
||||||
|
|
||||||
|
#if GTEST_HAS_ABSL
|
||||||
|
bool MatchAndExplain(const absl::string_view& s,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
return MatchAndExplain(std::string(s), listener);
|
||||||
|
}
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
// Accepts pointer types, particularly:
|
||||||
|
// const char*
|
||||||
|
// char*
|
||||||
|
// const wchar_t*
|
||||||
|
// wchar_t*
|
||||||
|
template <typename CharType>
|
||||||
|
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
|
||||||
|
return s != nullptr && MatchAndExplain(std::string(s), listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matches anything that can convert to std::string.
|
||||||
|
//
|
||||||
|
// This is a template, not just a plain function with const std::string&,
|
||||||
|
// because absl::string_view has some interfering non-explicit constructors.
|
||||||
|
template <class MatcheeStringType>
|
||||||
|
bool MatchAndExplain(const MatcheeStringType& s,
|
||||||
|
MatchResultListener* /* listener */) const {
|
||||||
|
const std::string& s2(s);
|
||||||
|
return full_match_ ? RE::FullMatch(s2, *regex_)
|
||||||
|
: RE::PartialMatch(s2, *regex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeTo(::std::ostream* os) const {
|
||||||
|
*os << (full_match_ ? "matches" : "contains") << " regular expression ";
|
||||||
|
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "doesn't " << (full_match_ ? "match" : "contain")
|
||||||
|
<< " regular expression ";
|
||||||
|
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::shared_ptr<const RE> regex_;
|
||||||
|
const bool full_match_;
|
||||||
|
};
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Matches a string that fully matches regular expression 'regex'.
|
||||||
|
// The matcher takes ownership of 'regex'.
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
||||||
|
const internal::RE* regex) {
|
||||||
|
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
|
||||||
|
}
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
||||||
|
const std::string& regex) {
|
||||||
|
return MatchesRegex(new internal::RE(regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matches a string that contains regular expression 'regex'.
|
||||||
|
// The matcher takes ownership of 'regex'.
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
||||||
|
const internal::RE* regex) {
|
||||||
|
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
|
||||||
|
}
|
||||||
|
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
||||||
|
const std::string& regex) {
|
||||||
|
return ContainsRegex(new internal::RE(regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything equal to x.
|
||||||
|
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
|
||||||
|
// wouldn't compile.
|
||||||
|
template <typename T>
|
||||||
|
inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
|
||||||
|
|
||||||
|
// Constructs a Matcher<T> from a 'value' of type T. The constructed
|
||||||
|
// matcher matches any value that's equal to 'value'.
|
||||||
|
template <typename T>
|
||||||
|
Matcher<T>::Matcher(T value) { *this = Eq(value); }
|
||||||
|
|
||||||
|
// Creates a monomorphic matcher that matches anything with type Lhs
|
||||||
|
// and equal to rhs. A user may need to use this instead of Eq(...)
|
||||||
|
// in order to resolve an overloading ambiguity.
|
||||||
|
//
|
||||||
|
// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
|
||||||
|
// or Matcher<T>(x), but more readable than the latter.
|
||||||
|
//
|
||||||
|
// We could define similar monomorphic matchers for other comparison
|
||||||
|
// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
|
||||||
|
// it yet as those are used much less than Eq() in practice. A user
|
||||||
|
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
|
||||||
|
// for example.
|
||||||
|
template <typename Lhs, typename Rhs>
|
||||||
|
inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything >= x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::GeMatcher<Rhs> Ge(Rhs x) {
|
||||||
|
return internal::GeMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything > x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::GtMatcher<Rhs> Gt(Rhs x) {
|
||||||
|
return internal::GtMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything <= x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::LeMatcher<Rhs> Le(Rhs x) {
|
||||||
|
return internal::LeMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything < x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::LtMatcher<Rhs> Lt(Rhs x) {
|
||||||
|
return internal::LtMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a polymorphic matcher that matches anything != x.
|
||||||
|
template <typename Rhs>
|
||||||
|
inline internal::NeMatcher<Rhs> Ne(Rhs x) {
|
||||||
|
return internal::NeMatcher<Rhs>(x);
|
||||||
|
}
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
|
||||||
|
|
||||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
@@ -106,14 +107,6 @@ class GTEST_API_ Message {
|
|||||||
*ss_ << str;
|
*ss_ << str;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_OS_SYMBIAN
|
|
||||||
// Streams a value (either a pointer or not) to this object.
|
|
||||||
template <typename T>
|
|
||||||
inline Message& operator <<(const T& value) {
|
|
||||||
StreamHelper(typename internal::is_pointer<T>::type(), value);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Streams a non-pointer value to this object.
|
// Streams a non-pointer value to this object.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline Message& operator <<(const T& val) {
|
inline Message& operator <<(const T& val) {
|
||||||
@@ -151,14 +144,13 @@ class GTEST_API_ Message {
|
|||||||
// as "(null)".
|
// as "(null)".
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline Message& operator <<(T* const& pointer) { // NOLINT
|
inline Message& operator <<(T* const& pointer) { // NOLINT
|
||||||
if (pointer == NULL) {
|
if (pointer == nullptr) {
|
||||||
*ss_ << "(null)";
|
*ss_ << "(null)";
|
||||||
} else {
|
} else {
|
||||||
*ss_ << pointer;
|
*ss_ << pointer;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif // GTEST_OS_SYMBIAN
|
|
||||||
|
|
||||||
// Since the basic IO manipulators are overloaded for both narrow
|
// Since the basic IO manipulators are overloaded for both narrow
|
||||||
// and wide streams, we have to provide this specialized definition
|
// and wide streams, we have to provide this specialized definition
|
||||||
@@ -187,12 +179,6 @@ class GTEST_API_ Message {
|
|||||||
Message& operator <<(const ::std::wstring& wstr);
|
Message& operator <<(const ::std::wstring& wstr);
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_WSTRING
|
|
||||||
// Converts the given wide string to a narrow string using the UTF-8
|
|
||||||
// encoding, and streams the result to this Message object.
|
|
||||||
Message& operator <<(const ::wstring& wstr);
|
|
||||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
|
||||||
|
|
||||||
// Gets the text streamed to this object so far as an std::string.
|
// Gets the text streamed to this object so far as an std::string.
|
||||||
// Each '\0' character in the buffer is replaced with "\\0".
|
// Each '\0' character in the buffer is replaced with "\\0".
|
||||||
//
|
//
|
||||||
@@ -200,31 +186,8 @@ class GTEST_API_ Message {
|
|||||||
std::string GetString() const;
|
std::string GetString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if GTEST_OS_SYMBIAN
|
|
||||||
// These are needed as the Nokia Symbian Compiler cannot decide between
|
|
||||||
// const T& and const T* in a function template. The Nokia compiler _can_
|
|
||||||
// decide between class template specializations for T and T*, so a
|
|
||||||
// tr1::type_traits-like is_pointer works, and we can overload on that.
|
|
||||||
template <typename T>
|
|
||||||
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
|
|
||||||
if (pointer == NULL) {
|
|
||||||
*ss_ << "(null)";
|
|
||||||
} else {
|
|
||||||
*ss_ << pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
inline void StreamHelper(internal::false_type /*is_pointer*/,
|
|
||||||
const T& value) {
|
|
||||||
// See the comments in Message& operator <<(const T&) above for why
|
|
||||||
// we need this using statement.
|
|
||||||
using ::operator <<;
|
|
||||||
*ss_ << value;
|
|
||||||
}
|
|
||||||
#endif // GTEST_OS_SYMBIAN
|
|
||||||
|
|
||||||
// We'll hold the text streamed to this object here.
|
// We'll hold the text streamed to this object here.
|
||||||
const internal::scoped_ptr< ::std::stringstream> ss_;
|
const std::unique_ptr< ::std::stringstream> ss_;
|
||||||
|
|
||||||
// We declare (but don't implement) this to prevent the compiler
|
// We declare (but don't implement) this to prevent the compiler
|
||||||
// from implementing the assignment operator.
|
// from implementing the assignment operator.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,500 +0,0 @@
|
|||||||
$$ -*- mode: c++; -*-
|
|
||||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
|
||||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
|
||||||
// Copyright 2008, Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Macros and functions for implementing parameterized tests
|
|
||||||
// in Google C++ Testing and Mocking Framework (Google Test)
|
|
||||||
//
|
|
||||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
|
||||||
//
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
|
||||||
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
|
||||||
|
|
||||||
|
|
||||||
// Value-parameterized tests allow you to test your code with different
|
|
||||||
// parameters without writing multiple copies of the same test.
|
|
||||||
//
|
|
||||||
// Here is how you use value-parameterized tests:
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
// To write value-parameterized tests, first you should define a fixture
|
|
||||||
// class. It is usually derived from testing::TestWithParam<T> (see below for
|
|
||||||
// another inheritance scheme that's sometimes useful in more complicated
|
|
||||||
// class hierarchies), where the type of your parameter values.
|
|
||||||
// TestWithParam<T> is itself derived from testing::Test. T can be any
|
|
||||||
// copyable type. If it's a raw pointer, you are responsible for managing the
|
|
||||||
// lifespan of the pointed values.
|
|
||||||
|
|
||||||
class FooTest : public ::testing::TestWithParam<const char*> {
|
|
||||||
// You can implement all the usual class fixture members here.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Then, use the TEST_P macro to define as many parameterized tests
|
|
||||||
// for this fixture as you want. The _P suffix is for "parameterized"
|
|
||||||
// or "pattern", whichever you prefer to think.
|
|
||||||
|
|
||||||
TEST_P(FooTest, DoesBlah) {
|
|
||||||
// Inside a test, access the test parameter with the GetParam() method
|
|
||||||
// of the TestWithParam<T> class:
|
|
||||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FooTest, HasBlahBlah) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
|
|
||||||
// case with any set of parameters you want. Google Test defines a number
|
|
||||||
// of functions for generating test parameters. They return what we call
|
|
||||||
// (surprise!) parameter generators. Here is a summary of them, which
|
|
||||||
// are all in the testing namespace:
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
|
||||||
// begin+step+step, ...}. The values do not
|
|
||||||
// include end. step defaults to 1.
|
|
||||||
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
|
||||||
// ValuesIn(container) - Yields values from a C-style array, an STL
|
|
||||||
// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
|
||||||
// Bool() - Yields sequence {false, true}.
|
|
||||||
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
|
||||||
// for the math savvy) of the values generated
|
|
||||||
// by the N generators.
|
|
||||||
//
|
|
||||||
// For more details, see comments at the definitions of these functions below
|
|
||||||
// in this file.
|
|
||||||
//
|
|
||||||
// The following statement will instantiate tests from the FooTest test case
|
|
||||||
// each with parameter values "meeny", "miny", and "moe".
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(InstantiationName,
|
|
||||||
FooTest,
|
|
||||||
Values("meeny", "miny", "moe"));
|
|
||||||
|
|
||||||
// To distinguish different instances of the pattern, (yes, you
|
|
||||||
// can instantiate it more then once) the first argument to the
|
|
||||||
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
|
|
||||||
// actual test case name. Remember to pick unique prefixes for different
|
|
||||||
// instantiations. The tests from the instantiation above will have
|
|
||||||
// these names:
|
|
||||||
//
|
|
||||||
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
|
||||||
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
|
||||||
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
|
||||||
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
|
||||||
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
|
||||||
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
|
||||||
//
|
|
||||||
// You can use these names in --gtest_filter.
|
|
||||||
//
|
|
||||||
// This statement will instantiate all tests from FooTest again, each
|
|
||||||
// with parameter values "cat" and "dog":
|
|
||||||
|
|
||||||
const char* pets[] = {"cat", "dog"};
|
|
||||||
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
|
||||||
|
|
||||||
// The tests from the instantiation above will have these names:
|
|
||||||
//
|
|
||||||
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
|
||||||
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
|
||||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
|
||||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
|
||||||
//
|
|
||||||
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
|
|
||||||
// in the given test case, whether their definitions come before or
|
|
||||||
// AFTER the INSTANTIATE_TEST_CASE_P statement.
|
|
||||||
//
|
|
||||||
// Please also note that generator expressions (including parameters to the
|
|
||||||
// generators) are evaluated in InitGoogleTest(), after main() has started.
|
|
||||||
// This allows the user on one hand, to adjust generator parameters in order
|
|
||||||
// to dynamically determine a set of tests to run and on the other hand,
|
|
||||||
// give the user a chance to inspect the generated tests with Google Test
|
|
||||||
// reflection API before RUN_ALL_TESTS() is executed.
|
|
||||||
//
|
|
||||||
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
|
||||||
// for more examples.
|
|
||||||
//
|
|
||||||
// In the future, we plan to publish the API for defining new parameter
|
|
||||||
// generators. But for now this interface remains part of the internal
|
|
||||||
// implementation and is subject to change.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// A parameterized test fixture must be derived from testing::Test and from
|
|
||||||
// testing::WithParamInterface<T>, where T is the type of the parameter
|
|
||||||
// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
|
||||||
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
|
||||||
// complicated hierarchies, however, it is occasionally useful to inherit
|
|
||||||
// separately from Test and WithParamInterface. For example:
|
|
||||||
|
|
||||||
class BaseTest : public ::testing::Test {
|
|
||||||
// You can inherit all the usual members for a non-parameterized test
|
|
||||||
// fixture here.
|
|
||||||
};
|
|
||||||
|
|
||||||
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
|
||||||
// The usual test fixture members go here too.
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(BaseTest, HasFoo) {
|
|
||||||
// This is an ordinary non-parameterized test.
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(DerivedTest, DoesBlah) {
|
|
||||||
// GetParam works just the same here as if you inherit from TestWithParam.
|
|
||||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
|
||||||
|
|
||||||
#if !GTEST_OS_SYMBIAN
|
|
||||||
# include <utility>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "gtest/internal/gtest-internal.h"
|
|
||||||
#include "gtest/internal/gtest-param-util.h"
|
|
||||||
#include "gtest/internal/gtest-param-util-generated.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// Functions producing parameter generators.
|
|
||||||
//
|
|
||||||
// Google Test uses these generators to produce parameters for value-
|
|
||||||
// parameterized tests. When a parameterized test case is instantiated
|
|
||||||
// with a particular generator, Google Test creates and runs tests
|
|
||||||
// for each element in the sequence produced by the generator.
|
|
||||||
//
|
|
||||||
// In the following sample, tests from test case FooTest are instantiated
|
|
||||||
// each three times with parameter values 3, 5, and 8:
|
|
||||||
//
|
|
||||||
// class FooTest : public TestWithParam<int> { ... };
|
|
||||||
//
|
|
||||||
// TEST_P(FooTest, TestThis) {
|
|
||||||
// }
|
|
||||||
// TEST_P(FooTest, TestThat) {
|
|
||||||
// }
|
|
||||||
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
|
|
||||||
//
|
|
||||||
|
|
||||||
// Range() returns generators providing sequences of values in a range.
|
|
||||||
//
|
|
||||||
// Synopsis:
|
|
||||||
// Range(start, end)
|
|
||||||
// - returns a generator producing a sequence of values {start, start+1,
|
|
||||||
// start+2, ..., }.
|
|
||||||
// Range(start, end, step)
|
|
||||||
// - returns a generator producing a sequence of values {start, start+step,
|
|
||||||
// start+step+step, ..., }.
|
|
||||||
// Notes:
|
|
||||||
// * The generated sequences never include end. For example, Range(1, 5)
|
|
||||||
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
|
||||||
// returns a generator producing {1, 3, 5, 7}.
|
|
||||||
// * start and end must have the same type. That type may be any integral or
|
|
||||||
// floating-point type or a user defined type satisfying these conditions:
|
|
||||||
// * It must be assignable (have operator=() defined).
|
|
||||||
// * It must have operator+() (operator+(int-compatible type) for
|
|
||||||
// two-operand version).
|
|
||||||
// * It must have operator<() defined.
|
|
||||||
// Elements in the resulting sequences will also have that type.
|
|
||||||
// * Condition start < end must be satisfied in order for resulting sequences
|
|
||||||
// to contain any elements.
|
|
||||||
//
|
|
||||||
template <typename T, typename IncrementT>
|
|
||||||
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
|
||||||
return internal::ParamGenerator<T>(
|
|
||||||
new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
internal::ParamGenerator<T> Range(T start, T end) {
|
|
||||||
return Range(start, end, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValuesIn() function allows generation of tests with parameters coming from
|
|
||||||
// a container.
|
|
||||||
//
|
|
||||||
// Synopsis:
|
|
||||||
// ValuesIn(const T (&array)[N])
|
|
||||||
// - returns a generator producing sequences with elements from
|
|
||||||
// a C-style array.
|
|
||||||
// ValuesIn(const Container& container)
|
|
||||||
// - returns a generator producing sequences with elements from
|
|
||||||
// an STL-style container.
|
|
||||||
// ValuesIn(Iterator begin, Iterator end)
|
|
||||||
// - returns a generator producing sequences with elements from
|
|
||||||
// a range [begin, end) defined by a pair of STL-style iterators. These
|
|
||||||
// iterators can also be plain C pointers.
|
|
||||||
//
|
|
||||||
// Please note that ValuesIn copies the values from the containers
|
|
||||||
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
|
||||||
//
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// This instantiates tests from test case StringTest
|
|
||||||
// each with C-string values of "foo", "bar", and "baz":
|
|
||||||
//
|
|
||||||
// const char* strings[] = {"foo", "bar", "baz"};
|
|
||||||
// INSTANTIATE_TEST_CASE_P(StringSequence, StringTest, ValuesIn(strings));
|
|
||||||
//
|
|
||||||
// This instantiates tests from test case StlStringTest
|
|
||||||
// each with STL strings with values "a" and "b":
|
|
||||||
//
|
|
||||||
// ::std::vector< ::std::string> GetParameterStrings() {
|
|
||||||
// ::std::vector< ::std::string> v;
|
|
||||||
// v.push_back("a");
|
|
||||||
// v.push_back("b");
|
|
||||||
// return v;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// INSTANTIATE_TEST_CASE_P(CharSequence,
|
|
||||||
// StlStringTest,
|
|
||||||
// ValuesIn(GetParameterStrings()));
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// This will also instantiate tests from CharTest
|
|
||||||
// each with parameter values 'a' and 'b':
|
|
||||||
//
|
|
||||||
// ::std::list<char> GetParameterChars() {
|
|
||||||
// ::std::list<char> list;
|
|
||||||
// list.push_back('a');
|
|
||||||
// list.push_back('b');
|
|
||||||
// return list;
|
|
||||||
// }
|
|
||||||
// ::std::list<char> l = GetParameterChars();
|
|
||||||
// INSTANTIATE_TEST_CASE_P(CharSequence2,
|
|
||||||
// CharTest,
|
|
||||||
// ValuesIn(l.begin(), l.end()));
|
|
||||||
//
|
|
||||||
template <typename ForwardIterator>
|
|
||||||
internal::ParamGenerator<
|
|
||||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
|
||||||
ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
|
||||||
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
|
|
||||||
::value_type ParamType;
|
|
||||||
return internal::ParamGenerator<ParamType>(
|
|
||||||
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, size_t N>
|
|
||||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
|
||||||
return ValuesIn(array, array + N);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Container>
|
|
||||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
|
||||||
const Container& container) {
|
|
||||||
return ValuesIn(container.begin(), container.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Values() allows generating tests from explicitly specified list of
|
|
||||||
// parameters.
|
|
||||||
//
|
|
||||||
// Synopsis:
|
|
||||||
// Values(T v1, T v2, ..., T vN)
|
|
||||||
// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
|
||||||
//
|
|
||||||
// For example, this instantiates tests from test case BarTest each
|
|
||||||
// with values "one", "two", and "three":
|
|
||||||
//
|
|
||||||
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
|
|
||||||
//
|
|
||||||
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
|
|
||||||
// The exact type of values will depend on the type of parameter in BazTest.
|
|
||||||
//
|
|
||||||
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
|
||||||
//
|
|
||||||
// Currently, Values() supports from 1 to $n parameters.
|
|
||||||
//
|
|
||||||
$range i 1..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
|
||||||
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
|
|
||||||
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// Bool() allows generating tests with parameters in a set of (false, true).
|
|
||||||
//
|
|
||||||
// Synopsis:
|
|
||||||
// Bool()
|
|
||||||
// - returns a generator producing sequences with elements {false, true}.
|
|
||||||
//
|
|
||||||
// It is useful when testing code that depends on Boolean flags. Combinations
|
|
||||||
// of multiple flags can be tested when several Bool()'s are combined using
|
|
||||||
// Combine() function.
|
|
||||||
//
|
|
||||||
// In the following example all tests in the test case FlagDependentTest
|
|
||||||
// will be instantiated twice with parameters false and true.
|
|
||||||
//
|
|
||||||
// class FlagDependentTest : public testing::TestWithParam<bool> {
|
|
||||||
// virtual void SetUp() {
|
|
||||||
// external_flag = GetParam();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
|
|
||||||
//
|
|
||||||
inline internal::ParamGenerator<bool> Bool() {
|
|
||||||
return Values(false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
# if GTEST_HAS_COMBINE
|
|
||||||
// Combine() allows the user to combine two or more sequences to produce
|
|
||||||
// values of a Cartesian product of those sequences' elements.
|
|
||||||
//
|
|
||||||
// Synopsis:
|
|
||||||
// Combine(gen1, gen2, ..., genN)
|
|
||||||
// - returns a generator producing sequences with elements coming from
|
|
||||||
// the Cartesian product of elements from the sequences generated by
|
|
||||||
// gen1, gen2, ..., genN. The sequence elements will have a type of
|
|
||||||
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
|
||||||
// of elements from sequences produces by gen1, gen2, ..., genN.
|
|
||||||
//
|
|
||||||
// Combine can have up to $maxtuple arguments. This number is currently limited
|
|
||||||
// by the maximum number of elements in the tuple implementation used by Google
|
|
||||||
// Test.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// This will instantiate tests in test case 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 };
|
|
||||||
// class AnimalTest
|
|
||||||
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
|
|
||||||
//
|
|
||||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
|
||||||
//
|
|
||||||
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
|
|
||||||
// Combine(Values("cat", "dog"),
|
|
||||||
// Values(BLACK, WHITE)));
|
|
||||||
//
|
|
||||||
// This will instantiate tests in FlagDependentTest with all variations of two
|
|
||||||
// Boolean flags:
|
|
||||||
//
|
|
||||||
// class FlagDependentTest
|
|
||||||
// : public testing::TestWithParam<tuple<bool, bool> > {
|
|
||||||
// virtual void SetUp() {
|
|
||||||
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
|
||||||
// tie(external_flag_1, external_flag_2) = GetParam();
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// TEST_P(FlagDependentTest, TestFeature1) {
|
|
||||||
// // Test your code using external_flag_1 and external_flag_2 here.
|
|
||||||
// }
|
|
||||||
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
|
|
||||||
// Combine(Bool(), Bool()));
|
|
||||||
//
|
|
||||||
$range i 2..maxtuple
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
|
|
||||||
template <$for j, [[typename Generator$j]]>
|
|
||||||
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
|
||||||
$for j, [[const Generator$j& g$j]]) {
|
|
||||||
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
|
|
||||||
$for j, [[g$j]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
# endif // GTEST_HAS_COMBINE
|
|
||||||
|
|
||||||
# define TEST_P(test_case_name, test_name) \
|
|
||||||
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
|
|
||||||
: public test_case_name { \
|
|
||||||
public: \
|
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
|
|
||||||
virtual void TestBody(); \
|
|
||||||
private: \
|
|
||||||
static int AddToRegistry() { \
|
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
|
||||||
#test_case_name, \
|
|
||||||
::testing::internal::CodeLocation(\
|
|
||||||
__FILE__, __LINE__))->AddTestPattern(\
|
|
||||||
GTEST_STRINGIFY_(test_case_name), \
|
|
||||||
GTEST_STRINGIFY_(test_name), \
|
|
||||||
new ::testing::internal::TestMetaFactory< \
|
|
||||||
GTEST_TEST_CLASS_NAME_(\
|
|
||||||
test_case_name, test_name)>()); \
|
|
||||||
return 0; \
|
|
||||||
} \
|
|
||||||
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
|
||||||
}; \
|
|
||||||
int GTEST_TEST_CLASS_NAME_(test_case_name, \
|
|
||||||
test_name)::gtest_registering_dummy_ = \
|
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
|
||||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
|
||||||
|
|
||||||
// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user
|
|
||||||
// to specify a function or functor that generates custom test name suffixes
|
|
||||||
// based on the test parameters. The function should accept one argument of
|
|
||||||
// type testing::TestParamInfo<class ParamType>, and return std::string.
|
|
||||||
//
|
|
||||||
// testing::PrintToStringParamName is a builtin test suffix generator that
|
|
||||||
// returns the value of testing::PrintToString(GetParam()).
|
|
||||||
//
|
|
||||||
// Note: test names must be non-empty, unique, and may only contain ASCII
|
|
||||||
// alphanumeric characters or underscore. Because PrintToString adds quotes
|
|
||||||
// to std::string and C strings, it won't work for these types.
|
|
||||||
|
|
||||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
|
||||||
static ::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
|
||||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
|
||||||
static ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
|
||||||
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
|
||||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
|
||||||
(__VA_ARGS__)(info); \
|
|
||||||
} \
|
|
||||||
static int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
|
||||||
#test_case_name, \
|
|
||||||
::testing::internal::CodeLocation(\
|
|
||||||
__FILE__, __LINE__))->AddTestCaseInstantiation(\
|
|
||||||
#prefix, \
|
|
||||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
|
||||||
>est_##prefix##test_case_name##_EvalGenerateName_, \
|
|
||||||
__FILE__, __LINE__)
|
|
||||||
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
|
||||||
@@ -100,17 +100,16 @@
|
|||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "gtest/internal/gtest-port.h"
|
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
# include <tuple>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GTEST_HAS_ABSL
|
#if GTEST_HAS_ABSL
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
@@ -152,9 +151,10 @@ class TypeWithoutFormatter {
|
|||||||
public:
|
public:
|
||||||
// This default version is called when kTypeKind is kOtherType.
|
// This default version is called when kTypeKind is kOtherType.
|
||||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||||
PrintBytesInObjectTo(static_cast<const unsigned char*>(
|
PrintBytesInObjectTo(
|
||||||
reinterpret_cast<const void*>(&value)),
|
static_cast<const unsigned char*>(
|
||||||
sizeof(value), os);
|
reinterpret_cast<const void*>(std::addressof(value))),
|
||||||
|
sizeof(value), os);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -233,12 +233,12 @@ template <typename Char, typename CharTraits, typename T>
|
|||||||
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
||||||
TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
|
TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
|
||||||
? kProtobuf
|
? kProtobuf
|
||||||
: internal::ImplicitlyConvertible<
|
: std::is_convertible<
|
||||||
const T&, internal::BiggestInt>::value
|
const T&, internal::BiggestInt>::value
|
||||||
? kConvertibleToInteger
|
? kConvertibleToInteger
|
||||||
:
|
:
|
||||||
#if GTEST_HAS_ABSL
|
#if GTEST_HAS_ABSL
|
||||||
internal::ImplicitlyConvertible<
|
std::is_convertible<
|
||||||
const T&, absl::string_view>::value
|
const T&, absl::string_view>::value
|
||||||
? kConvertibleToStringView
|
? kConvertibleToStringView
|
||||||
:
|
:
|
||||||
@@ -358,16 +358,6 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
|||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_STRING
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_WSTRING
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
||||||
@@ -448,7 +438,7 @@ void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
|
void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
|
||||||
T* p, ::std::ostream* os) {
|
T* p, ::std::ostream* os) {
|
||||||
if (p == NULL) {
|
if (p == nullptr) {
|
||||||
*os << "NULL";
|
*os << "NULL";
|
||||||
} else {
|
} else {
|
||||||
// T is not a function type. We just call << to print p,
|
// T is not a function type. We just call << to print p,
|
||||||
@@ -460,7 +450,7 @@ void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
|
void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
|
||||||
T* p, ::std::ostream* os) {
|
T* p, ::std::ostream* os) {
|
||||||
if (p == NULL) {
|
if (p == nullptr) {
|
||||||
*os << "NULL";
|
*os << "NULL";
|
||||||
} else {
|
} else {
|
||||||
// T is a function type, so '*os << p' doesn't do what we want
|
// T is a function type, so '*os << p' doesn't do what we want
|
||||||
@@ -515,13 +505,9 @@ void PrintTo(const T& value, ::std::ostream* os) {
|
|||||||
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
|
||||||
!IsRecursiveContainer<T>::value
|
!IsRecursiveContainer<T>::value
|
||||||
? kPrintContainer
|
? kPrintContainer
|
||||||
: !is_pointer<T>::value
|
: !std::is_pointer<T>::value
|
||||||
? kPrintOther
|
? kPrintOther
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
: std::is_function<typename std::remove_pointer<T>::type>::value
|
: std::is_function<typename std::remove_pointer<T>::type>::value
|
||||||
#else
|
|
||||||
: !internal::ImplicitlyConvertible<T, const void*>::value
|
|
||||||
#endif
|
|
||||||
? kPrintFunctionPointer
|
? kPrintFunctionPointer
|
||||||
: kPrintPointer > (),
|
: kPrintPointer > (),
|
||||||
value, os);
|
value, os);
|
||||||
@@ -603,27 +589,13 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for ::string and ::std::string.
|
// Overloads for ::std::string.
|
||||||
#if GTEST_HAS_GLOBAL_STRING
|
|
||||||
GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);
|
|
||||||
inline void PrintTo(const ::string& s, ::std::ostream* os) {
|
|
||||||
PrintStringTo(s, os);
|
|
||||||
}
|
|
||||||
#endif // GTEST_HAS_GLOBAL_STRING
|
|
||||||
|
|
||||||
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
|
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||||
PrintStringTo(s, os);
|
PrintStringTo(s, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for ::wstring and ::std::wstring.
|
// Overloads for ::std::wstring.
|
||||||
#if GTEST_HAS_GLOBAL_WSTRING
|
|
||||||
GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
|
|
||||||
inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
|
|
||||||
PrintWideStringTo(s, os);
|
|
||||||
}
|
|
||||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
|
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
|
||||||
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||||
@@ -638,99 +610,38 @@ inline void PrintTo(absl::string_view sp, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
#endif // GTEST_HAS_ABSL
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
|
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
template <typename T>
|
||||||
|
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
|
||||||
|
UniversalPrinter<T&>::Print(ref.get(), os);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function for printing a tuple. T must be instantiated with
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
// a tuple type.
|
// a tuple type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintTupleTo(const T& t, ::std::ostream* os);
|
void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
|
||||||
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
::std::ostream*) {}
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE
|
template <typename T, size_t I>
|
||||||
// Overload for ::std::tr1::tuple. Needed for printing function arguments,
|
void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
|
||||||
// which are packed as tuples.
|
::std::ostream* os) {
|
||||||
|
PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
|
||||||
// Overloaded PrintTo() for tuples of various arities. We support
|
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
||||||
// tuples of up-to 10 fields. The following implementation works
|
if (I > 1) {
|
||||||
// regardless of whether tr1::tuple is implemented using the
|
GTEST_INTENTIONAL_CONST_COND_POP_()
|
||||||
// non-standard variadic template feature or not.
|
*os << ", ";
|
||||||
|
}
|
||||||
inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
|
UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
|
||||||
PrintTupleTo(t, os);
|
std::get<I - 1>(t), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
|
|
||||||
::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
||||||
typename T6>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
|
|
||||||
::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
||||||
typename T6, typename T7>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
|
|
||||||
::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
||||||
typename T6, typename T7, typename T8>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
|
|
||||||
::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
||||||
typename T6, typename T7, typename T8, typename T9>
|
|
||||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
|
|
||||||
::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
||||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
|
||||||
void PrintTo(
|
|
||||||
const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
|
|
||||||
::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
#endif // GTEST_HAS_TR1_TUPLE
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
|
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
|
||||||
PrintTupleTo(t, os);
|
*os << "(";
|
||||||
|
PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
|
||||||
|
*os << ")";
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
// Overload for std::pair.
|
// Overload for std::pair.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
@@ -826,7 +737,6 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
|
|||||||
// If the array has more than kThreshold elements, we'll have to
|
// If the array has more than kThreshold elements, we'll have to
|
||||||
// omit some details by printing only the first and the last
|
// omit some details by printing only the first and the last
|
||||||
// kChunkSize elements.
|
// kChunkSize elements.
|
||||||
// FIXME: let the user control the threshold using a flag.
|
|
||||||
if (len <= kThreshold) {
|
if (len <= kThreshold) {
|
||||||
PrintRawArrayTo(begin, len, os);
|
PrintRawArrayTo(begin, len, os);
|
||||||
} else {
|
} else {
|
||||||
@@ -905,7 +815,7 @@ template <>
|
|||||||
class UniversalTersePrinter<const char*> {
|
class UniversalTersePrinter<const char*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const char* str, ::std::ostream* os) {
|
static void Print(const char* str, ::std::ostream* os) {
|
||||||
if (str == NULL) {
|
if (str == nullptr) {
|
||||||
*os << "NULL";
|
*os << "NULL";
|
||||||
} else {
|
} else {
|
||||||
UniversalPrint(std::string(str), os);
|
UniversalPrint(std::string(str), os);
|
||||||
@@ -925,7 +835,7 @@ template <>
|
|||||||
class UniversalTersePrinter<const wchar_t*> {
|
class UniversalTersePrinter<const wchar_t*> {
|
||||||
public:
|
public:
|
||||||
static void Print(const wchar_t* str, ::std::ostream* os) {
|
static void Print(const wchar_t* str, ::std::ostream* os) {
|
||||||
if (str == NULL) {
|
if (str == nullptr) {
|
||||||
*os << "NULL";
|
*os << "NULL";
|
||||||
} else {
|
} else {
|
||||||
UniversalPrint(::std::wstring(str), os);
|
UniversalPrint(::std::wstring(str), os);
|
||||||
@@ -961,109 +871,20 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
|
|||||||
|
|
||||||
typedef ::std::vector< ::std::string> Strings;
|
typedef ::std::vector< ::std::string> Strings;
|
||||||
|
|
||||||
// TuplePolicy<TupleT> must provide:
|
|
||||||
// - tuple_size
|
|
||||||
// size of tuple TupleT.
|
|
||||||
// - get<size_t I>(const TupleT& t)
|
|
||||||
// static function extracting element I of tuple TupleT.
|
|
||||||
// - tuple_element<size_t I>::type
|
|
||||||
// type of element I of tuple TupleT.
|
|
||||||
template <typename TupleT>
|
|
||||||
struct TuplePolicy;
|
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE
|
|
||||||
template <typename TupleT>
|
|
||||||
struct TuplePolicy {
|
|
||||||
typedef TupleT Tuple;
|
|
||||||
static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value;
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
struct tuple_element : ::std::tr1::tuple_element<static_cast<int>(I), Tuple> {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
static typename AddReference<const typename ::std::tr1::tuple_element<
|
|
||||||
static_cast<int>(I), Tuple>::type>::type
|
|
||||||
get(const Tuple& tuple) {
|
|
||||||
return ::std::tr1::get<I>(tuple);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename TupleT>
|
|
||||||
const size_t TuplePolicy<TupleT>::tuple_size;
|
|
||||||
#endif // GTEST_HAS_TR1_TUPLE
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
template <typename... Types>
|
|
||||||
struct TuplePolicy< ::std::tuple<Types...> > {
|
|
||||||
typedef ::std::tuple<Types...> Tuple;
|
|
||||||
static const size_t tuple_size = ::std::tuple_size<Tuple>::value;
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
struct tuple_element : ::std::tuple_element<I, Tuple> {};
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
static const typename ::std::tuple_element<I, Tuple>::type& get(
|
|
||||||
const Tuple& tuple) {
|
|
||||||
return ::std::get<I>(tuple);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename... Types>
|
|
||||||
const size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size;
|
|
||||||
#endif // GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
|
||||||
// This helper template allows PrintTo() for tuples and
|
|
||||||
// UniversalTersePrintTupleFieldsToStrings() to be defined by
|
|
||||||
// induction on the number of tuple fields. The idea is that
|
|
||||||
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
|
||||||
// fields in tuple t, and can be defined in terms of
|
|
||||||
// TuplePrefixPrinter<N - 1>.
|
|
||||||
//
|
|
||||||
// The inductive case.
|
|
||||||
template <size_t N>
|
|
||||||
struct TuplePrefixPrinter {
|
|
||||||
// Prints the first N fields of a tuple.
|
|
||||||
template <typename Tuple>
|
|
||||||
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
|
||||||
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
|
|
||||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
|
||||||
if (N > 1) {
|
|
||||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
|
||||||
*os << ", ";
|
|
||||||
}
|
|
||||||
UniversalPrinter<
|
|
||||||
typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type>
|
|
||||||
::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tersely prints the first N fields of a tuple to a string vector,
|
// Tersely prints the first N fields of a tuple to a string vector,
|
||||||
// one element for each field.
|
// one element for each field.
|
||||||
template <typename Tuple>
|
|
||||||
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
|
||||||
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
|
|
||||||
::std::stringstream ss;
|
|
||||||
UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss);
|
|
||||||
strings->push_back(ss.str());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Base case.
|
|
||||||
template <>
|
|
||||||
struct TuplePrefixPrinter<0> {
|
|
||||||
template <typename Tuple>
|
|
||||||
static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
|
|
||||||
|
|
||||||
template <typename Tuple>
|
|
||||||
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper function for printing a tuple.
|
|
||||||
// Tuple must be either std::tr1::tuple or std::tuple type.
|
|
||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
|
void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
|
||||||
*os << "(";
|
Strings*) {}
|
||||||
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os);
|
template <typename Tuple, size_t I>
|
||||||
*os << ")";
|
void TersePrintPrefixToStrings(const Tuple& t,
|
||||||
|
std::integral_constant<size_t, I>,
|
||||||
|
Strings* strings) {
|
||||||
|
TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
|
||||||
|
strings);
|
||||||
|
::std::stringstream ss;
|
||||||
|
UniversalTersePrint(std::get<I - 1>(t), &ss);
|
||||||
|
strings->push_back(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints the fields of a tuple tersely to a string vector, one
|
// Prints the fields of a tuple tersely to a string vector, one
|
||||||
@@ -1072,11 +893,11 @@ void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
|
|||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
||||||
Strings result;
|
Strings result;
|
||||||
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::
|
TersePrintPrefixToStrings(
|
||||||
TersePrintPrefixToStrings(value, &result);
|
value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
|
||||||
|
&result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
|||||||
@@ -72,14 +72,15 @@ class GTEST_API_ ScopedFakeTestPartResultReporter
|
|||||||
TestPartResultArray* result);
|
TestPartResultArray* result);
|
||||||
|
|
||||||
// The d'tor restores the previous test part result reporter.
|
// The d'tor restores the previous test part result reporter.
|
||||||
virtual ~ScopedFakeTestPartResultReporter();
|
~ScopedFakeTestPartResultReporter() override;
|
||||||
|
|
||||||
// Appends the TestPartResult object to the TestPartResultArray
|
// Appends the TestPartResult object to the TestPartResultArray
|
||||||
// received in the constructor.
|
// received in the constructor.
|
||||||
//
|
//
|
||||||
// This method is from the TestPartResultReporterInterface
|
// This method is from the TestPartResultReporterInterface
|
||||||
// interface.
|
// interface.
|
||||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
void ReportTestPartResult(const TestPartResult& result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
|||||||
@@ -53,22 +53,20 @@ class GTEST_API_ TestPartResult {
|
|||||||
enum Type {
|
enum Type {
|
||||||
kSuccess, // Succeeded.
|
kSuccess, // Succeeded.
|
||||||
kNonFatalFailure, // Failed but the test can continue.
|
kNonFatalFailure, // Failed but the test can continue.
|
||||||
kFatalFailure // Failed and the test should be terminated.
|
kFatalFailure, // Failed and the test should be terminated.
|
||||||
|
kSkip // Skipped.
|
||||||
};
|
};
|
||||||
|
|
||||||
// C'tor. TestPartResult does NOT have a default constructor.
|
// C'tor. TestPartResult does NOT have a default constructor.
|
||||||
// Always use this constructor (with parameters) to create a
|
// Always use this constructor (with parameters) to create a
|
||||||
// TestPartResult object.
|
// TestPartResult object.
|
||||||
TestPartResult(Type a_type,
|
TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
|
||||||
const char* a_file_name,
|
|
||||||
int a_line_number,
|
|
||||||
const char* a_message)
|
const char* a_message)
|
||||||
: type_(a_type),
|
: type_(a_type),
|
||||||
file_name_(a_file_name == NULL ? "" : a_file_name),
|
file_name_(a_file_name == nullptr ? "" : a_file_name),
|
||||||
line_number_(a_line_number),
|
line_number_(a_line_number),
|
||||||
summary_(ExtractSummary(a_message)),
|
summary_(ExtractSummary(a_message)),
|
||||||
message_(a_message) {
|
message_(a_message) {}
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the outcome of the test part.
|
// Gets the outcome of the test part.
|
||||||
Type type() const { return type_; }
|
Type type() const { return type_; }
|
||||||
@@ -76,7 +74,7 @@ class GTEST_API_ TestPartResult {
|
|||||||
// Gets the name of the source file where the test part took place, or
|
// Gets the name of the source file where the test part took place, or
|
||||||
// NULL if it's unknown.
|
// NULL if it's unknown.
|
||||||
const char* file_name() const {
|
const char* file_name() const {
|
||||||
return file_name_.empty() ? NULL : file_name_.c_str();
|
return file_name_.empty() ? nullptr : file_name_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the line in the source file where the test part took place,
|
// Gets the line in the source file where the test part took place,
|
||||||
@@ -89,18 +87,21 @@ class GTEST_API_ TestPartResult {
|
|||||||
// Gets the message associated with the test part.
|
// Gets the message associated with the test part.
|
||||||
const char* message() const { return message_.c_str(); }
|
const char* message() const { return message_.c_str(); }
|
||||||
|
|
||||||
// Returns true iff the test part passed.
|
// Returns true if and only if the test part was skipped.
|
||||||
|
bool skipped() const { return type_ == kSkip; }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part passed.
|
||||||
bool passed() const { return type_ == kSuccess; }
|
bool passed() const { return type_ == kSuccess; }
|
||||||
|
|
||||||
// Returns true iff the test part failed.
|
// Returns true if and only if the test part non-fatally failed.
|
||||||
bool failed() const { return type_ != kSuccess; }
|
|
||||||
|
|
||||||
// Returns true iff the test part non-fatally failed.
|
|
||||||
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||||
|
|
||||||
// Returns true iff the test part fatally failed.
|
// Returns true if and only if the test part fatally failed.
|
||||||
bool fatally_failed() const { return type_ == kFatalFailure; }
|
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||||
|
|
||||||
|
// Returns true if and only if the test part failed.
|
||||||
|
bool failed() const { return fatally_failed() || nonfatally_failed(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type type_;
|
Type type_;
|
||||||
|
|
||||||
@@ -164,8 +165,8 @@ class GTEST_API_ HasNewFatalFailureHelper
|
|||||||
: public TestPartResultReporterInterface {
|
: public TestPartResultReporterInterface {
|
||||||
public:
|
public:
|
||||||
HasNewFatalFailureHelper();
|
HasNewFatalFailureHelper();
|
||||||
virtual ~HasNewFatalFailureHelper();
|
~HasNewFatalFailureHelper() override;
|
||||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
void ReportTestPartResult(const TestPartResult& result) override;
|
||||||
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
||||||
private:
|
private:
|
||||||
bool has_new_fatal_failure_;
|
bool has_new_fatal_failure_;
|
||||||
|
|||||||
@@ -52,22 +52,22 @@ class FooTest : public testing::Test {
|
|||||||
T value_;
|
T value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Next, associate a list of types with the test case, which will be
|
// Next, associate a list of types with the test suite, which will be
|
||||||
// repeated for each type in the list. The typedef is necessary for
|
// repeated for each type in the list. The typedef is necessary for
|
||||||
// the macro to parse correctly.
|
// the macro to parse correctly.
|
||||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||||
TYPED_TEST_CASE(FooTest, MyTypes);
|
TYPED_TEST_SUITE(FooTest, MyTypes);
|
||||||
|
|
||||||
// If the type list contains only one type, you can write that type
|
// If the type list contains only one type, you can write that type
|
||||||
// directly without Types<...>:
|
// directly without Types<...>:
|
||||||
// TYPED_TEST_CASE(FooTest, int);
|
// TYPED_TEST_SUITE(FooTest, int);
|
||||||
|
|
||||||
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||||
// tests for this test case as you want.
|
// tests for this test suite as you want.
|
||||||
TYPED_TEST(FooTest, DoesBlah) {
|
TYPED_TEST(FooTest, DoesBlah) {
|
||||||
// Inside a test, refer to TypeParam to get the type parameter.
|
// Inside a test, refer to the special name TypeParam to get the type
|
||||||
// Since we are inside a derived class template, C++ requires use to
|
// parameter. Since we are inside a derived class template, C++ requires
|
||||||
// visit the members of FooTest via 'this'.
|
// us to visit the members of FooTest via 'this'.
|
||||||
TypeParam n = this->value_;
|
TypeParam n = this->value_;
|
||||||
|
|
||||||
// To visit static members of the fixture, add the TestFixture::
|
// To visit static members of the fixture, add the TestFixture::
|
||||||
@@ -83,7 +83,7 @@ TYPED_TEST(FooTest, DoesBlah) {
|
|||||||
|
|
||||||
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
||||||
|
|
||||||
// TYPED_TEST_CASE takes an optional third argument which allows to specify a
|
// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
|
||||||
// class that generates custom test name suffixes based on the type. This should
|
// class that generates custom test name suffixes based on the type. This should
|
||||||
// be a class which has a static template function GetName(int index) returning
|
// be a class which has a static template function GetName(int index) returning
|
||||||
// a string for each type. The provided integer index equals the index of the
|
// a string for each type. The provided integer index equals the index of the
|
||||||
@@ -99,7 +99,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... }
|
|||||||
// if (std::is_same<T, unsigned int>()) return "unsignedInt";
|
// if (std::is_same<T, unsigned int>()) return "unsignedInt";
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
// TYPED_TEST_CASE(FooTest, MyTypes, MyTypeNames);
|
// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
|
||||||
|
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
@@ -126,13 +126,13 @@ class FooTest : public testing::Test {
|
|||||||
...
|
...
|
||||||
};
|
};
|
||||||
|
|
||||||
// Next, declare that you will define a type-parameterized test case
|
// Next, declare that you will define a type-parameterized test suite
|
||||||
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||||
// prefer):
|
// prefer):
|
||||||
TYPED_TEST_CASE_P(FooTest);
|
TYPED_TEST_SUITE_P(FooTest);
|
||||||
|
|
||||||
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||||
// for this type-parameterized test case as you want.
|
// for this type-parameterized test suite as you want.
|
||||||
TYPED_TEST_P(FooTest, DoesBlah) {
|
TYPED_TEST_P(FooTest, DoesBlah) {
|
||||||
// Inside a test, refer to TypeParam to get the type parameter.
|
// Inside a test, refer to TypeParam to get the type parameter.
|
||||||
TypeParam n = 0;
|
TypeParam n = 0;
|
||||||
@@ -143,10 +143,10 @@ TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
|||||||
|
|
||||||
// Now the tricky part: you need to register all test patterns before
|
// Now the tricky part: you need to register all test patterns before
|
||||||
// you can instantiate them. The first argument of the macro is the
|
// you can instantiate them. The first argument of the macro is the
|
||||||
// test case name; the rest are the names of the tests in this test
|
// test suite name; the rest are the names of the tests in this test
|
||||||
// case.
|
// case.
|
||||||
REGISTER_TYPED_TEST_CASE_P(FooTest,
|
REGISTER_TYPED_TEST_SUITE_P(FooTest,
|
||||||
DoesBlah, HasPropertyA);
|
DoesBlah, HasPropertyA);
|
||||||
|
|
||||||
// Finally, you are free to instantiate the pattern with the types you
|
// Finally, you are free to instantiate the pattern with the types you
|
||||||
// want. If you put the above code in a header file, you can #include
|
// want. If you put the above code in a header file, you can #include
|
||||||
@@ -154,19 +154,19 @@ REGISTER_TYPED_TEST_CASE_P(FooTest,
|
|||||||
//
|
//
|
||||||
// To distinguish different instances of the pattern, the first
|
// To distinguish different instances of the pattern, the first
|
||||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||||
// to the actual test case name. Remember to pick unique prefixes for
|
// to the actual test suite name. Remember to pick unique prefixes for
|
||||||
// different instances.
|
// different instances.
|
||||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||||
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||||
|
|
||||||
// If the type list contains only one type, you can write that type
|
// If the type list contains only one type, you can write that type
|
||||||
// directly without Types<...>:
|
// directly without Types<...>:
|
||||||
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
|
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
|
||||||
//
|
//
|
||||||
// Similar to the optional argument of TYPED_TEST_CASE above,
|
// Similar to the optional argument of TYPED_TEST_SUITE above,
|
||||||
// INSTANTIATE_TEST_CASE_P takes an optional fourth argument which allows to
|
// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
|
||||||
// generate custom names.
|
// generate custom names.
|
||||||
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes, MyTypeNames);
|
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
|
||||||
|
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
@@ -180,21 +180,18 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
|||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// Expands to the name of the typedef for the type parameters of the
|
// Expands to the name of the typedef for the type parameters of the
|
||||||
// given test case.
|
// given test suite.
|
||||||
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
|
#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
|
||||||
|
|
||||||
// Expands to the name of the typedef for the NameGenerator, responsible for
|
// Expands to the name of the typedef for the NameGenerator, responsible for
|
||||||
// creating the suffixes of the name.
|
// creating the suffixes of the name.
|
||||||
#define GTEST_NAME_GENERATOR_(TestCaseName) \
|
#define GTEST_NAME_GENERATOR_(TestSuiteName) \
|
||||||
gtest_type_params_##TestCaseName##_NameGenerator
|
gtest_type_params_##TestSuiteName##_NameGenerator
|
||||||
|
|
||||||
// The 'Types' template argument below must have spaces around it
|
#define TYPED_TEST_SUITE(CaseName, Types, ...) \
|
||||||
// since some compilers may choke on '>>' when passing a template
|
typedef ::testing::internal::TypeList<Types>::type GTEST_TYPE_PARAMS_( \
|
||||||
// instance (e.g. Types<int>)
|
CaseName); \
|
||||||
# define TYPED_TEST_CASE(CaseName, Types, ...) \
|
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
||||||
typedef ::testing::internal::TypeList< Types >::type GTEST_TYPE_PARAMS_( \
|
|
||||||
CaseName); \
|
|
||||||
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) \
|
||||||
@@ -224,6 +221,13 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
|||||||
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
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define TYPED_TEST_CASE \
|
||||||
|
static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
|
||||||
|
TYPED_TEST_SUITE
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
#endif // GTEST_HAS_TYPED_TEST
|
#endif // GTEST_HAS_TYPED_TEST
|
||||||
|
|
||||||
// Implements type-parameterized tests.
|
// Implements type-parameterized tests.
|
||||||
@@ -233,73 +237,93 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
|||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// Expands to the namespace name that the type-parameterized tests for
|
// Expands to the namespace name that the type-parameterized tests for
|
||||||
// the given type-parameterized test case are defined in. The exact
|
// the given type-parameterized test suite are defined in. The exact
|
||||||
// name of the namespace is subject to change without notice.
|
// name of the namespace is subject to change without notice.
|
||||||
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
|
#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
|
||||||
gtest_case_##TestCaseName##_
|
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// Expands to the name of the variable used to remember the names of
|
// Expands to the name of the variable used to remember the names of
|
||||||
// the defined tests in the given test case.
|
// the defined tests in the given test suite.
|
||||||
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
|
#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
|
||||||
gtest_typed_test_case_p_state_##TestCaseName##_
|
gtest_typed_test_suite_p_state_##TestSuiteName##_
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||||
//
|
//
|
||||||
// Expands to the name of the variable used to remember the names of
|
// Expands to the name of the variable used to remember the names of
|
||||||
// the registered tests in the given test case.
|
// the registered tests in the given test suite.
|
||||||
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
|
#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
|
||||||
gtest_registered_test_names_##TestCaseName##_
|
gtest_registered_test_names_##TestSuiteName##_
|
||||||
|
|
||||||
// The variables defined in the type-parameterized test macros are
|
// The variables defined in the type-parameterized test macros are
|
||||||
// static as typically these macros are used in a .h file that can be
|
// static as typically these macros are used in a .h file that can be
|
||||||
// #included in multiple translation units linked together.
|
// #included in multiple translation units linked together.
|
||||||
# define TYPED_TEST_CASE_P(CaseName) \
|
#define TYPED_TEST_SUITE_P(SuiteName) \
|
||||||
static ::testing::internal::TypedTestCasePState \
|
static ::testing::internal::TypedTestSuitePState \
|
||||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
|
||||||
|
|
||||||
# define TYPED_TEST_P(CaseName, TestName) \
|
// Legacy API is deprecated but still available
|
||||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
template <typename gtest_TypeParam_> \
|
#define TYPED_TEST_CASE_P \
|
||||||
class TestName : public CaseName<gtest_TypeParam_> { \
|
static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
|
||||||
private: \
|
TYPED_TEST_SUITE_P
|
||||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
typedef gtest_TypeParam_ TypeParam; \
|
|
||||||
virtual void TestBody(); \
|
|
||||||
}; \
|
|
||||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
|
||||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
|
|
||||||
__FILE__, __LINE__, #CaseName, #TestName); \
|
|
||||||
} \
|
|
||||||
template <typename gtest_TypeParam_> \
|
|
||||||
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
|
|
||||||
|
|
||||||
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
|
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
|
template <typename gtest_TypeParam_> \
|
||||||
} \
|
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) \
|
private: \
|
||||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames( \
|
typedef gtest_TypeParam_ TypeParam; \
|
||||||
__FILE__, __LINE__, #__VA_ARGS__)
|
virtual void TestBody(); \
|
||||||
|
}; \
|
||||||
|
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||||
|
__FILE__, __LINE__, #SuiteName, #TestName); \
|
||||||
|
} \
|
||||||
|
template <typename gtest_TypeParam_> \
|
||||||
|
void GTEST_SUITE_NAMESPACE_( \
|
||||||
|
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
// The 'Types' template argument below must have spaces around it
|
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
|
||||||
// since some compilers may choke on '>>' when passing a template
|
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||||
// instance (e.g. Types<int>)
|
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
|
||||||
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types, ...) \
|
} \
|
||||||
static bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
|
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||||
::testing::internal::TypeParameterizedTestCase< \
|
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
CaseName, GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||||
::testing::internal::TypeList< Types >::type>:: \
|
__FILE__, __LINE__, #__VA_ARGS__)
|
||||||
Register(#Prefix, \
|
|
||||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
// Legacy API is deprecated but still available
|
||||||
>EST_TYPED_TEST_CASE_P_STATE_(CaseName), #CaseName, \
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
GTEST_REGISTERED_TEST_NAMES_(CaseName), \
|
#define REGISTER_TYPED_TEST_CASE_P \
|
||||||
::testing::internal::GenerateNames< \
|
static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
|
||||||
::testing::internal::NameGeneratorSelector< \
|
""); \
|
||||||
__VA_ARGS__>::type, \
|
REGISTER_TYPED_TEST_SUITE_P
|
||||||
::testing::internal::TypeList< Types >::type>())
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||||
|
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
|
::testing::internal::TypeParameterizedTestSuite< \
|
||||||
|
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||||
|
::testing::internal::TypeList<Types>::type>:: \
|
||||||
|
Register(#Prefix, \
|
||||||
|
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||||
|
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \
|
||||||
|
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||||
|
::testing::internal::GenerateNames< \
|
||||||
|
::testing::internal::NameGeneratorSelector< \
|
||||||
|
__VA_ARGS__>::type, \
|
||||||
|
::testing::internal::TypeList<Types>::type>())
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
#define INSTANTIATE_TYPED_TEST_CASE_P \
|
||||||
|
static_assert( \
|
||||||
|
::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
|
||||||
|
INSTANTIATE_TYPED_TEST_SUITE_P
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
#endif // GTEST_HAS_TYPED_TEST_P
|
#endif // GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,11 +27,10 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// This file is AUTOMATICALLY GENERATED on 01/02/2018 by command
|
// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
|
||||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
// Implements a family of generic predicate assertion macros.
|
// Implements a family of generic predicate assertion macros.
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
// GOOGLETEST_CM0001 DO NOT DELETE
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||||
@@ -67,6 +66,8 @@ namespace testing {
|
|||||||
// We also define the EXPECT_* variations.
|
// We also define the EXPECT_* variations.
|
||||||
//
|
//
|
||||||
// For now we only support predicates whose arity is at most 5.
|
// For now we only support predicates whose arity is at most 5.
|
||||||
|
// Please email googletestframework@googlegroups.com if you need
|
||||||
|
// support for higher arities.
|
||||||
|
|
||||||
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||||
// in this file reduce. Don't use this in your code.
|
// in this file reduce. Don't use this in your code.
|
||||||
@@ -89,9 +90,10 @@ AssertionResult AssertPred1Helper(const char* pred_text,
|
|||||||
const T1& v1) {
|
const T1& v1) {
|
||||||
if (pred(v1)) return AssertionSuccess();
|
if (pred(v1)) return AssertionSuccess();
|
||||||
|
|
||||||
return AssertionFailure() << pred_text << "("
|
return AssertionFailure()
|
||||||
<< e1 << ") evaluates to false, where"
|
<< pred_text << "(" << e1 << ") evaluates to false, where"
|
||||||
<< "\n" << e1 << " evaluates to " << v1;
|
<< "\n"
|
||||||
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||||
@@ -133,11 +135,12 @@ AssertionResult AssertPred2Helper(const char* pred_text,
|
|||||||
const T2& v2) {
|
const T2& v2) {
|
||||||
if (pred(v1, v2)) return AssertionSuccess();
|
if (pred(v1, v2)) return AssertionSuccess();
|
||||||
|
|
||||||
return AssertionFailure() << pred_text << "("
|
return AssertionFailure()
|
||||||
<< e1 << ", "
|
<< pred_text << "(" << e1 << ", " << e2
|
||||||
<< e2 << ") evaluates to false, where"
|
<< ") evaluates to false, where"
|
||||||
<< "\n" << e1 << " evaluates to " << v1
|
<< "\n"
|
||||||
<< "\n" << e2 << " evaluates to " << v2;
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||||
@@ -184,13 +187,13 @@ AssertionResult AssertPred3Helper(const char* pred_text,
|
|||||||
const T3& v3) {
|
const T3& v3) {
|
||||||
if (pred(v1, v2, v3)) return AssertionSuccess();
|
if (pred(v1, v2, v3)) return AssertionSuccess();
|
||||||
|
|
||||||
return AssertionFailure() << pred_text << "("
|
return AssertionFailure()
|
||||||
<< e1 << ", "
|
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3
|
||||||
<< e2 << ", "
|
<< ") evaluates to false, where"
|
||||||
<< e3 << ") evaluates to false, where"
|
<< "\n"
|
||||||
<< "\n" << e1 << " evaluates to " << v1
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
<< "\n" << e2 << " evaluates to " << v2
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||||
<< "\n" << e3 << " evaluates to " << v3;
|
<< e3 << " evaluates to " << ::testing::PrintToString(v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||||
@@ -242,15 +245,14 @@ AssertionResult AssertPred4Helper(const char* pred_text,
|
|||||||
const T4& v4) {
|
const T4& v4) {
|
||||||
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
||||||
|
|
||||||
return AssertionFailure() << pred_text << "("
|
return AssertionFailure()
|
||||||
<< e1 << ", "
|
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
||||||
<< e2 << ", "
|
<< ") evaluates to false, where"
|
||||||
<< e3 << ", "
|
<< "\n"
|
||||||
<< e4 << ") evaluates to false, where"
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
<< "\n" << e1 << " evaluates to " << v1
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||||
<< "\n" << e2 << " evaluates to " << v2
|
<< e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
||||||
<< "\n" << e3 << " evaluates to " << v3
|
<< e4 << " evaluates to " << ::testing::PrintToString(v4);
|
||||||
<< "\n" << e4 << " evaluates to " << v4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||||
@@ -307,17 +309,15 @@ AssertionResult AssertPred5Helper(const char* pred_text,
|
|||||||
const T5& v5) {
|
const T5& v5) {
|
||||||
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
||||||
|
|
||||||
return AssertionFailure() << pred_text << "("
|
return AssertionFailure()
|
||||||
<< e1 << ", "
|
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
||||||
<< e2 << ", "
|
<< ", " << e5 << ") evaluates to false, where"
|
||||||
<< e3 << ", "
|
<< "\n"
|
||||||
<< e4 << ", "
|
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||||
<< e5 << ") evaluates to false, where"
|
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||||
<< "\n" << e1 << " evaluates to " << v1
|
<< e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
||||||
<< "\n" << e2 << " evaluates to " << v2
|
<< e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
|
||||||
<< "\n" << e3 << " evaluates to " << v3
|
<< e5 << " evaluates to " << ::testing::PrintToString(v5);
|
||||||
<< "\n" << e4 << " evaluates to " << v4
|
|
||||||
<< "\n" << e5 << " evaluates to " << v5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||||
|
|||||||
@@ -36,9 +36,11 @@
|
|||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||||
|
|
||||||
|
#include "gtest/gtest-matchers.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@@ -78,7 +80,7 @@ class GTEST_API_ DeathTest {
|
|||||||
// argument is set. If the death test should be skipped, the pointer
|
// argument is set. If the death test should be skipped, the pointer
|
||||||
// is set to NULL; otherwise, it is set to the address of a new concrete
|
// is set to NULL; otherwise, it is set to the address of a new concrete
|
||||||
// DeathTest object that controls the execution of the current test.
|
// DeathTest object that controls the execution of the current test.
|
||||||
static bool Create(const char* statement, const RE* regex,
|
static bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||||
const char* file, int line, DeathTest** test);
|
const char* file, int line, DeathTest** test);
|
||||||
DeathTest();
|
DeathTest();
|
||||||
virtual ~DeathTest() { }
|
virtual ~DeathTest() { }
|
||||||
@@ -144,21 +146,44 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|||||||
class DeathTestFactory {
|
class DeathTestFactory {
|
||||||
public:
|
public:
|
||||||
virtual ~DeathTestFactory() { }
|
virtual ~DeathTestFactory() { }
|
||||||
virtual bool Create(const char* statement, const RE* regex,
|
virtual bool Create(const char* statement,
|
||||||
const char* file, int line, DeathTest** test) = 0;
|
Matcher<const std::string&> matcher, const char* file,
|
||||||
|
int line, DeathTest** test) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A concrete DeathTestFactory implementation for normal use.
|
// A concrete DeathTestFactory implementation for normal use.
|
||||||
class DefaultDeathTestFactory : public DeathTestFactory {
|
class DefaultDeathTestFactory : public DeathTestFactory {
|
||||||
public:
|
public:
|
||||||
virtual bool Create(const char* statement, const RE* regex,
|
bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||||
const char* file, int line, DeathTest** test);
|
const char* file, int line, DeathTest** test) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns true if exit_status describes a process that was terminated
|
// Returns true if exit_status describes a process that was terminated
|
||||||
// by a signal, or exited normally with a nonzero exit code.
|
// by a signal, or exited normally with a nonzero exit code.
|
||||||
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
||||||
|
|
||||||
|
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
|
||||||
|
// and interpreted as a regex (rather than an Eq matcher) for legacy
|
||||||
|
// compatibility.
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
::testing::internal::RE regex) {
|
||||||
|
return ContainsRegex(regex.pattern());
|
||||||
|
}
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
|
||||||
|
return ContainsRegex(regex);
|
||||||
|
}
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
const ::std::string& regex) {
|
||||||
|
return ContainsRegex(regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
|
||||||
|
// used directly.
|
||||||
|
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||||
|
Matcher<const ::std::string&> matcher) {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
|
||||||
// Traps C++ exceptions escaping statement and reports them as test
|
// Traps C++ exceptions escaping statement and reports them as test
|
||||||
// failures. Note that trapping SEH exceptions is not implemented here.
|
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||||
# if GTEST_HAS_EXCEPTIONS
|
# if GTEST_HAS_EXCEPTIONS
|
||||||
@@ -186,38 +211,38 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
|||||||
|
|
||||||
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
||||||
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||||
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
|
#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \
|
||||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
if (::testing::internal::AlwaysTrue()) { \
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
const ::testing::internal::RE& gtest_regex = (regex); \
|
::testing::internal::DeathTest* gtest_dt; \
|
||||||
::testing::internal::DeathTest* gtest_dt; \
|
if (!::testing::internal::DeathTest::Create( \
|
||||||
if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \
|
#statement, \
|
||||||
__FILE__, __LINE__, >est_dt)) { \
|
::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \
|
||||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
__FILE__, __LINE__, >est_dt)) { \
|
||||||
} \
|
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||||
if (gtest_dt != NULL) { \
|
} \
|
||||||
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
|
if (gtest_dt != nullptr) { \
|
||||||
gtest_dt_ptr(gtest_dt); \
|
std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
|
||||||
switch (gtest_dt->AssumeRole()) { \
|
switch (gtest_dt->AssumeRole()) { \
|
||||||
case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
||||||
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
||||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||||
::testing::internal::DeathTest::ReturnSentinel \
|
::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
|
||||||
gtest_sentinel(gtest_dt); \
|
gtest_dt); \
|
||||||
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
||||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
default: \
|
default: \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} else \
|
} else \
|
||||||
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
|
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
|
||||||
fail(::testing::internal::DeathTest::LastMessage())
|
: fail(::testing::internal::DeathTest::LastMessage())
|
||||||
// The symbol "fail" here expands to something into which a message
|
// The symbol "fail" here expands to something into which a message
|
||||||
// can be streamed.
|
// can be streamed.
|
||||||
|
|
||||||
@@ -226,14 +251,13 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
|||||||
// must accept a streamed message even though the message is never printed.
|
// must accept a streamed message even though the message is never printed.
|
||||||
// The regex object is not evaluated, but it is used to prevent "unused"
|
// The regex object is not evaluated, but it is used to prevent "unused"
|
||||||
// warnings and to avoid an expression that doesn't compile in debug mode.
|
// warnings and to avoid an expression that doesn't compile in debug mode.
|
||||||
#define GTEST_EXECUTE_STATEMENT_(statement, regex) \
|
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
||||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||||
if (::testing::internal::AlwaysTrue()) { \
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||||
} else if (!::testing::internal::AlwaysTrue()) { \
|
} else if (!::testing::internal::AlwaysTrue()) { \
|
||||||
const ::testing::internal::RE& gtest_regex = (regex); \
|
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||||
static_cast<void>(gtest_regex); \
|
} else \
|
||||||
} else \
|
|
||||||
::testing::Message()
|
::testing::Message()
|
||||||
|
|
||||||
// A class representing the parsed contents of the
|
// A class representing the parsed contents of the
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class GTEST_API_ FilePath {
|
|||||||
const FilePath& base_name,
|
const FilePath& base_name,
|
||||||
const char* extension);
|
const char* extension);
|
||||||
|
|
||||||
// Returns true iff the path is "".
|
// Returns true if and only if the path is "".
|
||||||
bool IsEmpty() const { return pathname_.empty(); }
|
bool IsEmpty() const { return pathname_.empty(); }
|
||||||
|
|
||||||
// If input name has a trailing separator character, removes it and returns
|
// If input name has a trailing separator character, removes it and returns
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
@@ -79,7 +80,6 @@
|
|||||||
// Stringifies its argument.
|
// Stringifies its argument.
|
||||||
#define GTEST_STRINGIFY_(name) #name
|
#define GTEST_STRINGIFY_(name) #name
|
||||||
|
|
||||||
class ProtocolMessage;
|
|
||||||
namespace proto2 { class Message; }
|
namespace proto2 { class Message; }
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@@ -91,7 +91,7 @@ class Message; // Represents a failure message.
|
|||||||
class Test; // Represents a test.
|
class Test; // Represents a test.
|
||||||
class TestInfo; // Information about a test.
|
class TestInfo; // Information about a test.
|
||||||
class TestPartResult; // Result of a test part.
|
class TestPartResult; // Result of a test part.
|
||||||
class UnitTest; // A collection of test cases.
|
class UnitTest; // A collection of test suites.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
::std::string PrintToString(const T& value);
|
::std::string PrintToString(const T& value);
|
||||||
@@ -106,34 +106,22 @@ class UnitTestImpl; // Opaque implementation of UnitTest
|
|||||||
// stack trace.
|
// stack trace.
|
||||||
GTEST_API_ extern const char kStackTraceMarker[];
|
GTEST_API_ extern const char kStackTraceMarker[];
|
||||||
|
|
||||||
// Two overloaded helpers for checking at compile time whether an
|
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||||
// expression is a null pointer literal (i.e. NULL or any 0-valued
|
class IgnoredValue {
|
||||||
// compile-time integral constant). Their return values have
|
struct Sink {};
|
||||||
// different sizes, so we can use sizeof() to test which version is
|
public:
|
||||||
// picked by the compiler. These helpers have no implementations, as
|
// This constructor template allows any value to be implicitly
|
||||||
// we only need their signatures.
|
// converted to IgnoredValue. The object has no data member and
|
||||||
//
|
// doesn't try to remember anything about the argument. We
|
||||||
// Given IsNullLiteralHelper(x), the compiler will pick the first
|
// deliberately omit the 'explicit' keyword in order to allow the
|
||||||
// version if x can be implicitly converted to Secret*, and pick the
|
// conversion to be implicit.
|
||||||
// second version otherwise. Since Secret is a secret and incomplete
|
// Disable the conversion if T already has a magical conversion operator.
|
||||||
// type, the only expression a user can write that has type Secret* is
|
// Otherwise we get ambiguity.
|
||||||
// a null pointer literal. Therefore, we know that x is a null
|
template <typename T,
|
||||||
// pointer literal if and only if the first version is picked by the
|
typename std::enable_if<!std::is_convertible<T, Sink>::value,
|
||||||
// compiler.
|
int>::type = 0>
|
||||||
char IsNullLiteralHelper(Secret* p);
|
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||||
char (&IsNullLiteralHelper(...))[2]; // NOLINT
|
};
|
||||||
|
|
||||||
// A compile-time bool constant that is true if and only if x is a
|
|
||||||
// null pointer literal (i.e. NULL or any 0-valued compile-time
|
|
||||||
// integral constant).
|
|
||||||
#ifdef GTEST_ELLIPSIS_NEEDS_POD_
|
|
||||||
// We lose support for NULL detection where the compiler doesn't like
|
|
||||||
// passing non-POD classes through ellipsis (...).
|
|
||||||
# define GTEST_IS_NULL_LITERAL_(x) false
|
|
||||||
#else
|
|
||||||
# define GTEST_IS_NULL_LITERAL_(x) \
|
|
||||||
(sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
|
|
||||||
#endif // GTEST_ELLIPSIS_NEEDS_POD_
|
|
||||||
|
|
||||||
// Appends the user-supplied message to the Google-Test-generated message.
|
// Appends the user-supplied message to the Google-Test-generated message.
|
||||||
GTEST_API_ std::string AppendUserMessage(
|
GTEST_API_ std::string AppendUserMessage(
|
||||||
@@ -201,7 +189,7 @@ GTEST_API_ std::string DiffStrings(const std::string& left,
|
|||||||
// expected_value: "5"
|
// expected_value: "5"
|
||||||
// actual_value: "6"
|
// actual_value: "6"
|
||||||
//
|
//
|
||||||
// The ignoring_case parameter is true iff the assertion is a
|
// The ignoring_case parameter is true if and only if the assertion is a
|
||||||
// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
|
// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
|
||||||
// be inserted into the message.
|
// be inserted into the message.
|
||||||
GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
|
GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
|
||||||
@@ -330,15 +318,15 @@ class FloatingPoint {
|
|||||||
// 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 & u_.bits_; }
|
||||||
|
|
||||||
// Returns true iff 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 {
|
||||||
// It's a NAN if the exponent bits are all ones and the fraction
|
// It's a NAN if the exponent bits are all ones and the fraction
|
||||||
// bits are not entirely zeros.
|
// bits are not entirely zeros.
|
||||||
return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
|
return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff this number is at most kMaxUlps ULP's away from
|
// Returns true if and only if this number is at most kMaxUlps ULP's away
|
||||||
// rhs. In particular, this function:
|
// from rhs. In particular, this function:
|
||||||
//
|
//
|
||||||
// - 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.
|
||||||
@@ -409,7 +397,7 @@ typedef FloatingPoint<float> Float;
|
|||||||
typedef FloatingPoint<double> Double;
|
typedef FloatingPoint<double> Double;
|
||||||
|
|
||||||
// In order to catch the mistake of putting tests that use different
|
// In order to catch the mistake of putting tests that use different
|
||||||
// test fixture classes in the same test case, we need to assign
|
// test fixture classes in the same test suite, we need to assign
|
||||||
// unique IDs to fixture classes and compare them. The TypeId type is
|
// unique IDs to fixture classes and compare them. The TypeId type is
|
||||||
// used to hold such IDs. The user should treat TypeId as an opaque
|
// used to hold such IDs. The user should treat TypeId as an opaque
|
||||||
// type: the only operation allowed on TypeId values is to compare
|
// type: the only operation allowed on TypeId values is to compare
|
||||||
@@ -469,7 +457,7 @@ class TestFactoryBase {
|
|||||||
template <class TestClass>
|
template <class TestClass>
|
||||||
class TestFactoryImpl : public TestFactoryBase {
|
class TestFactoryImpl : public TestFactoryBase {
|
||||||
public:
|
public:
|
||||||
virtual Test* CreateTest() { return new TestClass; }
|
Test* CreateTest() override { return new TestClass; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
@@ -485,9 +473,9 @@ GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
|
|||||||
|
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
// Types of SetUpTestCase() and TearDownTestCase() functions.
|
// Types of SetUpTestSuite() and TearDownTestSuite() functions.
|
||||||
typedef void (*SetUpTestCaseFunc)();
|
using SetUpTestSuiteFunc = void (*)();
|
||||||
typedef void (*TearDownTestCaseFunc)();
|
using TearDownTestSuiteFunc = void (*)();
|
||||||
|
|
||||||
struct CodeLocation {
|
struct CodeLocation {
|
||||||
CodeLocation(const std::string& a_file, int a_line)
|
CodeLocation(const std::string& a_file, int a_line)
|
||||||
@@ -497,12 +485,64 @@ struct CodeLocation {
|
|||||||
int line;
|
int line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper to identify which setup function for TestCase / TestSuite to call.
|
||||||
|
// Only one function is allowed, either TestCase or TestSute but not both.
|
||||||
|
|
||||||
|
// Utility functions to help SuiteApiResolver
|
||||||
|
using SetUpTearDownSuiteFuncType = void (*)();
|
||||||
|
|
||||||
|
inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
|
||||||
|
SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {
|
||||||
|
return a == def ? nullptr : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
// Note that SuiteApiResolver inherits from T because
|
||||||
|
// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way
|
||||||
|
// SuiteApiResolver can access them.
|
||||||
|
struct SuiteApiResolver : T {
|
||||||
|
// testing::Test is only forward declared at this point. So we make it a
|
||||||
|
// dependend class for the compiler to be OK with it.
|
||||||
|
using Test =
|
||||||
|
typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
|
||||||
|
|
||||||
|
static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
|
||||||
|
int line_num) {
|
||||||
|
SetUpTearDownSuiteFuncType test_case_fp =
|
||||||
|
GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
|
||||||
|
SetUpTearDownSuiteFuncType test_suite_fp =
|
||||||
|
GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);
|
||||||
|
|
||||||
|
GTEST_CHECK_(!test_case_fp || !test_suite_fp)
|
||||||
|
<< "Test can not provide both SetUpTestSuite and SetUpTestCase, please "
|
||||||
|
"make sure there is only one present at "
|
||||||
|
<< filename << ":" << line_num;
|
||||||
|
|
||||||
|
return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
|
||||||
|
int line_num) {
|
||||||
|
SetUpTearDownSuiteFuncType test_case_fp =
|
||||||
|
GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
|
||||||
|
SetUpTearDownSuiteFuncType test_suite_fp =
|
||||||
|
GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);
|
||||||
|
|
||||||
|
GTEST_CHECK_(!test_case_fp || !test_suite_fp)
|
||||||
|
<< "Test can not provide both TearDownTestSuite and TearDownTestCase,"
|
||||||
|
" please make sure there is only one present at"
|
||||||
|
<< filename << ":" << line_num;
|
||||||
|
|
||||||
|
return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Creates a new TestInfo object and registers it with Google Test;
|
// Creates a new TestInfo object and registers it with Google Test;
|
||||||
// returns the created object.
|
// returns the created object.
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
//
|
//
|
||||||
// test_case_name: name of the test case
|
// test_suite_name: name of the test suite
|
||||||
// name: name of the test
|
// name: name of the test
|
||||||
// type_param the name of the test's type parameter, or NULL if
|
// type_param the name of the test's type parameter, or NULL if
|
||||||
// this is not a typed or a type-parameterized test.
|
// this is not a typed or a type-parameterized test.
|
||||||
@@ -510,21 +550,16 @@ struct CodeLocation {
|
|||||||
// or NULL if this is not a type-parameterized test.
|
// or NULL if this is not a type-parameterized test.
|
||||||
// code_location: code location where the test is defined
|
// code_location: code location where the test is defined
|
||||||
// fixture_class_id: ID of the test fixture class
|
// fixture_class_id: ID of the test fixture class
|
||||||
// set_up_tc: pointer to the function that sets up the test case
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test case
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
// factory: pointer to the factory that creates a test object.
|
// factory: pointer to the factory that creates a test object.
|
||||||
// The newly created TestInfo instance will assume
|
// The newly created TestInfo instance will assume
|
||||||
// ownership of the factory object.
|
// ownership of the factory object.
|
||||||
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
||||||
const char* test_case_name,
|
const char* test_suite_name, const char* name, const char* type_param,
|
||||||
const char* name,
|
const char* value_param, CodeLocation code_location,
|
||||||
const char* type_param,
|
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
||||||
const char* value_param,
|
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
||||||
CodeLocation code_location,
|
|
||||||
TypeId fixture_class_id,
|
|
||||||
SetUpTestCaseFunc set_up_tc,
|
|
||||||
TearDownTestCaseFunc tear_down_tc,
|
|
||||||
TestFactoryBase* factory);
|
|
||||||
|
|
||||||
// If *pstr starts with the given prefix, modifies *pstr to be right
|
// If *pstr starts with the given prefix, modifies *pstr to be right
|
||||||
// past the prefix and returns true; otherwise leaves *pstr unchanged
|
// past the prefix and returns true; otherwise leaves *pstr unchanged
|
||||||
@@ -536,19 +571,20 @@ GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
|
|||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||||
|
|
||||||
// State of the definition of a type-parameterized test case.
|
// State of the definition of a type-parameterized test suite.
|
||||||
class GTEST_API_ TypedTestCasePState {
|
class GTEST_API_ TypedTestSuitePState {
|
||||||
public:
|
public:
|
||||||
TypedTestCasePState() : registered_(false) {}
|
TypedTestSuitePState() : registered_(false) {}
|
||||||
|
|
||||||
// Adds the given test name to defined_test_names_ and return true
|
// Adds the given test name to defined_test_names_ and return true
|
||||||
// if the test case hasn't been registered; otherwise aborts the
|
// if the test suite hasn't been registered; otherwise aborts the
|
||||||
// program.
|
// program.
|
||||||
bool AddTestName(const char* file, int line, const char* case_name,
|
bool AddTestName(const char* file, int line, const char* case_name,
|
||||||
const char* test_name) {
|
const char* test_name) {
|
||||||
if (registered_) {
|
if (registered_) {
|
||||||
fprintf(stderr, "%s Test %s must be defined before "
|
fprintf(stderr,
|
||||||
"REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
|
"%s Test %s must be defined before "
|
||||||
|
"REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n",
|
||||||
FormatFileLocation(file, line).c_str(), test_name, case_name);
|
FormatFileLocation(file, line).c_str(), test_name, case_name);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
posix::Abort();
|
posix::Abort();
|
||||||
@@ -581,14 +617,19 @@ class GTEST_API_ TypedTestCasePState {
|
|||||||
RegisteredTestsMap registered_tests_;
|
RegisteredTestsMap registered_tests_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
using TypedTestCasePState = TypedTestSuitePState;
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
|
|
||||||
// Skips to the first non-space char after the first comma in 'str';
|
// Skips to the first non-space char after the first comma in 'str';
|
||||||
// returns NULL if no comma is found in 'str'.
|
// returns NULL if no comma is found in 'str'.
|
||||||
inline const char* SkipComma(const char* str) {
|
inline const char* SkipComma(const char* str) {
|
||||||
const char* comma = strchr(str, ',');
|
const char* comma = strchr(str, ',');
|
||||||
if (comma == NULL) {
|
if (comma == nullptr) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
while (IsSpace(*(++comma))) {}
|
while (IsSpace(*(++comma))) {}
|
||||||
return comma;
|
return comma;
|
||||||
@@ -598,7 +639,7 @@ inline const char* SkipComma(const char* str) {
|
|||||||
// the entire string if it contains no comma.
|
// the entire string if it contains no comma.
|
||||||
inline std::string GetPrefixUntilComma(const char* str) {
|
inline std::string GetPrefixUntilComma(const char* str) {
|
||||||
const char* comma = strchr(str, ',');
|
const char* comma = strchr(str, ',');
|
||||||
return comma == NULL ? str : std::string(str, comma);
|
return comma == nullptr ? str : std::string(str, comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splits a given string on a given delimiter, populating a given
|
// Splits a given string on a given delimiter, populating a given
|
||||||
@@ -648,7 +689,7 @@ template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
|
|||||||
class TypeParameterizedTest {
|
class TypeParameterizedTest {
|
||||||
public:
|
public:
|
||||||
// 'index' is the index of the test in the type list 'Types'
|
// 'index' is the index of the test in the type list 'Types'
|
||||||
// specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
|
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
||||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||||
// length of Types.
|
// length of Types.
|
||||||
static bool Register(const char* prefix, const CodeLocation& code_location,
|
static bool Register(const char* prefix, const CodeLocation& code_location,
|
||||||
@@ -663,13 +704,17 @@ class TypeParameterizedTest {
|
|||||||
// list.
|
// list.
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
||||||
"/" + type_names[index])
|
"/" + type_names[static_cast<size_t>(index)])
|
||||||
.c_str(),
|
.c_str(),
|
||||||
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
||||||
GetTypeName<Type>().c_str(),
|
GetTypeName<Type>().c_str(),
|
||||||
NULL, // No value parameter.
|
nullptr, // No value parameter.
|
||||||
code_location, GetTypeId<FixtureClass>(), TestClass::SetUpTestCase,
|
code_location, GetTypeId<FixtureClass>(),
|
||||||
TestClass::TearDownTestCase, new TestFactoryImpl<TestClass>);
|
SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(
|
||||||
|
code_location.file.c_str(), code_location.line),
|
||||||
|
SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(
|
||||||
|
code_location.file.c_str(), code_location.line),
|
||||||
|
new TestFactoryImpl<TestClass>);
|
||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the type list.
|
// Next, recurses (at compile time) with the tail of the type list.
|
||||||
return TypeParameterizedTest<Fixture, TestSel,
|
return TypeParameterizedTest<Fixture, TestSel,
|
||||||
@@ -695,15 +740,15 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
|
// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()
|
||||||
// registers *all combinations* of 'Tests' and 'Types' with Google
|
// registers *all combinations* of 'Tests' and 'Types' with Google
|
||||||
// Test. The return value is insignificant - we just need to return
|
// Test. The return value is insignificant - we just need to return
|
||||||
// something such that we can call this function in a namespace scope.
|
// something such that we can call this function in a namespace scope.
|
||||||
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
||||||
class TypeParameterizedTestCase {
|
class TypeParameterizedTestSuite {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* prefix, CodeLocation code_location,
|
static bool Register(const char* prefix, CodeLocation code_location,
|
||||||
const TypedTestCasePState* state, const char* case_name,
|
const TypedTestSuitePState* state, const char* case_name,
|
||||||
const char* test_names,
|
const char* test_names,
|
||||||
const std::vector<std::string>& type_names =
|
const std::vector<std::string>& type_names =
|
||||||
GenerateNames<DefaultNameGenerator, Types>()) {
|
GenerateNames<DefaultNameGenerator, Types>()) {
|
||||||
@@ -726,20 +771,20 @@ class TypeParameterizedTestCase {
|
|||||||
prefix, test_location, case_name, test_names, 0, type_names);
|
prefix, test_location, case_name, test_names, 0, type_names);
|
||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the test list.
|
// Next, recurses (at compile time) with the tail of the test list.
|
||||||
return TypeParameterizedTestCase<Fixture, typename Tests::Tail,
|
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
||||||
Types>::Register(prefix, code_location,
|
Types>::Register(prefix, code_location,
|
||||||
state, case_name,
|
state, case_name,
|
||||||
SkipComma(test_names),
|
SkipComma(test_names),
|
||||||
type_names);
|
type_names);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The base case for the compile time recursion.
|
// The base case for the compile time recursion.
|
||||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||||
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
class TypeParameterizedTestSuite<Fixture, Templates0, Types> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
||||||
const TypedTestCasePState* /*state*/,
|
const TypedTestSuitePState* /*state*/,
|
||||||
const char* /*case_name*/, const char* /*test_names*/,
|
const char* /*case_name*/, const char* /*test_names*/,
|
||||||
const std::vector<std::string>& =
|
const std::vector<std::string>& =
|
||||||
std::vector<std::string>() /*type_names*/) {
|
std::vector<std::string>() /*type_names*/) {
|
||||||
@@ -802,120 +847,16 @@ class GTEST_API_ Random {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
|
|
||||||
// compiler error iff T1 and T2 are different types.
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct CompileAssertTypesEqual;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct CompileAssertTypesEqual<T, T> {
|
|
||||||
};
|
|
||||||
|
|
||||||
// Removes the reference from a type if it is a reference type,
|
|
||||||
// otherwise leaves it unchanged. This is the same as
|
|
||||||
// tr1::remove_reference, which is not widely available yet.
|
|
||||||
template <typename T>
|
|
||||||
struct RemoveReference { typedef T type; }; // NOLINT
|
|
||||||
template <typename T>
|
|
||||||
struct RemoveReference<T&> { typedef T type; }; // NOLINT
|
|
||||||
|
|
||||||
// A handy wrapper around RemoveReference that works when the argument
|
|
||||||
// T depends on template parameters.
|
|
||||||
#define GTEST_REMOVE_REFERENCE_(T) \
|
|
||||||
typename ::testing::internal::RemoveReference<T>::type
|
|
||||||
|
|
||||||
// Removes const from a type if it is a const type, otherwise leaves
|
|
||||||
// it unchanged. This is the same as tr1::remove_const, which is not
|
|
||||||
// widely available yet.
|
|
||||||
template <typename T>
|
|
||||||
struct RemoveConst { typedef T type; }; // NOLINT
|
|
||||||
template <typename T>
|
|
||||||
struct RemoveConst<const T> { typedef T type; }; // NOLINT
|
|
||||||
|
|
||||||
// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above
|
|
||||||
// definition to fail to remove the const in 'const int[3]' and 'const
|
|
||||||
// char[3][4]'. The following specialization works around the bug.
|
|
||||||
template <typename T, size_t N>
|
|
||||||
struct RemoveConst<const T[N]> {
|
|
||||||
typedef typename RemoveConst<T>::type type[N];
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
|
||||||
// This is the only specialization that allows VC++ 7.1 to remove const in
|
|
||||||
// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC
|
|
||||||
// and thus needs to be conditionally compiled.
|
|
||||||
template <typename T, size_t N>
|
|
||||||
struct RemoveConst<T[N]> {
|
|
||||||
typedef typename RemoveConst<T>::type type[N];
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// A handy wrapper around RemoveConst that works when the argument
|
|
||||||
// T depends on template parameters.
|
|
||||||
#define GTEST_REMOVE_CONST_(T) \
|
|
||||||
typename ::testing::internal::RemoveConst<T>::type
|
|
||||||
|
|
||||||
// Turns const U&, U&, const U, and U all into U.
|
// Turns const U&, U&, const U, and U all into U.
|
||||||
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
|
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
|
||||||
GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
|
typename std::remove_const<typename std::remove_reference<T>::type>::type
|
||||||
|
|
||||||
// ImplicitlyConvertible<From, To>::value is a compile-time bool
|
|
||||||
// constant that's true iff type From can be implicitly converted to
|
|
||||||
// type To.
|
|
||||||
template <typename From, typename To>
|
|
||||||
class ImplicitlyConvertible {
|
|
||||||
private:
|
|
||||||
// We need the following helper functions only for their types.
|
|
||||||
// They have no implementations.
|
|
||||||
|
|
||||||
// MakeFrom() is an expression whose type is From. We cannot simply
|
|
||||||
// use From(), as the type From may not have a public default
|
|
||||||
// constructor.
|
|
||||||
static typename AddReference<From>::type MakeFrom();
|
|
||||||
|
|
||||||
// These two functions are overloaded. Given an expression
|
|
||||||
// Helper(x), the compiler will pick the first version if x can be
|
|
||||||
// implicitly converted to type To; otherwise it will pick the
|
|
||||||
// second version.
|
|
||||||
//
|
|
||||||
// The first version returns a value of size 1, and the second
|
|
||||||
// version returns a value of size 2. Therefore, by checking the
|
|
||||||
// size of Helper(x), which can be done at compile time, we can tell
|
|
||||||
// which version of Helper() is used, and hence whether x can be
|
|
||||||
// implicitly converted to type To.
|
|
||||||
static char Helper(To);
|
|
||||||
static char (&Helper(...))[2]; // NOLINT
|
|
||||||
|
|
||||||
// We have to put the 'public' section after the 'private' section,
|
|
||||||
// or MSVC refuses to compile the code.
|
|
||||||
public:
|
|
||||||
#if defined(__BORLANDC__)
|
|
||||||
// C++Builder cannot use member overload resolution during template
|
|
||||||
// instantiation. The simplest workaround is to use its C++0x type traits
|
|
||||||
// functions (C++Builder 2009 and above only).
|
|
||||||
static const bool value = __is_convertible(From, To);
|
|
||||||
#else
|
|
||||||
// MSVC warns about implicitly converting from double to int for
|
|
||||||
// possible loss of data, so we need to temporarily disable the
|
|
||||||
// warning.
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244)
|
|
||||||
static const bool value =
|
|
||||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
};
|
|
||||||
template <typename From, typename To>
|
|
||||||
const bool ImplicitlyConvertible<From, To>::value;
|
|
||||||
|
|
||||||
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
|
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
|
||||||
// true iff T is type ProtocolMessage, proto2::Message, or a subclass
|
// true if and only if T is type proto2::Message or a subclass of it.
|
||||||
// of those.
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct IsAProtocolMessage
|
struct IsAProtocolMessage
|
||||||
: public bool_constant<
|
: public bool_constant<
|
||||||
ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
|
std::is_convertible<const T*, const ::proto2::Message*>::value> {};
|
||||||
ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
||||||
@@ -942,7 +883,6 @@ struct IsAProtocolMessage
|
|||||||
// IsContainerTest(typename C::const_iterator*) and
|
// IsContainerTest(typename C::const_iterator*) and
|
||||||
// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
|
// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
|
||||||
typedef int IsContainer;
|
typedef int IsContainer;
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
template <class C,
|
template <class C,
|
||||||
class Iterator = decltype(::std::declval<const C&>().begin()),
|
class Iterator = decltype(::std::declval<const C&>().begin()),
|
||||||
class = decltype(::std::declval<const C&>().end()),
|
class = decltype(::std::declval<const C&>().end()),
|
||||||
@@ -952,14 +892,6 @@ template <class C,
|
|||||||
IsContainer IsContainerTest(int /* dummy */) {
|
IsContainer IsContainerTest(int /* dummy */) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template <class C>
|
|
||||||
IsContainer IsContainerTest(int /* dummy */,
|
|
||||||
typename C::iterator* /* it */ = NULL,
|
|
||||||
typename C::const_iterator* /* const_it */ = NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif // GTEST_LANG_CXX11
|
|
||||||
|
|
||||||
typedef char IsNotContainer;
|
typedef char IsNotContainer;
|
||||||
template <class C>
|
template <class C>
|
||||||
@@ -980,47 +912,30 @@ struct IsHashTable {
|
|||||||
static char test(...);
|
static char test(...);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value = sizeof(test<T>(0, 0)) == sizeof(int);
|
static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const bool IsHashTable<T>::value;
|
const bool IsHashTable<T>::value;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct VoidT {
|
|
||||||
typedef void value_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename = void>
|
|
||||||
struct HasValueType : false_type {};
|
|
||||||
template <typename T>
|
|
||||||
struct HasValueType<T, VoidT<typename T::value_type> > : true_type {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename C,
|
template <typename C,
|
||||||
bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer),
|
bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>
|
||||||
bool = HasValueType<C>::value>
|
|
||||||
struct IsRecursiveContainerImpl;
|
struct IsRecursiveContainerImpl;
|
||||||
|
|
||||||
template <typename C, bool HV>
|
template <typename C>
|
||||||
struct IsRecursiveContainerImpl<C, false, HV> : public false_type {};
|
struct IsRecursiveContainerImpl<C, false> : public std::false_type {};
|
||||||
|
|
||||||
// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to
|
// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to
|
||||||
// obey the same inconsistencies as the IsContainerTest, namely check if
|
// obey the same inconsistencies as the IsContainerTest, namely check if
|
||||||
// something is a container is relying on only const_iterator in C++11 and
|
// something is a container is relying on only const_iterator in C++11 and
|
||||||
// is relying on both const_iterator and iterator otherwise
|
// is relying on both const_iterator and iterator otherwise
|
||||||
template <typename C>
|
template <typename C>
|
||||||
struct IsRecursiveContainerImpl<C, true, false> : public false_type {};
|
struct IsRecursiveContainerImpl<C, true> {
|
||||||
|
using value_type = decltype(*std::declval<typename C::const_iterator>());
|
||||||
template <typename C>
|
using type =
|
||||||
struct IsRecursiveContainerImpl<C, true, true> {
|
std::is_same<typename std::remove_const<
|
||||||
#if GTEST_LANG_CXX11
|
typename std::remove_reference<value_type>::type>::type,
|
||||||
typedef typename IteratorTraits<typename C::const_iterator>::value_type
|
C>;
|
||||||
value_type;
|
|
||||||
#else
|
|
||||||
typedef typename IteratorTraits<typename C::iterator>::value_type value_type;
|
|
||||||
#endif
|
|
||||||
typedef is_same<value_type, C> type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// IsRecursiveContainer<Type> is a unary compile-time predicate that
|
// IsRecursiveContainer<Type> is a unary compile-time predicate that
|
||||||
@@ -1032,13 +947,6 @@ struct IsRecursiveContainerImpl<C, true, true> {
|
|||||||
template <typename C>
|
template <typename C>
|
||||||
struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
|
struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
|
||||||
|
|
||||||
// EnableIf<condition>::type is void when 'Cond' is true, and
|
|
||||||
// undefined when 'Cond' is false. To use SFINAE to make a function
|
|
||||||
// overload only apply when a particular expression is true, add
|
|
||||||
// "typename EnableIf<expression>::type* = 0" as the last parameter.
|
|
||||||
template<bool> struct EnableIf;
|
|
||||||
template<> struct EnableIf<true> { typedef void type; }; // NOLINT
|
|
||||||
|
|
||||||
// Utilities for native arrays.
|
// Utilities for native arrays.
|
||||||
|
|
||||||
// ArrayEq() compares two k-dimensional native arrays using the
|
// ArrayEq() compares two k-dimensional native arrays using the
|
||||||
@@ -1161,10 +1069,9 @@ class NativeArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
static_assert(!std::is_const<Element>::value, "Type must not be const");
|
||||||
kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
|
static_assert(!std::is_reference<Element>::value,
|
||||||
Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value
|
"Type must not be a reference");
|
||||||
};
|
|
||||||
|
|
||||||
// Initializes this object with a copy of the input.
|
// Initializes this object with a copy of the input.
|
||||||
void InitCopy(const Element* array, size_t a_size) {
|
void InitCopy(const Element* array, size_t a_size) {
|
||||||
@@ -1189,6 +1096,139 @@ class NativeArray {
|
|||||||
GTEST_DISALLOW_ASSIGN_(NativeArray);
|
GTEST_DISALLOW_ASSIGN_(NativeArray);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Backport of std::index_sequence.
|
||||||
|
template <size_t... Is>
|
||||||
|
struct IndexSequence {
|
||||||
|
using type = IndexSequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Double the IndexSequence, and one if plus_one is true.
|
||||||
|
template <bool plus_one, typename T, size_t sizeofT>
|
||||||
|
struct DoubleSequence;
|
||||||
|
template <size_t... I, size_t sizeofT>
|
||||||
|
struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
|
||||||
|
using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
|
||||||
|
};
|
||||||
|
template <size_t... I, size_t sizeofT>
|
||||||
|
struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
|
||||||
|
using type = IndexSequence<I..., (sizeofT + I)...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backport of std::make_index_sequence.
|
||||||
|
// It uses O(ln(N)) instantiation depth.
|
||||||
|
template <size_t N>
|
||||||
|
struct MakeIndexSequence
|
||||||
|
: DoubleSequence<N % 2 == 1, typename MakeIndexSequence<N / 2>::type,
|
||||||
|
N / 2>::type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MakeIndexSequence<0> : IndexSequence<> {};
|
||||||
|
|
||||||
|
// FIXME: This implementation of ElemFromList is O(1) in instantiation depth,
|
||||||
|
// but it is O(N^2) in total instantiations. Not sure if this is the best
|
||||||
|
// tradeoff, as it will make it somewhat slow to compile.
|
||||||
|
template <typename T, size_t, size_t>
|
||||||
|
struct ElemFromListImpl {};
|
||||||
|
|
||||||
|
template <typename T, size_t I>
|
||||||
|
struct ElemFromListImpl<T, I, I> {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the Nth element from T...
|
||||||
|
// It uses O(1) instantiation depth.
|
||||||
|
template <size_t N, typename I, typename... T>
|
||||||
|
struct ElemFromList;
|
||||||
|
|
||||||
|
template <size_t N, size_t... I, typename... T>
|
||||||
|
struct ElemFromList<N, IndexSequence<I...>, T...>
|
||||||
|
: ElemFromListImpl<T, N, I>... {};
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
class FlatTuple;
|
||||||
|
|
||||||
|
template <typename Derived, size_t I>
|
||||||
|
struct FlatTupleElemBase;
|
||||||
|
|
||||||
|
template <typename... T, size_t I>
|
||||||
|
struct FlatTupleElemBase<FlatTuple<T...>, I> {
|
||||||
|
using value_type =
|
||||||
|
typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type,
|
||||||
|
T...>::type;
|
||||||
|
FlatTupleElemBase() = default;
|
||||||
|
explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {}
|
||||||
|
value_type value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Derived, typename Idx>
|
||||||
|
struct FlatTupleBase;
|
||||||
|
|
||||||
|
template <size_t... Idx, typename... T>
|
||||||
|
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
||||||
|
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
||||||
|
using Indices = IndexSequence<Idx...>;
|
||||||
|
FlatTupleBase() = default;
|
||||||
|
explicit FlatTupleBase(T... t)
|
||||||
|
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Analog to std::tuple but with different tradeoffs.
|
||||||
|
// This class minimizes the template instantiation depth, thus allowing more
|
||||||
|
// elements that std::tuple would. std::tuple has been seen to require an
|
||||||
|
// instantiation depth of more than 10x the number of elements in some
|
||||||
|
// implementations.
|
||||||
|
// FlatTuple and ElemFromList are not recursive and have a fixed depth
|
||||||
|
// regardless of T...
|
||||||
|
// MakeIndexSequence, on the other hand, it is recursive but with an
|
||||||
|
// instantiation depth of O(ln(N)).
|
||||||
|
template <typename... T>
|
||||||
|
class FlatTuple
|
||||||
|
: private FlatTupleBase<FlatTuple<T...>,
|
||||||
|
typename MakeIndexSequence<sizeof...(T)>::type> {
|
||||||
|
using Indices = typename FlatTuple::FlatTupleBase::Indices;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlatTuple() = default;
|
||||||
|
explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {}
|
||||||
|
|
||||||
|
template <size_t I>
|
||||||
|
const typename ElemFromList<I, Indices, T...>::type& Get() const {
|
||||||
|
return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t I>
|
||||||
|
typename ElemFromList<I, Indices, T...>::type& Get() {
|
||||||
|
return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Utility functions to be called with static_assert to induce deprecation
|
||||||
|
// warnings.
|
||||||
|
GTEST_INTERNAL_DEPRECATED(
|
||||||
|
"INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
||||||
|
"INSTANTIATE_TEST_SUITE_P")
|
||||||
|
constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
|
||||||
|
|
||||||
|
GTEST_INTERNAL_DEPRECATED(
|
||||||
|
"TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
|
"TYPED_TEST_SUITE_P")
|
||||||
|
constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
|
||||||
|
|
||||||
|
GTEST_INTERNAL_DEPRECATED(
|
||||||
|
"TYPED_TEST_CASE is deprecated, please use "
|
||||||
|
"TYPED_TEST_SUITE")
|
||||||
|
constexpr bool TypedTestCaseIsDeprecated() { return true; }
|
||||||
|
|
||||||
|
GTEST_INTERNAL_DEPRECATED(
|
||||||
|
"REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
|
"REGISTER_TYPED_TEST_SUITE_P")
|
||||||
|
constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
|
||||||
|
|
||||||
|
GTEST_INTERNAL_DEPRECATED(
|
||||||
|
"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
||||||
|
"INSTANTIATE_TYPED_TEST_SUITE_P")
|
||||||
|
constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
@@ -1208,7 +1248,10 @@ class NativeArray {
|
|||||||
#define GTEST_SUCCESS_(message) \
|
#define GTEST_SUCCESS_(message) \
|
||||||
GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
|
GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
|
||||||
|
|
||||||
// Suppress MSVC warning 4702 (unreachable code) for the code following
|
#define GTEST_SKIP_(message) \
|
||||||
|
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
|
||||||
|
|
||||||
|
// Suppress MSVC warning 4072 (unreachable code) for the code following
|
||||||
// statement if it returns or throws (or doesn't return or throw in some
|
// statement if it returns or throws (or doesn't return or throw in some
|
||||||
// situations).
|
// situations).
|
||||||
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
|
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
|
||||||
@@ -1300,31 +1343,38 @@ class NativeArray {
|
|||||||
" Actual: it does.")
|
" Actual: it does.")
|
||||||
|
|
||||||
// Expands to the name of the class that implements the given test.
|
// Expands to the name of the class that implements the given test.
|
||||||
#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
|
#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
||||||
test_case_name##_##test_name##_Test
|
test_suite_name##_##test_name##_Test
|
||||||
|
|
||||||
// Helper macro for defining tests.
|
// Helper macro for defining tests.
|
||||||
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
|
#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \
|
||||||
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
|
static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \
|
||||||
public:\
|
"test_suite_name must not be empty"); \
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
|
static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \
|
||||||
private:\
|
"test_name must not be empty"); \
|
||||||
virtual void TestBody();\
|
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
||||||
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
|
: public parent_class { \
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
public: \
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
|
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
||||||
};\
|
\
|
||||||
\
|
private: \
|
||||||
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
|
virtual void TestBody(); \
|
||||||
::test_info_ =\
|
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||||
::testing::internal::MakeAndRegisterTestInfo(\
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
#test_case_name, #test_name, NULL, NULL, \
|
test_name)); \
|
||||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
}; \
|
||||||
(parent_id), \
|
\
|
||||||
parent_class::SetUpTestCase, \
|
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||||
parent_class::TearDownTestCase, \
|
test_name)::test_info_ = \
|
||||||
new ::testing::internal::TestFactoryImpl<\
|
::testing::internal::MakeAndRegisterTestInfo( \
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
|
#test_suite_name, #test_name, nullptr, nullptr, \
|
||||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
|
||||||
|
::testing::internal::SuiteApiResolver< \
|
||||||
|
parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
|
||||||
|
::testing::internal::SuiteApiResolver< \
|
||||||
|
parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
|
||||||
|
new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
|
||||||
|
test_suite_name, test_name)>); \
|
||||||
|
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||||
|
|||||||
@@ -1,243 +0,0 @@
|
|||||||
// Copyright 2003 Google Inc.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// A "smart" pointer type with reference tracking. Every pointer to a
|
|
||||||
// particular object is kept on a circular linked list. When the last pointer
|
|
||||||
// to an object is destroyed or reassigned, the object is deleted.
|
|
||||||
//
|
|
||||||
// Used properly, this deletes the object when the last reference goes away.
|
|
||||||
// There are several caveats:
|
|
||||||
// - Like all reference counting schemes, cycles lead to leaks.
|
|
||||||
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
|
|
||||||
// - Every time a pointer is assigned, the entire list of pointers to that
|
|
||||||
// object is traversed. This class is therefore NOT SUITABLE when there
|
|
||||||
// will often be more than two or three pointers to a particular object.
|
|
||||||
// - References are only tracked as long as linked_ptr<> objects are copied.
|
|
||||||
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
|
|
||||||
// will happen (double deletion).
|
|
||||||
//
|
|
||||||
// A good use of this class is storing object references in STL containers.
|
|
||||||
// You can safely put linked_ptr<> in a vector<>.
|
|
||||||
// Other uses may not be as good.
|
|
||||||
//
|
|
||||||
// Note: If you use an incomplete type with linked_ptr<>, the class
|
|
||||||
// *containing* linked_ptr<> must have a constructor and destructor (even
|
|
||||||
// if they do nothing!).
|
|
||||||
//
|
|
||||||
// Bill Gibbons suggested we use something like this.
|
|
||||||
//
|
|
||||||
// Thread Safety:
|
|
||||||
// Unlike other linked_ptr implementations, in this implementation
|
|
||||||
// a linked_ptr object is thread-safe in the sense that:
|
|
||||||
// - it's safe to copy linked_ptr objects concurrently,
|
|
||||||
// - it's safe to copy *from* a linked_ptr and read its underlying
|
|
||||||
// raw pointer (e.g. via get()) concurrently, and
|
|
||||||
// - it's safe to write to two linked_ptrs that point to the same
|
|
||||||
// shared object concurrently.
|
|
||||||
// FIXME: rename this to safe_linked_ptr to avoid
|
|
||||||
// confusion with normal linked_ptr.
|
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
|
||||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Protects copying of all linked_ptr objects.
|
|
||||||
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
|
||||||
|
|
||||||
// This is used internally by all instances of linked_ptr<>. It needs to be
|
|
||||||
// a non-template class because different types of linked_ptr<> can refer to
|
|
||||||
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
|
|
||||||
// So, it needs to be possible for different types of linked_ptr to participate
|
|
||||||
// in the same circular linked list, so we need a single class type here.
|
|
||||||
//
|
|
||||||
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
|
|
||||||
class linked_ptr_internal {
|
|
||||||
public:
|
|
||||||
// Create a new circle that includes only this instance.
|
|
||||||
void join_new() {
|
|
||||||
next_ = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Many linked_ptr operations may change p.link_ for some linked_ptr
|
|
||||||
// variable p in the same circle as this object. Therefore we need
|
|
||||||
// to prevent two such operations from occurring concurrently.
|
|
||||||
//
|
|
||||||
// Note that different types of linked_ptr objects can coexist in a
|
|
||||||
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
|
|
||||||
// linked_ptr<Derived2>). Therefore we must use a single mutex to
|
|
||||||
// protect all linked_ptr objects. This can create serious
|
|
||||||
// contention in production code, but is acceptable in a testing
|
|
||||||
// framework.
|
|
||||||
|
|
||||||
// Join an existing circle.
|
|
||||||
void join(linked_ptr_internal const* ptr)
|
|
||||||
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
|
|
||||||
MutexLock lock(&g_linked_ptr_mutex);
|
|
||||||
|
|
||||||
linked_ptr_internal const* p = ptr;
|
|
||||||
while (p->next_ != ptr) {
|
|
||||||
assert(p->next_ != this &&
|
|
||||||
"Trying to join() a linked ring we are already in. "
|
|
||||||
"Is GMock thread safety enabled?");
|
|
||||||
p = p->next_;
|
|
||||||
}
|
|
||||||
p->next_ = this;
|
|
||||||
next_ = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Leave whatever circle we're part of. Returns true if we were the
|
|
||||||
// last member of the circle. Once this is done, you can join() another.
|
|
||||||
bool depart()
|
|
||||||
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
|
|
||||||
MutexLock lock(&g_linked_ptr_mutex);
|
|
||||||
|
|
||||||
if (next_ == this) return true;
|
|
||||||
linked_ptr_internal const* p = next_;
|
|
||||||
while (p->next_ != this) {
|
|
||||||
assert(p->next_ != next_ &&
|
|
||||||
"Trying to depart() a linked ring we are not in. "
|
|
||||||
"Is GMock thread safety enabled?");
|
|
||||||
p = p->next_;
|
|
||||||
}
|
|
||||||
p->next_ = next_;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable linked_ptr_internal const* next_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class linked_ptr {
|
|
||||||
public:
|
|
||||||
typedef T element_type;
|
|
||||||
|
|
||||||
// Take over ownership of a raw pointer. This should happen as soon as
|
|
||||||
// possible after the object is created.
|
|
||||||
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
|
|
||||||
~linked_ptr() { depart(); }
|
|
||||||
|
|
||||||
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
|
|
||||||
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
|
|
||||||
linked_ptr(linked_ptr const& ptr) { // NOLINT
|
|
||||||
assert(&ptr != this);
|
|
||||||
copy(&ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignment releases the old value and acquires the new.
|
|
||||||
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
|
|
||||||
depart();
|
|
||||||
copy(&ptr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
linked_ptr& operator=(linked_ptr const& ptr) {
|
|
||||||
if (&ptr != this) {
|
|
||||||
depart();
|
|
||||||
copy(&ptr);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Smart pointer members.
|
|
||||||
void reset(T* ptr = NULL) {
|
|
||||||
depart();
|
|
||||||
capture(ptr);
|
|
||||||
}
|
|
||||||
T* get() const { return value_; }
|
|
||||||
T* operator->() const { return value_; }
|
|
||||||
T& operator*() const { return *value_; }
|
|
||||||
|
|
||||||
bool operator==(T* p) const { return value_ == p; }
|
|
||||||
bool operator!=(T* p) const { return value_ != p; }
|
|
||||||
template <typename U>
|
|
||||||
bool operator==(linked_ptr<U> const& ptr) const {
|
|
||||||
return value_ == ptr.get();
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
bool operator!=(linked_ptr<U> const& ptr) const {
|
|
||||||
return value_ != ptr.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename U>
|
|
||||||
friend class linked_ptr;
|
|
||||||
|
|
||||||
T* value_;
|
|
||||||
linked_ptr_internal link_;
|
|
||||||
|
|
||||||
void depart() {
|
|
||||||
if (link_.depart()) delete value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void capture(T* ptr) {
|
|
||||||
value_ = ptr;
|
|
||||||
link_.join_new();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U> void copy(linked_ptr<U> const* ptr) {
|
|
||||||
value_ = ptr->get();
|
|
||||||
if (value_)
|
|
||||||
link_.join(&ptr->link_);
|
|
||||||
else
|
|
||||||
link_.join_new();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> inline
|
|
||||||
bool operator==(T* ptr, const linked_ptr<T>& x) {
|
|
||||||
return ptr == x.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> inline
|
|
||||||
bool operator!=(T* ptr, const linked_ptr<T>& x) {
|
|
||||||
return ptr != x.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A function to convert T* into linked_ptr<T>
|
|
||||||
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
|
|
||||||
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
|
|
||||||
template <typename T>
|
|
||||||
linked_ptr<T> make_linked_ptr(T* ptr) {
|
|
||||||
return linked_ptr<T>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,282 +0,0 @@
|
|||||||
$$ -*- mode: c++; -*-
|
|
||||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
|
||||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
|
||||||
// Copyright 2008 Google Inc.
|
|
||||||
// All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
// Type and function utilities for implementing parameterized tests.
|
|
||||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
|
||||||
//
|
|
||||||
// Currently Google Test supports at most $n arguments in Values,
|
|
||||||
// and at most $maxtuple arguments in Combine. Please contact
|
|
||||||
// googletestframework@googlegroups.com if you need more.
|
|
||||||
// Please note that the number of arguments to Combine is limited
|
|
||||||
// by the maximum arity of the implementation of tuple which is
|
|
||||||
// currently set at $maxtuple.
|
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
|
||||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
|
||||||
|
|
||||||
#include "gtest/internal/gtest-param-util.h"
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
|
||||||
|
|
||||||
namespace testing {
|
|
||||||
|
|
||||||
// Forward declarations of ValuesIn(), which is implemented in
|
|
||||||
// include/gtest/gtest-param-test.h.
|
|
||||||
template <typename ForwardIterator>
|
|
||||||
internal::ParamGenerator<
|
|
||||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
|
||||||
ValuesIn(ForwardIterator begin, ForwardIterator end);
|
|
||||||
|
|
||||||
template <typename T, size_t N>
|
|
||||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
|
|
||||||
|
|
||||||
template <class Container>
|
|
||||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
|
||||||
const Container& container);
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Used in the Values() function to provide polymorphic capabilities.
|
|
||||||
$range i 1..n
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
|
||||||
class ValueArray$i {
|
|
||||||
public:
|
|
||||||
$if i==1 [[explicit ]]ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
operator ParamGenerator<T>() const {
|
|
||||||
const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
|
|
||||||
return ValuesIn(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueArray$i(const ValueArray$i& other) : $for j, [[v$(j)_(other.v$(j)_)]] {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// No implementation - assignment is unsupported.
|
|
||||||
void operator=(const ValueArray$i& other);
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
|
|
||||||
const T$j v$(j)_;
|
|
||||||
]]
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
# if GTEST_HAS_COMBINE
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
||||||
//
|
|
||||||
// Generates values from the Cartesian product of values produced
|
|
||||||
// by the argument generators.
|
|
||||||
//
|
|
||||||
$range i 2..maxtuple
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
$range k 2..i
|
|
||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
|
||||||
class CartesianProductGenerator$i
|
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<$for j, [[T$j]]> > {
|
|
||||||
public:
|
|
||||||
typedef ::testing::tuple<$for j, [[T$j]]> ParamType;
|
|
||||||
|
|
||||||
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
|
|
||||||
: $for j, [[g$(j)_(g$j)]] {}
|
|
||||||
virtual ~CartesianProductGenerator$i() {}
|
|
||||||
|
|
||||||
virtual ParamIteratorInterface<ParamType>* Begin() const {
|
|
||||||
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
|
|
||||||
}
|
|
||||||
virtual ParamIteratorInterface<ParamType>* End() const {
|
|
||||||
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Iterator : public ParamIteratorInterface<ParamType> {
|
|
||||||
public:
|
|
||||||
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
|
|
||||||
|
|
||||||
const ParamGenerator<T$j>& g$j,
|
|
||||||
const typename ParamGenerator<T$j>::iterator& current$(j)]])
|
|
||||||
: base_(base),
|
|
||||||
$for j, [[
|
|
||||||
|
|
||||||
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
|
|
||||||
]] {
|
|
||||||
ComputeCurrentValue();
|
|
||||||
}
|
|
||||||
virtual ~Iterator() {}
|
|
||||||
|
|
||||||
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
|
|
||||||
return base_;
|
|
||||||
}
|
|
||||||
// Advance should not be called on beyond-of-range iterators
|
|
||||||
// so no component iterators must be beyond end of range, either.
|
|
||||||
virtual void Advance() {
|
|
||||||
assert(!AtEnd());
|
|
||||||
++current$(i)_;
|
|
||||||
|
|
||||||
$for k [[
|
|
||||||
if (current$(i+2-k)_ == end$(i+2-k)_) {
|
|
||||||
current$(i+2-k)_ = begin$(i+2-k)_;
|
|
||||||
++current$(i+2-k-1)_;
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
ComputeCurrentValue();
|
|
||||||
}
|
|
||||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
|
||||||
return new Iterator(*this);
|
|
||||||
}
|
|
||||||
virtual const ParamType* Current() const { return current_value_.get(); }
|
|
||||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
|
||||||
// Having the same base generator guarantees that the other
|
|
||||||
// iterator is of the same type and we can downcast.
|
|
||||||
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
|
||||||
<< "The program attempted to compare iterators "
|
|
||||||
<< "from different generators." << std::endl;
|
|
||||||
const Iterator* typed_other =
|
|
||||||
CheckedDowncastToActualType<const Iterator>(&other);
|
|
||||||
// We must report iterators equal if they both point beyond their
|
|
||||||
// respective ranges. That can happen in a variety of fashions,
|
|
||||||
// so we have to consult AtEnd().
|
|
||||||
return (AtEnd() && typed_other->AtEnd()) ||
|
|
||||||
($for j && [[
|
|
||||||
|
|
||||||
current$(j)_ == typed_other->current$(j)_
|
|
||||||
]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Iterator(const Iterator& other)
|
|
||||||
: base_(other.base_), $for j, [[
|
|
||||||
|
|
||||||
begin$(j)_(other.begin$(j)_),
|
|
||||||
end$(j)_(other.end$(j)_),
|
|
||||||
current$(j)_(other.current$(j)_)
|
|
||||||
]] {
|
|
||||||
ComputeCurrentValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComputeCurrentValue() {
|
|
||||||
if (!AtEnd())
|
|
||||||
current_value_.reset(new ParamType($for j, [[*current$(j)_]]));
|
|
||||||
}
|
|
||||||
bool AtEnd() const {
|
|
||||||
// We must report iterator past the end of the range when either of the
|
|
||||||
// component iterators has reached the end of its range.
|
|
||||||
return
|
|
||||||
$for j || [[
|
|
||||||
|
|
||||||
current$(j)_ == end$(j)_
|
|
||||||
]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
|
||||||
void operator=(const Iterator& other);
|
|
||||||
|
|
||||||
const ParamGeneratorInterface<ParamType>* const base_;
|
|
||||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
|
||||||
// current[i]_ is the actual traversing iterator.
|
|
||||||
$for j [[
|
|
||||||
|
|
||||||
const typename ParamGenerator<T$j>::iterator begin$(j)_;
|
|
||||||
const typename ParamGenerator<T$j>::iterator end$(j)_;
|
|
||||||
typename ParamGenerator<T$j>::iterator current$(j)_;
|
|
||||||
]]
|
|
||||||
|
|
||||||
linked_ptr<ParamType> current_value_;
|
|
||||||
}; // class CartesianProductGenerator$i::Iterator
|
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
|
||||||
void operator=(const CartesianProductGenerator$i& other);
|
|
||||||
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
const ParamGenerator<T$j> g$(j)_;
|
|
||||||
|
|
||||||
]]
|
|
||||||
}; // class CartesianProductGenerator$i
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
||||||
//
|
|
||||||
// Helper classes providing Combine() with polymorphic features. They allow
|
|
||||||
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
|
|
||||||
// convertible to U.
|
|
||||||
//
|
|
||||||
$range i 2..maxtuple
|
|
||||||
$for i [[
|
|
||||||
$range j 1..i
|
|
||||||
|
|
||||||
template <$for j, [[class Generator$j]]>
|
|
||||||
class CartesianProductHolder$i {
|
|
||||||
public:
|
|
||||||
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
|
|
||||||
: $for j, [[g$(j)_(g$j)]] {}
|
|
||||||
template <$for j, [[typename T$j]]>
|
|
||||||
operator ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >() const {
|
|
||||||
return ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >(
|
|
||||||
new CartesianProductGenerator$i<$for j, [[T$j]]>(
|
|
||||||
$for j,[[
|
|
||||||
|
|
||||||
static_cast<ParamGenerator<T$j> >(g$(j)_)
|
|
||||||
]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// No implementation - assignment is unsupported.
|
|
||||||
void operator=(const CartesianProductHolder$i& other);
|
|
||||||
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
const Generator$j g$(j)_;
|
|
||||||
|
|
||||||
]]
|
|
||||||
}; // class CartesianProductHolder$i
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
# endif // GTEST_HAS_COMBINE
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace testing
|
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
|
||||||
@@ -37,18 +37,19 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
#include "gtest/internal/gtest-linked_ptr.h"
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gtest/gtest-printers.h"
|
#include "gtest/gtest-printers.h"
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Input to a parameterized test name generator, describing a test parameter.
|
// Input to a parameterized test name generator, describing a test parameter.
|
||||||
// Consists of the parameter value and the integer parameter index.
|
// Consists of the parameter value and the integer parameter index.
|
||||||
template <class ParamType>
|
template <class ParamType>
|
||||||
@@ -72,13 +73,14 @@ struct PrintToStringParamName {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
// Utility Functions
|
||||||
|
|
||||||
// Outputs a message explaining invalid registration of different
|
// Outputs a message explaining invalid registration of different
|
||||||
// fixture class for the same test case. This may happen when
|
// fixture class for the same test suite. This may happen when
|
||||||
// TEST_P macro is used to define two tests with the same name
|
// TEST_P macro is used to define two tests with the same name
|
||||||
// but in different namespaces.
|
// but in different namespaces.
|
||||||
GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
|
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||||
CodeLocation code_location);
|
CodeLocation code_location);
|
||||||
|
|
||||||
template <typename> class ParamGeneratorInterface;
|
template <typename> class ParamGeneratorInterface;
|
||||||
template <typename> class ParamGenerator;
|
template <typename> class ParamGenerator;
|
||||||
@@ -153,7 +155,7 @@ class ParamIterator {
|
|||||||
private:
|
private:
|
||||||
friend class ParamGenerator<T>;
|
friend class ParamGenerator<T>;
|
||||||
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
|
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
|
||||||
scoped_ptr<ParamIteratorInterface<T> > impl_;
|
std::unique_ptr<ParamIteratorInterface<T> > impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ParamGeneratorInterface<T> is the binary interface to access generators
|
// ParamGeneratorInterface<T> is the binary interface to access generators
|
||||||
@@ -192,7 +194,7 @@ class ParamGenerator {
|
|||||||
iterator end() const { return iterator(impl_->End()); }
|
iterator end() const { return iterator(impl_->End()); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
linked_ptr<const ParamGeneratorInterface<T> > impl_;
|
std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generates values from a range of two comparable values. Can be used to
|
// Generates values from a range of two comparable values. Can be used to
|
||||||
@@ -205,12 +207,12 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
RangeGenerator(T begin, T end, IncrementT step)
|
RangeGenerator(T begin, T end, IncrementT step)
|
||||||
: begin_(begin), end_(end),
|
: begin_(begin), end_(end),
|
||||||
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
|
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
|
||||||
virtual ~RangeGenerator() {}
|
~RangeGenerator() override {}
|
||||||
|
|
||||||
virtual ParamIteratorInterface<T>* Begin() const {
|
ParamIteratorInterface<T>* Begin() const override {
|
||||||
return new Iterator(this, begin_, 0, step_);
|
return new Iterator(this, begin_, 0, step_);
|
||||||
}
|
}
|
||||||
virtual ParamIteratorInterface<T>* End() const {
|
ParamIteratorInterface<T>* End() const override {
|
||||||
return new Iterator(this, end_, end_index_, step_);
|
return new Iterator(this, end_, end_index_, step_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,20 +222,20 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
|
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
|
||||||
IncrementT step)
|
IncrementT step)
|
||||||
: base_(base), value_(value), index_(index), step_(step) {}
|
: base_(base), value_(value), index_(index), step_(step) {}
|
||||||
virtual ~Iterator() {}
|
~Iterator() override {}
|
||||||
|
|
||||||
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
|
const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
||||||
return base_;
|
return base_;
|
||||||
}
|
}
|
||||||
virtual void Advance() {
|
void Advance() override {
|
||||||
value_ = static_cast<T>(value_ + step_);
|
value_ = static_cast<T>(value_ + step_);
|
||||||
index_++;
|
index_++;
|
||||||
}
|
}
|
||||||
virtual ParamIteratorInterface<T>* Clone() const {
|
ParamIteratorInterface<T>* Clone() const override {
|
||||||
return new Iterator(*this);
|
return new Iterator(*this);
|
||||||
}
|
}
|
||||||
virtual const T* Current() const { return &value_; }
|
const T* Current() const override { return &value_; }
|
||||||
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
|
bool Equals(const ParamIteratorInterface<T>& other) const override {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||||
@@ -290,12 +292,12 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
template <typename ForwardIterator>
|
template <typename ForwardIterator>
|
||||||
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
||||||
: container_(begin, end) {}
|
: container_(begin, end) {}
|
||||||
virtual ~ValuesInIteratorRangeGenerator() {}
|
~ValuesInIteratorRangeGenerator() override {}
|
||||||
|
|
||||||
virtual ParamIteratorInterface<T>* Begin() const {
|
ParamIteratorInterface<T>* Begin() const override {
|
||||||
return new Iterator(this, container_.begin());
|
return new Iterator(this, container_.begin());
|
||||||
}
|
}
|
||||||
virtual ParamIteratorInterface<T>* End() const {
|
ParamIteratorInterface<T>* End() const override {
|
||||||
return new Iterator(this, container_.end());
|
return new Iterator(this, container_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,16 +309,16 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
Iterator(const ParamGeneratorInterface<T>* base,
|
Iterator(const ParamGeneratorInterface<T>* base,
|
||||||
typename ContainerType::const_iterator iterator)
|
typename ContainerType::const_iterator iterator)
|
||||||
: base_(base), iterator_(iterator) {}
|
: base_(base), iterator_(iterator) {}
|
||||||
virtual ~Iterator() {}
|
~Iterator() override {}
|
||||||
|
|
||||||
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
|
const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
||||||
return base_;
|
return base_;
|
||||||
}
|
}
|
||||||
virtual void Advance() {
|
void Advance() override {
|
||||||
++iterator_;
|
++iterator_;
|
||||||
value_.reset();
|
value_.reset();
|
||||||
}
|
}
|
||||||
virtual ParamIteratorInterface<T>* Clone() const {
|
ParamIteratorInterface<T>* Clone() const override {
|
||||||
return new Iterator(*this);
|
return new Iterator(*this);
|
||||||
}
|
}
|
||||||
// We need to use cached value referenced by iterator_ because *iterator_
|
// We need to use cached value referenced by iterator_ because *iterator_
|
||||||
@@ -326,12 +328,11 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
// can advance iterator_ beyond the end of the range, and we cannot
|
// can advance iterator_ beyond the end of the range, and we cannot
|
||||||
// detect that fact. The client code, on the other hand, is
|
// detect that fact. The client code, on the other hand, is
|
||||||
// responsible for not calling Current() on an out-of-range iterator.
|
// responsible for not calling Current() on an out-of-range iterator.
|
||||||
virtual const T* Current() const {
|
const T* Current() const override {
|
||||||
if (value_.get() == NULL)
|
if (value_.get() == nullptr) value_.reset(new T(*iterator_));
|
||||||
value_.reset(new T(*iterator_));
|
|
||||||
return value_.get();
|
return value_.get();
|
||||||
}
|
}
|
||||||
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
|
bool Equals(const ParamIteratorInterface<T>& other) const override {
|
||||||
// Having the same base generator guarantees that the other
|
// Having the same base generator guarantees that the other
|
||||||
// iterator is of the same type and we can downcast.
|
// iterator is of the same type and we can downcast.
|
||||||
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||||
@@ -354,9 +355,9 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
// A cached value of *iterator_. We keep it here to allow access by
|
// A cached value of *iterator_. We keep it here to allow access by
|
||||||
// pointer in the wrapping iterator's operator->().
|
// pointer in the wrapping iterator's operator->().
|
||||||
// value_ needs to be mutable to be accessed in Current().
|
// value_ needs to be mutable to be accessed in Current().
|
||||||
// Use of scoped_ptr helps manage cached value's lifetime,
|
// Use of std::unique_ptr helps manage cached value's lifetime,
|
||||||
// which is bound by the lifespan of the iterator itself.
|
// which is bound by the lifespan of the iterator itself.
|
||||||
mutable scoped_ptr<const T> value_;
|
mutable std::unique_ptr<const T> value_;
|
||||||
}; // class ValuesInIteratorRangeGenerator::Iterator
|
}; // class ValuesInIteratorRangeGenerator::Iterator
|
||||||
|
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
@@ -376,25 +377,12 @@ std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
|||||||
return name_stream.GetString();
|
return name_stream.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
template <typename T = int>
|
||||||
//
|
void TestNotEmpty() {
|
||||||
// Parameterized test name overload helpers, which help the
|
static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
|
||||||
// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized
|
|
||||||
// test name generator and user param name generator.
|
|
||||||
template <class ParamType, class ParamNameGenFunctor>
|
|
||||||
ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ParamType>
|
|
||||||
struct ParamNameGenFunc {
|
|
||||||
typedef std::string Type(const TestParamInfo<ParamType>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ParamType>
|
|
||||||
typename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() {
|
|
||||||
return DefaultParamName;
|
|
||||||
}
|
}
|
||||||
|
template <typename T = int>
|
||||||
|
void TestNotEmpty(const T&) {}
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
@@ -406,7 +394,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
|
|||||||
typedef typename TestClass::ParamType ParamType;
|
typedef typename TestClass::ParamType ParamType;
|
||||||
explicit ParameterizedTestFactory(ParamType parameter) :
|
explicit ParameterizedTestFactory(ParamType parameter) :
|
||||||
parameter_(parameter) {}
|
parameter_(parameter) {}
|
||||||
virtual Test* CreateTest() {
|
Test* CreateTest() override {
|
||||||
TestClass::SetParam(¶meter_);
|
TestClass::SetParam(¶meter_);
|
||||||
return new TestClass();
|
return new TestClass();
|
||||||
}
|
}
|
||||||
@@ -434,19 +422,19 @@ class TestMetaFactoryBase {
|
|||||||
// TestMetaFactory creates test factories for passing into
|
// TestMetaFactory creates test factories for passing into
|
||||||
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
|
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
|
||||||
// ownership of test factory pointer, same factory object cannot be passed
|
// ownership of test factory pointer, same factory object cannot be passed
|
||||||
// into that method twice. But ParameterizedTestCaseInfo is going to call
|
// into that method twice. But ParameterizedTestSuiteInfo is going to call
|
||||||
// it for each Test/Parameter value combination. Thus it needs meta factory
|
// it for each Test/Parameter value combination. Thus it needs meta factory
|
||||||
// creator class.
|
// creator class.
|
||||||
template <class TestCase>
|
template <class TestSuite>
|
||||||
class TestMetaFactory
|
class TestMetaFactory
|
||||||
: public TestMetaFactoryBase<typename TestCase::ParamType> {
|
: public TestMetaFactoryBase<typename TestSuite::ParamType> {
|
||||||
public:
|
public:
|
||||||
typedef typename TestCase::ParamType ParamType;
|
using ParamType = typename TestSuite::ParamType;
|
||||||
|
|
||||||
TestMetaFactory() {}
|
TestMetaFactory() {}
|
||||||
|
|
||||||
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
|
TestFactoryBase* CreateTestFactory(ParamType parameter) override {
|
||||||
return new ParameterizedTestFactory<TestCase>(parameter);
|
return new ParameterizedTestFactory<TestSuite>(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -455,93 +443,93 @@ class TestMetaFactory
|
|||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// ParameterizedTestCaseInfoBase is a generic interface
|
// ParameterizedTestSuiteInfoBase is a generic interface
|
||||||
// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
|
// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
|
||||||
// accumulates test information provided by TEST_P macro invocations
|
// accumulates test information provided by TEST_P macro invocations
|
||||||
// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
|
// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
|
||||||
// and uses that information to register all resulting test instances
|
// and uses that information to register all resulting test instances
|
||||||
// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
|
// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
|
||||||
// a collection of pointers to the ParameterizedTestCaseInfo objects
|
// a collection of pointers to the ParameterizedTestSuiteInfo objects
|
||||||
// and calls RegisterTests() on each of them when asked.
|
// and calls RegisterTests() on each of them when asked.
|
||||||
class ParameterizedTestCaseInfoBase {
|
class ParameterizedTestSuiteInfoBase {
|
||||||
public:
|
public:
|
||||||
virtual ~ParameterizedTestCaseInfoBase() {}
|
virtual ~ParameterizedTestSuiteInfoBase() {}
|
||||||
|
|
||||||
// Base part of test case name for display purposes.
|
// Base part of test suite name for display purposes.
|
||||||
virtual const std::string& GetTestCaseName() const = 0;
|
virtual const std::string& GetTestSuiteName() const = 0;
|
||||||
// Test case id to verify identity.
|
// Test case id to verify identity.
|
||||||
virtual TypeId GetTestCaseTypeId() const = 0;
|
virtual TypeId GetTestSuiteTypeId() const = 0;
|
||||||
// UnitTest class invokes this method to register tests in this
|
// UnitTest class invokes this method to register tests in this
|
||||||
// test case right before running them in RUN_ALL_TESTS macro.
|
// test suite right before running them in RUN_ALL_TESTS macro.
|
||||||
// This method should not be called more then once on any single
|
// This method should not be called more than once on any single
|
||||||
// instance of a ParameterizedTestCaseInfoBase derived class.
|
// instance of a ParameterizedTestSuiteInfoBase derived class.
|
||||||
virtual void RegisterTests() = 0;
|
virtual void RegisterTests() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ParameterizedTestCaseInfoBase() {}
|
ParameterizedTestSuiteInfoBase() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
|
||||||
};
|
};
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
|
// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
|
||||||
// macro invocations for a particular test case and generators
|
// macro invocations for a particular test suite and generators
|
||||||
// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
|
// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
|
||||||
// test case. It registers tests with all values generated by all
|
// test suite. It registers tests with all values generated by all
|
||||||
// generators when asked.
|
// generators when asked.
|
||||||
template <class TestCase>
|
template <class TestSuite>
|
||||||
class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
||||||
public:
|
public:
|
||||||
// ParamType and GeneratorCreationFunc are private types but are required
|
// ParamType and GeneratorCreationFunc are private types but are required
|
||||||
// for declarations of public methods AddTestPattern() and
|
// for declarations of public methods AddTestPattern() and
|
||||||
// AddTestCaseInstantiation().
|
// AddTestSuiteInstantiation().
|
||||||
typedef typename TestCase::ParamType ParamType;
|
using ParamType = typename TestSuite::ParamType;
|
||||||
// A function that returns an instance of appropriate generator type.
|
// A function that returns an instance of appropriate generator type.
|
||||||
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||||
typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc;
|
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
||||||
|
|
||||||
explicit ParameterizedTestCaseInfo(
|
explicit ParameterizedTestSuiteInfo(const char* name,
|
||||||
const char* name, CodeLocation code_location)
|
CodeLocation code_location)
|
||||||
: test_case_name_(name), code_location_(code_location) {}
|
: test_suite_name_(name), code_location_(code_location) {}
|
||||||
|
|
||||||
// Test case base name for display purposes.
|
// Test case base name for display purposes.
|
||||||
virtual const std::string& GetTestCaseName() const { return test_case_name_; }
|
const std::string& GetTestSuiteName() const override {
|
||||||
|
return test_suite_name_;
|
||||||
|
}
|
||||||
// Test case id to verify identity.
|
// Test case id to verify identity.
|
||||||
virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
|
TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
|
||||||
// TEST_P macro uses AddTestPattern() to record information
|
// TEST_P macro uses AddTestPattern() to record information
|
||||||
// about a single test in a LocalTestInfo structure.
|
// about a single test in a LocalTestInfo structure.
|
||||||
// test_case_name is the base name of the test case (without invocation
|
// test_suite_name is the base name of the test suite (without invocation
|
||||||
// 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 case base name and DoBar is test base name.
|
// test suite base name and DoBar is test base name.
|
||||||
void AddTestPattern(const char* test_case_name,
|
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
|
||||||
const char* test_base_name,
|
|
||||||
TestMetaFactoryBase<ParamType>* meta_factory) {
|
TestMetaFactoryBase<ParamType>* meta_factory) {
|
||||||
tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
|
tests_.push_back(std::shared_ptr<TestInfo>(
|
||||||
test_base_name,
|
new TestInfo(test_suite_name, test_base_name, meta_factory)));
|
||||||
meta_factory)));
|
|
||||||
}
|
}
|
||||||
// INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
|
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
||||||
// about a generator.
|
// about a generator.
|
||||||
int AddTestCaseInstantiation(const std::string& instantiation_name,
|
int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
||||||
GeneratorCreationFunc* func,
|
GeneratorCreationFunc* func,
|
||||||
ParamNameGeneratorFunc* name_func,
|
ParamNameGeneratorFunc* name_func,
|
||||||
const char* file, int line) {
|
const char* file, int line) {
|
||||||
instantiations_.push_back(
|
instantiations_.push_back(
|
||||||
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
||||||
return 0; // Return value used only to run this method in namespace scope.
|
return 0; // Return value used only to run this method in namespace scope.
|
||||||
}
|
}
|
||||||
// UnitTest class invokes this method to register tests in this test case
|
// UnitTest class invokes this method to register tests in this test suite
|
||||||
// test cases right before running tests in RUN_ALL_TESTS macro.
|
// test suites right before running tests in RUN_ALL_TESTS macro.
|
||||||
// This method should not be called more then once on any single
|
// This method should not be called more than once on any single
|
||||||
// instance of a ParameterizedTestCaseInfoBase derived class.
|
// instance of a ParameterizedTestSuiteInfoBase derived class.
|
||||||
// UnitTest has a guard to prevent from calling this method more then once.
|
// UnitTest has a guard to prevent from calling this method more than once.
|
||||||
virtual void RegisterTests() {
|
void RegisterTests() override {
|
||||||
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
||||||
test_it != tests_.end(); ++test_it) {
|
test_it != tests_.end(); ++test_it) {
|
||||||
linked_ptr<TestInfo> test_info = *test_it;
|
std::shared_ptr<TestInfo> test_info = *test_it;
|
||||||
for (typename InstantiationContainer::iterator gen_it =
|
for (typename InstantiationContainer::iterator gen_it =
|
||||||
instantiations_.begin(); gen_it != instantiations_.end();
|
instantiations_.begin(); gen_it != instantiations_.end();
|
||||||
++gen_it) {
|
++gen_it) {
|
||||||
@@ -551,10 +539,10 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
const char* file = gen_it->file;
|
const char* file = gen_it->file;
|
||||||
int line = gen_it->line;
|
int line = gen_it->line;
|
||||||
|
|
||||||
std::string test_case_name;
|
std::string test_suite_name;
|
||||||
if ( !instantiation_name.empty() )
|
if ( !instantiation_name.empty() )
|
||||||
test_case_name = instantiation_name + "/";
|
test_suite_name = instantiation_name + "/";
|
||||||
test_case_name += test_info->test_case_base_name;
|
test_suite_name += test_info->test_suite_base_name;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
std::set<std::string> test_param_names;
|
std::set<std::string> test_param_names;
|
||||||
@@ -577,39 +565,39 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
|
|
||||||
test_param_names.insert(param_name);
|
test_param_names.insert(param_name);
|
||||||
|
|
||||||
test_name_stream << test_info->test_base_name << "/" << param_name;
|
if (!test_info->test_base_name.empty()) {
|
||||||
|
test_name_stream << test_info->test_base_name << "/";
|
||||||
|
}
|
||||||
|
test_name_stream << param_name;
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
test_case_name.c_str(),
|
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
|
||||||
test_name_stream.GetString().c_str(),
|
nullptr, // No type parameter.
|
||||||
NULL, // No type parameter.
|
PrintToString(*param_it).c_str(), code_location_,
|
||||||
PrintToString(*param_it).c_str(),
|
GetTestSuiteTypeId(),
|
||||||
code_location_,
|
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||||
GetTestCaseTypeId(),
|
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
||||||
TestCase::SetUpTestCase,
|
|
||||||
TestCase::TearDownTestCase,
|
|
||||||
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
||||||
} // for param_it
|
} // for param_it
|
||||||
} // for gen_it
|
} // for gen_it
|
||||||
} // for test_it
|
} // for test_it
|
||||||
} // RegisterTests
|
} // RegisterTests
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// LocalTestInfo structure keeps information about a single test registered
|
// LocalTestInfo structure keeps information about a single test registered
|
||||||
// with TEST_P macro.
|
// with TEST_P macro.
|
||||||
struct TestInfo {
|
struct TestInfo {
|
||||||
TestInfo(const char* a_test_case_base_name,
|
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
|
||||||
const char* a_test_base_name,
|
TestMetaFactoryBase<ParamType>* a_test_meta_factory)
|
||||||
TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
|
: test_suite_base_name(a_test_suite_base_name),
|
||||||
test_case_base_name(a_test_case_base_name),
|
test_base_name(a_test_base_name),
|
||||||
test_base_name(a_test_base_name),
|
test_meta_factory(a_test_meta_factory) {}
|
||||||
test_meta_factory(a_test_meta_factory) {}
|
|
||||||
|
|
||||||
const std::string test_case_base_name;
|
const std::string test_suite_base_name;
|
||||||
const std::string test_base_name;
|
const std::string test_base_name;
|
||||||
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
|
const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
|
||||||
};
|
};
|
||||||
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
|
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
|
||||||
// Records data received from INSTANTIATE_TEST_CASE_P macros:
|
// Records data received from INSTANTIATE_TEST_SUITE_P macros:
|
||||||
// <Instantiation name, Sequence generator creation function,
|
// <Instantiation name, Sequence generator creation function,
|
||||||
// Name generator function, Source file, Source line>
|
// Name generator function, Source file, Source line>
|
||||||
struct InstantiationInfo {
|
struct InstantiationInfo {
|
||||||
@@ -646,76 +634,247 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string test_case_name_;
|
const std::string test_suite_name_;
|
||||||
CodeLocation code_location_;
|
CodeLocation code_location_;
|
||||||
TestInfoContainer tests_;
|
TestInfoContainer tests_;
|
||||||
InstantiationContainer instantiations_;
|
InstantiationContainer instantiations_;
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
|
||||||
}; // class ParameterizedTestCaseInfo
|
}; // class ParameterizedTestSuiteInfo
|
||||||
|
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
template <class TestCase>
|
||||||
|
using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
|
// ParameterizedTestSuiteRegistry contains a map of
|
||||||
// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
|
// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
|
||||||
// macros use it to locate their corresponding ParameterizedTestCaseInfo
|
// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
|
||||||
// descriptors.
|
// ParameterizedTestSuiteInfo descriptors.
|
||||||
class ParameterizedTestCaseRegistry {
|
class ParameterizedTestSuiteRegistry {
|
||||||
public:
|
public:
|
||||||
ParameterizedTestCaseRegistry() {}
|
ParameterizedTestSuiteRegistry() {}
|
||||||
~ParameterizedTestCaseRegistry() {
|
~ParameterizedTestSuiteRegistry() {
|
||||||
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
|
for (auto& test_suite_info : test_suite_infos_) {
|
||||||
it != test_case_infos_.end(); ++it) {
|
delete test_suite_info;
|
||||||
delete *it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looks up or creates and returns a structure containing information about
|
// Looks up or creates and returns a structure containing information about
|
||||||
// tests and instantiations of a particular test case.
|
// tests and instantiations of a particular test suite.
|
||||||
template <class TestCase>
|
template <class TestSuite>
|
||||||
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
||||||
const char* test_case_name,
|
const char* test_suite_name, CodeLocation code_location) {
|
||||||
CodeLocation code_location) {
|
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
||||||
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
|
for (auto& test_suite_info : test_suite_infos_) {
|
||||||
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
|
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
||||||
it != test_case_infos_.end(); ++it) {
|
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||||
if ((*it)->GetTestCaseName() == test_case_name) {
|
|
||||||
if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
|
|
||||||
// Complain about incorrect usage of Google Test facilities
|
// Complain about incorrect usage of Google Test facilities
|
||||||
// and terminate the program since we cannot guaranty correct
|
// and terminate the program since we cannot guaranty correct
|
||||||
// test case setup and tear-down in this case.
|
// test suite setup and tear-down in this case.
|
||||||
ReportInvalidTestCaseType(test_case_name, code_location);
|
ReportInvalidTestSuiteType(test_suite_name, code_location);
|
||||||
posix::Abort();
|
posix::Abort();
|
||||||
} else {
|
} else {
|
||||||
// At this point we are sure that the object we found is of the same
|
// At this point we are sure that the object we found is of the same
|
||||||
// type we are looking for, so we downcast it to that type
|
// type we are looking for, so we downcast it to that type
|
||||||
// without further checks.
|
// without further checks.
|
||||||
typed_test_info = CheckedDowncastToActualType<
|
typed_test_info = CheckedDowncastToActualType<
|
||||||
ParameterizedTestCaseInfo<TestCase> >(*it);
|
ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typed_test_info == NULL) {
|
if (typed_test_info == nullptr) {
|
||||||
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
|
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
||||||
test_case_name, code_location);
|
test_suite_name, code_location);
|
||||||
test_case_infos_.push_back(typed_test_info);
|
test_suite_infos_.push_back(typed_test_info);
|
||||||
}
|
}
|
||||||
return typed_test_info;
|
return typed_test_info;
|
||||||
}
|
}
|
||||||
void RegisterTests() {
|
void RegisterTests() {
|
||||||
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
|
for (auto& test_suite_info : test_suite_infos_) {
|
||||||
it != test_case_infos_.end(); ++it) {
|
test_suite_info->RegisterTests();
|
||||||
(*it)->RegisterTests();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Legacy API is deprecated but still available
|
||||||
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
template <class TestCase>
|
||||||
|
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||||
|
const char* test_case_name, CodeLocation code_location) {
|
||||||
|
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
|
|
||||||
|
private:
|
||||||
|
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
||||||
|
|
||||||
|
TestSuiteInfoContainer test_suite_infos_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Forward declarations of ValuesIn(), which is implemented in
|
||||||
|
// include/gtest/gtest-param-test.h.
|
||||||
|
template <class Container>
|
||||||
|
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||||
|
const Container& container);
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
// Used in the Values() function to provide polymorphic capabilities.
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
class ValueArray {
|
||||||
|
public:
|
||||||
|
ValueArray(Ts... v) : v_{std::move(v)...} {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
operator ParamGenerator<T>() const { // NOLINT
|
||||||
|
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
|
template <typename T, size_t... I>
|
||||||
|
std::vector<T> MakeVector(IndexSequence<I...>) const {
|
||||||
|
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
|
||||||
|
}
|
||||||
|
|
||||||
TestCaseInfoContainer test_case_infos_;
|
FlatTuple<Ts...> v_;
|
||||||
|
};
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
|
template <typename... T>
|
||||||
|
class CartesianProductGenerator
|
||||||
|
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
||||||
|
public:
|
||||||
|
typedef ::std::tuple<T...> ParamType;
|
||||||
|
|
||||||
|
CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
|
||||||
|
: generators_(g) {}
|
||||||
|
~CartesianProductGenerator() override {}
|
||||||
|
|
||||||
|
ParamIteratorInterface<ParamType>* Begin() const override {
|
||||||
|
return new Iterator(this, generators_, false);
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<ParamType>* End() const override {
|
||||||
|
return new Iterator(this, generators_, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class I>
|
||||||
|
class IteratorImpl;
|
||||||
|
template <size_t... I>
|
||||||
|
class IteratorImpl<IndexSequence<I...>>
|
||||||
|
: public ParamIteratorInterface<ParamType> {
|
||||||
|
public:
|
||||||
|
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
||||||
|
const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
|
||||||
|
: base_(base),
|
||||||
|
begin_(std::get<I>(generators).begin()...),
|
||||||
|
end_(std::get<I>(generators).end()...),
|
||||||
|
current_(is_end ? end_ : begin_) {
|
||||||
|
ComputeCurrentValue();
|
||||||
|
}
|
||||||
|
~IteratorImpl() override {}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
|
||||||
|
return base_;
|
||||||
|
}
|
||||||
|
// Advance should not be called on beyond-of-range iterators
|
||||||
|
// so no component iterators must be beyond end of range, either.
|
||||||
|
void Advance() override {
|
||||||
|
assert(!AtEnd());
|
||||||
|
// Advance the last iterator.
|
||||||
|
++std::get<sizeof...(T) - 1>(current_);
|
||||||
|
// if that reaches end, propagate that up.
|
||||||
|
AdvanceIfEnd<sizeof...(T) - 1>();
|
||||||
|
ComputeCurrentValue();
|
||||||
|
}
|
||||||
|
ParamIteratorInterface<ParamType>* Clone() const override {
|
||||||
|
return new IteratorImpl(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ParamType* Current() const override { return current_value_.get(); }
|
||||||
|
|
||||||
|
bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
|
||||||
|
// Having the same base generator guarantees that the other
|
||||||
|
// iterator is of the same type and we can downcast.
|
||||||
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||||
|
<< "The program attempted to compare iterators "
|
||||||
|
<< "from different generators." << std::endl;
|
||||||
|
const IteratorImpl* typed_other =
|
||||||
|
CheckedDowncastToActualType<const IteratorImpl>(&other);
|
||||||
|
|
||||||
|
// We must report iterators equal if they both point beyond their
|
||||||
|
// respective ranges. That can happen in a variety of fashions,
|
||||||
|
// so we have to consult AtEnd().
|
||||||
|
if (AtEnd() && typed_other->AtEnd()) return true;
|
||||||
|
|
||||||
|
bool same = true;
|
||||||
|
bool dummy[] = {
|
||||||
|
(same = same && std::get<I>(current_) ==
|
||||||
|
std::get<I>(typed_other->current_))...};
|
||||||
|
(void)dummy;
|
||||||
|
return same;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <size_t ThisI>
|
||||||
|
void AdvanceIfEnd() {
|
||||||
|
if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
|
||||||
|
|
||||||
|
bool last = ThisI == 0;
|
||||||
|
if (last) {
|
||||||
|
// We are done. Nothing else to propagate.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t NextI = ThisI - (ThisI != 0);
|
||||||
|
std::get<ThisI>(current_) = std::get<ThisI>(begin_);
|
||||||
|
++std::get<NextI>(current_);
|
||||||
|
AdvanceIfEnd<NextI>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeCurrentValue() {
|
||||||
|
if (!AtEnd())
|
||||||
|
current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
|
||||||
|
}
|
||||||
|
bool AtEnd() const {
|
||||||
|
bool at_end = false;
|
||||||
|
bool dummy[] = {
|
||||||
|
(at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
|
||||||
|
(void)dummy;
|
||||||
|
return at_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ParamGeneratorInterface<ParamType>* const base_;
|
||||||
|
std::tuple<typename ParamGenerator<T>::iterator...> begin_;
|
||||||
|
std::tuple<typename ParamGenerator<T>::iterator...> end_;
|
||||||
|
std::tuple<typename ParamGenerator<T>::iterator...> current_;
|
||||||
|
std::shared_ptr<ParamType> current_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
|
||||||
|
|
||||||
|
std::tuple<ParamGenerator<T>...> generators_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class... Gen>
|
||||||
|
class CartesianProductHolder {
|
||||||
|
public:
|
||||||
|
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
|
||||||
|
template <typename... T>
|
||||||
|
operator ParamGenerator<::std::tuple<T...>>() const {
|
||||||
|
return ParamGenerator<::std::tuple<T...>>(
|
||||||
|
new CartesianProductGenerator<T...>(generators_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::tuple<Gen...> generators_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|||||||
@@ -38,14 +38,13 @@
|
|||||||
// Determines the platform on which Google Test is compiled.
|
// Determines the platform on which Google Test is compiled.
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
# define GTEST_OS_CYGWIN 1
|
# define GTEST_OS_CYGWIN 1
|
||||||
#elif defined __SYMBIAN32__
|
# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
# define GTEST_OS_SYMBIAN 1
|
# define GTEST_OS_WINDOWS_MINGW 1
|
||||||
|
# define GTEST_OS_WINDOWS 1
|
||||||
#elif defined _WIN32
|
#elif defined _WIN32
|
||||||
# define GTEST_OS_WINDOWS 1
|
# define GTEST_OS_WINDOWS 1
|
||||||
# ifdef _WIN32_WCE
|
# ifdef _WIN32_WCE
|
||||||
# define GTEST_OS_WINDOWS_MOBILE 1
|
# define GTEST_OS_WINDOWS_MOBILE 1
|
||||||
# elif defined(__MINGW__) || defined(__MINGW32__)
|
|
||||||
# define GTEST_OS_WINDOWS_MINGW 1
|
|
||||||
# elif defined(WINAPI_FAMILY)
|
# elif defined(WINAPI_FAMILY)
|
||||||
# include <winapifamily.h>
|
# include <winapifamily.h>
|
||||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
@@ -65,15 +64,21 @@
|
|||||||
# else
|
# else
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
# define GTEST_OS_WINDOWS_DESKTOP 1
|
||||||
# endif // _WIN32_WCE
|
# endif // _WIN32_WCE
|
||||||
|
#elif defined __OS2__
|
||||||
|
# define GTEST_OS_OS2 1
|
||||||
#elif defined __APPLE__
|
#elif defined __APPLE__
|
||||||
# define GTEST_OS_MAC 1
|
# define GTEST_OS_MAC 1
|
||||||
# if TARGET_OS_IPHONE
|
# if TARGET_OS_IPHONE
|
||||||
# define GTEST_OS_IOS 1
|
# define GTEST_OS_IOS 1
|
||||||
# endif
|
# endif
|
||||||
|
#elif defined __DragonFly__
|
||||||
|
# define GTEST_OS_DRAGONFLY 1
|
||||||
#elif defined __FreeBSD__
|
#elif defined __FreeBSD__
|
||||||
# define GTEST_OS_FREEBSD 1
|
# define GTEST_OS_FREEBSD 1
|
||||||
#elif defined __Fuchsia__
|
#elif defined __Fuchsia__
|
||||||
# define GTEST_OS_FUCHSIA 1
|
# define GTEST_OS_FUCHSIA 1
|
||||||
|
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
||||||
|
# define GTEST_OS_GNU_KFREEBSD 1
|
||||||
#elif defined __linux__
|
#elif defined __linux__
|
||||||
# define GTEST_OS_LINUX 1
|
# define GTEST_OS_LINUX 1
|
||||||
# if defined __ANDROID__
|
# if defined __ANDROID__
|
||||||
@@ -95,6 +100,8 @@
|
|||||||
# define GTEST_OS_OPENBSD 1
|
# define GTEST_OS_OPENBSD 1
|
||||||
#elif defined __QNX__
|
#elif defined __QNX__
|
||||||
# define GTEST_OS_QNX 1
|
# define GTEST_OS_QNX 1
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
#define GTEST_OS_HAIKU 1
|
||||||
#endif // __CYGWIN__
|
#endif // __CYGWIN__
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -94,7 +94,8 @@ class GTEST_API_ String {
|
|||||||
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compares two C strings. Returns true iff they have the same content.
|
// Compares two C strings. Returns true if and only if they have the same
|
||||||
|
// content.
|
||||||
//
|
//
|
||||||
// Unlike strcmp(), this function can handle NULL argument(s). A
|
// Unlike strcmp(), this function can handle NULL argument(s). A
|
||||||
// NULL C string is considered different to any non-NULL C string,
|
// NULL C string is considered different to any non-NULL C string,
|
||||||
@@ -107,16 +108,16 @@ class GTEST_API_ String {
|
|||||||
// returned.
|
// returned.
|
||||||
static std::string ShowWideCString(const wchar_t* wide_c_str);
|
static std::string ShowWideCString(const wchar_t* wide_c_str);
|
||||||
|
|
||||||
// Compares two wide C strings. Returns true iff they have the same
|
// Compares two wide C strings. Returns true if and only if they have the
|
||||||
// content.
|
// same content.
|
||||||
//
|
//
|
||||||
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
||||||
// NULL C string is considered different to any non-NULL C string,
|
// NULL C string is considered different to any non-NULL C string,
|
||||||
// including the empty string.
|
// including the empty string.
|
||||||
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
|
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
|
||||||
|
|
||||||
// Compares two C strings, ignoring case. Returns true iff they
|
// Compares two C strings, ignoring case. Returns true if and only if
|
||||||
// have the same content.
|
// they have the same content.
|
||||||
//
|
//
|
||||||
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
||||||
// A NULL C string is considered different to any non-NULL C string,
|
// A NULL C string is considered different to any non-NULL C string,
|
||||||
@@ -124,8 +125,8 @@ class GTEST_API_ String {
|
|||||||
static bool CaseInsensitiveCStringEquals(const char* lhs,
|
static bool CaseInsensitiveCStringEquals(const char* lhs,
|
||||||
const char* rhs);
|
const char* rhs);
|
||||||
|
|
||||||
// Compares two wide C strings, ignoring case. Returns true iff they
|
// Compares two wide C strings, ignoring case. Returns true if and only if
|
||||||
// have the same content.
|
// they have the same content.
|
||||||
//
|
//
|
||||||
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
||||||
// A NULL C string is considered different to any non-NULL wide C string,
|
// A NULL C string is considered different to any non-NULL wide C string,
|
||||||
@@ -139,8 +140,8 @@ class GTEST_API_ String {
|
|||||||
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
||||||
const wchar_t* rhs);
|
const wchar_t* rhs);
|
||||||
|
|
||||||
// Returns true iff the given string ends with the given suffix, ignoring
|
// Returns true if and only if the given string ends with the given suffix,
|
||||||
// case. Any string is considered to end with an empty suffix.
|
// ignoring case. Any string is considered to end with an empty suffix.
|
||||||
static bool EndsWithCaseInsensitive(
|
static bool EndsWithCaseInsensitive(
|
||||||
const std::string& str, const std::string& suffix);
|
const std::string& str, const std::string& suffix);
|
||||||
|
|
||||||
@@ -150,6 +151,9 @@ class GTEST_API_ String {
|
|||||||
// Formats an int value as "%X".
|
// Formats an int value as "%X".
|
||||||
static std::string FormatHexInt(int value);
|
static std::string FormatHexInt(int value);
|
||||||
|
|
||||||
|
// Formats an int value as "%X".
|
||||||
|
static std::string FormatHexUInt32(UInt32 value);
|
||||||
|
|
||||||
// Formats a byte as "%02X".
|
// Formats a byte as "%02X".
|
||||||
static std::string FormatByte(unsigned char value);
|
static std::string FormatByte(unsigned char value);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,348 +0,0 @@
|
|||||||
$$ -*- mode: c++; -*-
|
|
||||||
$var n = 10 $$ Maximum number of tuple fields we want to support.
|
|
||||||
$$ This meta comment fixes auto-indentation in Emacs. }}
|
|
||||||
// Copyright 2009 Google Inc.
|
|
||||||
// All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
|
|
||||||
|
|
||||||
// GOOGLETEST_CM0001 DO NOT DELETE
|
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
|
||||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
|
||||||
|
|
||||||
#include <utility> // For ::std::pair.
|
|
||||||
|
|
||||||
// The compiler used in Symbian has a bug that prevents us from declaring the
|
|
||||||
// tuple template as a friend (it complains that tuple is redefined). This
|
|
||||||
// bypasses the bug by declaring the members that should otherwise be
|
|
||||||
// private as public.
|
|
||||||
// Sun Studio versions < 12 also have the above bug.
|
|
||||||
#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
|
|
||||||
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
|
|
||||||
#else
|
|
||||||
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
|
|
||||||
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
|
|
||||||
private:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
|
|
||||||
// with our own definitions. Therefore using our own tuple does not work on
|
|
||||||
// those compilers.
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
|
|
||||||
# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
|
|
||||||
GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
$range i 0..n-1
|
|
||||||
$range j 0..n
|
|
||||||
$range k 1..n
|
|
||||||
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
|
|
||||||
#define GTEST_0_TUPLE_(T) tuple<>
|
|
||||||
|
|
||||||
$for k [[
|
|
||||||
$range m 0..k-1
|
|
||||||
$range m2 k..n-1
|
|
||||||
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
$range m 0..j-1
|
|
||||||
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// In theory, defining stuff in the ::std namespace is undefined
|
|
||||||
// behavior. We can do this as we are playing the role of a standard
|
|
||||||
// library vendor.
|
|
||||||
namespace std {
|
|
||||||
namespace tr1 {
|
|
||||||
|
|
||||||
template <$for i, [[typename T$i = void]]>
|
|
||||||
class tuple;
|
|
||||||
|
|
||||||
// Anything in namespace gtest_internal is Google Test's INTERNAL
|
|
||||||
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
|
|
||||||
namespace gtest_internal {
|
|
||||||
|
|
||||||
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
|
|
||||||
template <typename T>
|
|
||||||
struct ByRef { typedef const T& type; }; // NOLINT
|
|
||||||
template <typename T>
|
|
||||||
struct ByRef<T&> { typedef T& type; }; // NOLINT
|
|
||||||
|
|
||||||
// A handy wrapper for ByRef.
|
|
||||||
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
|
|
||||||
|
|
||||||
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
|
|
||||||
// is the same as tr1::add_reference<T>::type.
|
|
||||||
template <typename T>
|
|
||||||
struct AddRef { typedef T& type; }; // NOLINT
|
|
||||||
template <typename T>
|
|
||||||
struct AddRef<T&> { typedef T& type; }; // NOLINT
|
|
||||||
|
|
||||||
// A handy wrapper for AddRef.
|
|
||||||
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
|
|
||||||
|
|
||||||
// A helper for implementing get<k>().
|
|
||||||
template <int k> class Get;
|
|
||||||
|
|
||||||
// A helper for implementing tuple_element<k, T>. kIndexValid is true
|
|
||||||
// iff k < the number of fields in tuple type T.
|
|
||||||
template <bool kIndexValid, int kIndex, class Tuple>
|
|
||||||
struct TupleElement;
|
|
||||||
|
|
||||||
|
|
||||||
$for i [[
|
|
||||||
template <GTEST_$(n)_TYPENAMES_(T)>
|
|
||||||
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
|
|
||||||
typedef T$i type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
} // namespace gtest_internal
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class tuple<> {
|
|
||||||
public:
|
|
||||||
tuple() {}
|
|
||||||
tuple(const tuple& /* t */) {}
|
|
||||||
tuple& operator=(const tuple& /* t */) { return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$for k [[
|
|
||||||
$range m 0..k-1
|
|
||||||
template <GTEST_$(k)_TYPENAMES_(T)>
|
|
||||||
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
|
|
||||||
public:
|
|
||||||
template <int k> friend class gtest_internal::Get;
|
|
||||||
|
|
||||||
tuple() : $for m, [[f$(m)_()]] {}
|
|
||||||
|
|
||||||
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
|
|
||||||
$for m, [[f$(m)_(f$m)]] {}
|
|
||||||
|
|
||||||
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
|
|
||||||
|
|
||||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
|
||||||
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
|
|
||||||
|
|
||||||
$if k == 2 [[
|
|
||||||
template <typename U0, typename U1>
|
|
||||||
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
|
||||||
|
|
||||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
|
||||||
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
|
|
||||||
return CopyFrom(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
$if k == 2 [[
|
|
||||||
template <typename U0, typename U1>
|
|
||||||
tuple& operator=(const ::std::pair<U0, U1>& p) {
|
|
||||||
f0_ = p.first;
|
|
||||||
f1_ = p.second;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
|
||||||
|
|
||||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
|
||||||
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
|
|
||||||
|
|
||||||
$for m [[
|
|
||||||
f$(m)_ = t.f$(m)_;
|
|
||||||
|
|
||||||
]]
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$for m [[
|
|
||||||
T$m f$(m)_;
|
|
||||||
|
|
||||||
]]
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
// 6.1.3.2 Tuple creation functions.
|
|
||||||
|
|
||||||
// Known limitations: we don't support passing an
|
|
||||||
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
|
|
||||||
// implement tie().
|
|
||||||
|
|
||||||
inline tuple<> make_tuple() { return tuple<>(); }
|
|
||||||
|
|
||||||
$for k [[
|
|
||||||
$range m 0..k-1
|
|
||||||
|
|
||||||
template <GTEST_$(k)_TYPENAMES_(T)>
|
|
||||||
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
|
|
||||||
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
// 6.1.3.3 Tuple helper classes.
|
|
||||||
|
|
||||||
template <typename Tuple> struct tuple_size;
|
|
||||||
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
template <GTEST_$(j)_TYPENAMES_(T)>
|
|
||||||
struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
|
|
||||||
static const int value = $j;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
template <int k, class Tuple>
|
|
||||||
struct tuple_element {
|
|
||||||
typedef typename gtest_internal::TupleElement<
|
|
||||||
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
|
|
||||||
|
|
||||||
// 6.1.3.4 Element access.
|
|
||||||
|
|
||||||
namespace gtest_internal {
|
|
||||||
|
|
||||||
|
|
||||||
$for i [[
|
|
||||||
template <>
|
|
||||||
class Get<$i> {
|
|
||||||
public:
|
|
||||||
template <class Tuple>
|
|
||||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
|
|
||||||
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
|
|
||||||
|
|
||||||
template <class Tuple>
|
|
||||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
|
|
||||||
ConstField(const Tuple& t) { return t.f$(i)_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
]]
|
|
||||||
} // namespace gtest_internal
|
|
||||||
|
|
||||||
template <int k, GTEST_$(n)_TYPENAMES_(T)>
|
|
||||||
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
|
|
||||||
get(GTEST_$(n)_TUPLE_(T)& t) {
|
|
||||||
return gtest_internal::Get<k>::Field(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int k, GTEST_$(n)_TYPENAMES_(T)>
|
|
||||||
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
|
|
||||||
get(const GTEST_$(n)_TUPLE_(T)& t) {
|
|
||||||
return gtest_internal::Get<k>::ConstField(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6.1.3.5 Relational operators
|
|
||||||
|
|
||||||
// We only implement == and !=, as we don't have a need for the rest yet.
|
|
||||||
|
|
||||||
namespace gtest_internal {
|
|
||||||
|
|
||||||
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
|
|
||||||
// first k fields of t1 equals the first k fields of t2.
|
|
||||||
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
|
|
||||||
// k1 != k2.
|
|
||||||
template <int kSize1, int kSize2>
|
|
||||||
struct SameSizeTuplePrefixComparator;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct SameSizeTuplePrefixComparator<0, 0> {
|
|
||||||
template <class Tuple1, class Tuple2>
|
|
||||||
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int k>
|
|
||||||
struct SameSizeTuplePrefixComparator<k, k> {
|
|
||||||
template <class Tuple1, class Tuple2>
|
|
||||||
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
|
|
||||||
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
|
|
||||||
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gtest_internal
|
|
||||||
|
|
||||||
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
|
|
||||||
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
|
|
||||||
const GTEST_$(n)_TUPLE_(U)& u) {
|
|
||||||
return gtest_internal::SameSizeTuplePrefixComparator<
|
|
||||||
tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
|
|
||||||
tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
|
|
||||||
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
|
|
||||||
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
|
|
||||||
|
|
||||||
// 6.1.4 Pairs.
|
|
||||||
// Unimplemented.
|
|
||||||
|
|
||||||
} // namespace tr1
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
#undef GTEST_$(j)_TUPLE_
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
|
|
||||||
$for j [[
|
|
||||||
#undef GTEST_$(j)_TYPENAMES_
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
|
|
||||||
#undef GTEST_BY_REF_
|
|
||||||
#undef GTEST_ADD_REF_
|
|
||||||
#undef GTEST_TUPLE_ELEMENT_
|
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
|
||||||
@@ -31,12 +31,11 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
// Type utilities needed for implementing typed and type-parameterized
|
// Type utilities needed for implementing typed and type-parameterized
|
||||||
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
// Currently we support at most 50 types in a list, and at most 50
|
// Currently we support at most 50 types in a list, and at most 50
|
||||||
// type-parameterized tests in one type-parameterized test case.
|
// type-parameterized tests in one type-parameterized test suite.
|
||||||
// Please contact googletestframework@googlegroups.com if you need
|
// Please contact googletestframework@googlegroups.com if you need
|
||||||
// more.
|
// more.
|
||||||
|
|
||||||
@@ -89,7 +88,7 @@ std::string GetTypeName() {
|
|||||||
# if GTEST_HAS_CXXABI_H_
|
# if GTEST_HAS_CXXABI_H_
|
||||||
using abi::__cxa_demangle;
|
using abi::__cxa_demangle;
|
||||||
# endif // GTEST_HAS_CXXABI_H_
|
# endif // GTEST_HAS_CXXABI_H_
|
||||||
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
|
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
||||||
const std::string name_str(status == 0 ? readable_name : name);
|
const std::string name_str(status == 0 ? readable_name : name);
|
||||||
free(readable_name);
|
free(readable_name);
|
||||||
return CanonicalizeForStdLibVersioning(name_str);
|
return CanonicalizeForStdLibVersioning(name_str);
|
||||||
@@ -106,18 +105,6 @@ std::string GetTypeName() {
|
|||||||
|
|
||||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
|
|
||||||
// type. This can be used as a compile-time assertion to ensure that
|
|
||||||
// two types are equal.
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct AssertTypeEq;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct AssertTypeEq<T, T> {
|
|
||||||
typedef bool type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A unique type used as the default value for the arguments of class
|
// A unique type used as the default value for the arguments of class
|
||||||
// template Types. This allows us to simulate variadic templates
|
// template Types. This allows us to simulate variadic templates
|
||||||
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
|
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
|
||||||
@@ -3312,8 +3299,8 @@ struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The TypeList template makes it possible to use either a single type
|
// The TypeList template makes it possible to use either a single type
|
||||||
// or a Types<...> list in TYPED_TEST_CASE() and
|
// or a Types<...> list in TYPED_TEST_SUITE() and
|
||||||
// INSTANTIATE_TYPED_TEST_CASE_P().
|
// INSTANTIATE_TYPED_TEST_SUITE_P().
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TypeList {
|
struct TypeList {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ $var n = 50 $$ Maximum length of type lists we want to support.
|
|||||||
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||||
//
|
//
|
||||||
// Currently we support at most $n types in a list, and at most $n
|
// Currently we support at most $n types in a list, and at most $n
|
||||||
// type-parameterized tests in one type-parameterized test case.
|
// type-parameterized tests in one type-parameterized test suite.
|
||||||
// Please contact googletestframework@googlegroups.com if you need
|
// Please contact googletestframework@googlegroups.com if you need
|
||||||
// more.
|
// more.
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ std::string GetTypeName() {
|
|||||||
# if GTEST_HAS_CXXABI_H_
|
# if GTEST_HAS_CXXABI_H_
|
||||||
using abi::__cxa_demangle;
|
using abi::__cxa_demangle;
|
||||||
# endif // GTEST_HAS_CXXABI_H_
|
# endif // GTEST_HAS_CXXABI_H_
|
||||||
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
|
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
||||||
const std::string name_str(status == 0 ? readable_name : name);
|
const std::string name_str(status == 0 ? readable_name : name);
|
||||||
free(readable_name);
|
free(readable_name);
|
||||||
return CanonicalizeForStdLibVersioning(name_str);
|
return CanonicalizeForStdLibVersioning(name_str);
|
||||||
@@ -104,18 +104,6 @@ std::string GetTypeName() {
|
|||||||
|
|
||||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
|
|
||||||
// type. This can be used as a compile-time assertion to ensure that
|
|
||||||
// two types are equal.
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct AssertTypeEq;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct AssertTypeEq<T, T> {
|
|
||||||
typedef bool type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A unique type used as the default value for the arguments of class
|
// A unique type used as the default value for the arguments of class
|
||||||
// template Types. This allows us to simulate variadic templates
|
// template Types. This allows us to simulate variadic templates
|
||||||
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
|
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
|
||||||
@@ -291,8 +279,8 @@ struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
|
|||||||
]]
|
]]
|
||||||
|
|
||||||
// The TypeList template makes it possible to use either a single type
|
// The TypeList template makes it possible to use either a single type
|
||||||
// or a Types<...> list in TYPED_TEST_CASE() and
|
// or a Types<...> list in TYPED_TEST_SUITE() and
|
||||||
// INSTANTIATE_TYPED_TEST_CASE_P().
|
// INSTANTIATE_TYPED_TEST_SUITE_P().
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TypeList {
|
struct TypeList {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user