diff options
Diffstat (limited to 'testing/gmock/include')
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 |