am f6ec81ff: Updated gMock to 1.7.0

* commit 'f6ec81ffe782c16e3153ee65a40bfbc25458825f':
  Updated gMock to 1.7.0
This commit is contained in:
Jeff Tinker
2014-03-10 18:57:10 +00:00
committed by Android Git Automerger
34 changed files with 3493 additions and 1629 deletions

View File

@@ -51,4 +51,9 @@ LOCAL_SHARED_LIBRARIES := \
libstlport \ libstlport \
libutils libutils
# Needed to use gMock 1.7.0 on Android
LOCAL_CFLAGS += \
-DGTEST_HAS_TR1_TUPLE \
-DGTEST_USE_OWN_TR1_TUPLE \
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)

View File

@@ -36,6 +36,11 @@ LOCAL_SHARED_LIBRARIES := \
libstlport \ libstlport \
libutils \ libutils \
# Needed to use gMock 1.7.0 on Android
LOCAL_CFLAGS += \
-DGTEST_HAS_TR1_TUPLE \
-DGTEST_USE_OWN_TR1_TUPLE \
# CDM's protobuffers are not part of the library # CDM's protobuffers are not part of the library
PROTO_SRC_DIR := $(proto_generated_cc_sources_dir)/$(LOCAL_PATH)/core/src PROTO_SRC_DIR := $(proto_generated_cc_sources_dir)/$(LOCAL_PATH)/core/src

View File

@@ -35,6 +35,11 @@ LOCAL_SHARED_LIBRARIES := \
libstlport \ libstlport \
libutils \ libutils \
# Needed to use gMock 1.7.0 on Android
LOCAL_CFLAGS += \
-DGTEST_HAS_TR1_TUPLE \
-DGTEST_USE_OWN_TR1_TUPLE \
# CDM's protobuffers are not part of the library # CDM's protobuffers are not part of the library
PROTO_SRC_DIR := $(proto_generated_cc_sources_dir)/$(LOCAL_PATH)/core/src PROTO_SRC_DIR := $(proto_generated_cc_sources_dir)/$(LOCAL_PATH)/core/src

View File

@@ -1,3 +1,3 @@
# Copyright 2013 Google Inc. All Rights Reserved. # Copyright 2014 Google Inc. All Rights Reserved.
include $(call all-subdir-makefiles) include $(call all-subdir-makefiles)

View File

@@ -1,3 +1,37 @@
Changes for 1.7.0:
* All new improvements in Google Test 1.7.0.
* New feature: matchers DoubleNear(), FloatNear(),
NanSensitiveDoubleNear(), NanSensitiveFloatNear(),
UnorderedElementsAre(), UnorderedElementsAreArray(), WhenSorted(),
WhenSortedBy(), IsEmpty(), and SizeIs().
* Improvement: Google Mock can now be built as a DLL.
* Improvement: when compiled by a C++11 compiler, matchers AllOf()
and AnyOf() can accept an arbitrary number of matchers.
* Improvement: when compiled by a C++11 compiler, matchers
ElementsAreArray() can accept an initializer list.
* Improvement: when exceptions are enabled, a mock method with no
default action now throws instead crashing the test.
* Improvement: added class testing::StringMatchResultListener to aid
definition of composite matchers.
* Improvement: function return types used in MOCK_METHOD*() macros can
now contain unprotected commas.
* Improvement (potentially breaking): EXPECT_THAT() and ASSERT_THAT()
are now more strict in ensuring that the value type and the matcher
type are compatible, catching potential bugs in tests.
* Improvement: Pointee() now works on an optional<T>.
* Improvement: the ElementsAreArray() matcher can now take a vector or
iterator range as input, and makes a copy of its input elements
before the conversion to a Matcher.
* Improvement: the Google Mock Generator can now generate mocks for
some class templates.
* Bug fix: mock object destruction triggerred by another mock object's
destruction no longer hangs.
* Improvement: Google Mock Doctor works better with newer Clang and
GCC now.
* Compatibility fixes.
* Bug/warning fixes.
Changes for 1.6.0: Changes for 1.6.0:
* Compilation is much faster and uses much less memory, especially * Compilation is much faster and uses much less memory, especially

View File

@@ -170,23 +170,31 @@ called by Visual Studio and Xcode) to compile
with with
${GTEST_DIR}/include, ${GTEST_DIR}, ${GMOCK_DIR}/include, and ${GMOCK_DIR} ${GTEST_DIR}/include and ${GMOCK_DIR}/include
in the header search path. Assuming a Linux-like system and gcc, in the system header search path, and
${GTEST_DIR} and ${GMOCK_DIR}
in the normal header search path. Assuming a Linux-like system and gcc,
something like the following will do: something like the following will do:
g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -I${GMOCK_DIR}/include \ g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
-I${GMOCK_DIR} -c ${GTEST_DIR}/src/gtest-all.cc -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \
g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -I${GMOCK_DIR}/include \ -pthread -c ${GTEST_DIR}/src/gtest-all.cc
-I${GMOCK_DIR} -c ${GMOCK_DIR}/src/gmock-all.cc g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
-isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \
-pthread -c ${GMOCK_DIR}/src/gmock-all.cc
ar -rv libgmock.a gtest-all.o gmock-all.o ar -rv libgmock.a gtest-all.o gmock-all.o
(We need -pthread as Google Test and Google Mock use threads.)
Next, you should compile your test source file with Next, you should compile your test source file with
${GTEST_DIR}/include and ${GMOCK_DIR}/include in the header search ${GTEST_DIR}/include and ${GMOCK_DIR}/include in the header search
path, and link it with gmock and any other necessary libraries: path, and link it with gmock and any other necessary libraries:
g++ -I${GTEST_DIR}/include -I${GMOCK_DIR}/include \ g++ -isystem ${GTEST_DIR}/include -isystem ${GMOCK_DIR}/include \
path/to/your_test.cc libgmock.a -o your_test -pthread path/to/your_test.cc libgmock.a -o your_test
As an example, the make/ directory contains a Makefile that you can As an example, the make/ directory contains a Makefile that you can
use to build Google Mock on systems where GNU make is available use to build Google Mock on systems where GNU make is available
@@ -265,7 +273,14 @@ If you want to use Boost's TR1 tuple library with Google Mock, please
refer to the Boost website (http://www.boost.org/) for how to obtain refer to the Boost website (http://www.boost.org/) for how to obtain
it and set it up. it and set it up.
### Tweaking Google Test ### ### As a Shared Library (DLL) ###
Google Mock is compact, so most users can build and link it as a static
library for the simplicity. Google Mock can be used as a DLL, but the
same DLL must contain Google Test as well. See Google Test's README
file for instructions on how to set up necessary compiler settings.
### Tweaking Google Mock ###
Most of Google Test's control macros apply to Google Mock as well. Most of Google Test's control macros apply to Google Mock as well.
Please see file ${GTEST_DIR}/README for how to tweak them. Please see file ${GTEST_DIR}/README for how to tweak them.

View File

@@ -1,5 +1,5 @@
URL: https://code.google.com/p/googlemock/downloads/list URL: https://code.google.com/p/googlemock/downloads/list
Version: 1.6.0 Version: 1.7.0
License: New BSD License License: New BSD License
Description: Description:
@@ -14,7 +14,35 @@ needs a different format of build script, and it needs to build against the OS'
modified version of gTest, rather than the packaged version. modified version of gTest, rather than the packaged version.
Local Modifications: Local Modifications:
Mon Mar 4, 2013 (juce) --Mon Feb 4, 2014 (juce)--
Upgraded to gMock 1.7.0. This is required for compatibility with the upgrade
of gTest on Android Master to 1.7.0. Note that after this change, this code
will no longer work on Android KLP branches. Our gMock must match the version
of gTest in the Android tree.
Updated src/Android.mk to turn on the gTest replacement for std::tr1::tuple.
On Android, gTest builds without using the platform's std::tr1::tuple (which
does not exist on Android) and without gTest's implementation of a subset of
std::tr1::tuple. This works on Android because it omits the few features that
rely on std::tr1::tuple. But gMock was written assuming std::tuple or the
gTest-defined subset would be available, and it cannot be used without one or
the other.
Updated src/Android.mk to account for the new compilers on Android Master.
Removed the unused Host build from src/Android.mk.
Updated the android-rsync-excludes file to reflect the new source and sorted it
alphabetically.
Updated Dr. gMock (which was again omitted from the release) to version 1.7.0.
--Wed Mar 20, 2013 (juce)--
Added the Dr. gMock script, which was missing from the 1.6.0 distribution.
--Mon Mar 4, 2013 (juce)--
Added this documentation Added this documentation

View File

@@ -36,13 +36,13 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#include <algorithm>
#include <string>
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
# include <errno.h> # include <errno.h>
#endif #endif
#include <algorithm>
#include <string>
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
@@ -189,6 +189,7 @@ class DefaultValue {
return value_ == NULL ? return value_ == NULL ?
internal::BuiltInDefaultValue<T>::Get() : *value_; internal::BuiltInDefaultValue<T>::Get() : *value_;
} }
private: private:
static const T* value_; static const T* value_;
}; };
@@ -224,6 +225,7 @@ class DefaultValue<T&> {
return address_ == NULL ? return address_ == NULL ?
internal::BuiltInDefaultValue<T&>::Get() : *address_; internal::BuiltInDefaultValue<T&>::Get() : *address_;
} }
private: private:
static T* address_; static T* address_;
}; };

View File

