summaryrefslogtreecommitdiffstats
path: root/testing/gmock/include
diff options
context:
space:
mode:
Diffstat (limited to 'testing/gmock/include')
-rw-r--r--testing/gmock/include/gmock/gmock-actions.h153
-rw-r--r--testing/gmock/include/gmock/gmock-generated-actions.h207
-rw-r--r--testing/gmock/include/gmock/gmock-generated-actions.h.pump209
-rw-r--r--testing/gmock/include/gmock/gmock-generated-function-mockers.h111
-rw-r--r--testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump49
-rw-r--r--testing/gmock/include/gmock/gmock-generated-matchers.h236
-rw-r--r--testing/gmock/include/gmock/gmock-generated-matchers.h.pump239
-rw-r--r--testing/gmock/include/gmock/gmock-generated-nice-strict.h72
-rw-r--r--testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump24
-rw-r--r--testing/gmock/include/gmock/gmock-matchers.h503
-rw-r--r--testing/gmock/include/gmock/gmock-more-actions.h190
-rw-r--r--testing/gmock/include/gmock/gmock-printers.h24
-rw-r--r--testing/gmock/include/gmock/gmock-spec-builders.h357
-rw-r--r--testing/gmock/include/gmock/gmock.h1
-rw-r--r--testing/gmock/include/gmock/internal/gmock-internal-utils.h82
-rw-r--r--testing/gmock/include/gmock/internal/gmock-port.h80
16 files changed, 1348 insertions, 1189 deletions
diff --git a/testing/gmock/include/gmock/gmock-actions.h b/testing/gmock/include/gmock/gmock-actions.h
index a283ed7..7f21a7d 100644
--- a/testing/gmock/include/gmock/gmock-actions.h
+++ b/testing/gmock/include/gmock/gmock-actions.h
@@ -43,6 +43,7 @@
#include <errno.h>
#endif
+#include <gmock/gmock-printers.h>
#include <gmock/internal/gmock-internal-utils.h>
#include <gmock/internal/gmock-port.h>
@@ -124,32 +125,13 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0');
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0');
-// 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
-//
-// MSVC does not recognize signed wchar_t or unsigned wchar_t. It
-// 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
-// specified.
-//
-// Therefore we provide a default action for wchar_t when compiled
-// with gcc or _NATIVE_WCHAR_T_DEFINED is defined.
-//
// There's no need for a default action for signed wchar_t, as that
// type is the same as wchar_t for gcc, and invalid for MSVC.
//
// There's also no need for a default action for unsigned wchar_t, as
// that type is the same as unsigned int for gcc, and invalid for
// MSVC.
-#if defined(__GNUC__) || defined(_NATIVE_WCHAR_T_DEFINED)
+#if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT
#endif
@@ -605,7 +587,7 @@ class AssignAction {
const T2 value_;
};
-#ifndef _WIN32_WCE
+#if !GTEST_OS_WINDOWS_MOBILE
// Implements the SetErrnoAndReturn action to simulate return from
// various system calls and libc functions.
@@ -625,7 +607,7 @@ class SetErrnoAndReturnAction {
const T result_;
};
-#endif // _WIN32_WCE
+#endif // !GTEST_OS_WINDOWS_MOBILE
// Implements the SetArgumentPointee<N>(x) action for any function
// whose N-th argument (0-based) is a pointer to x's type. The
@@ -668,39 +650,6 @@ class SetArgumentPointeeAction<N, Proto, true> {
const internal::linked_ptr<Proto> proto_;
};
-// Implements the SetArrayArgument<N>(first, last) action for any function
-// whose N-th argument (0-based) is a pointer or iterator to a type that can be
-// implicitly converted from *first.
-template <size_t N, typename InputIterator>
-class SetArrayArgumentAction {
- public:
- // Constructs an action that sets the variable pointed to by the
- // N-th function argument to 'value'.
- explicit SetArrayArgumentAction(InputIterator first, InputIterator last)
- : first_(first), last_(last) {
- }
-
- template <typename Result, typename ArgumentTuple>
- void Perform(const ArgumentTuple& args) const {
- CompileAssertTypesEqual<void, Result>();
-
- // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
- // 4996 (Function call with parameters that may be unsafe) there.
-#if GTEST_OS_WINDOWS
-#pragma warning(push) // Saves the current warning state.
-#pragma warning(disable:4996) // Temporarily disables warning 4996.
-#endif // GTEST_OS_WINDOWS
- ::std::copy(first_, last_, ::std::tr1::get<N>(args));
-#if GTEST_OS_WINDOWS
-#pragma warning(pop) // Restores the warning state.
-#endif // GTEST_OS_WINDOWS
- }
-
- private:
- const InputIterator first_;
- const InputIterator last_;
-};
-
// Implements the InvokeWithoutArgs(f) action. The template argument
// FunctionImpl is the implementation type of f, which can be either a
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
@@ -787,6 +736,74 @@ class IgnoreResultAction {
const A action_;
};
+// A ReferenceWrapper<T> object represents a reference to type T,
+// which can be either const or not. It can be explicitly converted
+// from, and implicitly converted to, a T&. Unlike a reference,
+// 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
+ // a T&.
+ operator T&() const { return *pointer_; }
+ private:
+ T* pointer_;
+};
+
+// Allows the expression ByRef(x) to be printed as a reference to x.
+template <typename T>
+void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
+ T& value = ref;
+ UniversalPrinter<T&>::Print(value, os);
+}
+
+// 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:
+ // Implements the DoAll(...) action for a particular function type F.
+ 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)
+ : action1_(action1), action2_(action2) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ action1_.Perform(args);
+ return action2_.Perform(args);
+ }
+
+ private:
+ const Action<VoidResult> action1_;
+ const Action<F> action2_;
+ };
+
+ Action1 action1_;
+ Action2 action2_;
+};
+
} // namespace internal
// An Unused object can be implicitly constructed from ANY value.
@@ -870,23 +887,13 @@ SetArgumentPointee(const T& x) {
N, T, internal::IsAProtocolMessage<T>::value>(x));
}
-// Creates an action that sets the elements of the array pointed to by the N-th
-// (0-based) function argument, which can be either a pointer or an iterator,
-// to the values of the elements in the source range [first, last).
-template <size_t N, typename InputIterator>
-PolymorphicAction<internal::SetArrayArgumentAction<N, InputIterator> >
-SetArrayArgument(InputIterator first, InputIterator last) {
- return MakePolymorphicAction(internal::SetArrayArgumentAction<
- N, InputIterator>(first, last));
-}
-
// Creates an action that sets a pointer referent to a given value.
template <typename T1, typename T2>
PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) {
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
}
-#ifndef _WIN32_WCE
+#if !GTEST_OS_WINDOWS_MOBILE
// Creates an action that sets errno and returns the appropriate error.
template <typename T>
@@ -896,7 +903,7 @@ SetErrnoAndReturn(int errval, T result) {
internal::SetErrnoAndReturnAction<T>(errval, result));
}
-#endif // _WIN32_WCE
+#endif // !GTEST_OS_WINDOWS_MOBILE
// Various overloads for InvokeWithoutArgs().
@@ -926,6 +933,18 @@ inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
return internal::IgnoreResultAction<A>(an_action);
}
+// Creates a reference wrapper for the given L-value. If necessary,
+// you can explicitly specify the type of the reference. For example,
+// suppose 'derived' is an object of type Derived, ByRef(derived)
+// would wrap a Derived&. If you want to wrap a const Base& instead,
+// where Base is a base class of Derived, just write:
+//
+// ByRef<const Base>(derived)
+template <typename T>
+inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
+ return internal::ReferenceWrapper<T>(l_value);
+}
+
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
diff --git a/testing/gmock/include/gmock/gmock-generated-actions.h b/testing/gmock/include/gmock/gmock-generated-actions.h
index fa02faa..143a99b 100644
--- a/testing/gmock/include/gmock/gmock-generated-actions.h
+++ b/testing/gmock/include/gmock/gmock-generated-actions.h
@@ -282,65 +282,6 @@ class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
}
};
-
-// 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_;
-};
-
-// Implements the Invoke(object_ptr, &Class::Method) action.
-template <class Class, typename MethodPtr>
-class InvokeMethodAction {
- public:
- InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
- : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) const {
- return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
- obj_ptr_, method_ptr_, args);
- }
- private:
- Class* const obj_ptr_;
- const MethodPtr method_ptr_;
-};
-
-// A ReferenceWrapper<T> object represents a reference to type T,
-// which can be either const or not. It can be explicitly converted
-// from, and implicitly converted to, a T&. Unlike a reference,
-// 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
- // a T&.
- operator T&() const { return *pointer_; }
- private:
- T* pointer_;
-};
-
// CallableHelper has static methods for invoking "callables",
// i.e. function pointers and functors. It uses overloading to
// provide a uniform interface for invoking different kinds of
@@ -676,47 +617,6 @@ class WithArgsAction {
const InnerAction action_;
};
-// 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:
- // Implements the DoAll(...) action for a particular function type F.
- 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)
- : action1_(action1), action2_(action2) {}
-
- virtual Result Perform(const ArgumentTuple& args) {
- action1_.Perform(args);
- return action2_.Perform(args);
- }
-
- private:
- const Action<VoidResult> action1_;
- const Action<F> action2_;
- };
-
- Action1 action1_;
- Action2 action2_;
-};
-
// A macro from the ACTION* family (defined later in this file)
// 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
@@ -852,57 +752,6 @@ class ActionHelper {
// 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));
-}
-
-// Creates a reference wrapper for the given L-value. If necessary,
-// you can explicitly specify the type of the reference. For example,
-// suppose 'derived' is an object of type Derived, ByRef(derived)
-// would wrap a Derived&. If you want to wrap a const Base& instead,
-// where Base is a base class of Derived, just write:
-//
-// ByRef<const Base>(derived)
-template <typename T>
-inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
- return internal::ReferenceWrapper<T>(l_value);
-}
-
-// 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);
-}
-
// 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
@@ -2430,48 +2279,6 @@ ACTION_TEMPLATE(InvokeArgument,
::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
-// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
-// mock function to *pointer.
-ACTION_TEMPLATE(SaveArg,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_1_VALUE_PARAMS(pointer)) {
- *pointer = ::std::tr1::get<k>(args);
-}
-
-// Action SetArgReferee<k>(value) assigns 'value' to the variable
-// referenced by the k-th (0-based) argument of the mock function.
-ACTION_TEMPLATE(SetArgReferee,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_1_VALUE_PARAMS(value)) {
- typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
- // Ensures that argument #k is a reference. If you get a compiler
- // 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.
- GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
- SetArgReferee_must_be_used_with_a_reference_argument);
- ::std::tr1::get<k>(args) = value;
-}
-
-// Action SetArrayArgument<k>(first, last) copies the elements in
-// source range [first, last) to the array pointed to by the k-th
-// (0-based) argument, which can be either a pointer or an
-// iterator. The action does not take ownership of the elements in the
-// source range.
-ACTION_TEMPLATE(SetArrayArgument,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_2_VALUE_PARAMS(first, last)) {
- // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
- // 4996 (Function call with parameters that may be unsafe) there.
-#ifdef _MSC_VER
-#pragma warning(push) // Saves the current warning state.
-#pragma warning(disable:4996) // Temporarily disables warning 4996.
-#endif
- ::std::copy(first, last, ::std::tr1::get<k>(args));
-#ifdef _MSC_VER
-#pragma warning(pop) // Restores the warning state.
-#endif
-}
-
// Various overloads for ReturnNew<T>().
//
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
@@ -2543,20 +2350,6 @@ ACTION_TEMPLATE(ReturnNew,
return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
-// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
-// function.
-ACTION_TEMPLATE(DeleteArg,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_0_VALUE_PARAMS()) {
- delete ::std::tr1::get<k>(args);
-}
-
-// Action Throw(exception) can be used in a mock function of any type
-// to throw the given exception. Any copyable value can be thrown.
-#if GTEST_HAS_EXCEPTIONS
-ACTION_P(Throw, exception) { throw exception; }
-#endif // GTEST_HAS_EXCEPTIONS
-
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/testing/gmock/include/gmock/gmock-generated-actions.h.pump b/testing/gmock/include/gmock/gmock-generated-actions.h.pump
index b5223a34..05bf3db 100644
--- a/testing/gmock/include/gmock/gmock-generated-actions.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-actions.h.pump
@@ -1,6 +1,6 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
-$$ gmock-generated-variadic-actions.h.
+$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$}} This meta comment fixes auto-indentation in editors.
@@ -84,65 +84,6 @@ $import return (obj_ptr->*method_ptr)($gets);
]]
-
-// 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_;
-};
-
-// Implements the Invoke(object_ptr, &Class::Method) action.
-template <class Class, typename MethodPtr>
-class InvokeMethodAction {
- public:
- InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
- : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) const {
- return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
- obj_ptr_, method_ptr_, args);
- }
- private:
- Class* const obj_ptr_;
- const MethodPtr method_ptr_;
-};
-
-// A ReferenceWrapper<T> object represents a reference to type T,
-// which can be either const or not. It can be explicitly converted
-// from, and implicitly converted to, a T&. Unlike a reference,
-// 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
- // a T&.
- operator T&() const { return *pointer_; }
- private:
- T* pointer_;
-};
-
// CallableHelper has static methods for invoking "callables",
// i.e. function pointers and functors. It uses overloading to
// provide a uniform interface for invoking different kinds of
@@ -289,47 +230,6 @@ class WithArgsAction {
const InnerAction action_;
};
-// 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:
- // Implements the DoAll(...) action for a particular function type F.
- 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)
- : action1_(action1), action2_(action2) {}
-
- virtual Result Perform(const ArgumentTuple& args) {
- action1_.Perform(args);
- return action2_.Perform(args);
- }
-
- private:
- const Action<VoidResult> action1_;
- const Action<F> action2_;
- };
-
- Action1 action1_;
- Action2 action2_;
-};
-
// A macro from the ACTION* family (defined later in this file)
// 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
@@ -377,57 +277,6 @@ $template
// 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));
-}
-
-// Creates a reference wrapper for the given L-value. If necessary,
-// you can explicitly specify the type of the reference. For example,
-// suppose 'derived' is an object of type Derived, ByRef(derived)
-// would wrap a Derived&. If you want to wrap a const Base& instead,
-// where Base is a base class of Derived, just write:
-//
-// ByRef<const Base>(derived)
-template <typename T>
-inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
- return internal::ReferenceWrapper<T>(l_value);
-}
-
-// 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);
-}
-
// 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
@@ -929,48 +778,6 @@ ACTION_TEMPLATE(InvokeArgument,
]]
-// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
-// mock function to *pointer.
-ACTION_TEMPLATE(SaveArg,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_1_VALUE_PARAMS(pointer)) {
- *pointer = ::std::tr1::get<k>(args);
-}
-
-// Action SetArgReferee<k>(value) assigns 'value' to the variable
-// referenced by the k-th (0-based) argument of the mock function.
-ACTION_TEMPLATE(SetArgReferee,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_1_VALUE_PARAMS(value)) {
- typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
- // Ensures that argument #k is a reference. If you get a compiler
- // 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.
- GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
- SetArgReferee_must_be_used_with_a_reference_argument);
- ::std::tr1::get<k>(args) = value;
-}
-
-// Action SetArrayArgument<k>(first, last) copies the elements in
-// source range [first, last) to the array pointed to by the k-th
-// (0-based) argument, which can be either a pointer or an
-// iterator. The action does not take ownership of the elements in the
-// source range.
-ACTION_TEMPLATE(SetArrayArgument,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_2_VALUE_PARAMS(first, last)) {
- // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
- // 4996 (Function call with parameters that may be unsafe) there.
-#ifdef _MSC_VER
-#pragma warning(push) // Saves the current warning state.
-#pragma warning(disable:4996) // Temporarily disables warning 4996.
-#endif
- ::std::copy(first, last, ::std::tr1::get<k>(args));
-#ifdef _MSC_VER
-#pragma warning(pop) // Restores the warning state.
-#endif
-}
-
// Various overloads for ReturnNew<T>().
//
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
@@ -989,20 +796,6 @@ ACTION_TEMPLATE(ReturnNew,
]]
-// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
-// function.
-ACTION_TEMPLATE(DeleteArg,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_0_VALUE_PARAMS()) {
- delete ::std::tr1::get<k>(args);
-}
-
-// Action Throw(exception) can be used in a mock function of any type
-// to throw the given exception. Any copyable value can be thrown.
-#if GTEST_HAS_EXCEPTIONS
-ACTION_P(Throw, exception) { throw exception; }
-#endif // GTEST_HAS_EXCEPTIONS
-
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/testing/gmock/include/gmock/gmock-generated-function-mockers.h b/testing/gmock/include/gmock/gmock-generated-function-mockers.h
index b6c1d82..3002b6c 100644
--- a/testing/gmock/include/gmock/gmock-generated-function-mockers.h
+++ b/testing/gmock/include/gmock/gmock-generated-function-mockers.h
@@ -712,6 +712,117 @@ using internal::FunctionMocker;
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
GMOCK_METHOD10_(typename, const, ct, m, F)
+// 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().
+template <typename F>
+class MockFunction;
+
+template <typename R>
+class MockFunction<R()> {
+ public:
+ MOCK_METHOD0_T(Call, R());
+};
+
+template <typename R, typename A0>
+class MockFunction<R(A0)> {
+ public:
+ MOCK_METHOD1_T(Call, R(A0));
+};
+
+template <typename R, typename A0, typename A1>
+class MockFunction<R(A0, A1)> {
+ public:
+ MOCK_METHOD2_T(Call, R(A0, A1));
+};
+
+template <typename R, typename A0, typename A1, typename A2>
+class MockFunction<R(A0, A1, A2)> {
+ public:
+ MOCK_METHOD3_T(Call, R(A0, A1, A2));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+class MockFunction<R(A0, A1, A2, A3)> {
+ public:
+ MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4>
+class MockFunction<R(A0, A1, A2, A3, A4)> {
+ public:
+ MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5>
+class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
+ public:
+ MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
+ public:
+ MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
+ public:
+ MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
+ public:
+ MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8,
+ typename A9>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
+ public:
+ MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
+};
+
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump b/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump
index 54b848f..3c84563 100644
--- a/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-function-mockers.h.pump
@@ -198,6 +198,55 @@ $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().
+template <typename F>
+class MockFunction;
+
+
+$for i [[
+$range j 0..i-1
+template <typename R$for j [[, typename A$j]]>
+class MockFunction<R($for j, [[A$j]])> {
+ public:
+ MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
+};
+
+
+]]
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/testing/gmock/include/gmock/gmock-generated-matchers.h b/testing/gmock/include/gmock/gmock-generated-matchers.h
index 1a3e60b..a59e457 100644
--- a/testing/gmock/include/gmock/gmock-generated-matchers.h
+++ b/testing/gmock/include/gmock/gmock-generated-matchers.h
@@ -290,163 +290,7 @@ class ArgsMatcher {
const InnerMatcher inner_matcher_;
};
-// Implements ElementsAre() and ElementsAreArray().
-template <typename Container>
-class ElementsAreMatcherImpl : public MatcherInterface<Container> {
- public:
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
- typedef internal::StlContainerView<RawContainer> View;
- typedef typename View::type StlContainer;
- typedef typename View::const_reference StlContainerReference;
- typedef typename StlContainer::value_type Element;
-
- // Constructs the matcher from a sequence of element values or
- // element matchers.
- template <typename InputIter>
- ElementsAreMatcherImpl(InputIter first, size_t count) {
- matchers_.reserve(count);
- InputIter it = first;
- for (size_t i = 0; i != count; ++i, ++it) {
- matchers_.push_back(MatcherCast<const Element&>(*it));
- }
- }
-
- // Returns true iff 'container' matches.
- virtual bool Matches(Container container) const {
- StlContainerReference stl_container = View::ConstReference(container);
- if (stl_container.size() != count())
- return false;
-
- typename StlContainer::const_iterator it = stl_container.begin();
- for (size_t i = 0; i != count(); ++it, ++i) {
- if (!matchers_[i].Matches(*it))
- return false;
- }
-
- return true;
- }
-
- // Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
- if (count() == 0) {
- *os << "is empty";
- } else if (count() == 1) {
- *os << "has 1 element that ";
- matchers_[0].DescribeTo(os);
- } else {
- *os << "has " << Elements(count()) << " where\n";
- for (size_t i = 0; i != count(); ++i) {
- *os << "element " << i << " ";
- matchers_[i].DescribeTo(os);
- if (i + 1 < count()) {
- *os << ",\n";
- }
- }
- }
- }
-
- // Describes what the negation of this matcher does.
- virtual void DescribeNegationTo(::std::ostream* os) const {
- if (count() == 0) {
- *os << "is not empty";
- return;
- }
-
- *os << "does not have " << Elements(count()) << ", or\n";
- for (size_t i = 0; i != count(); ++i) {
- *os << "element " << i << " ";
- matchers_[i].DescribeNegationTo(os);
- if (i + 1 < count()) {
- *os << ", or\n";
- }
- }
- }
-
- // Explains why 'container' matches, or doesn't match, this matcher.
- virtual void ExplainMatchResultTo(Container container,
- ::std::ostream* os) const {
- StlContainerReference stl_container = View::ConstReference(container);
- if (Matches(container)) {
- // We need to explain why *each* element matches (the obvious
- // ones can be skipped).
-
- bool reason_printed = false;
- typename StlContainer::const_iterator it = stl_container.begin();
- for (size_t i = 0; i != count(); ++it, ++i) {
- ::std::stringstream ss;
- matchers_[i].ExplainMatchResultTo(*it, &ss);
-
- const string s = ss.str();
- if (!s.empty()) {
- if (reason_printed) {
- *os << ",\n";
- }
- *os << "element " << i << " " << s;
- reason_printed = true;
- }
- }
- } else {
- // We need to explain why the container doesn't match.
- const size_t actual_count = stl_container.size();
- if (actual_count != count()) {
- // The element count doesn't match. If the container is
- // empty, there's no need to explain anything as Google Mock
- // already prints the empty container. Otherwise we just need
- // to show how many elements there actually are.
- if (actual_count != 0) {
- *os << "has " << Elements(actual_count);
- }
- return;
- }
-
- // The container has the right size but at least one element
- // doesn't match expectation. We need to find this element and
- // explain why it doesn't match.
- typename StlContainer::const_iterator it = stl_container.begin();
- for (size_t i = 0; i != count(); ++it, ++i) {
- if (matchers_[i].Matches(*it)) {
- continue;
- }
-
- *os << "element " << i << " doesn't match";
-
- ::std::stringstream ss;
- matchers_[i].ExplainMatchResultTo(*it, &ss);
- const string s = ss.str();
- if (!s.empty()) {
- *os << " (" << s << ")";
- }
- return;
- }
- }
- }
-
- private:
- static Message Elements(size_t count) {
- return Message() << count << (count == 1 ? " element" : " elements");
- }
-
- size_t count() const { return matchers_.size(); }
- std::vector<Matcher<const Element&> > matchers_;
-};
-
-// Implements ElementsAre() of 0-10 arguments.
-
-class ElementsAreMatcher0 {
- public:
- ElementsAreMatcher0() {}
-
- template <typename Container>
- operator Matcher<Container>() const {
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
- RawContainer;
- typedef typename internal::StlContainerView<RawContainer>::type::value_type
- Element;
-
- const Matcher<const Element&>* const matchers = NULL;
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
- }
-};
+// Implements ElementsAre() of 1-10 arguments.
template <typename T1>
class ElementsAreMatcher1 {
@@ -460,11 +304,15 @@ class ElementsAreMatcher1 {
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
- const Matcher<const Element&> matchers[] = {
- MatcherCast<const Element&>(e1_),
- };
-
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 1));
+ // Nokia's Symbian Compiler has a nasty bug where the object put
+ // in a one-element local array is not destructed when the array
+ // goes out of scope. This leads to obvious badness as we've
+ // added the linked_ptr in it to our other linked_ptrs list.
+ // Hence we implement ElementsAreMatcher1 specially to avoid using
+ // a local array.
+ const Matcher<const Element&> matcher =
+ MatcherCast<const Element&>(e1_);
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, 1));
}
private:
@@ -788,28 +636,6 @@ class ElementsAreMatcher10 {
const T10& e10_;
};
-// Implements ElementsAreArray().
-template <typename T>
-class ElementsAreArrayMatcher {
- public:
- ElementsAreArrayMatcher(const T* first, size_t count) :
- first_(first), count_(count) {}
-
- template <typename Container>
- operator Matcher<Container>() const {
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
- RawContainer;
- typedef typename internal::StlContainerView<RawContainer>::type::value_type
- Element;
-
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
- }
-
- private:
- const T* const first_;
- const size_t count_;
-};
-
} // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
@@ -1169,48 +995,6 @@ ElementsAreArray(const T (&array)[N]) {
// To learn more about using these macros, please search for 'MATCHER'
// on http://code.google.com/p/googlemock/wiki/CookBook.
-namespace testing {
-namespace internal {
-
-// Constants denoting interpolations in a matcher description string.
-const int kTupleInterpolation = -1; // "%(*)s"
-const int kPercentInterpolation = -2; // "%%"
-const int kInvalidInterpolation = -3; // "%" followed by invalid text
-
-// Records the location and content of an interpolation.
-struct Interpolation {
- Interpolation(const char* start, const char* end, int param)
- : start_pos(start), end_pos(end), param_index(param) {}
-
- // Points to the start of the interpolation (the '%' character).
- const char* start_pos;
- // Points to the first character after the interpolation.
- const char* end_pos;
- // 0-based index of the interpolated matcher parameter;
- // kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
- int param_index;
-};
-
-typedef ::std::vector<Interpolation> Interpolations;
-
-// Parses a matcher description string and returns a vector of
-// interpolations that appear in the string; generates non-fatal
-// failures iff 'description' is an invalid matcher description.
-// 'param_names' is a NULL-terminated array of parameter names in the
-// order they appear in the MATCHER_P*() parameter list.
-Interpolations ValidateMatcherDescription(
- const char* param_names[], const char* description);
-
-// Returns the actual matcher description, given the matcher name,
-// user-supplied description template string, interpolations in the
-// string, and the printed values of the matcher parameters.
-string FormatMatcherDescription(
- const char* matcher_name, const char* description,
- const Interpolations& interp, const Strings& param_values);
-
-} // namespace internal
-} // namespace testing
-
#define MATCHER(name, description)\
class name##Matcher {\
public:\
diff --git a/testing/gmock/include/gmock/gmock-generated-matchers.h.pump b/testing/gmock/include/gmock/gmock-generated-matchers.h.pump
index 653a2e8..c43aa87 100644
--- a/testing/gmock/include/gmock/gmock-generated-matchers.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-matchers.h.pump
@@ -1,6 +1,6 @@
$$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to
-$$ gmock-generated-variadic-actions.h.
+$$ gmock-generated-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$ }} This line fixes auto-indentation of the following code in Emacs.
@@ -173,163 +173,7 @@ class ArgsMatcher {
const InnerMatcher inner_matcher_;
};
-// Implements ElementsAre() and ElementsAreArray().
-template <typename Container>
-class ElementsAreMatcherImpl : public MatcherInterface<Container> {
- public:
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
- typedef internal::StlContainerView<RawContainer> View;
- typedef typename View::type StlContainer;
- typedef typename View::const_reference StlContainerReference;
- typedef typename StlContainer::value_type Element;
-
- // Constructs the matcher from a sequence of element values or
- // element matchers.
- template <typename InputIter>
- ElementsAreMatcherImpl(InputIter first, size_t count) {
- matchers_.reserve(count);
- InputIter it = first;
- for (size_t i = 0; i != count; ++i, ++it) {
- matchers_.push_back(MatcherCast<const Element&>(*it));
- }
- }
-
- // Returns true iff 'container' matches.
- virtual bool Matches(Container container) const {
- StlContainerReference stl_container = View::ConstReference(container);
- if (stl_container.size() != count())
- return false;
-
- typename StlContainer::const_iterator it = stl_container.begin();
- for (size_t i = 0; i != count(); ++it, ++i) {
- if (!matchers_[i].Matches(*it))
- return false;
- }
-
- return true;
- }
-
- // Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
- if (count() == 0) {
- *os << "is empty";
- } else if (count() == 1) {
- *os << "has 1 element that ";
- matchers_[0].DescribeTo(os);
- } else {
- *os << "has " << Elements(count()) << " where\n";
- for (size_t i = 0; i != count(); ++i) {
- *os << "element " << i << " ";
- matchers_[i].DescribeTo(os);
- if (i + 1 < count()) {
- *os << ",\n";
- }
- }
- }
- }
-
- // Describes what the negation of this matcher does.
- virtual void DescribeNegationTo(::std::ostream* os) const {
- if (count() == 0) {
- *os << "is not empty";
- return;
- }
-
- *os << "does not have " << Elements(count()) << ", or\n";
- for (size_t i = 0; i != count(); ++i) {
- *os << "element " << i << " ";
- matchers_[i].DescribeNegationTo(os);
- if (i + 1 < count()) {
- *os << ", or\n";
- }
- }
- }
-
- // Explains why 'container' matches, or doesn't match, this matcher.
- virtual void ExplainMatchResultTo(Container container,
- ::std::ostream* os) const {
- StlContainerReference stl_container = View::ConstReference(container);
- if (Matches(container)) {
- // We need to explain why *each* element matches (the obvious
- // ones can be skipped).
-
- bool reason_printed = false;
- typename StlContainer::const_iterator it = stl_container.begin();
- for (size_t i = 0; i != count(); ++it, ++i) {
- ::std::stringstream ss;
- matchers_[i].ExplainMatchResultTo(*it, &ss);
-
- const string s = ss.str();
- if (!s.empty()) {
- if (reason_printed) {
- *os << ",\n";
- }
- *os << "element " << i << " " << s;
- reason_printed = true;
- }
- }
- } else {
- // We need to explain why the container doesn't match.
- const size_t actual_count = stl_container.size();
- if (actual_count != count()) {
- // The element count doesn't match. If the container is
- // empty, there's no need to explain anything as Google Mock
- // already prints the empty container. Otherwise we just need
- // to show how many elements there actually are.
- if (actual_count != 0) {
- *os << "has " << Elements(actual_count);
- }
- return;
- }
-
- // The container has the right size but at least one element
- // doesn't match expectation. We need to find this element and
- // explain why it doesn't match.
- typename StlContainer::const_iterator it = stl_container.begin();
- for (size_t i = 0; i != count(); ++it, ++i) {
- if (matchers_[i].Matches(*it)) {
- continue;
- }
-
- *os << "element " << i << " doesn't match";
-
- ::std::stringstream ss;
- matchers_[i].ExplainMatchResultTo(*it, &ss);
- const string s = ss.str();
- if (!s.empty()) {
- *os << " (" << s << ")";
- }
- return;
- }
- }
- }
-
- private:
- static Message Elements(size_t count) {
- return Message() << count << (count == 1 ? " element" : " elements");
- }
-
- size_t count() const { return matchers_.size(); }
- std::vector<Matcher<const Element&> > matchers_;
-};
-
-// Implements ElementsAre() of 0-10 arguments.
-
-class ElementsAreMatcher0 {
- public:
- ElementsAreMatcher0() {}
-
- template <typename Container>
- operator Matcher<Container>() const {
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
- RawContainer;
- typedef typename internal::StlContainerView<RawContainer>::type::value_type
- Element;
-
- const Matcher<const Element&>* const matchers = NULL;
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
- }
-};
+// Implements ElementsAre() of 1-$n arguments.
$range i 1..n
@@ -348,6 +192,19 @@ class ElementsAreMatcher$i {
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
+$if i==1 [[
+
+ // Nokia's Symbian Compiler has a nasty bug where the object put
+ // in a one-element local array is not destructed when the array
+ // goes out of scope. This leads to obvious badness as we've
+ // added the linked_ptr in it to our other linked_ptrs list.
+ // Hence we implement ElementsAreMatcher1 specially to avoid using
+ // a local array.
+ const Matcher<const Element&> matcher =
+ MatcherCast<const Element&>(e1_);
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, 1));
+]] $else [[
+
const Matcher<const Element&> matchers[] = {
$for j [[
@@ -357,6 +214,8 @@ $for j [[
};
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i));
+]]
+
}
private:
@@ -369,28 +228,6 @@ $for j [[
]]
-// Implements ElementsAreArray().
-template <typename T>
-class ElementsAreArrayMatcher {
- public:
- ElementsAreArrayMatcher(const T* first, size_t count) :
- first_(first), count_(count) {}
-
- template <typename Container>
- operator Matcher<Container>() const {
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
- RawContainer;
- typedef typename internal::StlContainerView<RawContainer>::type::value_type
- Element;
-
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
- }
-
- private:
- const T* const first_;
- const size_t count_;
-};
-
} // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
@@ -625,48 +462,6 @@ $$ // show up in the generated code.
// To learn more about using these macros, please search for 'MATCHER'
// on http://code.google.com/p/googlemock/wiki/CookBook.
-namespace testing {
-namespace internal {
-
-// Constants denoting interpolations in a matcher description string.
-const int kTupleInterpolation = -1; // "%(*)s"
-const int kPercentInterpolation = -2; // "%%"
-const int kInvalidInterpolation = -3; // "%" followed by invalid text
-
-// Records the location and content of an interpolation.
-struct Interpolation {
- Interpolation(const char* start, const char* end, int param)
- : start_pos(start), end_pos(end), param_index(param) {}
-
- // Points to the start of the interpolation (the '%' character).
- const char* start_pos;
- // Points to the first character after the interpolation.
- const char* end_pos;
- // 0-based index of the interpolated matcher parameter;
- // kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
- int param_index;
-};
-
-typedef ::std::vector<Interpolation> Interpolations;
-
-// Parses a matcher description string and returns a vector of
-// interpolations that appear in the string; generates non-fatal
-// failures iff 'description' is an invalid matcher description.
-// 'param_names' is a NULL-terminated array of parameter names in the
-// order they appear in the MATCHER_P*() parameter list.
-Interpolations ValidateMatcherDescription(
- const char* param_names[], const char* description);
-
-// Returns the actual matcher description, given the matcher name,
-// user-supplied description template string, interpolations in the
-// string, and the printed values of the matcher parameters.
-string FormatMatcherDescription(
- const char* matcher_name, const char* description,
- const Interpolations& interp, const Strings& param_values);
-
-} // namespace internal
-} // namespace testing
-
$range i 0..n
$for i
diff --git a/testing/gmock/include/gmock/gmock-generated-nice-strict.h b/testing/gmock/include/gmock/gmock-generated-nice-strict.h
index f961d79..fc9a81b 100644
--- a/testing/gmock/include/gmock/gmock-generated-nice-strict.h
+++ b/testing/gmock/include/gmock/gmock-generated-nice-strict.h
@@ -70,42 +70,49 @@ class NiceMock : public MockClass {
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
NiceMock() {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2>
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -113,7 +120,8 @@ class NiceMock : public MockClass {
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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -121,7 +129,8 @@ class NiceMock : public MockClass {
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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -129,7 +138,8 @@ class NiceMock : public MockClass {
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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -137,11 +147,13 @@ class NiceMock : public MockClass {
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) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
virtual ~NiceMock() {
- Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::UnregisterCallReaction(
+ internal::implicit_cast<MockClass*>(this));
}
};
@@ -151,40 +163,47 @@ class StrictMock : public MockClass {
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
StrictMock() {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2>
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -192,7 +211,8 @@ class StrictMock : public MockClass {
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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -200,7 +220,8 @@ class StrictMock : public MockClass {
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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -208,7 +229,8 @@ class StrictMock : public MockClass {
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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
@@ -216,11 +238,13 @@ class StrictMock : public MockClass {
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) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
virtual ~StrictMock() {
- Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::UnregisterCallReaction(
+ internal::implicit_cast<MockClass*>(this));
}
};
diff --git a/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump b/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump
index 580e79f..b265c2e4 100644
--- a/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump
+++ b/testing/gmock/include/gmock/gmock-generated-nice-strict.h.pump
@@ -73,14 +73,16 @@ class NiceMock : public MockClass {
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
NiceMock() {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
$range i 2..n
@@ -88,13 +90,15 @@ $for i [[
$range j 1..i
template <$for j, [[typename A$j]]>
NiceMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
- Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
]]
virtual ~NiceMock() {
- Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::UnregisterCallReaction(
+ internal::implicit_cast<MockClass*>(this));
}
};
@@ -104,25 +108,29 @@ class StrictMock : public MockClass {
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
StrictMock() {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
$for i [[
$range j 1..i
template <$for j, [[typename A$j]]>
StrictMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
- Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::FailUninterestingCalls(
+ internal::implicit_cast<MockClass*>(this));
}
]]
virtual ~StrictMock() {
- Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ ::testing::Mock::UnregisterCallReaction(
+ internal::implicit_cast<MockClass*>(this));
}
};
diff --git a/testing/gmock/include/gmock/gmock-matchers.h b/testing/gmock/include/gmock/gmock-matchers.h
index dc252e3..3d82279 100644
--- a/testing/gmock/include/gmock/gmock-matchers.h
+++ b/testing/gmock/include/gmock/gmock-matchers.h
@@ -236,6 +236,14 @@ class PolymorphicMatcher {
public:
explicit PolymorphicMatcher(const Impl& impl) : impl_(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<T>(impl_));
@@ -273,11 +281,12 @@ class PolymorphicMatcher {
// doesn't need to customize it.
ExplainMatchResultTo(impl_, x, os);
}
+
private:
const Impl impl_;
};
- const Impl impl_;
+ Impl impl_;
};
// Creates a matcher from its implementation. This is easier to use
@@ -311,47 +320,59 @@ inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
template <typename T, typename M>
Matcher<T> MatcherCast(M m);
-// TODO(vladl@google.com): Modify the implementation to reject casting
-// Matcher<int> to Matcher<double>.
// Implements SafeMatcherCast().
//
-// This overload handles polymorphic matchers only since monomorphic
-// matchers are handled by the next one.
-template <typename T, typename M>
-inline Matcher<T> SafeMatcherCast(M polymorphic_matcher) {
- return Matcher<T>(polymorphic_matcher);
-}
+// We use an intermediate class to do the actual safe casting as Nokia's
+// Symbian compiler cannot decide between
+// template <T, M> ... (M) and
+// template <T, U> ... (const Matcher<U>&)
+// for function templates but can for member function templates.
+template <typename T>
+class SafeMatcherCastImpl {
+ public:
+ // This overload handles polymorphic matchers only since monomorphic
+ // matchers are handled by the next one.
+ template <typename M>
+ static inline Matcher<T> Cast(M polymorphic_matcher) {
+ return Matcher<T>(polymorphic_matcher);
+ }
-// This overload handles monomorphic matchers.
-//
-// In general, if type T can be implicitly converted to type U, we can
-// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
-// contravariant): just keep a copy of the original Matcher<U>, convert the
-// argument from type T to U, and then pass it to the underlying Matcher<U>.
-// The only exception is when U is a reference and T is not, as the
-// underlying Matcher<U> may be interested in the argument's address, which
-// is not preserved in the conversion from T to U.
-template <typename T, typename U>
-Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
- // Enforce that T can be implicitly converted to U.
- GMOCK_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value),
- T_must_be_implicitly_convertible_to_U);
- // Enforce that we are not converting a non-reference type T to a reference
- // type U.
- GMOCK_COMPILE_ASSERT_(
- internal::is_reference<T>::value || !internal::is_reference<U>::value,
- cannot_convert_non_referentce_arg_to_reference);
- // In case both T and U are arithmetic types, enforce that the
- // conversion is not lossy.
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(T)) RawT;
- typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(U)) RawU;
- const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
- const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
- GMOCK_COMPILE_ASSERT_(
- kTIsOther || kUIsOther ||
- (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
- conversion_of_arithmetic_types_must_be_lossless);
- return MatcherCast<T>(matcher);
+ // This overload handles monomorphic matchers.
+ //
+ // In general, if type T can be implicitly converted to type U, we can
+ // safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
+ // contravariant): just keep a copy of the original Matcher<U>, convert the
+ // argument from type T to U, and then pass it to the underlying Matcher<U>.
+ // The only exception is when U is a reference and T is not, as the
+ // underlying Matcher<U> may be interested in the argument's address, which
+ // is not preserved in the conversion from T to U.
+ template <typename U>
+ static inline Matcher<T> Cast(const Matcher<U>& matcher) {
+ // Enforce that T can be implicitly converted to U.
+ GMOCK_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value),
+ T_must_be_implicitly_convertible_to_U);
+ // Enforce that we are not converting a non-reference type T to a reference
+ // type U.
+ GMOCK_COMPILE_ASSERT_(
+ internal::is_reference<T>::value || !internal::is_reference<U>::value,
+ cannot_convert_non_referentce_arg_to_reference);
+ // In case both T and U are arithmetic types, enforce that the
+ // conversion is not lossy.
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(T)) RawT;
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(U)) RawU;
+ const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
+ const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
+ GMOCK_COMPILE_ASSERT_(
+ kTIsOther || kUIsOther ||
+ (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
+ conversion_of_arithmetic_types_must_be_lossless);
+ return MatcherCast<T>(matcher);
+ }
+};
+
+template <typename T, typename M>
+inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) {
+ return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher);
}
// A<T>() returns a matcher that matches any value of type T.
@@ -612,6 +633,19 @@ GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ne, !=, "not equal to");
#undef GMOCK_IMPLEMENT_COMPARISON_MATCHER_
+// Implements the polymorphic IsNull() matcher, which matches any
+// pointer that is NULL.
+class IsNullMatcher {
+ public:
+ template <typename T>
+ bool Matches(T* p) const { return p == NULL; }
+
+ void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "is not NULL";
+ }
+};
+
// Implements the polymorphic NotNull() matcher, which matches any
// pointer that is not NULL.
class NotNullMatcher {
@@ -1614,7 +1648,7 @@ struct CallableTraits<ResType(*)(ArgType)> {
typedef ResType(*StorageType)(ArgType);
static void CheckIsValid(ResType(*f)(ArgType)) {
- GMOCK_CHECK_(f != NULL)
+ GTEST_CHECK_(f != NULL)
<< "NULL function pointer is passed into ResultOf().";
}
template <typename T>
@@ -1867,6 +1901,367 @@ class ContainsMatcher {
const M inner_matcher_;
};
+// Implements Key(inner_matcher) for the given argument pair type.
+// Key(inner_matcher) matches an std::pair whose 'first' field matches
+// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
+// std::map that contains at least one element whose key is >= 5.
+template <typename PairType>
+class KeyMatcherImpl : public MatcherInterface<PairType> {
+ public:
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(PairType)) RawPairType;
+ typedef typename RawPairType::first_type KeyType;
+
+ template <typename InnerMatcher>
+ explicit KeyMatcherImpl(InnerMatcher inner_matcher)
+ : inner_matcher_(
+ testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {
+ }
+
+ // Returns true iff 'key_value.first' (the key) matches the inner matcher.
+ virtual bool Matches(PairType key_value) const {
+ return inner_matcher_.Matches(key_value.first);
+ }
+
+ // Describes what this matcher does.
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "has a key that ";
+ inner_matcher_.DescribeTo(os);
+ }
+
+ // Describes what the negation of this matcher does.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't have a key that ";
+ inner_matcher_.DescribeTo(os);
+ }
+
+ // Explains why 'key_value' matches, or doesn't match, this matcher.
+ virtual void ExplainMatchResultTo(PairType key_value,
+ ::std::ostream* os) const {
+ inner_matcher_.ExplainMatchResultTo(key_value.first, os);
+ }
+
+ private:
+ const Matcher<const KeyType&> inner_matcher_;
+};
+
+// Implements polymorphic Key(matcher_for_key).
+template <typename M>
+class KeyMatcher {
+ public:
+ explicit KeyMatcher(M m) : matcher_for_key_(m) {}
+
+ template <typename PairType>
+ operator Matcher<PairType>() const {
+ return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_));
+ }
+
+ private:
+ const M matcher_for_key_;
+};
+
+// Implements Pair(first_matcher, second_matcher) for the given argument pair
+// type with its two matchers. See Pair() function below.
+template <typename PairType>
+class PairMatcherImpl : public MatcherInterface<PairType> {
+ public:
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(PairType)) RawPairType;
+ typedef typename RawPairType::first_type FirstType;
+ typedef typename RawPairType::second_type SecondType;
+
+ template <typename FirstMatcher, typename SecondMatcher>
+ PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher)
+ : first_matcher_(
+ testing::SafeMatcherCast<const FirstType&>(first_matcher)),
+ second_matcher_(
+ testing::SafeMatcherCast<const SecondType&>(second_matcher)) {
+ }
+
+ // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second'
+ // matches second_matcher.
+ virtual bool Matches(PairType a_pair) const {
+ return first_matcher_.Matches(a_pair.first) &&
+ second_matcher_.Matches(a_pair.second);
+ }
+
+ // Describes what this matcher does.
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "has a first field that ";
+ first_matcher_.DescribeTo(os);
+ *os << ", and has a second field that ";
+ second_matcher_.DescribeTo(os);
+ }
+
+ // Describes what the negation of this matcher does.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "has a first field that ";
+ first_matcher_.DescribeNegationTo(os);
+ *os << ", or has a second field that ";
+ second_matcher_.DescribeNegationTo(os);
+ }
+
+ // Explains why 'a_pair' matches, or doesn't match, this matcher.
+ virtual void ExplainMatchResultTo(PairType a_pair,
+ ::std::ostream* os) const {
+ ::std::stringstream ss1;
+ first_matcher_.ExplainMatchResultTo(a_pair.first, &ss1);
+ internal::string s1 = ss1.str();
+ if (s1 != "") {
+ s1 = "the first field " + s1;
+ }
+
+ ::std::stringstream ss2;
+ second_matcher_.ExplainMatchResultTo(a_pair.second, &ss2);
+ internal::string s2 = ss2.str();
+ if (s2 != "") {
+ s2 = "the second field " + s2;
+ }
+
+ *os << s1;
+ if (s1 != "" && s2 != "") {
+ *os << ", and ";
+ }
+ *os << s2;
+ }
+
+ private:
+ const Matcher<const FirstType&> first_matcher_;
+ const Matcher<const SecondType&> second_matcher_;
+};
+
+// Implements polymorphic Pair(first_matcher, second_matcher).
+template <typename FirstMatcher, typename SecondMatcher>
+class PairMatcher {
+ public:
+ PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)
+ : first_matcher_(first_matcher), second_matcher_(second_matcher) {}
+
+ template <typename PairType>
+ operator Matcher<PairType> () const {
+ return MakeMatcher(
+ new PairMatcherImpl<PairType>(
+ first_matcher_, second_matcher_));
+ }
+
+ private:
+ const FirstMatcher first_matcher_;
+ const SecondMatcher second_matcher_;
+};
+
+// Implements ElementsAre() and ElementsAreArray().
+template <typename Container>
+class ElementsAreMatcherImpl : public MatcherInterface<Container> {
+ public:
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
+ typedef internal::StlContainerView<RawContainer> View;
+ typedef typename View::type StlContainer;
+ typedef typename View::const_reference StlContainerReference;
+ typedef typename StlContainer::value_type Element;
+
+ // Constructs the matcher from a sequence of element values or
+ // element matchers.
+ template <typename InputIter>
+ ElementsAreMatcherImpl(InputIter first, size_t count) {
+ matchers_.reserve(count);
+ InputIter it = first;
+ for (size_t i = 0; i != count; ++i, ++it) {
+ matchers_.push_back(MatcherCast<const Element&>(*it));
+ }
+ }
+
+ // Returns true iff 'container' matches.
+ virtual bool Matches(Container container) const {
+ StlContainerReference stl_container = View::ConstReference(container);
+ if (stl_container.size() != count())
+ return false;
+
+ typename StlContainer::const_iterator it = stl_container.begin();
+ for (size_t i = 0; i != count(); ++it, ++i) {
+ if (!matchers_[i].Matches(*it))
+ return false;
+ }
+
+ return true;
+ }
+
+ // Describes what this matcher does.
+ virtual void DescribeTo(::std::ostream* os) const {
+ if (count() == 0) {
+ *os << "is empty";
+ } else if (count() == 1) {
+ *os << "has 1 element that ";
+ matchers_[0].DescribeTo(os);
+ } else {
+ *os << "has " << Elements(count()) << " where\n";
+ for (size_t i = 0; i != count(); ++i) {
+ *os << "element " << i << " ";
+ matchers_[i].DescribeTo(os);
+ if (i + 1 < count()) {
+ *os << ",\n";
+ }
+ }
+ }
+ }
+
+ // Describes what the negation of this matcher does.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ if (count() == 0) {
+ *os << "is not empty";
+ return;
+ }
+
+ *os << "does not have " << Elements(count()) << ", or\n";
+ for (size_t i = 0; i != count(); ++i) {
+ *os << "element " << i << " ";
+ matchers_[i].DescribeNegationTo(os);
+ if (i + 1 < count()) {
+ *os << ", or\n";
+ }
+ }
+ }
+
+ // Explains why 'container' matches, or doesn't match, this matcher.
+ virtual void ExplainMatchResultTo(Container container,
+ ::std::ostream* os) const {
+ StlContainerReference stl_container = View::ConstReference(container);
+ if (Matches(container)) {
+ // We need to explain why *each* element matches (the obvious
+ // ones can be skipped).
+
+ bool reason_printed = false;
+ typename StlContainer::const_iterator it = stl_container.begin();
+ for (size_t i = 0; i != count(); ++it, ++i) {
+ ::std::stringstream ss;
+ matchers_[i].ExplainMatchResultTo(*it, &ss);
+
+ const string s = ss.str();
+ if (!s.empty()) {
+ if (reason_printed) {
+ *os << ",\n";
+ }
+ *os << "element " << i << " " << s;
+ reason_printed = true;
+ }
+ }
+ } else {
+ // We need to explain why the container doesn't match.
+ const size_t actual_count = stl_container.size();
+ if (actual_count != count()) {
+ // The element count doesn't match. If the container is
+ // empty, there's no need to explain anything as Google Mock
+ // already prints the empty container. Otherwise we just need
+ // to show how many elements there actually are.
+ if (actual_count != 0) {
+ *os << "has " << Elements(actual_count);
+ }
+ return;
+ }
+
+ // The container has the right size but at least one element
+ // doesn't match expectation. We need to find this element and
+ // explain why it doesn't match.
+ typename StlContainer::const_iterator it = stl_container.begin();
+ for (size_t i = 0; i != count(); ++it, ++i) {
+ if (matchers_[i].Matches(*it)) {
+ continue;
+ }
+
+ *os << "element " << i << " doesn't match";
+
+ ::std::stringstream ss;
+ matchers_[i].ExplainMatchResultTo(*it, &ss);
+ const string s = ss.str();
+ if (!s.empty()) {
+ *os << " (" << s << ")";
+ }
+ return;
+ }
+ }
+ }
+
+ private:
+ static Message Elements(size_t count) {
+ return Message() << count << (count == 1 ? " element" : " elements");
+ }
+
+ size_t count() const { return matchers_.size(); }
+ std::vector<Matcher<const Element&> > matchers_;
+};
+
+// Implements ElementsAre() of 0 arguments.
+class ElementsAreMatcher0 {
+ public:
+ ElementsAreMatcher0() {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
+ RawContainer;
+ typedef typename internal::StlContainerView<RawContainer>::type::value_type
+ Element;
+
+ const Matcher<const Element&>* const matchers = NULL;
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
+ }
+};
+
+// Implements ElementsAreArray().
+template <typename T>
+class ElementsAreArrayMatcher {
+ public:
+ ElementsAreArrayMatcher(const T* first, size_t count) :
+ first_(first), count_(count) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
+ RawContainer;
+ typedef typename internal::StlContainerView<RawContainer>::type::value_type
+ Element;
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
+ }
+
+ private:
+ const T* const first_;
+ const size_t count_;
+};
+
+// Constants denoting interpolations in a matcher description string.
+const int kTupleInterpolation = -1; // "%(*)s"
+const int kPercentInterpolation = -2; // "%%"
+const int kInvalidInterpolation = -3; // "%" followed by invalid text
+
+// Records the location and content of an interpolation.
+struct Interpolation {
+ Interpolation(const char* start, const char* end, int param)
+ : start_pos(start), end_pos(end), param_index(param) {}
+
+ // Points to the start of the interpolation (the '%' character).
+ const char* start_pos;
+ // Points to the first character after the interpolation.
+ const char* end_pos;
+ // 0-based index of the interpolated matcher parameter;
+ // kTupleInterpolation for "%(*)s"; kPercentInterpolation for "%%".
+ int param_index;
+};
+
+typedef ::std::vector<Interpolation> Interpolations;
+
+// Parses a matcher description string and returns a vector of
+// interpolations that appear in the string; generates non-fatal
+// failures iff 'description' is an invalid matcher description.
+// 'param_names' is a NULL-terminated array of parameter names in the
+// order they appear in the MATCHER_P*() parameter list.
+Interpolations ValidateMatcherDescription(
+ const char* param_names[], const char* description);
+
+// Returns the actual matcher description, given the matcher name,
+// user-supplied description template string, interpolations in the
+// string, and the printed values of the matcher parameters.
+string FormatMatcherDescription(
+ const char* matcher_name, const char* description,
+ const Interpolations& interp, const Strings& param_values);
+
} // namespace internal
// Implements MatcherCast().
@@ -1949,6 +2344,11 @@ inline internal::NeMatcher<Rhs> Ne(Rhs x) {
return internal::NeMatcher<Rhs>(x);
}
+// Creates a polymorphic matcher that matches any NULL pointer.
+inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() {
+ return MakePolymorphicMatcher(internal::IsNullMatcher());
+}
+
// Creates a polymorphic matcher that matches any non-NULL pointer.
// This is convenient as Not(NULL) doesn't compile (the compiler
// thinks that that expression is comparing a pointer with an integer).
@@ -2332,7 +2732,8 @@ inline PolymorphicMatcher<internal::ContainerEqMatcher<
//
// ::std::map<int, size_t> page_lengths;
// page_lengths[1] = 100;
-// EXPECT_THAT(map_int, Contains(::std::pair<const int, size_t>(1, 100)));
+// EXPECT_THAT(page_lengths,
+// Contains(::std::pair<const int, size_t>(1, 100)));
//
// const char* user_ids[] = { "joe", "mike", "tom" };
// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom"))));
@@ -2341,6 +2742,26 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
return internal::ContainsMatcher<M>(matcher);
}
+// Key(inner_matcher) matches an std::pair whose 'first' field matches
+// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
+// std::map that contains at least one element whose key is >= 5.
+template <typename M>
+inline internal::KeyMatcher<M> Key(M inner_matcher) {
+ return internal::KeyMatcher<M>(inner_matcher);
+}
+
+// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field
+// matches first_matcher and whose 'second' field matches second_matcher. For
+// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used
+// to match a std::map<int, string> that contains exactly one element whose key
+// is >= 5 and whose value equals "foo".
+template <typename FirstMatcher, typename SecondMatcher>
+inline internal::PairMatcher<FirstMatcher, SecondMatcher>
+Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
+ return internal::PairMatcher<FirstMatcher, SecondMatcher>(
+ first_matcher, second_matcher);
+}
+
// Returns a predicate that is satisfied by anything that matches the
// given matcher.
template <typename M>
diff --git a/testing/gmock/include/gmock/gmock-more-actions.h b/testing/gmock/include/gmock/gmock-more-actions.h
new file mode 100644
index 0000000..c6fa6bb
--- /dev/null
+++ b/testing/gmock/include/gmock/gmock-more-actions.h
@@ -0,0 +1,190 @@
+// 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.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some actions that depend on gmock-generated-actions.h.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
+
+#include <gmock/gmock-generated-actions.h>
+
+namespace testing {
+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_;
+};
+
+// Implements the Invoke(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+class InvokeMethodAction {
+ public:
+ InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
+ : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) const {
+ return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
+ obj_ptr_, method_ptr_, args);
+ }
+ private:
+ Class* const obj_ptr_;
+ const MethodPtr method_ptr_;
+};
+
+} // namespace internal
+
+// 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);
+}
+
+// Action ReturnArg<k>() returns the k-th argument of the mock function.
+ACTION_TEMPLATE(ReturnArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_0_VALUE_PARAMS()) {
+ return std::tr1::get<k>(args);
+}
+
+// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
+// mock function to *pointer.
+ACTION_TEMPLATE(SaveArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(pointer)) {
+ *pointer = ::std::tr1::get<k>(args);
+}
+
+// Action SetArgReferee<k>(value) assigns 'value' to the variable
+// referenced by the k-th (0-based) argument of the mock function.
+ACTION_TEMPLATE(SetArgReferee,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(value)) {
+ typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
+ // Ensures that argument #k is a reference. If you get a compiler
+ // 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.
+ GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
+ SetArgReferee_must_be_used_with_a_reference_argument);
+ ::std::tr1::get<k>(args) = value;
+}
+
+// Action SetArrayArgument<k>(first, last) copies the elements in
+// source range [first, last) to the array pointed to by the k-th
+// (0-based) argument, which can be either a pointer or an
+// iterator. The action does not take ownership of the elements in the
+// source range.
+ACTION_TEMPLATE(SetArrayArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_2_VALUE_PARAMS(first, last)) {
+ // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
+ // 4996 (Function call with parameters that may be unsafe) there.
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4996) // Temporarily disables warning 4996.
+#endif
+ ::std::copy(first, last, ::std::tr1::get<k>(args));
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif
+}
+
+// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
+// function.
+ACTION_TEMPLATE(DeleteArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_0_VALUE_PARAMS()) {
+ delete ::std::tr1::get<k>(args);
+}
+
+// Action Throw(exception) can be used in a mock function of any type
+// to throw the given exception. Any copyable value can be thrown.
+#if GTEST_HAS_EXCEPTIONS
+ACTION_P(Throw, exception) { throw exception; }
+#endif // GTEST_HAS_EXCEPTIONS
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
diff --git a/testing/gmock/include/gmock/gmock-printers.h b/testing/gmock/include/gmock/gmock-printers.h
index 561de3d..e07d92a 100644
--- a/testing/gmock/include/gmock/gmock-printers.h
+++ b/testing/gmock/include/gmock/gmock-printers.h
@@ -129,14 +129,21 @@ class TypeWithoutFormatter {
sizeof(value), os);
}
};
+
+// We print a protobuf using its ShortDebugString() when the string
+// doesn't exceed this many characters; otherwise we print it using
+// DebugString() for better readability.
+const size_t kProtobufOneLinerMaxLength = 50;
+
template <typename T>
class TypeWithoutFormatter<T, true> {
public:
static void PrintValue(const T& value, ::std::ostream* os) {
- // Both ProtocolMessage and proto2::Message have the
- // ShortDebugString() method, so the same implementation works for
- // both.
- ::std::operator<<(*os, "<" + value.ShortDebugString() + ">");
+ const ::testing::internal::string short_str = value.ShortDebugString();
+ const ::testing::internal::string pretty_str =
+ short_str.length() <= kProtobufOneLinerMaxLength ?
+ short_str : ("\n" + value.DebugString());
+ ::std::operator<<(*os, "<" + pretty_str + ">");
}
};
@@ -272,9 +279,12 @@ void DefaultPrintTo(IsNotContainer /* dummy */,
if (p == NULL) {
*os << "NULL";
} else {
- // We cannot use implicit_cast or static_cast here, as they don't
- // work when p is a function pointer.
- *os << reinterpret_cast<const void*>(p);
+ // We want to print p as a const void*. However, we cannot cast
+ // it to const void* directly, even using reinterpret_cast, as
+ // earlier versions of gcc (e.g. 3.4.5) cannot compile the cast
+ // when p is a function pointer. Casting to UInt64 first solves
+ // the problem.
+ *os << reinterpret_cast<const void*>(reinterpret_cast<internal::UInt64>(p));
}
}
diff --git a/testing/gmock/include/gmock/gmock-spec-builders.h b/testing/gmock/include/gmock/gmock-spec-builders.h
index a22bcd1..765e06d 100644
--- a/testing/gmock/include/gmock/gmock-spec-builders.h
+++ b/testing/gmock/include/gmock/gmock-spec-builders.h
@@ -49,13 +49,13 @@
// .With(multi-argument-matchers)
// .Times(cardinality)
// .InSequence(sequences)
+// .After(expectations)
// .WillOnce(action)
// .WillRepeatedly(action)
// .RetiresOnSaturation();
//
-// where all clauses are optional, .InSequence() and .WillOnce() can
-// appear any number of times, and .Times() can be omitted only if
-// .WillOnce() or .WillRepeatedly() is present.
+// where all clauses are optional, and .InSequence()/.After()/
+// .WillOnce() can appear any number of times.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
@@ -76,22 +76,30 @@
namespace testing {
+// An abstract handle of an expectation.
+class Expectation;
+
+// A set of expectation handles.
+class ExpectationSet;
+
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
namespace internal {
-template <typename F>
-class FunctionMocker;
+// Implements a mock function.
+template <typename F> class FunctionMocker;
// Base class for expectations.
class ExpectationBase;
+// Implements an expectation.
+template <typename F> class TypedExpectation;
+
// Helper class for testing the Expectation class template.
class ExpectationTester;
// Base class for function mockers.
-template <typename F>
-class FunctionMockerBase;
+template <typename F> class FunctionMockerBase;
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
@@ -232,7 +240,8 @@ class DefaultActionSpec {
Clause last_clause_;
}; // class DefaultActionSpec
-// Possible reactions on uninteresting calls.
+// Possible reactions on uninteresting calls. TODO(wan@google.com):
+// rename the enum values to the kFoo style.
enum CallReaction {
ALLOW,
WARN,
@@ -327,31 +336,173 @@ class Mock {
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker);
}; // class Mock
+// An abstract handle of an expectation. Useful in the .After()
+// clause of EXPECT_CALL() for setting the (partial) order of
+// expectations. The syntax:
+//
+// Expectation e1 = EXPECT_CALL(...)...;
+// EXPECT_CALL(...).After(e1)...;
+//
+// sets two expectations where the latter can only be matched after
+// the former has been satisfied.
+//
+// Notes:
+// - This class is copyable and has value semantics.
+// - Constness is shallow: a const Expectation object itself cannot
+// be modified, but the mutable methods of the ExpectationBase
+// 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 Expectation {
+ public:
+ // Constructs a null object that doesn't reference any expectation.
+ Expectation();
+
+ ~Expectation();
+
+ // This single-argument ctor must not be explicit, in order to support the
+ // Expectation e = EXPECT_CALL(...);
+ // syntax.
+ //
+ // A TypedExpectation object stores its pre-requisites as
+ // Expectation objects, and needs to call the non-const Retire()
+ // method on the ExpectationBase objects they reference. Therefore
+ // Expectation must receive a *non-const* reference to the
+ // ExpectationBase object.
+ Expectation(internal::ExpectationBase& exp); // NOLINT
+
+ // The compiler-generated copy ctor and operator= work exactly as
+ // intended, so we don't need to define our own.
+
+ // Returns true iff rhs references the same expectation as this object does.
+ bool operator==(const Expectation& rhs) const {
+ return expectation_base_ == rhs.expectation_base_;
+ }
+
+ bool operator!=(const Expectation& rhs) const { return !(*this == rhs); }
+
+ private:
+ friend class ExpectationSet;
+ friend class Sequence;
+ friend class ::testing::internal::ExpectationBase;
+
+ template <typename F>
+ friend class ::testing::internal::FunctionMockerBase;
+
+ template <typename F>
+ friend class ::testing::internal::TypedExpectation;
+
+ // This comparator is needed for putting Expectation objects into a set.
+ class Less {
+ public:
+ bool operator()(const Expectation& lhs, const Expectation& rhs) const {
+ return lhs.expectation_base_.get() < rhs.expectation_base_.get();
+ }
+ };
+
+ typedef ::std::set<Expectation, Less> Set;
+
+ Expectation(
+ const internal::linked_ptr<internal::ExpectationBase>& expectation_base);
+
+ // Returns the expectation this object references.
+ const internal::linked_ptr<internal::ExpectationBase>&
+ expectation_base() const {
+ return expectation_base_;
+ }
+
+ // A linked_ptr that co-owns the expectation this handle references.
+ internal::linked_ptr<internal::ExpectationBase> expectation_base_;
+};
+
+// A set of expectation handles. Useful in the .After() clause of
+// EXPECT_CALL() for setting the (partial) order of expectations. The
+// syntax:
+//
+// ExpectationSet es;
+// es += EXPECT_CALL(...)...;
+// es += EXPECT_CALL(...)...;
+// EXPECT_CALL(...).After(es)...;
+//
+// sets three expectations where the last one can only be matched
+// after the first two have both been satisfied.
+//
+// This class is copyable and has value semantics.
+class ExpectationSet {
+ public:
+ // A bidirectional iterator that can read a const element in the set.
+ typedef Expectation::Set::const_iterator const_iterator;
+
+ // An object stored in the set. This is an alias of Expectation.
+ typedef Expectation::Set::value_type value_type;
+
+ // Constructs an empty set.
+ ExpectationSet() {}
+
+ // This single-argument ctor must not be explicit, in order to support the
+ // ExpectationSet es = EXPECT_CALL(...);
+ // syntax.
+ ExpectationSet(internal::ExpectationBase& exp) { // NOLINT
+ *this += Expectation(exp);
+ }
+
+ // This single-argument ctor implements implicit conversion from
+ // Expectation and thus must not be explicit. This allows either an
+ // Expectation or an ExpectationSet to be used in .After().
+ ExpectationSet(const Expectation& e) { // NOLINT
+ *this += e;
+ }
+
+ // The compiler-generator ctor and operator= works exactly as
+ // intended, so we don't need to define our own.
+
+ // Returns true iff rhs contains the same set of Expectation objects
+ // as this does.
+ bool operator==(const ExpectationSet& rhs) const {
+ return expectations_ == rhs.expectations_;
+ }
+
+ bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); }
+
+ // Implements the syntax
+ // expectation_set += EXPECT_CALL(...);
+ ExpectationSet& operator+=(const Expectation& e) {
+ expectations_.insert(e);
+ return *this;
+ }
+
+ int size() const { return static_cast<int>(expectations_.size()); }
+
+ const_iterator begin() const { return expectations_.begin(); }
+ const_iterator end() const { return expectations_.end(); }
+
+ private:
+ Expectation::Set expectations_;
+};
+
+
// Sequence objects are used by a user to specify the relative order
// in which the expectations should match. They are copyable (we rely
// on the compiler-defined copy constructor and assignment operator).
class Sequence {
public:
// Constructs an empty sequence.
- Sequence()
- : last_expectation_(
- new internal::linked_ptr<internal::ExpectationBase>(NULL)) {}
+ Sequence() : last_expectation_(new Expectation) {}
// Adds an expectation to this sequence. The caller must ensure
// that no other thread is accessing this Sequence object.
- void AddExpectation(
- const internal::linked_ptr<internal::ExpectationBase>& expectation) const;
+ void AddExpectation(const Expectation& expectation) const;
+
private:
- // The last expectation in this sequence. We use a nested
- // linked_ptr here because:
- // - Sequence objects are copyable, and we want the copies to act
- // as aliases. The outer linked_ptr allows the copies to co-own
- // and share the same state.
- // - An Expectation object is co-owned (via linked_ptr) by its
- // FunctionMocker and its successors (other Expectation objects).
- // Hence the inner linked_ptr.
- internal::linked_ptr<internal::linked_ptr<internal::ExpectationBase> >
- last_expectation_;
+ // The last expectation in this sequence. We use a linked_ptr here
+ // because Sequence objects are copyable and we want the copies to
+ // 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
// An object of this type causes all EXPECT_CALL() statements
@@ -431,9 +582,7 @@ class ExpectationBase {
// L >= g_gmock_mutex
virtual void DescribeCallCountTo(::std::ostream* os) const = 0;
protected:
- typedef std::set<linked_ptr<ExpectationBase>,
- LinkedPtrLessThan<ExpectationBase> >
- ExpectationBaseSet;
+ friend class ::testing::Expectation;
enum Clause {
// Don't change the order of the enum members!
@@ -441,11 +590,16 @@ class ExpectationBase {
kWith,
kTimes,
kInSequence,
+ kAfter,
kWillOnce,
kWillRepeatedly,
kRetiresOnSaturation,
};
+ // Returns an Expectation object that references and co-owns this
+ // expectation.
+ virtual Expectation GetHandle() = 0;
+
// Asserts that the EXPECT_CALL() statement has the given property.
void AssertSpecProperty(bool property, const string& failure_message) const {
Assert(property, file_, line_, failure_message);
@@ -518,7 +672,7 @@ class ExpectationBase {
// Adds unsatisfied pre-requisites of this expectation to 'result'.
// L >= g_gmock_mutex
- void FindUnsatisfiedPrerequisites(ExpectationBaseSet* result) const;
+ void FindUnsatisfiedPrerequisites(ExpectationSet* result) const;
// Returns the number this expectation has been invoked.
// L >= g_gmock_mutex
@@ -539,7 +693,7 @@ class ExpectationBase {
friend class ::testing::internal::ExpectationTester;
template <typename Function>
- friend class Expectation;
+ friend class TypedExpectation;
// This group of fields are part of the spec and won't change after
// an EXPECT_CALL() statement finishes.
@@ -548,11 +702,13 @@ class ExpectationBase {
// True iff the cardinality is specified explicitly.
bool cardinality_specified_;
Cardinality cardinality_; // The cardinality of the expectation.
- // The immediate pre-requisites of this expectation. We use
- // linked_ptr in the set because we want an Expectation object to be
- // co-owned by its FunctionMocker and its successors. This allows
- // multiple mock objects to be deleted at different times.
- ExpectationBaseSet immediate_prerequisites_;
+ // The immediate pre-requisites (i.e. expectations that must be
+ // satisfied before this expectation can be matched) of this
+ // expectation. We use linked_ptr in the set because we want an
+ // Expectation object to be co-owned by its FunctionMocker and its
+ // successors. This allows multiple mock objects to be deleted at
+ // different times.
+ ExpectationSet immediate_prerequisites_;
// This group of fields are the current state of the expectation,
// and can change as the mock function is called.
@@ -562,14 +718,14 @@ class ExpectationBase {
// Impements an expectation for the given function type.
template <typename F>
-class Expectation : public ExpectationBase {
+class TypedExpectation : public ExpectationBase {
public:
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
typedef typename Function<F>::Result Result;
- Expectation(FunctionMockerBase<F>* owner, const char* file, int line,
- const ArgumentMatcherTuple& m)
+ TypedExpectation(FunctionMockerBase<F>* owner, const char* file, int line,
+ const ArgumentMatcherTuple& m)
: ExpectationBase(file, line),
owner_(owner),
matchers_(m),
@@ -584,14 +740,14 @@ class Expectation : public ExpectationBase {
last_clause_(kNone),
action_count_checked_(false) {}
- virtual ~Expectation() {
+ virtual ~TypedExpectation() {
// Check the validity of the action count if it hasn't been done
// yet (for example, if the expectation was never used).
CheckActionCountIfNotDone();
}
// Implements the .With() clause.
- Expectation& With(const Matcher<const ArgumentTuple&>& m) {
+ TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) {
if (last_clause_ == kWith) {
ExpectSpecProperty(false,
".With() cannot appear "
@@ -608,7 +764,7 @@ class Expectation : public ExpectationBase {
}
// Implements the .Times() clause.
- Expectation& Times(const Cardinality& cardinality) {
+ TypedExpectation& Times(const Cardinality& cardinality) {
if (last_clause_ ==kTimes) {
ExpectSpecProperty(false,
".Times() cannot appear "
@@ -626,40 +782,70 @@ class Expectation : public ExpectationBase {
}
// Implements the .Times() clause.
- Expectation& Times(int n) {
+ TypedExpectation& Times(int n) {
return Times(Exactly(n));
}
// Implements the .InSequence() clause.
- Expectation& InSequence(const Sequence& s) {
+ TypedExpectation& InSequence(const Sequence& s) {
ExpectSpecProperty(last_clause_ <= kInSequence,
- ".InSequence() cannot appear after .WillOnce(),"
- " .WillRepeatedly(), or "
+ ".InSequence() cannot appear after .After(),"
+ " .WillOnce(), .WillRepeatedly(), or "
".RetiresOnSaturation().");
last_clause_ = kInSequence;
- s.AddExpectation(owner_->GetLinkedExpectationBase(this));
+ s.AddExpectation(GetHandle());
return *this;
}
- Expectation& InSequence(const Sequence& s1, const Sequence& s2) {
+ TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) {
return InSequence(s1).InSequence(s2);
}
- Expectation& InSequence(const Sequence& s1, const Sequence& s2,
- const Sequence& s3) {
+ TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
+ const Sequence& s3) {
return InSequence(s1, s2).InSequence(s3);
}
- Expectation& InSequence(const Sequence& s1, const Sequence& s2,
- const Sequence& s3, const Sequence& s4) {
+ TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
+ const Sequence& s3, const Sequence& s4) {
return InSequence(s1, s2, s3).InSequence(s4);
}
- Expectation& InSequence(const Sequence& s1, const Sequence& s2,
- const Sequence& s3, const Sequence& s4,
- const Sequence& s5) {
+ TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
+ const Sequence& s3, const Sequence& s4,
+ const Sequence& s5) {
return InSequence(s1, s2, s3, s4).InSequence(s5);
}
+ // Implements that .After() clause.
+ TypedExpectation& After(const ExpectationSet& s) {
+ ExpectSpecProperty(last_clause_ <= kAfter,
+ ".After() cannot appear after .WillOnce(),"
+ " .WillRepeatedly(), or "
+ ".RetiresOnSaturation().");
+ last_clause_ = kAfter;
+
+ for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) {
+ immediate_prerequisites_ += *it;
+ }
+ return *this;
+ }
+ TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) {
+ return After(s1).After(s2);
+ }
+ TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
+ const ExpectationSet& s3) {
+ return After(s1, s2).After(s3);
+ }
+ TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
+ const ExpectationSet& s3, const ExpectationSet& s4) {
+ return After(s1, s2, s3).After(s4);
+ }
+ TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
+ const ExpectationSet& s3, const ExpectationSet& s4,
+ const ExpectationSet& s5) {
+ return After(s1, s2, s3, s4).After(s5);
+ }
+
// Implements the .WillOnce() clause.
- Expectation& WillOnce(const Action<F>& action) {
+ TypedExpectation& WillOnce(const Action<F>& action) {
ExpectSpecProperty(last_clause_ <= kWillOnce,
".WillOnce() cannot appear after "
".WillRepeatedly() or .RetiresOnSaturation().");
@@ -673,7 +859,7 @@ class Expectation : public ExpectationBase {
}
// Implements the .WillRepeatedly() clause.
- Expectation& WillRepeatedly(const Action<F>& action) {
+ TypedExpectation& WillRepeatedly(const Action<F>& action) {
if (last_clause_ == kWillRepeatedly) {
ExpectSpecProperty(false,
".WillRepeatedly() cannot appear "
@@ -698,7 +884,7 @@ class Expectation : public ExpectationBase {
}
// Implements the .RetiresOnSaturation() clause.
- Expectation& RetiresOnSaturation() {
+ TypedExpectation& RetiresOnSaturation() {
ExpectSpecProperty(last_clause_ < kRetiresOnSaturation,
".RetiresOnSaturation() cannot appear "
"more than once.");
@@ -756,6 +942,12 @@ class Expectation : public ExpectationBase {
template <typename Function>
friend class FunctionMockerBase;
+ // Returns an Expectation object that references and co-owns this
+ // expectation.
+ virtual Expectation GetHandle() {
+ return owner_->GetHandleOf(this);
+ }
+
// The following methods will be called only after the EXPECT_CALL()
// statement finishes and when the current thread holds
// g_gmock_mutex.
@@ -807,12 +999,12 @@ class Expectation : public ExpectationBase {
*os << " Expected: all pre-requisites are satisfied\n"
<< " Actual: the following immediate pre-requisites "
<< "are not satisfied:\n";
- ExpectationBaseSet unsatisfied_prereqs;
+ ExpectationSet unsatisfied_prereqs;
FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);
int i = 0;
- for (ExpectationBaseSet::const_iterator it = unsatisfied_prereqs.begin();
+ for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin();
it != unsatisfied_prereqs.end(); ++it) {
- (*it)->DescribeLocationTo(os);
+ it->expectation_base()->DescribeLocationTo(os);
*os << "pre-requisite #" << i++ << "\n";
}
*os << " (end of pre-requisites)\n";
@@ -957,7 +1149,7 @@ class Expectation : public ExpectationBase {
Clause last_clause_;
mutable bool action_count_checked_; // Under mutex_.
mutable Mutex mutex_; // Protects action_count_checked_.
-}; // class Expectation
+}; // class TypedExpectation
// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
// specifying the default behavior of, or expectation on, a mock
@@ -992,7 +1184,7 @@ class MockSpec {
// Adds a new expectation spec to the function mocker and returns
// the newly created spec.
- internal::Expectation<F>& InternalExpectedAt(
+ internal::TypedExpectation<F>& InternalExpectedAt(
const char* file, int line, const char* obj, const char* call) {
LogWithLocation(internal::INFO, file, line,
string("EXPECT_CALL(") + obj + ", " + call + ") invoked");
@@ -1247,18 +1439,18 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Adds and returns an expectation spec for this mock function.
// L < g_gmock_mutex
- Expectation<F>& AddNewExpectation(
+ TypedExpectation<F>& AddNewExpectation(
const char* file, int line,
const ArgumentMatcherTuple& m) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
- const linked_ptr<Expectation<F> > expectation(
- new Expectation<F>(this, file, line, m));
+ const linked_ptr<TypedExpectation<F> > expectation(
+ new TypedExpectation<F>(this, file, line, m));
expectations_.push_back(expectation);
// Adds this expectation into the implicit sequence if there is one.
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
if (implicit_sequence != NULL) {
- implicit_sequence->AddExpectation(expectation);
+ implicit_sequence->AddExpectation(Expectation(expectation));
}
return *expectation;
@@ -1268,22 +1460,23 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// being described on this function mocker.
MockSpec<F>& current_spec() { return current_spec_; }
private:
- template <typename Func> friend class Expectation;
+ template <typename Func> friend class TypedExpectation;
- typedef std::vector<internal::linked_ptr<Expectation<F> > > Expectations;
+ typedef std::vector<internal::linked_ptr<TypedExpectation<F> > >
+ TypedExpectations;
- // Gets the internal::linked_ptr<ExpectationBase> object that co-owns 'exp'.
- internal::linked_ptr<ExpectationBase> GetLinkedExpectationBase(
- Expectation<F>* exp) {
- for (typename Expectations::const_iterator it = expectations_.begin();
+ // Returns an Expectation object that references and co-owns exp,
+ // which must be an expectation on this mock function.
+ Expectation GetHandleOf(TypedExpectation<F>* exp) {
+ for (typename TypedExpectations::const_iterator it = expectations_.begin();
it != expectations_.end(); ++it) {
if (it->get() == exp) {
- return *it;
+ return Expectation(*it);
}
}
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
- return internal::linked_ptr<ExpectationBase>(NULL);
+ return Expectation();
// The above statement is just to make the code compile, and will
// never be executed.
}
@@ -1330,7 +1523,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// mock function) and excessive locking could cause a dead lock.
// L < g_gmock_mutex
bool FindMatchingExpectationAndAction(
- const ArgumentTuple& args, Expectation<F>** exp, Action<F>* action,
+ const ArgumentTuple& args, TypedExpectation<F>** exp, Action<F>* action,
bool* is_excessive, ::std::ostream* what, ::std::ostream* why) {
MutexLock l(&g_gmock_mutex);
*exp = this->FindMatchingExpectationLocked(args);
@@ -1351,13 +1544,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the expectation that matches the arguments, or NULL if no
// expectation matches them.
// L >= g_gmock_mutex
- Expectation<F>* FindMatchingExpectationLocked(
+ TypedExpectation<F>* FindMatchingExpectationLocked(
const ArgumentTuple& args) const {
g_gmock_mutex.AssertHeld();
- for (typename Expectations::const_reverse_iterator it =
+ for (typename TypedExpectations::const_reverse_iterator it =
expectations_.rbegin();
it != expectations_.rend(); ++it) {
- Expectation<F>* const exp = it->get();
+ TypedExpectation<F>* const exp = it->get();
if (exp->ShouldHandleArguments(args)) {
return exp;
}
@@ -1415,7 +1608,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// All default action specs for this function mocker.
std::vector<DefaultActionSpec<F> > default_actions_;
// All expectations for this function mocker.
- Expectations expectations_;
+ TypedExpectations expectations_;
// There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error.
@@ -1446,9 +1639,9 @@ template <typename F>
bool FunctionMockerBase<F>::VerifyAndClearExpectationsLocked() {
g_gmock_mutex.AssertHeld();
bool expectations_met = true;
- for (typename Expectations::const_iterator it = expectations_.begin();
+ for (typename TypedExpectations::const_iterator it = expectations_.begin();
it != expectations_.end(); ++it) {
- Expectation<F>* const exp = it->get();
+ TypedExpectation<F>* const exp = it->get();
if (exp->IsOverSaturated()) {
// There was an upper-bound violation. Since the error was
@@ -1532,7 +1725,7 @@ typename Function<F>::Result FunctionMockerBase<F>::InvokeWith(
::std::stringstream why;
::std::stringstream loc;
Action<F> action;
- Expectation<F>* exp;
+ TypedExpectation<F>* exp;
// The FindMatchingExpectationAndAction() function acquires and
// releases g_gmock_mutex.
@@ -1605,6 +1798,10 @@ using internal::MockSpec;
template <typename T>
inline const T& Const(const T& x) { return x; }
+// Constructs an Expectation object that references and co-owns exp.
+inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT
+ : expectation_base_(exp.GetHandle().expectation_base()) {}
+
} // namespace testing
// A separate macro is required to avoid compile errors when the name
diff --git a/testing/gmock/include/gmock/gmock.h b/testing/gmock/include/gmock/gmock.h
index 29d9727..daf5288 100644
--- a/testing/gmock/include/gmock/gmock.h
+++ b/testing/gmock/include/gmock/gmock.h
@@ -60,6 +60,7 @@
#include <gmock/gmock-generated-actions.h>
#include <gmock/gmock-generated-function-mockers.h>
#include <gmock/gmock-generated-matchers.h>
+#include <gmock/gmock-more-actions.h>
#include <gmock/gmock-generated-nice-strict.h>
#include <gmock/gmock-matchers.h>
#include <gmock/gmock-printers.h>
diff --git a/testing/gmock/include/gmock/internal/gmock-internal-utils.h b/testing/gmock/include/gmock/internal/gmock-internal-utils.h
index ee6aa1e..7b17335 100644
--- a/testing/gmock/include/gmock/internal/gmock-internal-utils.h
+++ b/testing/gmock/include/gmock/internal/gmock-internal-utils.h
@@ -221,6 +221,34 @@ class ImplicitlyConvertible {
template <typename From, typename To>
const bool ImplicitlyConvertible<From, To>::value;
+// 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
+// same as unsigned short when the compiler option /Zc:wchar_t- is
+// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
+// is a native type.
+#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
+ (defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
+// wchar_t is a typedef.
+#else
+#define GMOCK_WCHAR_T_IS_NATIVE_ 1
+#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__
+#define GMOCK_HAS_SIGNED_WCHAR_T_ 1 // signed/unsigned wchar_t are valid types.
+#endif
+
// In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type,
// or none of them. This categorization is useful for determining
@@ -252,10 +280,7 @@ GMOCK_DECLARE_KIND_(unsigned int, kInteger);
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
-// MSVC can be configured to define wchar_t as a typedef of unsigned
-// short. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t is a
-// native type.
-#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+#if GMOCK_WCHAR_T_IS_NATIVE_
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif
@@ -581,21 +606,9 @@ class NativeArray {
typedef Element value_type;
typedef const Element* const_iterator;
- // Constructs from a native array passed by reference.
- template <size_t N>
- NativeArray(const Element (&array)[N], RelationToSource relation) {
- Init(array, N, relation);
- }
-
- // Constructs from a native array passed by a pointer and a size.
- // For generality we don't artificially restrict the types of the
- // pointer and the size.
- template <typename Pointer, typename Size>
- NativeArray(const ::std::tr1::tuple<Pointer, Size>& array,
- RelationToSource relation) {
- Init(internal::GetRawPointer(::std::tr1::get<0>(array)),
- ::std::tr1::get<1>(array),
- relation);
+ // Constructs from a native array.
+ NativeArray(const Element* array, size_t count, RelationToSource relation) {
+ Init(array, count, relation);
}
// Copy constructor.
@@ -691,10 +704,31 @@ class StlContainerView<Element[N]> {
static const_reference ConstReference(const Element (&array)[N]) {
// Ensures that Element is not a const type.
testing::StaticAssertTypeEq<Element, RawElement>();
- return type(array, kReference);
+#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, kReference);
+#else
+ return type(array, N, kReference);
+#endif // GTEST_OS_SYMBIAN
}
static type Copy(const Element (&array)[N]) {
- return type(array, kCopy);
+#if GTEST_OS_SYMBIAN
+ return type(const_cast<Element*>(&array[0]), N, kCopy);
+#else
+ return type(array, N, kCopy);
+#endif // GTEST_OS_SYMBIAN
}
};
@@ -710,10 +744,12 @@ class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
static const_reference ConstReference(
const ::std::tr1::tuple<ElementPointer, Size>& array) {
- return type(array, kReference);
+ using ::std::tr1::get;
+ return type(get<0>(array), get<1>(array), kReference);
}
static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) {
- return type(array, kCopy);
+ using ::std::tr1::get;
+ return type(get<0>(array), get<1>(array), kCopy);
}
};
diff --git a/testing/gmock/include/gmock/internal/gmock-port.h b/testing/gmock/include/gmock/internal/gmock-port.h
index 9ee8f72..0263491 100644
--- a/testing/gmock/include/gmock/internal/gmock-port.h
+++ b/testing/gmock/include/gmock/internal/gmock-port.h
@@ -75,33 +75,11 @@
namespace testing {
namespace internal {
-// For Windows, check the compiler version. At least VS 2005 SP1 is
+// For MS Visual C++, check the compiler version. At least VS 2003 is
// required to compile Google Mock.
-#if GTEST_OS_WINDOWS
-
-#if _MSC_VER < 1400
-#error "At least Visual Studio 2005 SP1 is required to compile Google Mock."
-#elif _MSC_VER == 1400
-
-// Unfortunately there is no unique _MSC_VER number for SP1. So for VS 2005
-// we have to check if it has SP1 by checking whether a bug fixed in SP1
-// is present. The bug in question is
-// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702
-// where the compiler incorrectly reports sizeof(poiter to an array).
-
-class TestForSP1 {
- private: // GCC complains if x_ is used by sizeof before defining it.
- static char x_[100];
- // VS 2005 RTM incorrectly reports sizeof(&x) as 100, and that value
- // is used to trigger 'invalid negative array size' error. If you
- // see this error, upgrade to VS 2005 SP1 since Google Mock will not
- // compile in VS 2005 RTM.
- static char Google_Mock_requires_Visual_Studio_2005_SP1_or_later_to_compile_[
- sizeof(&x_) != 100 ? 1 : -1];
-};
-
-#endif // _MSC_VER
-#endif // GTEST_OS_WINDOWS
+#if defined(_MSC_VER) && _MSC_VER < 1310
+#error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
+#endif
// Use implicit_cast as a safe version of static_cast or const_cast
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
@@ -236,56 +214,6 @@ typedef ::wstring wstring;
typedef ::std::wstring wstring;
#endif // GTEST_HAS_GLOBAL_WSTRING
-// Prints the file location in the format native to the compiler.
-inline void FormatFileLocation(const char* file, int line, ::std::ostream* os) {
- if (file == NULL)
- file = "unknown file";
- if (line < 0) {
- *os << file << ":";
- } else {
-#if _MSC_VER
- *os << file << "(" << line << "):";
-#else
- *os << file << ":" << line << ":";
-#endif
- }
-}
-
-// INTERNAL IMPLEMENTATION - DO NOT USE.
-//
-// GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
-// is not satisfied.
-// Synopsys:
-// GMOCK_CHECK_(boolean_condition);
-// or
-// GMOCK_CHECK_(boolean_condition) << "Additional message";
-//
-// This checks the condition and if the condition is not satisfied
-// it prints message about the condition violation, including the
-// condition itself, plus additional message streamed into it, if any,
-// and then it aborts the program. It aborts the program irrespective of
-// whether it is built in the debug mode or not.
-
-class GMockCheckProvider {
- public:
- GMockCheckProvider(const char* condition, const char* file, int line) {
- FormatFileLocation(file, line, &::std::cerr);
- ::std::cerr << " ERROR: Condition " << condition << " failed. ";
- }
- ~GMockCheckProvider() {
- ::std::cerr << ::std::endl;
- abort();
- }
- ::std::ostream& GetStream() { return ::std::cerr; }
-};
-#define GMOCK_CHECK_(condition) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (condition) \
- ; \
- else \
- ::testing::internal::GMockCheckProvider(\
- #condition, __FILE__, __LINE__).GetStream()
-
} // namespace internal
} // namespace testing