@@ -80,7 +80,7 @@ class CardinalityInterface {
// be called. The implementation of Cardinality is just a linked_ptr // be called. The implementation of Cardinality is just a linked_ptr
// to const CardinalityInterface, so copying is fairly cheap. // to const CardinalityInterface, so copying is fairly cheap.
// Don't inherit from Cardinality! // Don't inherit from Cardinality!
class Cardinality { class GTEST_API_ Cardinality {
public: public:
// Constructs a null cardinality. Needed for storing Cardinality // Constructs a null cardinality. Needed for storing Cardinality
// objects in STL containers. // objects in STL containers.
@@ -117,24 +117,25 @@ class Cardinality {
// Describes the given actual call count to an ostream. // Describes the given actual call count to an ostream.
static void DescribeActualCallCountTo(int actual_call_count, static void DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os); ::std::ostream* os);
private: private:
internal::linked_ptr<const CardinalityInterface> impl_; internal::linked_ptr<const CardinalityInterface> impl_;
}; };
// Creates a cardinality that allows at least n calls. // Creates a cardinality that allows at least n calls.
Cardinality AtLeast(int n); GTEST_API_ Cardinality AtLeast(int n);
// Creates a cardinality that allows at most n calls. // Creates a cardinality that allows at most n calls.
Cardinality AtMost(int n); GTEST_API_ Cardinality AtMost(int n);
// Creates a cardinality that allows any number of calls. // Creates a cardinality that allows any number of calls.
Cardinality AnyNumber(); GTEST_API_ Cardinality AnyNumber();
// Creates a cardinality that allows between min and max calls. // Creates a cardinality that allows between min and max calls.
Cardinality Between(int min, int max); GTEST_API_ Cardinality Between(int min, int max);
// Creates a cardinality that allows exactly n calls. // Creates a cardinality that allows exactly n calls.
Cardinality Exactly(int n); GTEST_API_ Cardinality Exactly(int n);
// Creates a cardinality from its implementation. // Creates a cardinality from its implementation.
inline Cardinality MakeCardinality(const CardinalityInterface* c) { inline Cardinality MakeCardinality(const CardinalityInterface* c) {

View File

@@ -381,7 +381,6 @@ class CallableHelper {
A7 a7, A8 a8, A9 a9, A10 a10) { A7 a7, A8 a8, A9 a9, A10 a10) {
return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
} }
}; // class CallableHelper }; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's
@@ -1018,16 +1017,16 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
// An internal macro needed for implementing ACTION*(). // An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_,\ const args_type& args GTEST_ATTRIBUTE_UNUSED_, \
arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_,\ arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \
arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_,\ arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \
arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_,\ arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \
arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_,\ arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \
arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_,\ arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \
arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_,\ arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \
arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_,\ arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \
arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_,\ arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \
arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_,\ arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \
arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_ arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_
// Sometimes you want to give an action explicit template parameters // Sometimes you want to give an action explicit template parameters
@@ -1433,9 +1432,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
template <GMOCK_INTERNAL_DECL_##template_params\ template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\ GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\ template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type,\ template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type,\ typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type,\ typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\ typename arg9_type>\
typename ::testing::internal::Function<F>::Result\ typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\ GMOCK_ACTION_CLASS_(name, value_params)<\
@@ -2217,9 +2216,6 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
p9##_type>::gmock_Impl<F>::gmock_PerformImpl(\ p9##_type>::gmock_Impl<F>::gmock_PerformImpl(\
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
// TODO(wan@google.com): move the following to a different .h file
// such that we don't have to run 'pump' every time the code is
// updated.
namespace testing { namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal // The ACTION*() macros trigger warning C4100 (unreferenced formal

View File

@@ -136,7 +136,6 @@ $var Ts = [[$for j, [[T$j]]]]
} }
]] ]]
}; // class CallableHelper }; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's
@@ -427,7 +426,7 @@ $range k 0..n-1
// An internal macro needed for implementing ACTION*(). // An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_ const args_type& args GTEST_ATTRIBUTE_UNUSED_
$for k [[,\ $for k [[, \
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]] arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
@@ -657,9 +656,9 @@ $for k [[, arg$k[[]]_type arg$k]]) const;\
template <GMOCK_INTERNAL_DECL_##template_params\ template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\ GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\ template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type,\ template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type,\ typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type,\ typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\ typename arg9_type>\
typename ::testing::internal::Function<F>::Result\ typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\ GMOCK_ACTION_CLASS_(name, value_params)<\
@@ -740,9 +739,6 @@ $$ } // This meta comment fixes auto-indentation in Emacs. It won't
$$ // show up in the generated code. $$ // show up in the generated code.
// TODO(wan@google.com): move the following to a different .h file
// such that we don't have to run 'pump' every time the code is
// updated.
namespace testing { namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal // The ACTION*() macros trigger warning C4100 (unreferenced formal

View File

@@ -326,17 +326,23 @@ class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
// cannot handle it if we define FunctionMocker in ::testing. // cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker; using internal::FunctionMocker;
// The result type of function type F. // GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, F) tn ::testing::internal::Function<F>::Result #define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of function type F. // The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, F, N) tn ::testing::internal::Function<F>::Argument##N #define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
// The matcher type for argument N of function type F. // The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, F, N) const ::testing::Matcher<GMOCK_ARG_(tn, F, N)>& #define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method. // The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
@@ -344,419 +350,475 @@ using internal::FunctionMocker;
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD0_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method() constness { \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ ) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 0, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 0), \
this_method_does_not_take_0_arguments); \ this_method_does_not_take_0_arguments); \
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method() constness { \ gmock_##Method() constness { \
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(0, constness, Method).With(); \ return GMOCK_MOCKER_(0, constness, Method).With(); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(0, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD1_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1) constness { \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 1, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 1), \
this_method_does_not_take_1_argument); \ this_method_does_not_take_1_argument); \
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \ return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1) constness { \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(1, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD2_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2) constness { \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 2, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 2), \
this_method_does_not_take_2_arguments); \ this_method_does_not_take_2_arguments); \
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \ return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2) constness { \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(2, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD3_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3) constness { \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 3, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 3), \
this_method_does_not_take_3_arguments); \ this_method_does_not_take_3_arguments); \
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3); \ gmock_a3); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3) constness { \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3); \ gmock_a3); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(3, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD4_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4) constness { \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 4, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 4), \
this_method_does_not_take_4_arguments); \ this_method_does_not_take_4_arguments); \
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4); \ gmock_a3, gmock_a4); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4) constness { \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4); \ gmock_a3, gmock_a4); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(4, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD5_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, F, 5) gmock_a5) constness { \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 5, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 5), \
this_method_does_not_take_5_arguments); \ this_method_does_not_take_5_arguments); \
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5); \ gmock_a3, gmock_a4, gmock_a5); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5) constness { \ GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5); \ gmock_a3, gmock_a4, gmock_a5); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(5, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD6_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, F, 5) gmock_a5, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, F, 6) gmock_a6) constness { \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 6, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 6), \
this_method_does_not_take_6_arguments); \ this_method_does_not_take_6_arguments); \
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \ GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6) constness { \ GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(6, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD7_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, F, 5) gmock_a5, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, F, 6) gmock_a6, \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, F, 7) gmock_a7) constness { \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 7, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 7), \
this_method_does_not_take_7_arguments); \ this_method_does_not_take_7_arguments); \
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \ GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \ GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, F, 7) gmock_a7) constness { \ GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(7, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD8_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, F, 5) gmock_a5, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, F, 6) gmock_a6, \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, F, 7) gmock_a7, \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, F, 8) gmock_a8) constness { \ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 8, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 8), \
this_method_does_not_take_8_arguments); \ this_method_does_not_take_8_arguments); \
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \ GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \ GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, F, 7) gmock_a7, \ GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, F, 8) gmock_a8) constness { \ GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(8, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD9_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, F, 5) gmock_a5, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, F, 6) gmock_a6, \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, F, 7) gmock_a7, \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, F, 8) gmock_a8, \ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_ARG_(tn, F, 9) gmock_a9) constness { \ GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 9, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 9), \
this_method_does_not_take_9_arguments); \ this_method_does_not_take_9_arguments); \
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
gmock_a9); \ gmock_a9); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \ GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \ GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, F, 7) gmock_a7, \ GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, F, 8) gmock_a8, \ GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_MATCHER_(tn, F, 9) gmock_a9) constness { \ GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
gmock_a9); \ gmock_a9); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(9, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD10_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method(GMOCK_ARG_(tn, F, 1) gmock_a1, \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, F, 2) gmock_a2, \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_ARG_(tn, F, 3) gmock_a3, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_ARG_(tn, F, 4) gmock_a4, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_ARG_(tn, F, 5) gmock_a5, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_ARG_(tn, F, 6) gmock_a6, \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_ARG_(tn, F, 7) gmock_a7, \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_ARG_(tn, F, 8) gmock_a8, \ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_ARG_(tn, F, 9) gmock_a9, \ GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_ARG_(tn, F, 10) gmock_a10) constness { \ GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 10, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
== 10), \
this_method_does_not_take_10_arguments); \ this_method_does_not_take_10_arguments); \
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \ gmock_a10); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \ gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, F, 2) gmock_a2, \ GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, F, 3) gmock_a3, \ GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
GMOCK_MATCHER_(tn, F, 4) gmock_a4, \ GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
GMOCK_MATCHER_(tn, F, 5) gmock_a5, \ GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
GMOCK_MATCHER_(tn, F, 6) gmock_a6, \ GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
GMOCK_MATCHER_(tn, F, 7) gmock_a7, \ GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
GMOCK_MATCHER_(tn, F, 8) gmock_a8, \ GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
GMOCK_MATCHER_(tn, F, 9) gmock_a9, \ GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
GMOCK_MATCHER_(tn, F, 10) gmock_a10) constness { \ GMOCK_MATCHER_(tn, 10, \
__VA_ARGS__) gmock_a10) constness { \
GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \ return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \ gmock_a10); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_(10, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
Method)
#define MOCK_METHOD0(m, F) GMOCK_METHOD0_(, , , m, F) #define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
#define MOCK_METHOD1(m, F) GMOCK_METHOD1_(, , , m, F) #define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
#define MOCK_METHOD2(m, F) GMOCK_METHOD2_(, , , m, F) #define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
#define MOCK_METHOD3(m, F) GMOCK_METHOD3_(, , , m, F) #define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
#define MOCK_METHOD4(m, F) GMOCK_METHOD4_(, , , m, F) #define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
#define MOCK_METHOD5(m, F) GMOCK_METHOD5_(, , , m, F) #define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
#define MOCK_METHOD6(m, F) GMOCK_METHOD6_(, , , m, F) #define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
#define MOCK_METHOD7(m, F) GMOCK_METHOD7_(, , , m, F) #define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
#define MOCK_METHOD8(m, F) GMOCK_METHOD8_(, , , m, F) #define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
#define MOCK_METHOD9(m, F) GMOCK_METHOD9_(, , , m, F) #define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
#define MOCK_METHOD10(m, F) GMOCK_METHOD10_(, , , m, F) #define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
#define MOCK_CONST_METHOD0(m, F) GMOCK_METHOD0_(, const, , m, F) #define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD1(m, F) GMOCK_METHOD1_(, const, , m, F) #define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD2(m, F) GMOCK_METHOD2_(, const, , m, F) #define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD3(m, F) GMOCK_METHOD3_(, const, , m, F) #define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD4(m, F) GMOCK_METHOD4_(, const, , m, F) #define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD5(m, F) GMOCK_METHOD5_(, const, , m, F) #define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6(m, F) GMOCK_METHOD6_(, const, , m, F) #define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD7(m, F) GMOCK_METHOD7_(, const, , m, F) #define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8(m, F) GMOCK_METHOD8_(, const, , m, F) #define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD9(m, F) GMOCK_METHOD9_(, const, , m, F) #define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10(m, F) GMOCK_METHOD10_(, const, , m, F) #define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
#define MOCK_METHOD0_T(m, F) GMOCK_METHOD0_(typename, , , m, F) #define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD1_T(m, F) GMOCK_METHOD1_(typename, , , m, F) #define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD2_T(m, F) GMOCK_METHOD2_(typename, , , m, F) #define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD3_T(m, F) GMOCK_METHOD3_(typename, , , m, F) #define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD4_T(m, F) GMOCK_METHOD4_(typename, , , m, F) #define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD5_T(m, F) GMOCK_METHOD5_(typename, , , m, F) #define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD6_T(m, F) GMOCK_METHOD6_(typename, , , m, F) #define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD7_T(m, F) GMOCK_METHOD7_(typename, , , m, F) #define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD8_T(m, F) GMOCK_METHOD8_(typename, , , m, F) #define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD9_T(m, F) GMOCK_METHOD9_(typename, , , m, F) #define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
#define MOCK_METHOD10_T(m, F) GMOCK_METHOD10_(typename, , , m, F) #define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T(m, F) GMOCK_METHOD0_(typename, const, , m, F) #define MOCK_CONST_METHOD0_T(m, ...) \
#define MOCK_CONST_METHOD1_T(m, F) GMOCK_METHOD1_(typename, const, , m, F) GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T(m, F) GMOCK_METHOD2_(typename, const, , m, F) #define MOCK_CONST_METHOD1_T(m, ...) \
#define MOCK_CONST_METHOD3_T(m, F) GMOCK_METHOD3_(typename, const, , m, F) GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T(m, F) GMOCK_METHOD4_(typename, const, , m, F) #define MOCK_CONST_METHOD2_T(m, ...) \
#define MOCK_CONST_METHOD5_T(m, F) GMOCK_METHOD5_(typename, const, , m, F) GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T(m, F) GMOCK_METHOD6_(typename, const, , m, F) #define MOCK_CONST_METHOD3_T(m, ...) \
#define MOCK_CONST_METHOD7_T(m, F) GMOCK_METHOD7_(typename, const, , m, F) GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T(m, F) GMOCK_METHOD8_(typename, const, , m, F) #define MOCK_CONST_METHOD4_T(m, ...) \
#define MOCK_CONST_METHOD9_T(m, F) GMOCK_METHOD9_(typename, const, , m, F) GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T(m, F) GMOCK_METHOD10_(typename, const, , m, F) #define MOCK_CONST_METHOD5_T(m, ...) \
GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T(m, ...) \
GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T(m, ...) \
GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T(m, ...) \
GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T(m, ...) \
GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T(m, ...) \
GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD0_(, , ct, m, F) #define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD1_(, , ct, m, F) GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD2_(, , ct, m, F) #define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD3_(, , ct, m, F) GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD4_(, , ct, m, F) #define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD5_(, , ct, m, F) GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD6_(, , ct, m, F) #define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD7_(, , ct, m, F) GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD8_(, , ct, m, F) #define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD9_(, , ct, m, F) GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD10_(, , ct, m, F) #define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(, const, ct, m, F) GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(, const, ct, m, F) GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(, const, ct, m, F) GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(, const, ct, m, F) GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(, const, ct, m, F) GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(, const, ct, m, F) GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(, const, ct, m, F) GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(, const, ct, m, F) GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(, const, ct, m, F) GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(, const, ct, m, F) GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(, const, ct, m, F) GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(typename, , ct, m, F) GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(typename, , ct, m, F) GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(typename, , ct, m, F) GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(typename, , ct, m, F) GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(typename, , ct, m, F) GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(typename, , ct, m, F) GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(typename, , ct, m, F) GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(typename, , ct, m, F) GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(typename, , ct, m, F) GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(typename, , ct, m, F) GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, , ct, m, F) GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD0_(typename, const, ct, m, F) GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD1_(typename, const, ct, m, F) GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD2_(typename, const, ct, m, F) GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD3_(typename, const, ct, m, F) GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD4_(typename, const, ct, m, F) GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD5_(typename, const, ct, m, F) GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD6_(typename, const, ct, m, F) GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD7_(typename, const, ct, m, F) GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD8_(typename, const, ct, m, F) GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD9_(typename, const, ct, m, F) GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, const, ct, m, F) GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
// A MockFunction<F> class has one mock method whose type is F. It is // 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 // useful when you just want your test code to emit some messages and

View File

@@ -104,17 +104,23 @@ $if i >= 1 [[
// cannot handle it if we define FunctionMocker in ::testing. // cannot handle it if we define FunctionMocker in ::testing.
using internal::FunctionMocker; using internal::FunctionMocker;
// The result type of function type F. // GMOCK_RESULT_(tn, F) expands to the result type of function type F.
// We define this as a variadic macro in case F contains unprotected
// commas (the same reason that we use variadic macros in other places
// in this file).
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_RESULT_(tn, F) tn ::testing::internal::Function<F>::Result #define GMOCK_RESULT_(tn, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Result
// The type of argument N of function type F. // The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, F, N) tn ::testing::internal::Function<F>::Argument##N #define GMOCK_ARG_(tn, N, ...) \
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
// The matcher type for argument N of function type F. // The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_MATCHER_(tn, F, N) const ::testing::Matcher<GMOCK_ARG_(tn, F, N)>& #define GMOCK_MATCHER_(tn, N, ...) \
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
// The variable for mocking the given method. // The variable for mocking the given method.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
@@ -125,77 +131,78 @@ using internal::FunctionMocker;
$for i [[ $for i [[
$range j 1..i $range j 1..i
$var arg_as = [[$for j, \ $var arg_as = [[$for j, \
[[GMOCK_ARG_(tn, F, $j) gmock_a$j]]]] [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
$var as = [[$for j, [[gmock_a$j]]]] $var as = [[$for j, [[gmock_a$j]]]]
$var matcher_as = [[$for j, \ $var matcher_as = [[$for j, \
[[GMOCK_MATCHER_(tn, F, $j) gmock_a$j]]]] [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, F) \ #define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
GMOCK_RESULT_(tn, F) ct Method($arg_as) constness { \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GTEST_COMPILE_ASSERT_(::std::tr1::tuple_size< \ $arg_as) constness { \
tn ::testing::internal::Function<F>::ArgumentTuple>::value == $i, \ GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \ this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
} \ } \
::testing::MockSpec<F>& \ ::testing::MockSpec<__VA_ARGS__>& \
gmock_##Method($matcher_as) constness { \ gmock_##Method($matcher_as) constness { \
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_($i, constness, Method).With($as); \ return GMOCK_MOCKER_($i, constness, Method).With($as); \
} \ } \
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER_($i, constness, Method) mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
]] ]]
$for i [[ $for i [[
#define MOCK_METHOD$i(m, F) GMOCK_METHOD$i[[]]_(, , , m, F) #define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_CONST_METHOD$i(m, F) GMOCK_METHOD$i[[]]_(, const, , m, F) #define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i[[]]_(typename, , , m, F) #define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_CONST_METHOD$i[[]]_T(m, F) [[]] #define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, , m, F) GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) [[]] #define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, , ct, m, F) GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(, const, ct, m, F) GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, , ct, m, F) GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
]] ]]
$for i [[ $for i [[
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \ #define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD$i[[]]_(typename, const, ct, m, F) GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
]] ]]

View File

@@ -40,6 +40,7 @@ $$ }} This line fixes auto-indentation of the following code in Emacs.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#include <iterator>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -186,62 +187,66 @@ class ArgsMatcher {
GTEST_DISALLOW_ASSIGN_(ArgsMatcher); GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
}; };
// Implements ElementsAre() of 1-$n arguments. // A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
$range i 1..n // to simplify the implementation.
$for i [[ template <typename M1>
$range j 1..i struct AllOfResult1 {
template <$for j, [[typename T$j]]> typedef M1 type;
class ElementsAreMatcher$i {
public:
$if i==1 [[explicit ]]ElementsAreMatcher$i($for j, [[const T$j& e$j]])$if i > 0 [[ : ]]
$for j, [[e$j[[]]_(e$j)]] {}
template <typename Container>
operator Matcher<Container>() const {
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
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 [[
MatcherCast<const Element&>(e$j[[]]_),
]]
};
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i));
]]
}
private:
$for j [[
const T$j& e$j[[]]_;
]]
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher$i);
}; };
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AllOfResult$i {
typedef BothOfMatcher<
typename AllOfResult$m<$for k, [[M$k]]>::type,
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]] ]]
// A set of metafunctions for computing the result type of AnyOf.
// AnyOf(m1, ..., mN) returns
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AnyOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AnyOfResult$i {
typedef EitherOfMatcher<
typename AnyOfResult$m<$for k, [[M$k]]>::type,
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
} // namespace internal } // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected // Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
@@ -259,48 +264,72 @@ Args(const InnerMatcher& matcher) {
]] ]]
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with // ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
// (n + 1) elements, where the i-th element in the container must // n elements, where the i-th element in the container must
// match the i-th argument in the list. Each argument of // match the i-th argument in the list. Each argument of
// ElementsAre() can be either a value or a matcher. We support up to // ElementsAre() can be either a value or a matcher. We support up to
// $n arguments. // $n arguments.
// //
// The use of DecayArray in the implementation allows ElementsAre()
// to accept string literals, whose type is const char[N], but we
// want to treat them as const char*.
//
// NOTE: Since ElementsAre() cares about the order of the elements, it // NOTE: Since ElementsAre() cares about the order of the elements, it
// must not be used with containers whose elements's order is // must not be used with containers whose elements's order is
// undefined (e.g. hash_map). // undefined (e.g. hash_map).
inline internal::ElementsAreMatcher0 ElementsAre() { $range i 0..n
return internal::ElementsAreMatcher0();
}
$range i 1..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$if i>0 [[
template <$for j, [[typename T$j]]> template <$for j, [[typename T$j]]>
inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[const T$j& e$j]]) { ]]
return internal::ElementsAreMatcher$i<$for j, [[T$j]]>($for j, [[e$j]]);
inline internal::ElementsAreMatcher<
std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> >
ElementsAre($for j, [[const T$j& e$j]]) {
typedef std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> Args;
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
} }
]] ]]
// ElementsAreArray(array) and ElementAreArray(array, count) are like // UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
// ElementsAre(), except that they take an array of values or // that matches n elements in any order. We support up to n=$n arguments.
// matchers. The former form infers the size of 'array', which must
// be a static C-style array. In the latter form, 'array' can either
// be a static array or a pointer to a dynamically created array.
template <typename T> $range i 0..n
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( $for i [[
const T* first, size_t count) {
return internal::ElementsAreArrayMatcher<T>(first, count); $range j 1..i
$if i>0 [[
template <$for j, [[typename T$j]]>
]]
inline internal::UnorderedElementsAreMatcher<
std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> >
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
typedef std::tr1::tuple<
$for j, [[
typename internal::DecayArray<T$j[[]]>::type]]> Args;
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
} }
template <typename T, size_t N> ]]
inline internal::ElementsAreArrayMatcher<T>
ElementsAreArray(const T (&array)[N]) {
return internal::ElementsAreArrayMatcher<T>(array, N);
}
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given // AllOf(m1, m2, ..., mk) matches any value that matches all of the given
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. // sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
@@ -308,19 +337,16 @@ ElementsAreArray(const T (&array)[N]) {
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$range k 1..i-1 $var m = i/2
$range k 1..m
template <$for j, [[typename Matcher$j]]> $range t m+1..i
inline $for k[[internal::BothOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
AllOf($for j, [[Matcher$j m$j]]) {
$if i == 2 [[
return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
]] $else [[
return ::testing::AllOf(m1, ::testing::AllOf($for k, [[m$(k + 1)]]));
]]
template <$for j, [[typename M$j]]>
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
AllOf($for j, [[M$j m$j]]) {
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
} }
]] ]]
@@ -331,19 +357,16 @@ $if i == 2 [[
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$range k 1..i-1 $var m = i/2
$range k 1..m
template <$for j, [[typename Matcher$j]]> $range t m+1..i
inline $for k[[internal::EitherOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
AnyOf($for j, [[Matcher$j m$j]]) {
$if i == 2 [[
return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
]] $else [[
return ::testing::AnyOf(m1, ::testing::AnyOf($for k, [[m$(k + 1)]]));
]]
template <$for j, [[typename M$j]]>
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
AnyOf($for j, [[M$j m$j]]) {
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
} }
]] ]]
@@ -621,7 +644,7 @@ $var param_field_decls2 = [[$for j
if (!gmock_description.empty())\ if (!gmock_description.empty())\
return gmock_description;\ return gmock_description;\
return ::testing::internal::FormatMatcherDescription(\ return ::testing::internal::FormatMatcherDescription(\
negation, #name,\ negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ ::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
}\ }\
@@ -642,7 +665,7 @@ $var param_field_decls2 = [[$for j
}\$template }\$template
template <typename arg_type>\ template <typename arg_type>\
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\ bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
arg_type arg,\ arg_type arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const const
]] ]]

View File

@@ -1,4 +1,6 @@
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! // This file was GENERATED by command:
// pump.py gmock-generated-nice-strict.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2008, Google Inc. // Copyright 2008, Google Inc.
// All rights reserved. // All rights reserved.
@@ -31,26 +33,36 @@
// //
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
// Implements class templates NiceMock and StrictMock. // Implements class templates NiceMock, NaggyMock, and StrictMock.
// //
// Given a mock class MockFoo that is created using Google Mock, // Given a mock class MockFoo that is created using Google Mock,
// NiceMock<MockFoo> is a subclass of MockFoo that allows // NiceMock<MockFoo> is a subclass of MockFoo that allows
// uninteresting calls (i.e. calls to mock methods that have no // uninteresting calls (i.e. calls to mock methods that have no
// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of // EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
// MockFoo that treats all uninteresting calls as errors. // that prints a warning when an uninteresting call occurs, and
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
// uninteresting calls as errors.
// //
// NiceMock and StrictMock "inherits" the constructors of their // Currently a mock is naggy by default, so MockFoo and
// respective base class, with up-to 10 arguments. Therefore you can // NaggyMock<MockFoo> behave like the same. However, we will soon
// write NiceMock<MockFoo>(5, "a") to construct a nice mock where // switch the default behavior of mocks to be nice, as that in general
// MockFoo has a constructor that accepts (int, const char*), for // leads to more maintainable tests. When that happens, MockFoo will
// example. // stop behaving like NaggyMock<MockFoo> and start behaving like
// NiceMock<MockFoo>.
// //
// A known limitation is that NiceMock<MockFoo> and // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// StrictMock<MockFoo> only works for mock methods defined using the // their respective base class, with up-to 10 arguments. Therefore
// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a // you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
// mock method is defined in a base class of MockFoo, the "nice" or // where MockFoo has a constructor that accepts (int, const char*),
// "strict" modifier may not affect it, depending on the compiler. In // for example.
// particular, nesting NiceMock and StrictMock is NOT supported. //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
// If a mock method is defined in a base class of MockFoo, the "nice"
// or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported.
// //
// Another known limitation is that the constructors of the base mock // Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are // cannot have arguments passed by non-const reference, which are
@@ -160,6 +172,102 @@ class NiceMock : public MockClass {
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
}; };
template <class MockClass>
class NaggyMock : public MockClass {
public:
// We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass.
NaggyMock() {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1>
explicit NaggyMock(const A1& a1) : MockClass(a1) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2>
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3>
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4>
NaggyMock(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) : MockClass(a1, a2, a3, a4) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
a6, a7) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
a2, a3, a4, a5, a6, a7, a8) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename A3, typename A4, typename A5,
typename A6, typename A7, typename A8, typename A9, typename A10>
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
virtual ~NaggyMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
};
template <class MockClass> template <class MockClass>
class StrictMock : public MockClass { class StrictMock : public MockClass {
public: public:
@@ -170,6 +278,8 @@ class StrictMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity.
template <typename A1> template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) { explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls( ::testing::Mock::FailUninterestingCalls(
@@ -258,15 +368,28 @@ class StrictMock : public MockClass {
// user errors of nesting nice and strict mocks. They do NOT catch // user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors. // all possible errors.
// These specializations are declared but not defined, as NiceMock and // These specializations are declared but not defined, as NiceMock,
// StrictMock cannot be nested. // NaggyMock, and StrictMock cannot be nested.
template <typename MockClass> template <typename MockClass>
class NiceMock<NiceMock<MockClass> >; class NiceMock<NiceMock<MockClass> >;
template <typename MockClass> template <typename MockClass>
class NiceMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NiceMock<StrictMock<MockClass> >; class NiceMock<StrictMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NiceMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NaggyMock<StrictMock<MockClass> >;
template <typename MockClass> template <typename MockClass>
class StrictMock<NiceMock<MockClass> >; class StrictMock<NiceMock<MockClass> >;
template <typename MockClass> template <typename MockClass>
class StrictMock<NaggyMock<MockClass> >;
template <typename MockClass>
class StrictMock<StrictMock<MockClass> >; class StrictMock<StrictMock<MockClass> >;
} // namespace testing } // namespace testing

View File

@@ -34,26 +34,36 @@ $var n = 10 $$ The maximum arity we support.
// //
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
// Implements class templates NiceMock and StrictMock. // Implements class templates NiceMock, NaggyMock, and StrictMock.
// //
// Given a mock class MockFoo that is created using Google Mock, // Given a mock class MockFoo that is created using Google Mock,
// NiceMock<MockFoo> is a subclass of MockFoo that allows // NiceMock<MockFoo> is a subclass of MockFoo that allows
// uninteresting calls (i.e. calls to mock methods that have no // uninteresting calls (i.e. calls to mock methods that have no
// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of // EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
// MockFoo that treats all uninteresting calls as errors. // that prints a warning when an uninteresting call occurs, and
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
// uninteresting calls as errors.
// //
// NiceMock and StrictMock "inherits" the constructors of their // Currently a mock is naggy by default, so MockFoo and
// respective base class, with up-to $n arguments. Therefore you can // NaggyMock<MockFoo> behave like the same. However, we will soon
// write NiceMock<MockFoo>(5, "a") to construct a nice mock where // switch the default behavior of mocks to be nice, as that in general
// MockFoo has a constructor that accepts (int, const char*), for // leads to more maintainable tests. When that happens, MockFoo will
// example. // stop behaving like NaggyMock<MockFoo> and start behaving like
// NiceMock<MockFoo>.
// //
// A known limitation is that NiceMock<MockFoo> and // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// StrictMock<MockFoo> only works for mock methods defined using the // their respective base class, with up-to $n arguments. Therefore
// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a // you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
// mock method is defined in a base class of MockFoo, the "nice" or // where MockFoo has a constructor that accepts (int, const char*),
// "strict" modifier may not affect it, depending on the compiler. In // for example.
// particular, nesting NiceMock and StrictMock is NOT supported. //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
// If a mock method is defined in a base class of MockFoo, the "nice"
// or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported.
// //
// Another known limitation is that the constructors of the base mock // Another known limitation is that the constructors of the base mock
// cannot have arguments passed by non-const reference, which are // cannot have arguments passed by non-const reference, which are
@@ -67,21 +77,32 @@ $var n = 10 $$ The maximum arity we support.
namespace testing { namespace testing {
$range kind 0..2
$for kind [[
$var clazz=[[$if kind==0 [[NiceMock]]
$elif kind==1 [[NaggyMock]]
$else [[StrictMock]]]]
$var method=[[$if kind==0 [[AllowUninterestingCalls]]
$elif kind==1 [[WarnUninterestingCalls]]
$else [[FailUninterestingCalls]]]]
template <class MockClass> template <class MockClass>
class NiceMock : public MockClass { class $clazz : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as // We don't factor out the constructor body to a common method, as
// we have to avoid a possible clash with members of MockClass. // we have to avoid a possible clash with members of MockClass.
NiceMock() { $clazz() {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have // C++ doesn't (yet) allow inheritance of constructors, so we have
// to define it for each arity. // to define it for each arity.
template <typename A1> template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) { explicit $clazz(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
@@ -89,70 +110,50 @@ $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
template <$for j, [[typename A$j]]> template <$for j, [[typename A$j]]>
NiceMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) { $clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
]] ]]
virtual ~NiceMock() { virtual ~$clazz() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
}; };
template <class MockClass>
class StrictMock : public MockClass {
public:
// 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() {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<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]]) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
]] ]]
virtual ~StrictMock() {
::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this));
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
};
// The following specializations catch some (relatively more common) // The following specializations catch some (relatively more common)
// user errors of nesting nice and strict mocks. They do NOT catch // user errors of nesting nice and strict mocks. They do NOT catch
// all possible errors. // all possible errors.
// These specializations are declared but not defined, as NiceMock and // These specializations are declared but not defined, as NiceMock,
// StrictMock cannot be nested. // NaggyMock, and StrictMock cannot be nested.
template <typename MockClass> template <typename MockClass>
class NiceMock<NiceMock<MockClass> >; class NiceMock<NiceMock<MockClass> >;
template <typename MockClass> template <typename MockClass>
class NiceMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NiceMock<StrictMock<MockClass> >; class NiceMock<StrictMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NiceMock<MockClass> >;
template <typename MockClass>
class NaggyMock<NaggyMock<MockClass> >;
template <typename MockClass>
class NaggyMock<StrictMock<MockClass> >;
template <typename MockClass> template <typename MockClass>
class StrictMock<NiceMock<MockClass> >; class StrictMock<NiceMock<MockClass> >;
template <typename MockClass> template <typename MockClass>
class StrictMock<NaggyMock<MockClass> >;
template <typename MockClass>
class StrictMock<StrictMock<MockClass> >; class StrictMock<StrictMock<MockClass> >;
} // namespace testing } // namespace testing

File diff suppressed because it is too large Load Diff

View File

@@ -66,6 +66,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#if GTEST_HAS_EXCEPTIONS
# include <stdexcept> // NOLINT
#endif
#include "gmock/gmock-actions.h" #include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h" #include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-matchers.h" #include "gmock/gmock-matchers.h"
@@ -111,7 +115,7 @@ template <typename F> class FunctionMockerBase;
// expectations when InSequence() is used, and thus affect which // expectations when InSequence() is used, and thus affect which
// expectation gets picked. Therefore, we sequence all mock function // expectation gets picked. Therefore, we sequence all mock function
// calls to ensure the integrity of the mock objects' states. // calls to ensure the integrity of the mock objects' states.
GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex); GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
// Untyped base class for ActionResultHolder<R>. // Untyped base class for ActionResultHolder<R>.
class UntypedActionResultHolderBase; class UntypedActionResultHolderBase;
@@ -119,7 +123,7 @@ class UntypedActionResultHolderBase;
// Abstract base class of FunctionMockerBase. This is the // Abstract base class of FunctionMockerBase. This is the
// type-agnostic part of the function mocker interface. Its pure // type-agnostic part of the function mocker interface. Its pure
// virtual methods are implemented by FunctionMockerBase. // virtual methods are implemented by FunctionMockerBase.
class UntypedFunctionMockerBase { class GTEST_API_ UntypedFunctionMockerBase {
public: public:
UntypedFunctionMockerBase(); UntypedFunctionMockerBase();
virtual ~UntypedFunctionMockerBase(); virtual ~UntypedFunctionMockerBase();
@@ -127,12 +131,12 @@ class UntypedFunctionMockerBase {
// Verifies that all expectations on this mock function have been // Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures // satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not. // and returns false if not.
// L >= g_gmock_mutex bool VerifyAndClearExpectationsLocked()
bool VerifyAndClearExpectationsLocked(); GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// Clears the ON_CALL()s set on this mock function. // Clears the ON_CALL()s set on this mock function.
// L >= g_gmock_mutex virtual void ClearDefaultActionsLocked()
virtual void ClearDefaultActionsLocked() = 0; GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0;
// In all of the following Untyped* functions, it's the caller's // In all of the following Untyped* functions, it's the caller's
// responsibility to guarantee the correctness of the arguments' // responsibility to guarantee the correctness of the arguments'
@@ -157,9 +161,10 @@ class UntypedFunctionMockerBase {
// Writes a message that the call is uninteresting (i.e. neither // Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given // explicitly expected nor explicitly unexpected) to the given
// ostream. // ostream.
// L < g_gmock_mutex virtual void UntypedDescribeUninterestingCall(
virtual void UntypedDescribeUninterestingCall(const void* untyped_args, const void* untyped_args,
::std::ostream* os) const = 0; ::std::ostream* os) const
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
// Returns the expectation that matches the given function arguments // Returns the expectation that matches the given function arguments
// (or NULL is there's no match); when a match is found, // (or NULL is there's no match); when a match is found,
@@ -167,11 +172,11 @@ class UntypedFunctionMockerBase {
// performed (or NULL if the action is "do default"), and // performed (or NULL if the action is "do default"), and
// is_excessive is modified to indicate whether the call exceeds the // is_excessive is modified to indicate whether the call exceeds the
// expected number. // expected number.
// L < g_gmock_mutex
virtual const ExpectationBase* UntypedFindMatchingExpectation( virtual const ExpectationBase* UntypedFindMatchingExpectation(
const void* untyped_args, const void* untyped_args,
const void** untyped_action, bool* is_excessive, const void** untyped_action, bool* is_excessive,
::std::ostream* what, ::std::ostream* why) = 0; ::std::ostream* what, ::std::ostream* why)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
// Prints the given function arguments to the ostream. // Prints the given function arguments to the ostream.
virtual void UntypedPrintArgs(const void* untyped_args, virtual void UntypedPrintArgs(const void* untyped_args,
@@ -182,33 +187,33 @@ class UntypedFunctionMockerBase {
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method. // method.
// TODO(wan@google.com): rename to SetAndRegisterOwner(). // TODO(wan@google.com): rename to SetAndRegisterOwner().
// L < g_gmock_mutex void RegisterOwner(const void* mock_obj)
void RegisterOwner(const void* mock_obj); GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
// Sets the mock object this mock method belongs to, and sets the // Sets the mock object this mock method belongs to, and sets the
// name of the mock function. Will be called upon each invocation // name of the mock function. Will be called upon each invocation
// of this mock function. // of this mock function.
// L < g_gmock_mutex void SetOwnerAndName(const void* mock_obj, const char* name)
void SetOwnerAndName(const void* mock_obj, const char* name); GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
// Returns the mock object this mock method belongs to. Must be // Returns the mock object this mock method belongs to. Must be
// called after RegisterOwner() or SetOwnerAndName() has been // called after RegisterOwner() or SetOwnerAndName() has been
// called. // called.
// L < g_gmock_mutex const void* MockObject() const
const void* MockObject() const; GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
// Returns the name of this mock method. Must be called after // Returns the name of this mock method. Must be called after
// SetOwnerAndName() has been called. // SetOwnerAndName() has been called.
// L < g_gmock_mutex const char* Name() const
const char* Name() const; GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
// Returns the result of invoking this mock function with the given // Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. The caller is responsible for deleting the // threads concurrently. The caller is responsible for deleting the
// result. // result.
// L < g_gmock_mutex
const UntypedActionResultHolderBase* UntypedInvokeWith( const UntypedActionResultHolderBase* UntypedInvokeWith(
const void* untyped_args); const void* untyped_args)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
protected: protected:
typedef std::vector<const void*> UntypedOnCallSpecs; typedef std::vector<const void*> UntypedOnCallSpecs;
@@ -352,34 +357,38 @@ class OnCallSpec : public UntypedOnCallSpecBase {
Action<F> action_; Action<F> action_;
}; // class OnCallSpec }; // class OnCallSpec
// Possible reactions on uninteresting calls. TODO(wan@google.com): // Possible reactions on uninteresting calls.
// rename the enum values to the kFoo style.
enum CallReaction { enum CallReaction {
ALLOW, kAllow,
WARN, kWarn,
FAIL kFail,
kDefault = kWarn // By default, warn about uninteresting calls.
}; };
} // namespace internal } // namespace internal
// Utilities for manipulating mock objects. // Utilities for manipulating mock objects.
class Mock { class GTEST_API_ Mock {
public: public:
// The following public methods can be called concurrently. // The following public methods can be called concurrently.
// Tells Google Mock to ignore mock_obj when checking for leaked // Tells Google Mock to ignore mock_obj when checking for leaked
// mock objects. // mock objects.
static void AllowLeak(const void* mock_obj); static void AllowLeak(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Verifies and clears all expectations on the given mock object. // Verifies and clears all expectations on the given mock object.
// If the expectations aren't satisfied, generates one or more // If the expectations aren't satisfied, generates one or more
// Google Test non-fatal failures and returns false. // Google Test non-fatal failures and returns false.
static bool VerifyAndClearExpectations(void* mock_obj); static bool VerifyAndClearExpectations(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Verifies all expectations on the given mock object and clears its // Verifies all expectations on the given mock object and clears its
// default actions and expectations. Returns true iff the // default actions and expectations. Returns true iff the
// verification was successful. // verification was successful.
static bool VerifyAndClear(void* mock_obj); static bool VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
private: private:
friend class internal::UntypedFunctionMockerBase; friend class internal::UntypedFunctionMockerBase;
@@ -391,63 +400,67 @@ class Mock {
template <typename M> template <typename M>
friend class NiceMock; friend class NiceMock;
template <typename M>
friend class NaggyMock;
template <typename M> template <typename M>
friend class StrictMock; friend class StrictMock;
// Tells Google Mock to allow uninteresting calls on the given mock // Tells Google Mock to allow uninteresting calls on the given mock
// object. // object.
// L < g_gmock_mutex static void AllowUninterestingCalls(const void* mock_obj)
static void AllowUninterestingCalls(const void* mock_obj); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock to warn the user about uninteresting calls on // Tells Google Mock to warn the user about uninteresting calls on
// the given mock object. // the given mock object.
// L < g_gmock_mutex static void WarnUninterestingCalls(const void* mock_obj)
static void WarnUninterestingCalls(const void* mock_obj); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock to fail uninteresting calls on the given mock // Tells Google Mock to fail uninteresting calls on the given mock
// object. // object.
// L < g_gmock_mutex static void FailUninterestingCalls(const void* mock_obj)
static void FailUninterestingCalls(const void* mock_obj); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock the given mock object is being destroyed and // Tells Google Mock the given mock object is being destroyed and
// its entry in the call-reaction table should be removed. // its entry in the call-reaction table should be removed.
// L < g_gmock_mutex static void UnregisterCallReaction(const void* mock_obj)
static void UnregisterCallReaction(const void* mock_obj); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Returns the reaction Google Mock will have on uninteresting calls // Returns the reaction Google Mock will have on uninteresting calls
// made on the given mock object. // made on the given mock object.
// L < g_gmock_mutex
static internal::CallReaction GetReactionOnUninterestingCalls( static internal::CallReaction GetReactionOnUninterestingCalls(
const void* mock_obj); const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Verifies that all expectations on the given mock object have been // Verifies that all expectations on the given mock object have been
// satisfied. Reports one or more Google Test non-fatal failures // satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not. // and returns false if not.
// L >= g_gmock_mutex static bool VerifyAndClearExpectationsLocked(void* mock_obj)
static bool VerifyAndClearExpectationsLocked(void* mock_obj); GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
// Clears all ON_CALL()s set on the given mock object. // Clears all ON_CALL()s set on the given mock object.
// L >= g_gmock_mutex static void ClearDefaultActionsLocked(void* mock_obj)
static void ClearDefaultActionsLocked(void* mock_obj); GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
// Registers a mock object and a mock method it owns. // Registers a mock object and a mock method it owns.
// L < g_gmock_mutex static void Register(
static void Register(const void* mock_obj, const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker); internal::UntypedFunctionMockerBase* mocker)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Tells Google Mock where in the source code mock_obj is used in an // Tells Google Mock where in the source code mock_obj is used in an
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this // ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
// information helps the user identify which object it is. // information helps the user identify which object it is.
// L < g_gmock_mutex
static void RegisterUseByOnCallOrExpectCall( static void RegisterUseByOnCallOrExpectCall(
const void* mock_obj, const char* file, int line); const void* mock_obj, const char* file, int line)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Unregisters a mock method; removes the owning mock object from // Unregisters a mock method; removes the owning mock object from
// the registry when the last mock method associated with it has // the registry when the last mock method associated with it has
// been unregistered. This is called only in the destructor of // been unregistered. This is called only in the destructor of
// FunctionMockerBase. // FunctionMockerBase.
// L >= g_gmock_mutex static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker); GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
}; // class Mock }; // class Mock
// An abstract handle of an expectation. Useful in the .After() // An abstract handle of an expectation. Useful in the .After()
@@ -471,7 +484,7 @@ class Mock {
// ExpectationBase available yet, leading to incorrect destruction // ExpectationBase available yet, leading to incorrect destruction
// in the linked_ptr (or compilation errors if using a checking // in the linked_ptr (or compilation errors if using a checking
// linked_ptr). // linked_ptr).
class Expectation { class GTEST_API_ Expectation {
public: public:
// Constructs a null object that doesn't reference any expectation. // Constructs a null object that doesn't reference any expectation.
Expectation(); Expectation();
@@ -603,7 +616,7 @@ class ExpectationSet {
// Sequence objects are used by a user to specify the relative order // Sequence objects are used by a user to specify the relative order
// in which the expectations should match. They are copyable (we rely // in which the expectations should match. They are copyable (we rely
// on the compiler-defined copy constructor and assignment operator). // on the compiler-defined copy constructor and assignment operator).
class Sequence { class GTEST_API_ Sequence {
public: public:
// Constructs an empty sequence. // Constructs an empty sequence.
Sequence() : last_expectation_(new Expectation) {} Sequence() : last_expectation_(new Expectation) {}
@@ -644,7 +657,7 @@ class Sequence {
// thread. However, for clarity of your tests we recommend you to set // thread. However, for clarity of your tests we recommend you to set
// up mocks in the main thread unless you have a good reason not to do // up mocks in the main thread unless you have a good reason not to do
// so. // so.
class InSequence { class GTEST_API_ InSequence {
public: public:
InSequence(); InSequence();
~InSequence(); ~InSequence();
@@ -658,7 +671,7 @@ namespace internal {
// Points to the implicit sequence introduced by a living InSequence // Points to the implicit sequence introduced by a living InSequence
// object (if any) in the current thread or NULL. // object (if any) in the current thread or NULL.
extern ThreadLocal<Sequence*> g_gmock_implicit_sequence; GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;
// Base class for implementing expectations. // Base class for implementing expectations.
// //
@@ -674,7 +687,7 @@ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;
// on the template argument of Expectation to the base class. // on the template argument of Expectation to the base class.
// //
// This class is internal and mustn't be used by user code directly. // This class is internal and mustn't be used by user code directly.
class ExpectationBase { class GTEST_API_ ExpectationBase {
public: public:
// source_text is the EXPECT_CALL(...) source that created this Expectation. // source_text is the EXPECT_CALL(...) source that created this Expectation.
ExpectationBase(const char* file, int line, const string& source_text); ExpectationBase(const char* file, int line, const string& source_text);
@@ -695,8 +708,8 @@ class ExpectationBase {
// Describes how many times a function call matching this // Describes how many times a function call matching this
// expectation has occurred. // expectation has occurred.
// L >= g_gmock_mutex void DescribeCallCountTo(::std::ostream* os) const
void DescribeCallCountTo(::std::ostream* os) const; GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// If this mock method has an extra matcher (i.e. .With(matcher)), // If this mock method has an extra matcher (i.e. .With(matcher)),
// describes it to the ostream. // describes it to the ostream.
@@ -752,62 +765,62 @@ class ExpectationBase {
// the current thread. // the current thread.
// Retires all pre-requisites of this expectation. // Retires all pre-requisites of this expectation.
// L >= g_gmock_mutex void RetireAllPreRequisites()
void RetireAllPreRequisites(); GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// Returns true iff this expectation is retired. // Returns true iff this expectation is retired.
// L >= g_gmock_mutex bool is_retired() const
bool is_retired() const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
return retired_; return retired_;
} }
// Retires this expectation. // Retires this expectation.
// L >= g_gmock_mutex void Retire()
void Retire() { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
retired_ = true; retired_ = true;
} }
// Returns true iff this expectation is satisfied. // Returns true iff this expectation is satisfied.
// L >= g_gmock_mutex bool IsSatisfied() const
bool IsSatisfied() const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
return cardinality().IsSatisfiedByCallCount(call_count_); return cardinality().IsSatisfiedByCallCount(call_count_);
} }
// Returns true iff this expectation is saturated. // Returns true iff this expectation is saturated.
// L >= g_gmock_mutex bool IsSaturated() const
bool IsSaturated() const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
return cardinality().IsSaturatedByCallCount(call_count_); return cardinality().IsSaturatedByCallCount(call_count_);
} }
// Returns true iff this expectation is over-saturated. // Returns true iff this expectation is over-saturated.
// L >= g_gmock_mutex bool IsOverSaturated() const
bool IsOverSaturated() const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
return cardinality().IsOverSaturatedByCallCount(call_count_); return cardinality().IsOverSaturatedByCallCount(call_count_);
} }
// Returns true iff all pre-requisites of this expectation are satisfied. // Returns true iff all pre-requisites of this expectation are satisfied.
// L >= g_gmock_mutex bool AllPrerequisitesAreSatisfied() const
bool AllPrerequisitesAreSatisfied() const; GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// Adds unsatisfied pre-requisites of this expectation to 'result'. // Adds unsatisfied pre-requisites of this expectation to 'result'.
// L >= g_gmock_mutex void FindUnsatisfiedPrerequisites(ExpectationSet* result) const
void FindUnsatisfiedPrerequisites(ExpectationSet* result) const; GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
// Returns the number this expectation has been invoked. // Returns the number this expectation has been invoked.
// L >= g_gmock_mutex int call_count() const
int call_count() const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
return call_count_; return call_count_;
} }
// Increments the number this expectation has been invoked. // Increments the number this expectation has been invoked.
// L >= g_gmock_mutex void IncrementCallCount()
void IncrementCallCount() { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
call_count_++; call_count_++;
} }
@@ -816,8 +829,8 @@ class ExpectationBase {
// WillRepeatedly() clauses) against the cardinality if this hasn't // WillRepeatedly() clauses) against the cardinality if this hasn't
// been done before. Prints a warning if there are too many or too // been done before. Prints a warning if there are too many or too
// few actions. // few actions.
// L < mutex_ void CheckActionCountIfNotDone() const
void CheckActionCountIfNotDone() const; GTEST_LOCK_EXCLUDED_(mutex_);
friend class ::testing::Sequence; friend class ::testing::Sequence;
friend class ::testing::internal::ExpectationTester; friend class ::testing::internal::ExpectationTester;
@@ -1069,15 +1082,15 @@ class TypedExpectation : public ExpectationBase {
// g_gmock_mutex. // g_gmock_mutex.
// Returns true iff this expectation matches the given arguments. // Returns true iff this expectation matches the given arguments.
// L >= g_gmock_mutex bool Matches(const ArgumentTuple& args) const
bool Matches(const ArgumentTuple& args) const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args); return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
} }
// Returns true iff this expectation should handle the given arguments. // Returns true iff this expectation should handle the given arguments.
// L >= g_gmock_mutex bool ShouldHandleArguments(const ArgumentTuple& args) const
bool ShouldHandleArguments(const ArgumentTuple& args) const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
// In case the action count wasn't checked when the expectation // In case the action count wasn't checked when the expectation
@@ -1090,9 +1103,10 @@ class TypedExpectation : public ExpectationBase {
// Describes the result of matching the arguments against this // Describes the result of matching the arguments against this
// expectation to the given ostream. // expectation to the given ostream.
// L >= g_gmock_mutex void ExplainMatchResultTo(
void ExplainMatchResultTo(const ArgumentTuple& args, const ArgumentTuple& args,
::std::ostream* os) const { ::std::ostream* os) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
if (is_retired()) { if (is_retired()) {
@@ -1134,9 +1148,10 @@ class TypedExpectation : public ExpectationBase {
} }
// Returns the action that should be taken for the current invocation. // Returns the action that should be taken for the current invocation.
// L >= g_gmock_mutex const Action<F>& GetCurrentAction(
const Action<F>& GetCurrentAction(const FunctionMockerBase<F>* mocker, const FunctionMockerBase<F>* mocker,
const ArgumentTuple& args) const { const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
const int count = call_count(); const int count = call_count();
Assert(count >= 1, __FILE__, __LINE__, Assert(count >= 1, __FILE__, __LINE__,
@@ -1155,7 +1170,7 @@ class TypedExpectation : public ExpectationBase {
<< action_count << " WillOnce()" << action_count << " WillOnce()"
<< (action_count == 1 ? " is" : "s are") << " specified - "; << (action_count == 1 ? " is" : "s are") << " specified - ";
mocker->DescribeDefaultActionTo(args, &ss); mocker->DescribeDefaultActionTo(args, &ss);
Log(WARNING, ss.str(), 1); Log(kWarning, ss.str(), 1);
} }
return count <= action_count ? return count <= action_count ?
@@ -1170,11 +1185,12 @@ class TypedExpectation : public ExpectationBase {
// Mock does it to 'why'. This method is not const as it calls // Mock does it to 'why'. This method is not const as it calls
// IncrementCallCount(). A return value of NULL means the default // IncrementCallCount(). A return value of NULL means the default
// action. // action.
// L >= g_gmock_mutex const Action<F>* GetActionForArguments(
const Action<F>* GetActionForArguments(const FunctionMockerBase<F>* mocker, const FunctionMockerBase<F>* mocker,
const ArgumentTuple& args, const ArgumentTuple& args,
::std::ostream* what, ::std::ostream* what,
::std::ostream* why) { ::std::ostream* why)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
if (IsSaturated()) { if (IsSaturated()) {
// We have an excessive call. // We have an excessive call.
@@ -1222,9 +1238,9 @@ class TypedExpectation : public ExpectationBase {
// ::testing::internal and import it into ::testing. // ::testing::internal and import it into ::testing.
// Logs a message including file and line number information. // Logs a message including file and line number information.
void LogWithLocation(testing::internal::LogSeverity severity, GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line, const char* file, int line,
const string& message); const string& message);
template <typename F> template <typename F>
class MockSpec { class MockSpec {
@@ -1242,7 +1258,7 @@ class MockSpec {
// the newly created spec. // the newly created spec.
internal::OnCallSpec<F>& InternalDefaultActionSetAt( internal::OnCallSpec<F>& InternalDefaultActionSetAt(
const char* file, int line, const char* obj, const char* call) { const char* file, int line, const char* obj, const char* call) {
LogWithLocation(internal::INFO, file, line, LogWithLocation(internal::kInfo, file, line,
string("ON_CALL(") + obj + ", " + call + ") invoked"); string("ON_CALL(") + obj + ", " + call + ") invoked");
return function_mocker_->AddNewOnCallSpec(file, line, matchers_); return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
} }
@@ -1252,7 +1268,7 @@ class MockSpec {
internal::TypedExpectation<F>& InternalExpectedAt( internal::TypedExpectation<F>& InternalExpectedAt(
const char* file, int line, const char* obj, const char* call) { const char* file, int line, const char* obj, const char* call) {
const string source_text(string("EXPECT_CALL(") + obj + ", " + call + ")"); const string source_text(string("EXPECT_CALL(") + obj + ", " + call + ")");
LogWithLocation(internal::INFO, file, line, source_text + " invoked"); LogWithLocation(internal::kInfo, file, line, source_text + " invoked");
return function_mocker_->AddNewExpectation( return function_mocker_->AddNewExpectation(
file, line, source_text, matchers_); file, line, source_text, matchers_);
} }
@@ -1393,8 +1409,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// The destructor verifies that all expectations on this mock // The destructor verifies that all expectations on this mock
// function have been satisfied. If not, it will report Google Test // function have been satisfied. If not, it will report Google Test
// non-fatal failures for the violations. // non-fatal failures for the violations.
// L < g_gmock_mutex virtual ~FunctionMockerBase()
virtual ~FunctionMockerBase() { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
MutexLock l(&g_gmock_mutex); MutexLock l(&g_gmock_mutex);
VerifyAndClearExpectationsLocked(); VerifyAndClearExpectationsLocked();
Mock::UnregisterLocked(this); Mock::UnregisterLocked(this);
@@ -1417,10 +1433,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
return NULL; return NULL;
} }
// Performs the default action of this mock function on the given arguments // Performs the default action of this mock function on the given
// and returns the result. Asserts with a helpful call descrption if there is // arguments and returns the result. Asserts (or throws if
// no valid return value. This method doesn't depend on the mutable state of // exceptions are enabled) with a helpful call descrption if there
// this object, and thus can be called concurrently without locking. // is no valid return value. This method doesn't depend on the
// mutable state of this object, and thus can be called concurrently
// without locking.
// L = * // L = *
Result PerformDefaultAction(const ArgumentTuple& args, Result PerformDefaultAction(const ArgumentTuple& args,
const string& call_description) const { const string& call_description) const {
@@ -1429,9 +1447,16 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
if (spec != NULL) { if (spec != NULL) {
return spec->GetAction().Perform(args); return spec->GetAction().Perform(args);
} }
Assert(DefaultValue<Result>::Exists(), "", -1, const string message = call_description +
call_description + "\n The mock function has no default action " "\n The mock function has no default action "
"set, and its return type has no default value set."); "set, and its return type has no default value set.";
#if GTEST_HAS_EXCEPTIONS
if (!DefaultValue<Result>::Exists()) {
throw std::runtime_error(message);
}
#else
Assert(DefaultValue<Result>::Exists(), "", -1, message);
#endif
return DefaultValue<Result>::Get(); return DefaultValue<Result>::Get();
} }
@@ -1464,15 +1489,30 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
// clears the ON_CALL()s set on this mock function. // clears the ON_CALL()s set on this mock function.
// L >= g_gmock_mutex virtual void ClearDefaultActionsLocked()
virtual void ClearDefaultActionsLocked() { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
// Deleting our default actions may trigger other mock objects to be
// deleted, for example if an action contains a reference counted smart
// pointer to that mock object, and that is the last reference. So if we
// delete our actions within the context of the global mutex we may deadlock
// when this method is called again. Instead, make a copy of the set of
// actions to delete, clear our set within the mutex, and then delete the
// actions outside of the mutex.
UntypedOnCallSpecs specs_to_delete;
untyped_on_call_specs_.swap(specs_to_delete);
g_gmock_mutex.Unlock();
for (UntypedOnCallSpecs::const_iterator it = for (UntypedOnCallSpecs::const_iterator it =
untyped_on_call_specs_.begin(); specs_to_delete.begin();
it != untyped_on_call_specs_.end(); ++it) { it != specs_to_delete.end(); ++it) {
delete static_cast<const OnCallSpec<F>*>(*it); delete static_cast<const OnCallSpec<F>*>(*it);
} }
untyped_on_call_specs_.clear();
// Lock the mutex again, since the caller expects it to be locked when we
// return.
g_gmock_mutex.Lock();
} }
protected: protected:
@@ -1484,17 +1524,17 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the result of invoking this mock function with the given // Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. // threads concurrently.
// L < g_gmock_mutex Result InvokeWith(const ArgumentTuple& args)
Result InvokeWith(const ArgumentTuple& args) { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
return static_cast<const ResultHolder*>( return static_cast<const ResultHolder*>(
this->UntypedInvokeWith(&args))->GetValueAndDelete(); this->UntypedInvokeWith(&args))->GetValueAndDelete();
} }
// Adds and returns a default action spec for this mock function. // Adds and returns a default action spec for this mock function.
// L < g_gmock_mutex
OnCallSpec<F>& AddNewOnCallSpec( OnCallSpec<F>& AddNewOnCallSpec(
const char* file, int line, const char* file, int line,
const ArgumentMatcherTuple& m) { const ArgumentMatcherTuple& m)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m); OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);
untyped_on_call_specs_.push_back(on_call_spec); untyped_on_call_specs_.push_back(on_call_spec);
@@ -1502,12 +1542,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
} }
// Adds and returns an expectation spec for this mock function. // Adds and returns an expectation spec for this mock function.
// L < g_gmock_mutex
TypedExpectation<F>& AddNewExpectation( TypedExpectation<F>& AddNewExpectation(
const char* file, const char* file,
int line, int line,
const string& source_text, const string& source_text,
const ArgumentMatcherTuple& m) { const ArgumentMatcherTuple& m)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
TypedExpectation<F>* const expectation = TypedExpectation<F>* const expectation =
new TypedExpectation<F>(this, file, line, source_text, m); new TypedExpectation<F>(this, file, line, source_text, m);
@@ -1552,9 +1592,10 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Writes a message that the call is uninteresting (i.e. neither // Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given // explicitly expected nor explicitly unexpected) to the given
// ostream. // ostream.
// L < g_gmock_mutex virtual void UntypedDescribeUninterestingCall(
virtual void UntypedDescribeUninterestingCall(const void* untyped_args, const void* untyped_args,
::std::ostream* os) const { ::std::ostream* os) const
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args = const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args); *static_cast<const ArgumentTuple*>(untyped_args);
*os << "Uninteresting mock function call - "; *os << "Uninteresting mock function call - ";
@@ -1579,11 +1620,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// section. The reason is that we have no control on what the // section. The reason is that we have no control on what the
// action does (it can invoke an arbitrary user function or even a // action does (it can invoke an arbitrary user function or even a
// mock function) and excessive locking could cause a dead lock. // mock function) and excessive locking could cause a dead lock.
// L < g_gmock_mutex
virtual const ExpectationBase* UntypedFindMatchingExpectation( virtual const ExpectationBase* UntypedFindMatchingExpectation(
const void* untyped_args, const void* untyped_args,
const void** untyped_action, bool* is_excessive, const void** untyped_action, bool* is_excessive,
::std::ostream* what, ::std::ostream* why) { ::std::ostream* what, ::std::ostream* why)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args = const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args); *static_cast<const ArgumentTuple*>(untyped_args);
MutexLock l(&g_gmock_mutex); MutexLock l(&g_gmock_mutex);
@@ -1614,9 +1655,9 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the expectation that matches the arguments, or NULL if no // Returns the expectation that matches the arguments, or NULL if no
// expectation matches them. // expectation matches them.
// L >= g_gmock_mutex
TypedExpectation<F>* FindMatchingExpectationLocked( TypedExpectation<F>* FindMatchingExpectationLocked(
const ArgumentTuple& args) const { const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
for (typename UntypedExpectations::const_reverse_iterator it = for (typename UntypedExpectations::const_reverse_iterator it =
untyped_expectations_.rbegin(); untyped_expectations_.rbegin();
@@ -1631,10 +1672,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
} }
// Returns a message that the arguments don't match any expectation. // Returns a message that the arguments don't match any expectation.
// L >= g_gmock_mutex void FormatUnexpectedCallMessageLocked(
void FormatUnexpectedCallMessageLocked(const ArgumentTuple& args, const ArgumentTuple& args,
::std::ostream* os, ::std::ostream* os,
::std::ostream* why) const { ::std::ostream* why) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
*os << "\nUnexpected mock function call - "; *os << "\nUnexpected mock function call - ";
DescribeDefaultActionTo(args, os); DescribeDefaultActionTo(args, os);
@@ -1643,9 +1685,10 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Prints a list of expectations that have been tried against the // Prints a list of expectations that have been tried against the
// current mock function call. // current mock function call.
// L >= g_gmock_mutex void PrintTriedExpectationsLocked(
void PrintTriedExpectationsLocked(const ArgumentTuple& args, const ArgumentTuple& args,
::std::ostream* why) const { ::std::ostream* why) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
const int count = static_cast<int>(untyped_expectations_.size()); const int count = static_cast<int>(untyped_expectations_.size());
*why << "Google Mock tried the following " << count << " " *why << "Google Mock tried the following " << count << " "
@@ -1694,7 +1737,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Verifies that all expectations on this mock function have been // Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures and // satisfied. Reports one or more Google Test non-fatal failures and
// returns false if not. // returns false if not.
// L >= g_gmock_mutex
// Reports an uninteresting call (whose description is in msg) in the // Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'. // manner specified by 'reaction'.

View File

@@ -59,10 +59,11 @@
#include "gmock/gmock-cardinalities.h" #include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-generated-actions.h" #include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h" #include "gmock/gmock-generated-function-mockers.h"
#include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-generated-nice-strict.h" #include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-matchers.h" #include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
namespace testing { namespace testing {
@@ -82,11 +83,11 @@ GMOCK_DECLARE_string_(verbose);
// Since Google Test is needed for Google Mock to work, this function // Since Google Test is needed for Google Mock to work, this function
// also initializes Google Test and parses its flags, if that hasn't // also initializes Google Test and parses its flags, if that hasn't
// been done. // been done.
void InitGoogleMock(int* argc, char** argv); GTEST_API_ void InitGoogleMock(int* argc, char** argv);
// This overloaded version can be used in Windows programs compiled in // This overloaded version can be used in Windows programs compiled in
// UNICODE mode. // UNICODE mode.
void InitGoogleMock(int* argc, wchar_t** argv); GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
} // namespace testing } // namespace testing

View File

@@ -1,4 +1,6 @@
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! // This file was GENERATED by command:
// pump.py gmock-generated-internal-utils.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc. // Copyright 2007, Google Inc.
// All rights reserved. // All rights reserved.
@@ -58,7 +60,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
template <typename T> template <typename T>
IgnoredValue(const T&) {} IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// MatcherTuple<T>::type is a tuple type where each field is a Matcher // MatcherTuple<T>::type is a tuple type where each field is a Matcher

View File

@@ -61,7 +61,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
template <typename T> template <typename T>
IgnoredValue(const T&) {} IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// MatcherTuple<T>::type is a tuple type where each field is a Matcher // MatcherTuple<T>::type is a tuple type where each field is a Matcher

View File

@@ -53,7 +53,7 @@ namespace internal {
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and // treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123". // "foo_bar_123" are converted to "foo bar 123".
string ConvertIdentifierNameToWords(const char* id_name); GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
// PointeeOf<Pointer>::type is the type of a value pointed to by a // PointeeOf<Pointer>::type is the type of a value pointed to by a
// Pointer, which can be either a smart pointer or a raw pointer. The // Pointer, which can be either a smart pointer or a raw pointer. The
@@ -73,7 +73,7 @@ struct PointeeOf<T*> { typedef T type; }; // NOLINT
// smart pointer, or returns p itself when p is already a raw pointer. // smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case. // The following default implementation is for the smart pointer case.
template <typename Pointer> template <typename Pointer>
inline typename Pointer::element_type* GetRawPointer(const Pointer& p) { inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
return p.get(); return p.get();
} }
// This overloaded version is for the raw pointer case. // This overloaded version is for the raw pointer case.
@@ -260,7 +260,7 @@ class FailureReporterInterface {
public: public:
// The type of a failure (either non-fatal or fatal). // The type of a failure (either non-fatal or fatal).
enum FailureType { enum FailureType {
NONFATAL, FATAL kNonfatal, kFatal
}; };
virtual ~FailureReporterInterface() {} virtual ~FailureReporterInterface() {}
@@ -271,7 +271,7 @@ class FailureReporterInterface {
}; };
// Returns the failure reporter used by Google Mock. // Returns the failure reporter used by Google Mock.
FailureReporterInterface* GetFailureReporter(); GTEST_API_ FailureReporterInterface* GetFailureReporter();
// Asserts that condition is true; aborts the process with the given // Asserts that condition is true; aborts the process with the given
// message if condition is false. We cannot use LOG(FATAL) or CHECK() // message if condition is false. We cannot use LOG(FATAL) or CHECK()
@@ -281,7 +281,7 @@ FailureReporterInterface* GetFailureReporter();
inline void Assert(bool condition, const char* file, int line, inline void Assert(bool condition, const char* file, int line,
const string& msg) { const string& msg) {
if (!condition) { if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::FATAL, GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
file, line, msg); file, line, msg);
} }
} }
@@ -294,7 +294,7 @@ inline void Assert(bool condition, const char* file, int line) {
inline void Expect(bool condition, const char* file, int line, inline void Expect(bool condition, const char* file, int line,
const string& msg) { const string& msg) {
if (!condition) { if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::NONFATAL, GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
file, line, msg); file, line, msg);
} }
} }
@@ -304,8 +304,8 @@ inline void Expect(bool condition, const char* file, int line) {
// Severity level of a log. // Severity level of a log.
enum LogSeverity { enum LogSeverity {
INFO = 0, kInfo = 0,
WARNING = 1 kWarning = 1
}; };
// Valid values for the --gmock_verbose flag. // Valid values for the --gmock_verbose flag.
@@ -319,7 +319,7 @@ const char kErrorVerbosity[] = "error";
// Returns true iff a log with the given severity is visible according // Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag. // to the --gmock_verbose flag.
bool LogIsVisible(LogSeverity severity); GTEST_API_ bool LogIsVisible(LogSeverity severity);
// Prints the given message to stdout iff 'severity' >= the level // Prints the given message to stdout iff 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >= // specified by the --gmock_verbose flag. If stack_frames_to_skip >=
@@ -328,7 +328,9 @@ bool LogIsVisible(LogSeverity severity);
// stack_frames_to_skip is treated as 0, since we don't know which // stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be // function calls will be inlined by the compiler and need to be
// conservative. // conservative.
void Log(LogSeverity severity, const string& message, int stack_frames_to_skip); GTEST_API_ void Log(LogSeverity severity,
const string& message,
int stack_frames_to_skip);
// TODO(wan@google.com): group all type utilities together. // TODO(wan@google.com): group all type utilities together.
@@ -346,13 +348,27 @@ template <typename T> struct type_equals<T, T> : public true_type {};
template <typename T> struct remove_reference { typedef T type; }; // NOLINT template <typename T> struct remove_reference { typedef T type; }; // NOLINT
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
// other types. Useful for saving a copy of a function argument.
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
template <typename T, size_t N> struct DecayArray<T[N]> {
typedef const T* type;
};
// Sometimes people use arrays whose size is not available at the use site
// (e.g. extern const char kNamePrefix[]). This specialization covers that
// case.
template <typename T> struct DecayArray<T[]> {
typedef const T* type;
};
// Invalid<T>() returns an invalid value of type T. This is useful // Invalid<T>() returns an invalid value of type T. This is useful
// when a value of type T is needed for compilation, but the statement // when a value of type T is needed for compilation, but the statement
// will not really be executed (or we don't care if the statement // will not really be executed (or we don't care if the statement
// crashes). // crashes).
template <typename T> template <typename T>
inline T Invalid() { inline T Invalid() {
return *static_cast<typename remove_reference<T>::type*>(NULL); return const_cast<typename remove_reference<T>::type&>(
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
} }
template <> template <>
inline void Invalid<void>() {} inline void Invalid<void>() {}
@@ -457,6 +473,25 @@ class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
// StlContainer with a reference type. // StlContainer with a reference type.
template <typename T> class StlContainerView<T&>; template <typename T> class StlContainerView<T&>;
// A type transform to remove constness from the first part of a pair.
// Pairs like that are used as the value_type of associative containers,
// and this transform produces a similar but assignable pair.
template <typename T>
struct RemoveConstFromKey {
typedef T type;
};
// Partially specialized to remove constness from std::pair<const K, V>.
template <typename K, typename V>
struct RemoveConstFromKey<std::pair<const K, V> > {
typedef std::pair<K, V> type;
};
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
// std::integral_constant<bool, kValue>.
template <bool kValue>
struct BooleanConstant {};
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

View File

@@ -61,18 +61,18 @@
#define GMOCK_FLAG(name) FLAGS_gmock_##name #define GMOCK_FLAG(name) FLAGS_gmock_##name
// Macros for declaring flags. // Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) extern bool GMOCK_FLAG(name) #define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
#define GMOCK_DECLARE_int32_(name) \ #define GMOCK_DECLARE_int32_(name) \
extern ::testing::internal::Int32 GMOCK_FLAG(name) extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
#define GMOCK_DECLARE_string_(name) \ #define GMOCK_DECLARE_string_(name) \
extern ::testing::internal::String GMOCK_FLAG(name) extern GTEST_API_ ::std::string GMOCK_FLAG(name)
// Macros for defining flags. // Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \ #define GMOCK_DEFINE_bool_(name, default_val, doc) \
bool GMOCK_FLAG(name) = (default_val) GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_int32_(name, default_val, doc) \ #define GMOCK_DEFINE_int32_(name, default_val, doc) \
::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_string_(name, default_val, doc) \ #define GMOCK_DEFINE_string_(name, default_val, doc) \
::testing::internal::String GMOCK_FLAG(name) = (default_val) GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

View File

@@ -1546,7 +1546,7 @@ class AstBuilder(object):
self._AddBackToken(token) self._AddBackToken(token)
return class_type(class_token.start, class_token.end, class_name, return class_type(class_token.start, class_token.end, class_name,
bases, None, body, self.namespace_stack) bases, templated_types, body, self.namespace_stack)
def handle_namespace(self): def handle_namespace(self):
token = self._GetNextToken() token = self._GetNextToken()

View File

@@ -82,20 +82,40 @@ def _GenerateMethods(output_lines, source, class_node):
return_type += '*' return_type += '*'
if node.return_type.reference: if node.return_type.reference:
return_type += '&' return_type += '&'
mock_method_macro = 'MOCK_%sMETHOD%d' % (const, len(node.parameters)) num_parameters = len(node.parameters)
if len(node.parameters) == 1:
first_param = node.parameters[0]
if source[first_param.start:first_param.end].strip() == 'void':
# We must treat T(void) as a function with no parameters.
num_parameters = 0
tmpl = ''
if class_node.templated_types:
tmpl = '_T'
mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl)
args = '' args = ''
if node.parameters: if node.parameters:
# Get the full text of the parameters from the start # Due to the parser limitations, it is impossible to keep comments
# of the first parameter to the end of the last parameter. # while stripping the default parameters. When defaults are
start = node.parameters[0].start # present, we choose to strip them and comments (and produce
end = node.parameters[-1].end # compilable code).
# Remove // comments. # TODO(nnorwitz@google.com): Investigate whether it is possible to
args_strings = re.sub(r'//.*', '', source[start:end]) # preserve parameter name when reconstructing parameter text from
# Condense multiple spaces and eliminate newlines putting the # the AST.
# parameters together on a single line. Ensure there is a if len([param for param in node.parameters if param.default]) > 0:
# space in an argument which is split by a newline without args = ', '.join(param.type.name for param in node.parameters)
# intervening whitespace, e.g.: int\nBar else:
args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) # Get the full text of the parameters from the start
# of the first parameter to the end of the last parameter.
start = node.parameters[0].start
end = node.parameters[-1].end
# Remove // comments.
args_strings = re.sub(r'//.*', '', source[start:end])
# Condense multiple spaces and eliminate newlines putting the
# parameters together on a single line. Ensure there is a
# space in an argument which is split by a newline without
# intervening whitespace, e.g.: int\nBar
args = re.sub(' +', ' ', args_strings.replace('\n', ' '))
# Create the mock method definition. # Create the mock method definition.
output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name), output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name),
@@ -110,6 +130,7 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
# desired_class_names being None means that all classes are selected. # desired_class_names being None means that all classes are selected.
(not desired_class_names or node.name in desired_class_names)): (not desired_class_names or node.name in desired_class_names)):
class_name = node.name class_name = node.name
parent_name = class_name
processed_class_names.add(class_name) processed_class_names.add(class_name)
class_node = node class_node = node
# Add namespace before the class. # Add namespace before the class.
@@ -117,8 +138,21 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
lines.append('') lines.append('')
# Add template args for templated classes.
if class_node.templated_types:
# TODO(paulchang): The AST doesn't preserve template argument order,
# so we have to make up names here.
# TODO(paulchang): Handle non-type template arguments (e.g.
# template<typename T, int N>).
template_arg_count = len(class_node.templated_types.keys())
template_args = ['T%d' % n for n in range(template_arg_count)]
template_decls = ['typename ' + arg for arg in template_args]
lines.append('template <' + ', '.join(template_decls) + '>')
parent_name += '<' + ', '.join(template_args) + '>'
# Add the class prolog. # Add the class prolog.
lines.append('class Mock%s : public %s {' % (class_name, class_name)) # } lines.append('class Mock%s : public %s {' # }
% (class_name, parent_name))
lines.append('%spublic:' % (' ' * (_INDENT // 2))) lines.append('%spublic:' % (' ' * (_INDENT // 2)))
# Add all the methods. # Add all the methods.

View File

@@ -332,7 +332,7 @@ def _OverloadedMethodActionDiagnoser(msg):
r'(.*\n)*?' r'(.*\n)*?'
r'.*\bgmock-\w+-actions\.h:\d+:\d+: ' r'.*\bgmock-\w+-actions\.h:\d+:\d+: '
r'note: candidate function template not viable: ' r'note: candidate function template not viable: '
r'requires 1 argument, but 2 were provided') r'requires .*, but 2 (arguments )?were provided')
diagnosis = """ diagnosis = """
The second argument you gave to Invoke() is an overloaded method. Please The second argument you gave to Invoke() is an overloaded method. Please
tell your compiler which overloaded version you want to use. tell your compiler which overloaded version you want to use.
@@ -416,7 +416,7 @@ def _NeedToUseReturnNullDiagnoser(msg):
'::operator testing::Action<Func>\(\) const.*\n' + '::operator testing::Action<Func>\(\) const.*\n' +
_GCC_FILE_LINE_RE + r'instantiated from here\n' _GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*error: no matching function for call to \'ImplicitCast_\(' r'.*error: no matching function for call to \'ImplicitCast_\('
r'long int&\)') r'(:?long )?int&\)')
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for ' clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
r'call to \'ImplicitCast_\'\r?\n' r'call to \'ImplicitCast_\'\r?\n'
r'(.*\n)*?' + r'(.*\n)*?' +
@@ -474,6 +474,10 @@ def _TypeInTemplatedBaseDiagnoser(msg):
r'(?P=file):(?P=line):(?P=column): error: ' r'(?P=file):(?P=line):(?P=column): error: '
r'C\+\+ requires a type specifier for all declarations' r'C\+\+ requires a type specifier for all declarations'
) )
clang_regex_unknown_type = (
_CLANG_FILE_LINE_RE +
r'error: unknown type name \'(?P<type>[^\']+)\''
)
diagnosis = """ diagnosis = """
In a mock class template, types or typedefs defined in the base class In a mock class template, types or typedefs defined in the base class
@@ -483,7 +487,7 @@ need to make it visible. One way to do it is:
typedef typename Base<T>::%(type)s %(type)s;""" typedef typename Base<T>::%(type)s %(type)s;"""
return _GenericDiagnoser( for diag in _GenericDiagnoser(
'TTB', 'Type in Template Base', 'TTB', 'Type in Template Base',
[(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}), [(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
(gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}), (gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
@@ -491,7 +495,13 @@ need to make it visible. One way to do it is:
(gcc_regex_type_of_a_param, diagnosis), (gcc_regex_type_of_a_param, diagnosis),
(clang_regex_type_of_retval_or_sole_param, diagnosis), (clang_regex_type_of_retval_or_sole_param, diagnosis),
(clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})], (clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
msg) msg):
yield diag
# Avoid overlap with the NUS pattern.
for m in _FindAllMatches(clang_regex_unknown_type, msg):
type_ = m.groupdict()['type']
if type_ not in _COMMON_GMOCK_SYMBOLS:
yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict())
def _WrongMockMethodMacroDiagnoser(msg): def _WrongMockMethodMacroDiagnoser(msg):

View File

@@ -1,70 +1,37 @@
# Copyright 2013 Google Inc. All Rights Reserved. # Copyright 2014 Google Inc. All Rights Reserved.
# gMock builds 2 libraries: libgmock and libgmock_main. libgmock # gMock builds 2 libraries: libgmock and libgmock_main. libgmock contains most
# contains most of the code and libgmock_main just # of the code and libgmock_main just provides a common main to run the test.
# provide a common main to run the test. (i.e. If you link against # (i.e. If you link against libgmock_main you shouldn't provide a main() entry
# libgmock_main you shouldn't provide a main() entry point.) # point. If you link against libgmock_main, do not also link against
# libgtest_main, as libgmock_main is a superset of libgtest_main, and they will
# conflict in subtle ways.)
# #
# We build these 2 libraries for the target device and for the host if # We build these 2 libraries for the target device only.
# it is running linux and using ASTL.
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
libgmock_target_includes := \ libgmock_target_includes := \
$(LOCAL_PATH)/.. \ $(LOCAL_PATH)/.. \
$(LOCAL_PATH)/../include \ $(LOCAL_PATH)/../include \
external/gtest/include \ $(TOP)/external/gtest/include \
libgmock_host_includes := \ libgmock_host_includes := \
$(LOCAL_PATH)/.. \ $(LOCAL_PATH)/.. \
$(LOCAL_PATH)/../include \ $(LOCAL_PATH)/../include \
external/gtest/include \ $(TOP)/external/gtest/include \
####################################################################### libgmock_cflags := \
# gmock lib host -DGTEST_HAS_TR1_TUPLE \
-DGTEST_USE_OWN_TR1_TUPLE \
include $(CLEAR_VARS) -Wno-missing-field-initializers \
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := gmock-all.cc
LOCAL_C_INCLUDES := $(libgmock_host_includes)
LOCAL_CFLAGS += -O0
LOCAL_MODULE := libgmock_host
include $(BUILD_HOST_STATIC_LIBRARY)
#######################################################################
# gmock_main lib host
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := gmock_main.cc
LOCAL_C_INCLUDES := $(libgmock_host_includes)
LOCAL_CFLAGS += -O0
LOCAL_MODULE := libgmock_main_host
include $(BUILD_HOST_STATIC_LIBRARY)
####################################################################### #######################################################################
# gmock lib target # gmock lib target
include $(CLEAR_VARS) include $(CLEAR_VARS)
ifeq ($(TARGET_ARCH), arm) LOCAL_SDK_VERSION := 9
LOCAL_SDK_VERSION := 8
else
# NDK support of other archs (ie. x86 and mips) are only available after android-9
LOCAL_SDK_VERSION := 9
endif
LOCAL_NDK_STL_VARIANT := stlport_static LOCAL_NDK_STL_VARIANT := stlport_static
@@ -74,6 +41,8 @@ LOCAL_SRC_FILES := gmock-all.cc
LOCAL_C_INCLUDES := $(libgmock_target_includes) LOCAL_C_INCLUDES := $(libgmock_target_includes)
LOCAL_CFLAGS += $(libgmock_cflags)
LOCAL_MODULE := libgmock LOCAL_MODULE := libgmock
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
@@ -83,12 +52,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
ifeq ($(TARGET_ARCH), arm) LOCAL_SDK_VERSION := 9
LOCAL_SDK_VERSION := 8
else
# NDK support of other archs (ie. x86 and mips) are only available after android-9
LOCAL_SDK_VERSION := 9
endif
LOCAL_NDK_STL_VARIANT := stlport_static LOCAL_NDK_STL_VARIANT := stlport_static
@@ -98,6 +62,8 @@ LOCAL_SRC_FILES := gmock_main.cc
LOCAL_C_INCLUDES := $(libgmock_target_includes) LOCAL_C_INCLUDES := $(libgmock_target_includes)
LOCAL_CFLAGS += $(libgmock_cflags)
LOCAL_MODULE := libgmock_main LOCAL_MODULE := libgmock_main
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)

View File

@@ -75,7 +75,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
virtual int ConservativeUpperBound() const { return max_; } virtual int ConservativeUpperBound() const { return max_; }
virtual bool IsSatisfiedByCallCount(int call_count) const { virtual bool IsSatisfiedByCallCount(int call_count) const {
return min_ <= call_count && call_count <= max_ ; return min_ <= call_count && call_count <= max_;
} }
virtual bool IsSaturatedByCallCount(int call_count) const { virtual bool IsSaturatedByCallCount(int call_count) const {
@@ -83,6 +83,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
} }
virtual void DescribeTo(::std::ostream* os) const; virtual void DescribeTo(::std::ostream* os) const;
private: private:
const int min_; const int min_;
const int max_; const int max_;
@@ -136,20 +137,20 @@ void Cardinality::DescribeActualCallCountTo(int actual_call_count,
} }
// Creates a cardinality that allows at least n calls. // Creates a cardinality that allows at least n calls.
Cardinality AtLeast(int n) { return Between(n, INT_MAX); } GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
// Creates a cardinality that allows at most n calls. // Creates a cardinality that allows at most n calls.
Cardinality AtMost(int n) { return Between(0, n); } GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
// Creates a cardinality that allows any number of calls. // Creates a cardinality that allows any number of calls.
Cardinality AnyNumber() { return AtLeast(0); } GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
// Creates a cardinality that allows between min and max calls. // Creates a cardinality that allows between min and max calls.
Cardinality Between(int min, int max) { GTEST_API_ Cardinality Between(int min, int max) {
return Cardinality(new BetweenCardinalityImpl(min, max)); return Cardinality(new BetweenCardinalityImpl(min, max));
} }
// Creates a cardinality that allows exactly n calls. // Creates a cardinality that allows exactly n calls.
Cardinality Exactly(int n) { return Between(n, n); } GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
} // namespace testing } // namespace testing

View File

@@ -51,7 +51,7 @@ namespace internal {
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and // treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123". // "foo_bar_123" are converted to "foo bar 123".
string ConvertIdentifierNameToWords(const char* id_name) { GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
string result; string result;
char prev_char = '\0'; char prev_char = '\0';
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
@@ -77,13 +77,13 @@ class GoogleTestFailureReporter : public FailureReporterInterface {
public: public:
virtual void ReportFailure(FailureType type, const char* file, int line, virtual void ReportFailure(FailureType type, const char* file, int line,
const string& message) { const string& message) {
AssertHelper(type == FATAL ? AssertHelper(type == kFatal ?
TestPartResult::kFatalFailure : TestPartResult::kFatalFailure :
TestPartResult::kNonFatalFailure, TestPartResult::kNonFatalFailure,
file, file,
line, line,
message.c_str()) = Message(); message.c_str()) = Message();
if (type == FATAL) { if (type == kFatal) {
posix::Abort(); posix::Abort();
} }
} }
@@ -91,7 +91,7 @@ class GoogleTestFailureReporter : public FailureReporterInterface {
// Returns the global failure reporter. Will create a // Returns the global failure reporter. Will create a
// GoogleTestFailureReporter and return it the first time called. // GoogleTestFailureReporter and return it the first time called.
FailureReporterInterface* GetFailureReporter() { GTEST_API_ FailureReporterInterface* GetFailureReporter() {
// Points to the global failure reporter used by Google Mock. gcc // Points to the global failure reporter used by Google Mock. gcc
// guarantees that the following use of failure_reporter is // guarantees that the following use of failure_reporter is
// thread-safe. We may need to add additional synchronization to // thread-safe. We may need to add additional synchronization to
@@ -107,7 +107,7 @@ static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
// Returns true iff a log with the given severity is visible according // Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag. // to the --gmock_verbose flag.
bool LogIsVisible(LogSeverity severity) { GTEST_API_ bool LogIsVisible(LogSeverity severity) {
if (GMOCK_FLAG(verbose) == kInfoVerbosity) { if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
// Always show the log if --gmock_verbose=info. // Always show the log if --gmock_verbose=info.
return true; return true;
@@ -117,7 +117,7 @@ bool LogIsVisible(LogSeverity severity) {
} else { } else {
// If --gmock_verbose is neither "info" nor "error", we treat it // If --gmock_verbose is neither "info" nor "error", we treat it
// as "warning" (its default value). // as "warning" (its default value).
return severity == WARNING; return severity == kWarning;
} }
} }
@@ -128,8 +128,9 @@ bool LogIsVisible(LogSeverity severity) {
// stack_frames_to_skip is treated as 0, since we don't know which // stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be // function calls will be inlined by the compiler and need to be
// conservative. // conservative.
void Log(LogSeverity severity, const string& message, GTEST_API_ void Log(LogSeverity severity,
int stack_frames_to_skip) { const string& message,
int stack_frames_to_skip) {
if (!LogIsVisible(severity)) if (!LogIsVisible(severity))
return; return;
@@ -139,7 +140,7 @@ void Log(LogSeverity severity, const string& message,
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
// macro. // macro.
if (severity == WARNING) { if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable. // Prints a GMOCK WARNING marker to make the warnings easily searchable.
std::cout << "\nGMOCK WARNING:"; std::cout << "\nGMOCK WARNING:";
} }

View File

@@ -63,11 +63,46 @@ Matcher<internal::string>::Matcher(const char* s) {
*this = Eq(internal::string(s)); *this = Eq(internal::string(s));
} }
#if GTEST_HAS_STRING_PIECE_
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
#endif // GTEST_HAS_STRING_PIECE_
namespace internal { namespace internal {
// Joins a vector of strings as if they are fields of a tuple; returns // Joins a vector of strings as if they are fields of a tuple; returns
// the joined string. // the joined string.
string JoinAsTuple(const Strings& fields) { GTEST_API_ string JoinAsTuple(const Strings& fields) {
switch (fields.size()) { switch (fields.size()) {
case 0: case 0:
return ""; return "";
@@ -89,13 +124,375 @@ string JoinAsTuple(const Strings& fields) {
// 'negation' is false; otherwise returns the description of the // 'negation' is false; otherwise returns the description of the
// negation of the matcher. 'param_values' contains a list of strings // negation of the matcher. 'param_values' contains a list of strings
// that are the print-out of the matcher's parameters. // that are the print-out of the matcher's parameters.
string FormatMatcherDescription(bool negation, const char* matcher_name, GTEST_API_ string FormatMatcherDescription(bool negation,
const Strings& param_values) { const char* matcher_name,
const Strings& param_values) {
string result = ConvertIdentifierNameToWords(matcher_name); string result = ConvertIdentifierNameToWords(matcher_name);
if (param_values.size() >= 1) if (param_values.size() >= 1)
result += " " + JoinAsTuple(param_values); result += " " + JoinAsTuple(param_values);
return negation ? "not (" + result + ")" : result; return negation ? "not (" + result + ")" : result;
} }
// FindMaxBipartiteMatching and its helper class.
//
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
// bipartite matching. Flow is considered to be from left to right.
// There is an implicit source node that is connected to all of the left
// nodes, and an implicit sink node that is connected to all of the
// right nodes. All edges have unit capacity.
//
// Neither the flow graph nor the residual flow graph are represented
// explicitly. Instead, they are implied by the information in 'graph' and
// a vector<int> called 'left_' whose elements are initialized to the
// value kUnused. This represents the initial state of the algorithm,
// where the flow graph is empty, and the residual flow graph has the
// following edges:
// - An edge from source to each left_ node
// - An edge from each right_ node to sink
// - An edge from each left_ node to each right_ node, if the
// corresponding edge exists in 'graph'.
//
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
// nodes l and r. This induces the following changes:
// - The edges (source, l), (l, r), and (r, sink) are added to the
// flow graph.
// - The same three edges are removed from the residual flow graph.
// - The reverse edges (l, source), (r, l), and (sink, r) are added
// to the residual flow graph, which is a directional graph
// representing unused flow capacity.
//
// When the method augments a flow (moving left_[l] from some r1 to some
// other r2), this can be thought of as "undoing" the above steps with
// respect to r1 and "redoing" them with respect to r2.
//
// It bears repeating that the flow graph and residual flow graph are
// never represented explicitly, but can be derived by looking at the
// information in 'graph' and in left_.
//
// As an optimization, there is a second vector<int> called right_ which
// does not provide any new information. Instead, it enables more
// efficient queries about edges entering or leaving the right-side nodes
// of the flow or residual flow graphs. The following invariants are
// maintained:
//
// left[l] == kUnused or right[left[l]] == l
// right[r] == kUnused or left[right[r]] == r
//
// . [ source ] .
// . ||| .
// . ||| .
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
// . || | | .
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
// . | || .
// . \----> left[2]=2 ------> right[2]=2 --\|| .
// . ||| .
// . elements matchers vvv .
// . [ sink ] .
//
// See Also:
// [1] Cormen, et al (2001). "Section 26.2: The FordFulkerson method".
// "Introduction to Algorithms (Second ed.)", pp. 651664.
// [2] "FordFulkerson algorithm", Wikipedia,
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
class MaxBipartiteMatchState {
public:
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
: graph_(&graph),
left_(graph_->LhsSize(), kUnused),
right_(graph_->RhsSize(), kUnused) {
}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs Compute() {
// 'seen' is used for path finding { 0: unseen, 1: seen }.
::std::vector<char> seen;
// Searches the residual flow graph for a path from each left node to
// the sink in the residual flow graph, and if one is found, add flow
// to the graph. It's okay to search through the left nodes once. The
// edge from the implicit source node to each previously-visited left
// node will have flow if that left node has any path to the sink
// whatsoever. Subsequent augmentations can only add flow to the
// network, and cannot take away that previous flow unit from the source.
// Since the source-to-left edge can only carry one flow unit (or,
// each element can be matched to only one matcher), there is no need
// to visit the left nodes more than once looking for augmented paths.
// The flow is known to be possible or impossible by looking at the
// node once.
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
// Reset the path-marking vector and try to find a path from
// source to sink starting at the left_[ilhs] node.
GTEST_CHECK_(left_[ilhs] == kUnused)
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
seen.assign(graph_->RhsSize(), 0);
TryAugment(ilhs, &seen);
}
ElementMatcherPairs result;
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
size_t irhs = left_[ilhs];
if (irhs == kUnused) continue;
result.push_back(ElementMatcherPair(ilhs, irhs));
}
return result;
}
private:
static const size_t kUnused = static_cast<size_t>(-1);
// Perform a depth-first search from left node ilhs to the sink. If a
// path is found, flow is added to the network by linking the left and
// right vector elements corresponding each segment of the path.
// Returns true if a path to sink was found, which means that a unit of
// flow was added to the network. The 'seen' vector elements correspond
// to right nodes and are marked to eliminate cycles from the search.
//
// Left nodes will only be explored at most once because they
// are accessible from at most one right node in the residual flow
// graph.
//
// Note that left_[ilhs] is the only element of left_ that TryAugment will
// potentially transition from kUnused to another value. Any other
// left_ element holding kUnused before TryAugment will be holding it
// when TryAugment returns.
//
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
if ((*seen)[irhs])
continue;
if (!graph_->HasEdge(ilhs, irhs))
continue;
// There's an available edge from ilhs to irhs.
(*seen)[irhs] = 1;
// Next a search is performed to determine whether
// this edge is a dead end or leads to the sink.
//
// right_[irhs] == kUnused means that there is residual flow from
// right node irhs to the sink, so we can use that to finish this
// flow path and return success.
//
// Otherwise there is residual flow to some ilhs. We push flow
// along that path and call ourselves recursively to see if this
// ultimately leads to sink.
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
// Add flow from left_[ilhs] to right_[irhs].
left_[ilhs] = irhs;
right_[irhs] = ilhs;
return true;
}
}
return false;
}
const MatchMatrix* graph_; // not owned
// Each element of the left_ vector represents a left hand side node
// (i.e. an element) and each element of right_ is a right hand side
// node (i.e. a matcher). The values in the left_ vector indicate
// outflow from that node to a node on the the right_ side. The values
// in the right_ indicate inflow, and specify which left_ node is
// feeding that right_ node, if any. For example, left_[3] == 1 means
// there's a flow from element #3 to matcher #1. Such a flow would also
// be redundantly represented in the right_ vector as right_[1] == 3.
// Elements of left_ and right_ are either kUnused or mutually
// referent. Mutually referent means that left_[right_[i]] = i and
// right_[left_[i]] = i.
::std::vector<size_t> left_;
::std::vector<size_t> right_;
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
};
const size_t MaxBipartiteMatchState::kUnused;
GTEST_API_ ElementMatcherPairs
FindMaxBipartiteMatching(const MatchMatrix& g) {
return MaxBipartiteMatchState(g).Compute();
}
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
::std::ostream* stream) {
typedef ElementMatcherPairs::const_iterator Iter;
::std::ostream& os = *stream;
os << "{";
const char *sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n ("
<< "element #" << it->first << ", "
<< "matcher #" << it->second << ")";
sep = ",";
}
os << "\n}";
}
// Tries to find a pairing, and explains the result.
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
MatchResultListener* listener) {
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
size_t max_flow = matches.size();
bool result = (max_flow == matrix.RhsSize());
if (!result) {
if (listener->IsInterested()) {
*listener << "where no permutation of the elements can "
"satisfy all matchers, and the closest match is "
<< max_flow << " of " << matrix.RhsSize()
<< " matchers with the pairings:\n";
LogElementMatcherPairVec(matches, listener->stream());
}
return false;
}
if (matches.size() > 1) {
if (listener->IsInterested()) {
const char *sep = "where:\n";
for (size_t mi = 0; mi < matches.size(); ++mi) {
*listener << sep << " - element #" << matches[mi].first
<< " is matched by matcher #" << matches[mi].second;
sep = ",\n";
}
}
}
return true;
}
bool MatchMatrix::NextGraph() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
char& b = matched_[SpaceIndex(ilhs, irhs)];
if (!b) {
b = 1;
return true;
}
b = 0;
}
}
return false;
}
void MatchMatrix::Randomize() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
char& b = matched_[SpaceIndex(ilhs, irhs)];
b = static_cast<char>(rand() & 1); // NOLINT
}
}
}
string MatchMatrix::DebugString() const {
::std::stringstream ss;
const char *sep = "";
for (size_t i = 0; i < LhsSize(); ++i) {
ss << sep;
for (size_t j = 0; j < RhsSize(); ++j) {
ss << HasEdge(i, j);
}
sep = ";";
}
return ss.str();
}
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
::std::ostream* os) const {
if (matcher_describers_.empty()) {
*os << "is empty";
return;
}
if (matcher_describers_.size() == 1) {
*os << "has " << Elements(1) << " and that element ";
matcher_describers_[0]->DescribeTo(os);
return;
}
*os << "has " << Elements(matcher_describers_.size())
<< " and there exists some permutation of elements such that:\n";
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
*os << sep << " - element #" << i << " ";
matcher_describers_[i]->DescribeTo(os);
sep = ", and\n";
}
}
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
::std::ostream* os) const {
if (matcher_describers_.empty()) {
*os << "isn't empty";
return;
}
if (matcher_describers_.size() == 1) {
*os << "doesn't have " << Elements(1)
<< ", or has " << Elements(1) << " that ";
matcher_describers_[0]->DescribeNegationTo(os);
return;
}
*os << "doesn't have " << Elements(matcher_describers_.size())
<< ", or there exists no permutation of elements such that:\n";
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
*os << sep << " - element #" << i << " ";
matcher_describers_[i]->DescribeTo(os);
sep = ", and\n";
}
}
// Checks that all matchers match at least one element, and that all
// elements match at least one matcher. This enables faster matching
// and better error reporting.
// Returns false, writing an explanation to 'listener', if and only
// if the success criteria are not met.
bool UnorderedElementsAreMatcherImplBase::
VerifyAllElementsAndMatchersAreMatched(
const ::std::vector<string>& element_printouts,
const MatchMatrix& matrix,
MatchResultListener* listener) const {
bool result = true;
::std::vector<char> element_matched(matrix.LhsSize(), 0);
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
char matched = matrix.HasEdge(ilhs, irhs);
element_matched[ilhs] |= matched;
matcher_matched[irhs] |= matched;
}
}
{
const char* sep =
"where the following matchers don't match any elements:\n";
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
if (matcher_matched[mi])
continue;
result = false;
if (listener->IsInterested()) {
*listener << sep << "matcher #" << mi << ": ";
matcher_describers_[mi]->DescribeTo(listener->stream());
sep = ",\n";
}
}
}
{
const char* sep =
"where the following elements don't match any matchers:\n";
const char* outer_sep = "";
if (!result) {
outer_sep = "\nand ";
}
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
if (element_matched[ei])
continue;
result = false;
if (listener->IsInterested()) {
*listener << outer_sep << sep << "element #" << ei << ": "
<< element_printouts[ei];
sep = ",\n";
outer_sep = "";
}
}
}
return result;
}
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

View File

@@ -53,12 +53,12 @@ namespace internal {
// Protects the mock object registry (in class Mock), all function // Protects the mock object registry (in class Mock), all function
// mockers, and all expectations. // mockers, and all expectations.
GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
// Logs a message including file and line number information. // Logs a message including file and line number information.
void LogWithLocation(testing::internal::LogSeverity severity, GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line, const char* file, int line,
const string& message) { const string& message) {
::std::ostringstream s; ::std::ostringstream s;
s << file << ":" << line << ": " << message << ::std::endl; s << file << ":" << line << ": " << message << ::std::endl;
Log(severity, s.str(), 0); Log(severity, s.str(), 0);
@@ -92,7 +92,8 @@ void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
} }
// Retires all pre-requisites of this expectation. // Retires all pre-requisites of this expectation.
void ExpectationBase::RetireAllPreRequisites() { void ExpectationBase::RetireAllPreRequisites()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
if (is_retired()) { if (is_retired()) {
// We can take this short-cut as we never retire an expectation // We can take this short-cut as we never retire an expectation
// until we have retired all its pre-requisites. // until we have retired all its pre-requisites.
@@ -111,8 +112,8 @@ void ExpectationBase::RetireAllPreRequisites() {
// Returns true iff all pre-requisites of this expectation have been // Returns true iff all pre-requisites of this expectation have been
// satisfied. // satisfied.
// L >= g_gmock_mutex bool ExpectationBase::AllPrerequisitesAreSatisfied() const
bool ExpectationBase::AllPrerequisitesAreSatisfied() const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
it != immediate_prerequisites_.end(); ++it) { it != immediate_prerequisites_.end(); ++it) {
@@ -124,9 +125,8 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
} }
// Adds unsatisfied pre-requisites of this expectation to 'result'. // Adds unsatisfied pre-requisites of this expectation to 'result'.
// L >= g_gmock_mutex void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
void ExpectationBase::FindUnsatisfiedPrerequisites( GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
ExpectationSet* result) const {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
it != immediate_prerequisites_.end(); ++it) { it != immediate_prerequisites_.end(); ++it) {
@@ -147,8 +147,8 @@ void ExpectationBase::FindUnsatisfiedPrerequisites(
// Describes how many times a function call matching this // Describes how many times a function call matching this
// expectation has occurred. // expectation has occurred.
// L >= g_gmock_mutex void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
// Describes how many times the function is expected to be called. // Describes how many times the function is expected to be called.
@@ -170,8 +170,8 @@ void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const {
// WillRepeatedly() clauses) against the cardinality if this hasn't // WillRepeatedly() clauses) against the cardinality if this hasn't
// been done before. Prints a warning if there are too many or too // been done before. Prints a warning if there are too many or too
// few actions. // few actions.
// L < mutex_ void ExpectationBase::CheckActionCountIfNotDone() const
void ExpectationBase::CheckActionCountIfNotDone() const { GTEST_LOCK_EXCLUDED_(mutex_) {
bool should_check = false; bool should_check = false;
{ {
MutexLock l(&mutex_); MutexLock l(&mutex_);
@@ -217,7 +217,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const {
ss << " and a WillRepeatedly()"; ss << " and a WillRepeatedly()";
} }
ss << "."; ss << ".";
Log(WARNING, ss.str(), -1); // -1 means "don't print stack trace". Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
} }
} }
@@ -240,17 +240,17 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
// Points to the implicit sequence introduced by a living InSequence // Points to the implicit sequence introduced by a living InSequence
// object (if any) in the current thread or NULL. // object (if any) in the current thread or NULL.
ThreadLocal<Sequence*> g_gmock_implicit_sequence; GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
// Reports an uninteresting call (whose description is in msg) in the // Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'. // manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const string& msg) { void ReportUninterestingCall(CallReaction reaction, const string& msg) {
switch (reaction) { switch (reaction) {
case ALLOW: case kAllow:
Log(INFO, msg, 3); Log(kInfo, msg, 3);
break; break;
case WARN: case kWarn:
Log(WARNING, msg, 3); Log(kWarning, msg, 3);
break; break;
default: // FAIL default: // FAIL
Expect(false, NULL, -1, msg); Expect(false, NULL, -1, msg);
@@ -266,8 +266,8 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
// this information in the global mock registry. Will be called // this information in the global mock registry. Will be called
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method. // method.
// L < g_gmock_mutex void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
{ {
MutexLock l(&g_gmock_mutex); MutexLock l(&g_gmock_mutex);
mock_obj_ = mock_obj; mock_obj_ = mock_obj;
@@ -278,9 +278,9 @@ void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) {
// Sets the mock object this mock method belongs to, and sets the name // Sets the mock object this mock method belongs to, and sets the name
// of the mock function. Will be called upon each invocation of this // of the mock function. Will be called upon each invocation of this
// mock function. // mock function.
// L < g_gmock_mutex void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
void UntypedFunctionMockerBase::SetOwnerAndName( const char* name)
const void* mock_obj, const char* name) { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// We protect name_ under g_gmock_mutex in case this mock function // We protect name_ under g_gmock_mutex in case this mock function
// is called from two threads concurrently. // is called from two threads concurrently.
MutexLock l(&g_gmock_mutex); MutexLock l(&g_gmock_mutex);
@@ -290,8 +290,8 @@ void UntypedFunctionMockerBase::SetOwnerAndName(
// Returns the name of the function being mocked. Must be called // Returns the name of the function being mocked. Must be called
// after RegisterOwner() or SetOwnerAndName() has been called. // after RegisterOwner() or SetOwnerAndName() has been called.
// L < g_gmock_mutex const void* UntypedFunctionMockerBase::MockObject() const
const void* UntypedFunctionMockerBase::MockObject() const { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const void* mock_obj; const void* mock_obj;
{ {
// We protect mock_obj_ under g_gmock_mutex in case this mock // We protect mock_obj_ under g_gmock_mutex in case this mock
@@ -307,8 +307,8 @@ const void* UntypedFunctionMockerBase::MockObject() const {
// Returns the name of this mock method. Must be called after // Returns the name of this mock method. Must be called after
// SetOwnerAndName() has been called. // SetOwnerAndName() has been called.
// L < g_gmock_mutex const char* UntypedFunctionMockerBase::Name() const
const char* UntypedFunctionMockerBase::Name() const { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const char* name; const char* name;
{ {
// We protect name_ under g_gmock_mutex in case this mock // We protect name_ under g_gmock_mutex in case this mock
@@ -325,9 +325,9 @@ const char* UntypedFunctionMockerBase::Name() const {
// Calculates the result of invoking this mock function with the given // Calculates the result of invoking this mock function with the given
// arguments, prints it, and returns it. The caller is responsible // arguments, prints it, and returns it. The caller is responsible
// for deleting the result. // for deleting the result.
// L < g_gmock_mutex
const UntypedActionResultHolderBase* const UntypedActionResultHolderBase*
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) { UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
if (untyped_expectations_.size() == 0) { if (untyped_expectations_.size() == 0) {
// No expectation is set on this mock method - we have an // No expectation is set on this mock method - we have an
// uninteresting call. // uninteresting call.
@@ -345,10 +345,10 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
const bool need_to_report_uninteresting_call = const bool need_to_report_uninteresting_call =
// If the user allows this uninteresting call, we print it // If the user allows this uninteresting call, we print it
// only when he wants informational messages. // only when he wants informational messages.
reaction == ALLOW ? LogIsVisible(INFO) : reaction == kAllow ? LogIsVisible(kInfo) :
// If the user wants this to be a warning, we print it only // If the user wants this to be a warning, we print it only
// when he wants to see warnings. // when he wants to see warnings.
reaction == WARN ? LogIsVisible(WARNING) : reaction == kWarn ? LogIsVisible(kWarning) :
// Otherwise, the user wants this to be an error, and we // Otherwise, the user wants this to be an error, and we
// should always print detailed information in the error. // should always print detailed information in the error.
true; true;
@@ -391,7 +391,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
// True iff we need to print the call's arguments and return value. // True iff we need to print the call's arguments and return value.
// This definition must be kept in sync with the uses of Expect() // This definition must be kept in sync with the uses of Expect()
// and Log() in this function. // and Log() in this function.
const bool need_to_report_call = !found || is_excessive || LogIsVisible(INFO); const bool need_to_report_call =
!found || is_excessive || LogIsVisible(kInfo);
if (!need_to_report_call) { if (!need_to_report_call) {
// Perform the action without printing the call information. // Perform the action without printing the call information.
return return
@@ -427,7 +428,7 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
} else { } else {
// We had an expected call and the matching expectation is // We had an expected call and the matching expectation is
// described in ss. // described in ss.
Log(INFO, loc.str() + ss.str(), 2); Log(kInfo, loc.str() + ss.str(), 2);
} }
return result; return result;
@@ -453,8 +454,8 @@ Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
// Verifies that all expectations on this mock function have been // Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures // satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not. // and returns false if not.
// L >= g_gmock_mutex bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
bool expectations_met = true; bool expectations_met = true;
for (UntypedExpectations::const_iterator it = for (UntypedExpectations::const_iterator it =
@@ -480,7 +481,21 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() {
untyped_expectation->line(), ss.str()); untyped_expectation->line(), ss.str());
} }
} }
untyped_expectations_.clear();
// Deleting our expectations may trigger other mock objects to be deleted, for
// example if an action contains a reference counted smart pointer to that
// mock object, and that is the last reference. So if we delete our
// expectations within the context of the global mutex we may deadlock when
// this method is called again. Instead, make a copy of the set of
// expectations to delete, clear our set within the mutex, and then clear the
// copied set outside of it.
UntypedExpectations expectations_to_delete;
untyped_expectations_.swap(expectations_to_delete);
g_gmock_mutex.Unlock();
expectations_to_delete.clear();
g_gmock_mutex.Lock();
return expectations_met; return expectations_met;
} }
@@ -565,6 +580,7 @@ class MockObjectRegistry {
} }
StateMap& states() { return states_; } StateMap& states() { return states_; }
private: private:
StateMap states_; StateMap states_;
}; };
@@ -578,9 +594,9 @@ std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
// Sets the reaction Google Mock should have when an uninteresting // Sets the reaction Google Mock should have when an uninteresting
// method of the given mock object is called. // method of the given mock object is called.
// L < g_gmock_mutex
void SetReactionOnUninterestingCalls(const void* mock_obj, void SetReactionOnUninterestingCalls(const void* mock_obj,
internal::CallReaction reaction) { internal::CallReaction reaction)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
g_uninteresting_call_reaction[mock_obj] = reaction; g_uninteresting_call_reaction[mock_obj] = reaction;
} }
@@ -589,47 +605,47 @@ void SetReactionOnUninterestingCalls(const void* mock_obj,
// Tells Google Mock to allow uninteresting calls on the given mock // Tells Google Mock to allow uninteresting calls on the given mock
// object. // object.
// L < g_gmock_mutex void Mock::AllowUninterestingCalls(const void* mock_obj)
void Mock::AllowUninterestingCalls(const void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW); SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
} }
// Tells Google Mock to warn the user about uninteresting calls on the // Tells Google Mock to warn the user about uninteresting calls on the
// given mock object. // given mock object.
// L < g_gmock_mutex void Mock::WarnUninterestingCalls(const void* mock_obj)
void Mock::WarnUninterestingCalls(const void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::WARN); SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
} }
// Tells Google Mock to fail uninteresting calls on the given mock // Tells Google Mock to fail uninteresting calls on the given mock
// object. // object.
// L < g_gmock_mutex void Mock::FailUninterestingCalls(const void* mock_obj)
void Mock::FailUninterestingCalls(const void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::FAIL); SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
} }
// Tells Google Mock the given mock object is being destroyed and its // Tells Google Mock the given mock object is being destroyed and its
// entry in the call-reaction table should be removed. // entry in the call-reaction table should be removed.
// L < g_gmock_mutex void Mock::UnregisterCallReaction(const void* mock_obj)
void Mock::UnregisterCallReaction(const void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
g_uninteresting_call_reaction.erase(mock_obj); g_uninteresting_call_reaction.erase(mock_obj);
} }
// Returns the reaction Google Mock will have on uninteresting calls // Returns the reaction Google Mock will have on uninteresting calls
// made on the given mock object. // made on the given mock object.
// L < g_gmock_mutex
internal::CallReaction Mock::GetReactionOnUninterestingCalls( internal::CallReaction Mock::GetReactionOnUninterestingCalls(
const void* mock_obj) { const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
internal::WARN : g_uninteresting_call_reaction[mock_obj]; internal::kDefault : g_uninteresting_call_reaction[mock_obj];
} }
// Tells Google Mock to ignore mock_obj when checking for leaked mock // Tells Google Mock to ignore mock_obj when checking for leaked mock
// objects. // objects.
// L < g_gmock_mutex void Mock::AllowLeak(const void* mock_obj)
void Mock::AllowLeak(const void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].leakable = true; g_mock_object_registry.states()[mock_obj].leakable = true;
} }
@@ -637,8 +653,8 @@ void Mock::AllowLeak(const void* mock_obj) {
// Verifies and clears all expectations on the given mock object. If // Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google // the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false. // Test non-fatal failures and returns false.
// L < g_gmock_mutex bool Mock::VerifyAndClearExpectations(void* mock_obj)
bool Mock::VerifyAndClearExpectations(void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
return VerifyAndClearExpectationsLocked(mock_obj); return VerifyAndClearExpectationsLocked(mock_obj);
} }
@@ -646,8 +662,8 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj) {
// Verifies all expectations on the given mock object and clears its // Verifies all expectations on the given mock object and clears its
// default actions and expectations. Returns true iff the // default actions and expectations. Returns true iff the
// verification was successful. // verification was successful.
// L < g_gmock_mutex bool Mock::VerifyAndClear(void* mock_obj)
bool Mock::VerifyAndClear(void* mock_obj) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
ClearDefaultActionsLocked(mock_obj); ClearDefaultActionsLocked(mock_obj);
return VerifyAndClearExpectationsLocked(mock_obj); return VerifyAndClearExpectationsLocked(mock_obj);
@@ -656,8 +672,8 @@ bool Mock::VerifyAndClear(void* mock_obj) {
// Verifies and clears all expectations on the given mock object. If // Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google // the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false. // Test non-fatal failures and returns false.
// L >= g_gmock_mutex bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld(); internal::g_gmock_mutex.AssertHeld();
if (g_mock_object_registry.states().count(mock_obj) == 0) { if (g_mock_object_registry.states().count(mock_obj) == 0) {
// No EXPECT_CALL() was set on the given mock object. // No EXPECT_CALL() was set on the given mock object.
@@ -682,9 +698,9 @@ bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
} }
// Registers a mock object and a mock method it owns. // Registers a mock object and a mock method it owns.
// L < g_gmock_mutex
void Mock::Register(const void* mock_obj, void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker) { internal::UntypedFunctionMockerBase* mocker)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
} }
@@ -692,9 +708,9 @@ void Mock::Register(const void* mock_obj,
// Tells Google Mock where in the source code mock_obj is used in an // Tells Google Mock where in the source code mock_obj is used in an
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this // ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
// information helps the user identify which object it is. // information helps the user identify which object it is.
// L < g_gmock_mutex void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
void Mock::RegisterUseByOnCallOrExpectCall( const char* file, int line)
const void* mock_obj, const char* file, int line) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
MockObjectState& state = g_mock_object_registry.states()[mock_obj]; MockObjectState& state = g_mock_object_registry.states()[mock_obj];
if (state.first_used_file == NULL) { if (state.first_used_file == NULL) {
@@ -716,8 +732,8 @@ void Mock::RegisterUseByOnCallOrExpectCall(
// registry when the last mock method associated with it has been // registry when the last mock method associated with it has been
// unregistered. This is called only in the destructor of // unregistered. This is called only in the destructor of
// FunctionMockerBase. // FunctionMockerBase.
// L >= g_gmock_mutex void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld(); internal::g_gmock_mutex.AssertHeld();
for (MockObjectRegistry::StateMap::iterator it = for (MockObjectRegistry::StateMap::iterator it =
g_mock_object_registry.states().begin(); g_mock_object_registry.states().begin();
@@ -734,8 +750,8 @@ void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
} }
// Clears all ON_CALL()s set on the given mock object. // Clears all ON_CALL()s set on the given mock object.
// L >= g_gmock_mutex void Mock::ClearDefaultActionsLocked(void* mock_obj)
void Mock::ClearDefaultActionsLocked(void* mock_obj) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
internal::g_gmock_mutex.AssertHeld(); internal::g_gmock_mutex.AssertHeld();
if (g_mock_object_registry.states().count(mock_obj) == 0) { if (g_mock_object_registry.states().count(mock_obj) == 0) {

View File

@@ -62,7 +62,7 @@ static const char* ParseGoogleMockFlagValue(const char* str,
if (str == NULL || flag == NULL) return NULL; if (str == NULL || flag == NULL) return NULL;
// The flag must start with "--gmock_". // The flag must start with "--gmock_".
const String flag_str = String::Format("--gmock_%s", flag); const std::string flag_str = std::string("--gmock_") + flag;
const size_t flag_len = flag_str.length(); const size_t flag_len = flag_str.length();
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
@@ -107,7 +107,7 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
// On success, stores the value of the flag in *value, and returns // On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value. // true. On failure, returns false without changing *value.
static bool ParseGoogleMockStringFlag(const char* str, const char* flag, static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
String* value) { std::string* value) {
// Gets the value of the flag as a string. // Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
@@ -131,7 +131,7 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
if (*argc <= 0) return; if (*argc <= 0) return;
for (int i = 1; i != *argc; i++) { for (int i = 1; i != *argc; i++) {
const String arg_string = StreamableToString(argv[i]); const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str(); const char* const arg = arg_string.c_str();
// Do we see a Google Mock flag? // Do we see a Google Mock flag?
@@ -169,13 +169,13 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
// Since Google Test is needed for Google Mock to work, this function // Since Google Test is needed for Google Mock to work, this function
// also initializes Google Test and parses its flags, if that hasn't // also initializes Google Test and parses its flags, if that hasn't
// been done. // been done.
void InitGoogleMock(int* argc, char** argv) { GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
internal::InitGoogleMockImpl(argc, argv); internal::InitGoogleMockImpl(argc, argv);
} }
// This overloaded version can be used in Windows programs compiled in // This overloaded version can be used in Windows programs compiled in
// UNICODE mode. // UNICODE mode.
void InitGoogleMock(int* argc, wchar_t** argv) { GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
internal::InitGoogleMockImpl(argc, argv); internal::InitGoogleMockImpl(argc, argv);
} }

View File

@@ -41,9 +41,9 @@
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
# include <tchar.h> // NOLINT # include <tchar.h> // NOLINT
int _tmain(int argc, TCHAR** argv) { GTEST_API_ int _tmain(int argc, TCHAR** argv) {
#else #else
int main(int argc, char** argv) { GTEST_API_ int main(int argc, char** argv) {
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
std::cout << "Running main() from gmock_main.cc\n"; std::cout << "Running main() from gmock_main.cc\n";
// Since Google Mock depends on Google Test, InitGoogleMock() is // Since Google Mock depends on Google Test, InitGoogleMock() is