Upgrade gtest to r267 and gmock to r173.

This is step1 into removing the boost + tr1 dependency in windows.  It also includes a hack to avoid brining in tr1/functional on gcc, which will move us closer to enabling -fno-rtti.

This CL has passed the try servers.  I've also tried compiling gmock, gmock_main, base, base_unittests, and webcore modules in vs2008 express editions.

Review URL: http://codereview.chromium.org/140003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18923 0039d316-1c4b-4281-b951-d872f2087c98
Esse commit está contido em:
ajwong@chromium.org
2009-06-22 18:32:21 +00:00
commit 85c4afb00a
36 arquivos alterados com 2452 adições e 1051 exclusões
+1 -1
Ver Arquivo
@@ -16,7 +16,7 @@ deps = {
"http://open-vcdiff.googlecode.com/svn/trunk@26",
"src/testing/gtest":
"http://googletest.googlecode.com/svn/trunk@243",
"http://googletest.googlecode.com/svn/trunk@267",
"src/third_party/WebKit":
"/trunk/deps/third_party/WebKit@15773",
+13 -32
Ver Arquivo
@@ -1,7 +1,7 @@
We include a snapshot of gmock from http://googlemock.googlecode.com/svn/trunk
with chromium.patch applied.
Current revision: 157
Current revision: 173
-- HOW TO USE --
@@ -21,38 +21,19 @@ In particular, the "For Dummies" guide is a good place to start. The
-- RECREATING PACKAGE --
Gmock requires tr1 tuple. However, Visual Studio 2005 does not include
tr1 tuple, so a version of boost tuple was added into the third_party
tree for chromium. Our version of gmock has been patched to search for
this version of tuple inside our source tree.
Starting with r173, gmock began distributing a pared down version of tr1 tuple
that can be used on compilers without TR1. This means that we will no longer
need TR1 or boost on windows.
chromium.patch modifies gmock/include/gmock/internal/gmock-port.h so that
for _MSC_VER < 1500 (anything newer than Visual Studio 2008), boost tuple
is loaded from boost/tr1/tr1/tuple.
Recreating this package is now just exporting the wanted revision.
Example:
To recreate this install, do the following:
svn export --ignore-externals \
http://googlemock.googlecode.com/svn/trunk/ gmock
*1) Checkout a copy from svn trunk using --ignore-externals to avoid
getting an extra copy of gtest. Use the following command:
svn export --ignore-externals \
http://googlemock.googlecode.com/svn/trunk/ gmock
2) Patch it with chromium.patch.
When checking out a copy from svn, --ignore-externals should be used to avoid
getting an extra copy of gtest.
* Pass -r [revision number] to svn export if you want a specific revision.
The current revision of the source is listed at the top of the README.
-- ALTERNATIVES TO PATCHING --
The patching of gmock to use boost in VS2005 was settled upon as the lowest
impact solution for getting gmock working in VS2005. Patching gmock trades
making some assumptions regarding the internal implementations of gmock
and boost for a simple, easy to underatnd, implementation that provides
relatively good insulation for the rest of the build from the boost dependency.
Alternate soltuions are:
1) Drop support for VS2005 -- too heavy-handed.
2) Add a "tuple" file parallel to gmock-port.h -- still makes assumptions
about boost's structure.
3) Add boost/tr1/tr1 into the include path -- dirties the include path for
all dependencies.
This command will grab the head of trunk. Optionally, -r [revision number] to
can be passed to svn export if you want a specific revision. The current
revision of the source is listed at the top of the README.
-20
Ver Arquivo
@@ -1,20 +0,0 @@
diff -ru gmock.orig/include/gmock/internal/gmock-port.h gmock/include/gmock/internal/gmock-port.h
--- gmock.orig/include/gmock/internal/gmock-port.h 2009-05-22 23:58:41.000000000 -0700
+++ gmock/include/gmock/internal/gmock-port.h 2009-05-23 00:49:01.000000000 -0700
@@ -54,9 +54,14 @@
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
// not conform to the TR1 spec, which requires the header to be <tuple>.
#include <tr1/tuple>
+#elif defined(_MSC_VER) && _MSC_VER < 1500
+// For Visual Studio older than 2008, we redirect directly to boost tuple
+// searching from boost's root. This is to avoid extra dirtying of the
+// compiler include paths.
+#include "boost/tr1/tr1/tuple"
#else
-// If the compiler is not GCC 4.0+, we assume the user is using a
-// spec-conforming TR1 implementation.
+// If the compiler is neither GCC 4.0+, nor Visual Studio 2008, we assume the
+// user is using a spec-conforming TR1 implementation.
#include <tuple>
#endif // __GNUC__
+1
Ver Arquivo
@@ -15,6 +15,7 @@
'gtest.gyp:gtest',
],
'sources': [
# Sources based on files in r173 of gmock.
'gmock/include/gmock/gmock-actions.h',
'gmock/include/gmock/gmock-cardinalities.h',
'gmock/include/gmock/gmock-generated-actions.h',
+22
Ver Arquivo
@@ -135,6 +135,28 @@ check_PROGRAMS += test/gmock_test
test_gmock_test_SOURCES = test/gmock_test.cc
test_gmock_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
# A sanity test for verifying that Google Mock works when RTTI is
# disabled. We pick gmock-spec-builders_test.cc as it exercises all
# components of Google Mock.
TESTS += test/gmock_no_rtti_test
check_PROGRAMS += test/gmock_no_rtti_test
test_gmock_no_rtti_test_SOURCES = test/gmock-spec-builders_test.cc \
src/gmock-all.cc
test_gmock_no_rtti_test_CXXFLAGS = $(AM_CXXFLAGS) -fno-rtti -DGTEST_HAS_RTTI=0
test_gmock_no_rtti_test_LDADD = $(GTEST_LIBS)
# A sanity test for verifying that Google Mock works with Google
# Test's TR1 tuple implementation. We pick
# gmock-spec-builders_test.cc as it exercises all components of Google
# Mock.
TESTS += test/gmock_use_own_tuple_test
check_PROGRAMS += test/gmock_use_own_tuple_test
test_gmock_use_own_tuple_test_SOURCES = test/gmock-spec-builders_test.cc \
src/gmock-all.cc
test_gmock_use_own_tuple_test_CXXFLAGS = \
$(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
test_gmock_use_own_tuple_test_LDADD = $(GTEST_LIBS)
# The following tests depend on the presence of a Python installation and are
# keyed off of it. We only add them to the TESTS variable when a Python
# interpreter is available. TODO(chandlerc@google.com): While we currently only
+32 -49
Ver Arquivo
@@ -40,7 +40,7 @@ testing framework for writing tests. It works with Google Test
(http://code.google.com/p/googletest/) out of the box. You can use
either the copy of Google Test that comes with Google Mock, or a
compatible version you already have. This version of Google Mock
requires Google Test 1.3.0.
requires Google Test 1.4.0.
You can also easily configure Google Mock to work with another testing
framework of your choice; although it will still need Google Test as
@@ -57,8 +57,7 @@ package (as described below):
* GNU-compatible Make or "gmake"
* POSIX-standard shell
* POSIX(-2) Regular Expressions (regex.h)
* gcc 4.0 or newer, or gcc 3.4 or newer with the tr1 tuple library
(from Boost or other vendors).
* gcc 3.4 or newer.
Furthermore, if you are building Google Mock from a VCS Checkout (also
described below), there are further requirements:
@@ -69,12 +68,6 @@ described below), there are further requirements:
### Windows Requirements ###
* Microsoft Visual C++ 8.0 SP1 or newer
* An implementation of the tr1 tuple C++ library (You can get it for
free from http://www.boost.org/. We have verified that version
1.36.0 works. One caveat is this implementation exposes a bug in
Visual C++'s <type_info> header when exceptions are disabled.
Therefore your project must enable exceptions for this
configuration to work.)
### Mac OS X Requirements ###
* Mac OS X 10.4 Tiger or newer
@@ -141,6 +134,32 @@ which contains all of the source code. Here are some examples in Linux:
tar -xvjf gmock-X.Y.Z.tar.bz2
unzip gmock-X.Y.Z.zip
Choosing a TR1 Tuple Library
----------------------------
Google Mock uses the C++ Technical Report 1 (TR1) tuple library
heavily. Unfortunately TR1 tuple is not yet widely available with all
compilers. The good news is that Google Test 1.4.0+ implements a
subset of TR1 tuple that's enough for Google Mock's need. Google Mock
will automatically use that implementation when the compiler doesn't
provide TR1 tuple.
Usually you don't need to care about which tuple library Google Test
and Google Mock use. However, if your project already uses TR1 tuple,
you need to tell Google Test and Google Mock to use the same TR1 tuple
library the rest of your project uses (this requirement is new in
Google Test 1.4.0 and Google Mock 1.2.0, so you may need to take care
of it when upgrading from an earlier version), or the two tuple
implementations will clash. To do that, add
-DGTEST_USE_OWN_TR1_TUPLE=0
to the compiler flags while compiling Google Test, Google Mock, and
your tests.
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
it and set it up.
Building the Source
-------------------
### Linux and Mac OS X (without Xcode) ###
@@ -236,46 +255,15 @@ separately.
### Windows ###
The msvc/ directory contains VC++ 2005 projects for building Google
Mock and selected tests. In order to build Google Mock you must have
an implementation of TR1 tuple. One library that provides such
implementation is Boost. If you choose to use Boost, download it from
www.boost.org and install it on your system. Note that Boost TR1 tuple
is a header-only library, so the installation only involves unpacking
it to a suitable location - you don't need to compile it or download a
pre-compiled Boost binary.
Since Boost is quite large, you may prefer to only install the files
actually needed by Google Mock. If so, you can download TR1 tuple
without other parts of Boost from
http://code.google.com/p/googlemock/downloads/list.
After that you have two options: either set up Boost globally or
modify the Google Mock project to point to your copy of Boost. The
former will let all your tests use the same Boost library while the
latter will allow each of your projects use its own copy. You can also
use a hybrid solution: your project settings will override the
system-wide one.
For example, if you unpacked boost v1.36.0 into C:\boost:
To set up Boost such that all projects can use it:
* Assuming you are using the Visual Studio 2005 IDE, select Tools |
Options | Projects And Solutions | VC++ Directories.
* In the "Show directories for" drop-down select Include Files. Add
C:\boost\boost_1_36_0\boost\tr1\tr1 and C:\boost\boost_1_36_0 to the
list of directories.
To configure your project to point to that version of Boost, replace
the value of the BoostDir user macro with C:\boost\boost_1_36_0 in the
msvc/gmock_config.vsprops file. You can use any text editor to edit
that file.
Mock and selected tests.
If you want to use a version of Google Test other then the one bundled with
Google Mock, change the value of the GTestDir macro in gmock_config.vsprop
to point to the new location.
After configuring Boost, just open msvc/gmock.sln and build the library and
tests. If you want to create your own project to use with Google Mock, you'll
have to configure it to use the gmock_config propety sheet. For that:
Open msvc/gmock.sln and build the library and tests. If you want to
create your own project to use with Google Mock, you'll have to
configure it to use the gmock_config propety sheet. For that:
* Open the Property Manager window (View | Other Windows | Property Manager)
* Right-click on your project and select "Add Existing Property Sheet..."
* Navigate to gmock_config.vsprops and select it.
@@ -320,11 +308,6 @@ something like the following will do:
g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
path/to/your_test.cc libgmock.a -o your_test
On Windows, you'll also need to add the include path for the boost
headers to the compiler command line. See
http://www.boost.org/doc/libs/1_36_0/doc/html/boost_tr1/usage.html for
how to do it.
Regenerating Source Files
-------------------------
Some of Google Mock's source files are generated from templates (not
+1 -1
Ver Arquivo
@@ -80,7 +80,7 @@ AC_ARG_VAR([GTEST_VERSION],
[The version of Google Test available.])
HAVE_BUILT_GTEST="no"
GTEST_MIN_VERSION="1.2.1"
GTEST_MIN_VERSION="1.3.0"
AS_IF([test "x${enable_external_gtest}" = "xyes"],
[# Begin filling in variables as we are able.
@@ -45,12 +45,260 @@
namespace testing {
namespace internal {
// The type of the i-th (0-based) field of Tuple.
#define GMOCK_FIELD_TYPE_(Tuple, i) \
typename ::std::tr1::tuple_element<i, Tuple>::type
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
// tuple of type Tuple. It has two members:
//
// type: a tuple type whose i-th field is the ki-th field of Tuple.
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
//
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
//
// type is tuple<int, bool>, and
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
template <class Tuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
int k9 = -1>
class TupleFields;
// This generic version is used when there are 10 selectors.
template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
int k7, int k8, int k9>
class TupleFields {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8),
GMOCK_FIELD_TYPE_(Tuple, k9)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t), get<k9>(t));
}
};
// The following specialization is used for 0 ~ 9 selectors.
template <class Tuple>
class TupleFields<Tuple, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type();
}
};
template <class Tuple, int k0>
class TupleFields<Tuple, k0, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t));
}
};
template <class Tuple, int k0, int k1>
class TupleFields<Tuple, k0, k1, -1, -1, -1, -1, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t));
}
};
template <class Tuple, int k0, int k1, int k2>
class TupleFields<Tuple, k0, k1, k2, -1, -1, -1, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t));
}
};
template <class Tuple, int k0, int k1, int k2, int k3>
class TupleFields<Tuple, k0, k1, k2, k3, -1, -1, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t));
}
};
template <class Tuple, int k0, int k1, int k2, int k3, int k4>
class TupleFields<Tuple, k0, k1, k2, k3, k4, -1, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t));
}
};
template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5>
class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, -1, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
GMOCK_FIELD_TYPE_(Tuple, k5)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
get<k5>(t));
}
};
template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6>
class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, -1, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
get<k5>(t), get<k6>(t));
}
};
template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
int k7>
class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, -1, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
GMOCK_FIELD_TYPE_(Tuple, k7)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
get<k5>(t), get<k6>(t), get<k7>(t));
}
};
template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
int k7, int k8>
class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, -1> {
public:
typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8)> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t));
}
};
#undef GMOCK_FIELD_TYPE_
// Implements the Args() matcher.
template <class ArgsTuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
int k9 = -1>
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
public:
// ArgsTuple may have top-level const or reference modifiers.
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(ArgsTuple)) RawArgsTuple;
typedef typename internal::TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5,
k6, k7, k8, k9>::type SelectedArgs;
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
template <typename InnerMatcher>
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
virtual bool Matches(ArgsTuple args) const {
return inner_matcher_.Matches(GetSelectedArgs(args));
}
virtual void DescribeTo(::std::ostream* os) const {
PrintIndices(os);
inner_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
PrintIndices(os);
inner_matcher_.DescribeNegationTo(os);
}
virtual void ExplainMatchResultTo(ArgsTuple args,
::std::ostream* os) const {
inner_matcher_.ExplainMatchResultTo(GetSelectedArgs(args), os);
}
private:
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8,
k9>::GetSelectedFields(args);
}
// Prints the indices of the selected fields.
static void PrintIndices(::std::ostream* os) {
*os << "are a tuple whose fields (";
const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 };
for (int i = 0; i < 10; i++) {
if (indices[i] < 0)
break;
if (i >= 1)
*os << ", ";
*os << "#" << indices[i];
}
*os << ") ";
}
const MonomorphicInnerMatcher inner_matcher_;
};
template <class InnerMatcher, int k0 = -1, int k1 = -1, int k2 = -1,
int k3 = -1, int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1,
int k8 = -1, int k9 = -1>
class ArgsMatcher {
public:
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
: inner_matcher_(inner_matcher) {}
template <typename ArgsTuple>
operator Matcher<ArgsTuple>() const {
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k0, k1, k2, k3, k4, k5,
k6, k7, k8, k9>(inner_matcher_));
}
const InnerMatcher inner_matcher_;
};
// Implements ElementsAre() and ElementsAreArray().
template <typename Container>
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
public:
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
typedef typename RawContainer::value_type Element;
typedef internal::StlContainerView<RawContainer> View;
typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference;
typedef typename StlContainer::value_type Element;
// Constructs the matcher from a sequence of element values or
// element matchers.
@@ -65,12 +313,13 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// Returns true iff 'container' matches.
virtual bool Matches(Container container) const {
if (container.size() != count())
StlContainerReference stl_container = View::ConstReference(container);
if (stl_container.size() != count())
return false;
typename RawContainer::const_iterator container_iter = container.begin();
for (size_t i = 0; i != count(); ++container_iter, ++i) {
if (!matchers_[i].Matches(*container_iter))
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; i != count(); ++it, ++i) {
if (!matchers_[i].Matches(*it))
return false;
}
@@ -116,15 +365,16 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// Explains why 'container' matches, or doesn't match, this matcher.
virtual void ExplainMatchResultTo(Container container,
::std::ostream* os) const {
StlContainerReference stl_container = View::ConstReference(container);
if (Matches(container)) {
// We need to explain why *each* element matches (the obvious
// ones can be skipped).
bool reason_printed = false;
typename RawContainer::const_iterator container_iter = container.begin();
for (size_t i = 0; i != count(); ++container_iter, ++i) {
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; i != count(); ++it, ++i) {
::std::stringstream ss;
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
matchers_[i].ExplainMatchResultTo(*it, &ss);
const string s = ss.str();
if (!s.empty()) {
@@ -137,7 +387,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
}
} else {
// We need to explain why the container doesn't match.
const size_t actual_count = container.size();
const size_t actual_count = stl_container.size();
if (actual_count != count()) {
// The element count doesn't match. If the container is
// empty, there's no need to explain anything as Google Mock
@@ -152,16 +402,16 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// The container has the right size but at least one element
// doesn't match expectation. We need to find this element and
// explain why it doesn't match.
typename RawContainer::const_iterator container_iter = container.begin();
for (size_t i = 0; i != count(); ++container_iter, ++i) {
if (matchers_[i].Matches(*container_iter)) {
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; i != count(); ++it, ++i) {
if (matchers_[i].Matches(*it)) {
continue;
}
*os << "element " << i << " doesn't match";
::std::stringstream ss;
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
matchers_[i].ExplainMatchResultTo(*it, &ss);
const string s = ss.str();
if (!s.empty()) {
*os << " (" << s << ")";
@@ -190,7 +440,8 @@ class ElementsAreMatcher0 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&>* const matchers = NULL;
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
@@ -206,7 +457,8 @@ class ElementsAreMatcher1 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -228,7 +480,8 @@ class ElementsAreMatcher2 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -253,7 +506,8 @@ class ElementsAreMatcher3 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -280,7 +534,8 @@ class ElementsAreMatcher4 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -309,7 +564,8 @@ class ElementsAreMatcher5 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -342,7 +598,8 @@ class ElementsAreMatcher6 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -377,7 +634,8 @@ class ElementsAreMatcher7 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -414,7 +672,8 @@ class ElementsAreMatcher8 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -454,7 +713,8 @@ class ElementsAreMatcher9 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -496,7 +756,8 @@ class ElementsAreMatcher10 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
MatcherCast<const Element&>(e1_),
@@ -538,7 +799,8 @@ class ElementsAreArrayMatcher {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
}
@@ -550,6 +812,84 @@ class ElementsAreArrayMatcher {
} // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// fields of it matches a_matcher. C++ doesn't support default
// arguments for function templates, so we have to overload it.
template <typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher>(matcher);
}
template <int k1, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1>(matcher);
}
template <int k1, int k2, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2>(matcher);
}
template <int k1, int k2, int k3, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3>(matcher);
}
template <int k1, int k2, int k3, int k4, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>(matcher);
}
template <int k1, int k2, int k3, int k4, int k5, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>(matcher);
}
template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>(matcher);
}
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6,
k7>(matcher);
}
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7,
k8>(matcher);
}
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
int k9, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
k9>(matcher);
}
template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
int k9, int k10, typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9,
k10>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
k9, k10>(matcher);
}
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with
// (n + 1) elements, where the i-th element in the container must
// match the i-th argument in the list. Each argument of
@@ -1573,45 +1913,4 @@ string FormatMatcherDescription(
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, p9##_type>::\
gmock_Impl<arg_type>::Matches(arg_type arg) const
namespace testing {
namespace internal {
// Returns true iff element is in the STL-style container.
template <typename Container, typename Element>
inline bool Contains(const Container& container, const Element& element) {
return ::std::find(container.begin(), container.end(), element) !=
container.end();
}
// Returns true iff element is in the C-style array.
template <typename ArrayElement, size_t N, typename Element>
inline bool Contains(const ArrayElement (&array)[N], const Element& element) {
return ::std::find(array, array + N, element) != array + N;
}
} // namespace internal
// Matches an STL-style container or a C-style array that contains the given
// element.
//
// Examples:
// ::std::set<int> page_ids;
// page_ids.insert(3);
// page_ids.insert(1);
// EXPECT_THAT(page_ids, Contains(1));
// EXPECT_THAT(page_ids, Contains(3.0));
// EXPECT_THAT(page_ids, Not(Contains(4)));
//
// ::std::map<int, size_t> page_lengths;
// page_lengths[1] = 100;
// EXPECT_THAT(map_int, Contains(::std::pair<const int, size_t>(1, 100)));
//
// const char* user_ids[] = { "joe", "mike", "tom" };
// EXPECT_THAT(user_ids, Contains(::std::string("tom")));
MATCHER_P(Contains, element, "") {
return internal::Contains(arg, element);
}
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
@@ -3,6 +3,7 @@ $$ This is a Pump source file. Please use Pump to convert it to
$$ gmock-generated-variadic-actions.h.
$$
$var n = 10 $$ The maximum arity we support.
$$ }} This line fixes auto-indentation of the following code in Emacs.
// Copyright 2008, Google Inc.
// All rights reserved.
//
@@ -48,12 +49,139 @@ $var n = 10 $$ The maximum arity we support.
namespace testing {
namespace internal {
$range i 0..n-1
// The type of the i-th (0-based) field of Tuple.
#define GMOCK_FIELD_TYPE_(Tuple, i) \
typename ::std::tr1::tuple_element<i, Tuple>::type
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
// tuple of type Tuple. It has two members:
//
// type: a tuple type whose i-th field is the ki-th field of Tuple.
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
//
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
//
// type is tuple<int, bool>, and
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
template <class Tuple$for i [[, int k$i = -1]]>
class TupleFields;
// This generic version is used when there are $n selectors.
template <class Tuple$for i [[, int k$i]]>
class TupleFields {
public:
typedef ::std::tr1::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type($for i, [[get<k$i>(t)]]);
}
};
// The following specialization is used for 0 ~ $(n-1) selectors.
$for i [[
$$ }}}
$range j 0..i-1
$range k 0..n-1
template <class Tuple$for j [[, int k$j]]>
class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
public:
typedef ::std::tr1::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
static type GetSelectedFields(const Tuple& t) {
using ::std::tr1::get;
return type($for j, [[get<k$j>(t)]]);
}
};
]]
#undef GMOCK_FIELD_TYPE_
// Implements the Args() matcher.
$var ks = [[$for i, [[k$i]]]]
template <class ArgsTuple$for i [[, int k$i = -1]]>
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
public:
// ArgsTuple may have top-level const or reference modifiers.
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(ArgsTuple)) RawArgsTuple;
typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
template <typename InnerMatcher>
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
virtual bool Matches(ArgsTuple args) const {
return inner_matcher_.Matches(GetSelectedArgs(args));
}
virtual void DescribeTo(::std::ostream* os) const {
PrintIndices(os);
inner_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
PrintIndices(os);
inner_matcher_.DescribeNegationTo(os);
}
virtual void ExplainMatchResultTo(ArgsTuple args,
::std::ostream* os) const {
inner_matcher_.ExplainMatchResultTo(GetSelectedArgs(args), os);
}
private:
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
}
// Prints the indices of the selected fields.
static void PrintIndices(::std::ostream* os) {
*os << "are a tuple whose fields (";
const int indices[$n] = { $ks };
for (int i = 0; i < $n; i++) {
if (indices[i] < 0)
break;
if (i >= 1)
*os << ", ";
*os << "#" << indices[i];
}
*os << ") ";
}
const MonomorphicInnerMatcher inner_matcher_;
};
template <class InnerMatcher$for i [[, int k$i = -1]]>
class ArgsMatcher {
public:
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
: inner_matcher_(inner_matcher) {}
template <typename ArgsTuple>
operator Matcher<ArgsTuple>() const {
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
}
const InnerMatcher inner_matcher_;
};
// Implements ElementsAre() and ElementsAreArray().
template <typename Container>
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
public:
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
typedef typename RawContainer::value_type Element;
typedef internal::StlContainerView<RawContainer> View;
typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference;
typedef typename StlContainer::value_type Element;
// Constructs the matcher from a sequence of element values or
// element matchers.
@@ -68,12 +196,13 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// Returns true iff 'container' matches.
virtual bool Matches(Container container) const {
if (container.size() != count())
StlContainerReference stl_container = View::ConstReference(container);
if (stl_container.size() != count())
return false;
typename RawContainer::const_iterator container_iter = container.begin();
for (size_t i = 0; i != count(); ++container_iter, ++i) {
if (!matchers_[i].Matches(*container_iter))
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; i != count(); ++it, ++i) {
if (!matchers_[i].Matches(*it))
return false;
}
@@ -119,15 +248,16 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// Explains why 'container' matches, or doesn't match, this matcher.
virtual void ExplainMatchResultTo(Container container,
::std::ostream* os) const {
StlContainerReference stl_container = View::ConstReference(container);
if (Matches(container)) {
// We need to explain why *each* element matches (the obvious
// ones can be skipped).
bool reason_printed = false;
typename RawContainer::const_iterator container_iter = container.begin();
for (size_t i = 0; i != count(); ++container_iter, ++i) {
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; i != count(); ++it, ++i) {
::std::stringstream ss;
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
matchers_[i].ExplainMatchResultTo(*it, &ss);
const string s = ss.str();
if (!s.empty()) {
@@ -140,7 +270,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
}
} else {
// We need to explain why the container doesn't match.
const size_t actual_count = container.size();
const size_t actual_count = stl_container.size();
if (actual_count != count()) {
// The element count doesn't match. If the container is
// empty, there's no need to explain anything as Google Mock
@@ -155,16 +285,16 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// The container has the right size but at least one element
// doesn't match expectation. We need to find this element and
// explain why it doesn't match.
typename RawContainer::const_iterator container_iter = container.begin();
for (size_t i = 0; i != count(); ++container_iter, ++i) {
if (matchers_[i].Matches(*container_iter)) {
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; i != count(); ++it, ++i) {
if (matchers_[i].Matches(*it)) {
continue;
}
*os << "element " << i << " doesn't match";
::std::stringstream ss;
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
matchers_[i].ExplainMatchResultTo(*it, &ss);
const string s = ss.str();
if (!s.empty()) {
*os << " (" << s << ")";
@@ -193,7 +323,8 @@ class ElementsAreMatcher0 {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&>* const matchers = NULL;
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
@@ -214,7 +345,8 @@ class ElementsAreMatcher$i {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
const Matcher<const Element&> matchers[] = {
@@ -248,7 +380,8 @@ class ElementsAreArrayMatcher {
operator Matcher<Container>() const {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))
RawContainer;
typedef typename RawContainer::value_type Element;
typedef typename internal::StlContainerView<RawContainer>::type::value_type
Element;
return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
}
@@ -260,6 +393,21 @@ class ElementsAreArrayMatcher {
} // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
// fields of it matches a_matcher. C++ doesn't support default
// arguments for function templates, so we have to overload it.
$range i 0..n
$for i [[
$range j 1..i
template <$for j [[int k$j, ]]typename InnerMatcher>
inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
Args(const InnerMatcher& matcher) {
return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
}
]]
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with
// (n + 1) elements, where the i-th element in the container must
// match the i-th argument in the list. Each argument of
@@ -274,6 +422,7 @@ inline internal::ElementsAreMatcher0 ElementsAre() {
return internal::ElementsAreMatcher0();
}
$range i 1..n
$for i [[
$range j 1..i
@@ -590,45 +739,4 @@ $var param_field_decls2 = [[$for j
]]
namespace testing {
namespace internal {
// Returns true iff element is in the STL-style container.
template <typename Container, typename Element>
inline bool Contains(const Container& container, const Element& element) {
return ::std::find(container.begin(), container.end(), element) !=
container.end();
}
// Returns true iff element is in the C-style array.
template <typename ArrayElement, size_t N, typename Element>
inline bool Contains(const ArrayElement (&array)[N], const Element& element) {
return ::std::find(array, array + N, element) != array + N;
}
} // namespace internal
// Matches an STL-style container or a C-style array that contains the given
// element.
//
// Examples:
// ::std::set<int> page_ids;
// page_ids.insert(3);
// page_ids.insert(1);
// EXPECT_THAT(page_ids, Contains(1));
// EXPECT_THAT(page_ids, Contains(3.0));
// EXPECT_THAT(page_ids, Not(Contains(4)));
//
// ::std::map<int, size_t> page_lengths;
// page_lengths[1] = 100;
// EXPECT_THAT(map_int, Contains(::std::pair<const int, size_t>(1, 100)));
//
// const char* user_ids[] = { "joe", "mike", "tom" };
// EXPECT_THAT(user_ids, Contains(::std::string("tom")));
MATCHER_P(Contains, element, "") {
return internal::Contains(arg, element);
}
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
+172 -26
Ver Arquivo
@@ -938,7 +938,7 @@ class MatchesRegexMatcher {
//
// We define this as a macro in order to eliminate duplicated source
// code.
#define GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(name, op, relation) \
#define GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(name, op) \
class name##2Matcher { \
public: \
template <typename T1, typename T2> \
@@ -953,21 +953,21 @@ class MatchesRegexMatcher {
return ::std::tr1::get<0>(args) op ::std::tr1::get<1>(args); \
} \
virtual void DescribeTo(::std::ostream* os) const { \
*os << "argument #0 is " relation " argument #1"; \
*os << "are a pair (x, y) where x " #op " y"; \
} \
virtual void DescribeNegationTo(::std::ostream* os) const { \
*os << "argument #0 is not " relation " argument #1"; \
*os << "are a pair (x, y) where x " #op " y is false"; \
} \
}; \
}
// Implements Eq(), Ge(), Gt(), Le(), Lt(), and Ne() respectively.
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Eq, ==, "equal to");
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ge, >=, "greater than or equal to");
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Gt, >, "greater than");
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Le, <=, "less than or equal to");
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Lt, <, "less than");
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=, "not equal to");
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Eq, ==);
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ge, >=);
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Gt, >);
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Le, <=);
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Lt, <);
GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=);
#undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_
@@ -1709,60 +1709,164 @@ void ExplainMatchResultTo(const ResultOfMatcher<Callable>& matcher,
template <typename Container>
class ContainerEqMatcher {
public:
explicit ContainerEqMatcher(const Container& rhs) : rhs_(rhs) {}
bool Matches(const Container& lhs) const { return lhs == rhs_; }
typedef internal::StlContainerView<Container> View;
typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference;
// We make a copy of rhs in case the elements in it are modified
// after this matcher is created.
explicit ContainerEqMatcher(const Container& rhs) : rhs_(View::Copy(rhs)) {
// Makes sure the user doesn't instantiate this class template
// with a const or reference type.
testing::StaticAssertTypeEq<Container,
GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container))>();
}
template <typename LhsContainer>
bool Matches(const LhsContainer& lhs) const {
// GMOCK_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug
// that causes LhsContainer to be a const type sometimes.
typedef internal::StlContainerView<GMOCK_REMOVE_CONST_(LhsContainer)>
LhsView;
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
return lhs_stl_container == rhs_;
}
void DescribeTo(::std::ostream* os) const {
*os << "equals ";
UniversalPrinter<Container>::Print(rhs_, os);
UniversalPrinter<StlContainer>::Print(rhs_, os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "does not equal ";
UniversalPrinter<Container>::Print(rhs_, os);
UniversalPrinter<StlContainer>::Print(rhs_, os);
}
void ExplainMatchResultTo(const Container& lhs,
template <typename LhsContainer>
void ExplainMatchResultTo(const LhsContainer& lhs,
::std::ostream* os) const {
// GMOCK_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug
// that causes LhsContainer to be a const type sometimes.
typedef internal::StlContainerView<GMOCK_REMOVE_CONST_(LhsContainer)>
LhsView;
typedef typename LhsView::type LhsStlContainer;
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
// Something is different. Check for missing values first.
bool printed_header = false;
for (typename Container::const_iterator it = lhs.begin();
it != lhs.end(); ++it) {
if (std::find(rhs_.begin(), rhs_.end(), *it) == rhs_.end()) {
for (typename LhsStlContainer::const_iterator it =
lhs_stl_container.begin();
it != lhs_stl_container.end(); ++it) {
if (internal::ArrayAwareFind(rhs_.begin(), rhs_.end(), *it) ==
rhs_.end()) {
if (printed_header) {
*os << ", ";
} else {
*os << "Only in actual: ";
printed_header = true;
}
UniversalPrinter<typename Container::value_type>::Print(*it, os);
UniversalPrinter<typename LhsStlContainer::value_type>::Print(*it, os);
}
}
// Now check for extra values.
bool printed_header2 = false;
for (typename Container::const_iterator it = rhs_.begin();
for (typename StlContainer::const_iterator it = rhs_.begin();
it != rhs_.end(); ++it) {
if (std::find(lhs.begin(), lhs.end(), *it) == lhs.end()) {
if (internal::ArrayAwareFind(
lhs_stl_container.begin(), lhs_stl_container.end(), *it) ==
lhs_stl_container.end()) {
if (printed_header2) {
*os << ", ";
} else {
*os << (printed_header ? "; not" : "Not") << " in actual: ";
printed_header2 = true;
}
UniversalPrinter<typename Container::value_type>::Print(*it, os);
UniversalPrinter<typename StlContainer::value_type>::Print(*it, os);
}
}
}
private:
const Container rhs_;
const StlContainer rhs_;
};
template <typename Container>
template <typename LhsContainer, typename Container>
void ExplainMatchResultTo(const ContainerEqMatcher<Container>& matcher,
const Container& lhs,
const LhsContainer& lhs,
::std::ostream* os) {
matcher.ExplainMatchResultTo(lhs, os);
}
// Implements Contains(element_matcher) for the given argument type Container.
template <typename Container>
class ContainsMatcherImpl : public MatcherInterface<Container> {
public:
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Container)) RawContainer;
typedef StlContainerView<RawContainer> View;
typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference;
typedef typename StlContainer::value_type Element;
template <typename InnerMatcher>
explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
: inner_matcher_(
testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
// Returns true iff 'container' matches.
virtual bool Matches(Container container) const {
StlContainerReference stl_container = View::ConstReference(container);
for (typename StlContainer::const_iterator it = stl_container.begin();
it != stl_container.end(); ++it) {
if (inner_matcher_.Matches(*it))
return true;
}
return false;
}
// Describes what this matcher does.
virtual void DescribeTo(::std::ostream* os) const {
*os << "contains at least one element that ";
inner_matcher_.DescribeTo(os);
}
// Describes what the negation of this matcher does.
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't contain any element that ";
inner_matcher_.DescribeTo(os);
}
// Explains why 'container' matches, or doesn't match, this matcher.
virtual void ExplainMatchResultTo(Container container,
::std::ostream* os) const {
StlContainerReference stl_container = View::ConstReference(container);
// We need to explain which (if any) element matches inner_matcher_.
typename StlContainer::const_iterator it = stl_container.begin();
for (size_t i = 0; it != stl_container.end(); ++it, ++i) {
if (inner_matcher_.Matches(*it)) {
*os << "element " << i << " matches";
return;
}
}
}
private:
const Matcher<const Element&> inner_matcher_;
};
// Implements polymorphic Contains(element_matcher).
template <typename M>
class ContainsMatcher {
public:
explicit ContainsMatcher(M m) : inner_matcher_(m) {}
template <typename Container>
operator Matcher<Container>() const {
return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_));
}
private:
const M inner_matcher_;
};
} // namespace internal
// Implements MatcherCast().
@@ -2206,9 +2310,35 @@ Truly(Predicate pred) {
// values that are included in one container but not the other. (Duplicate
// values and order differences are not explained.)
template <typename Container>
inline PolymorphicMatcher<internal::ContainerEqMatcher<Container> >
inline PolymorphicMatcher<internal::ContainerEqMatcher<
GMOCK_REMOVE_CONST_(Container)> >
ContainerEq(const Container& rhs) {
return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));
// This following line is for working around a bug in MSVC 8.0,
// which causes Container to be a const type sometimes.
typedef GMOCK_REMOVE_CONST_(Container) RawContainer;
return MakePolymorphicMatcher(internal::ContainerEqMatcher<RawContainer>(rhs));
}
// Matches an STL-style container or a native array that contains at
// least one element matching the given value or matcher.
//
// Examples:
// ::std::set<int> page_ids;
// page_ids.insert(3);
// page_ids.insert(1);
// EXPECT_THAT(page_ids, Contains(1));
// EXPECT_THAT(page_ids, Contains(Gt(2)));
// EXPECT_THAT(page_ids, Not(Contains(4)));
//
// ::std::map<int, size_t> page_lengths;
// page_lengths[1] = 100;
// EXPECT_THAT(map_int, Contains(::std::pair<const int, size_t>(1, 100)));
//
// const char* user_ids[] = { "joe", "mike", "tom" };
// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom"))));
template <typename M>
inline internal::ContainsMatcher<M> Contains(M matcher) {
return internal::ContainsMatcher<M>(matcher);
}
// Returns a predicate that is satisfied by anything that matches the
@@ -2218,6 +2348,22 @@ inline internal::MatcherAsPredicate<M> Matches(M matcher) {
return internal::MatcherAsPredicate<M>(matcher);
}
// Returns true iff the value matches the matcher.
template <typename T, typename M>
inline bool Value(const T& value, M matcher) {
return testing::Matches(matcher)(value);
}
// AllArgs(m) is a synonym of m. This is useful in
//
// EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq()));
//
// which is easier to read than
//
// EXPECT_CALL(foo, Bar(_, _)).With(Eq());
template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed iff the value matches the matcher. If the assertion fails,
+70 -31
Ver Arquivo
@@ -66,10 +66,28 @@
// // printed.
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
//
// // Prints value using the type inferred by the compiler. The difference
// // from UniversalTersePrint() is that this function prints both the
// // pointer and the NUL-terminated string for a (const) char pointer.
// void ::testing::internal::UniversalPrint(const T& value, ostream*);
//
// // Prints the fields of a tuple tersely to a string vector, one
// // element for each field.
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
// const Tuple& value);
//
// Known limitation:
//
// The print primitives print the elements of an STL-style container
// using the compiler-inferred type of *iter where iter is a
// const_iterator of the container. When const_iterator is an input
// iterator but not a forward iterator, this inferred type may not
// match value_type, and the print output may be incorrect. In
// practice, this is rarely a problem as for most containers
// const_iterator is a forward iterator. We'll fix this if there's an
// actual need for it. Note that this fix cannot rely on value_type
// being defined as many user-defined container types don't have
// value_type.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
@@ -208,6 +226,9 @@ namespace internal {
template <typename T>
class UniversalPrinter;
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
template <typename C>
@@ -227,7 +248,9 @@ void DefaultPrintTo(IsContainer /* dummy */,
}
}
*os << ' ';
PrintTo(*it, os);
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
// handle *it being a native array.
internal::UniversalPrint(*it, os);
}
if (count > 0) {
@@ -580,6 +603,41 @@ class UniversalPrinter {
#endif // _MSC_VER
};
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
template <typename T>
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
if (len == 0) {
*os << "{}";
} else {
*os << "{ ";
const size_t kThreshold = 18;
const size_t kChunkSize = 8;
// If the array has more than kThreshold elements, we'll have to
// omit some details by printing only the first and the last
// kChunkSize elements.
// TODO(wan@google.com): let the user control the threshold using a flag.
if (len <= kThreshold) {
PrintRawArrayTo(begin, len, os);
} else {
PrintRawArrayTo(begin, kChunkSize, os);
*os << ", ..., ";
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
}
*os << " }";
}
}
// This overload prints a (const) char array compactly.
void UniversalPrintArray(const char* begin, size_t len, ::std::ostream* os);
// Prints an array of 'len' elements, starting at address 'begin', to a string.
template <typename T>
string UniversalPrintArrayToString(const T* begin, size_t len) {
::std::stringstream ss;
UniversalPrintArray(begin, len, &ss);
return ss.str();
}
// Implements printing an array type T[N].
template <typename T, size_t N>
class UniversalPrinter<T[N]> {
@@ -587,41 +645,13 @@ class UniversalPrinter<T[N]> {
// Prints the given array, omitting some elements when there are too
// many.
static void Print(const T (&a)[N], ::std::ostream* os) {
// Prints a char array as a C string. Note that we compare 'const
// T' with 'const char' instead of comparing T with char, in case
// that T is already a const type.
if (internal::type_equals<const T, const char>::value) {
UniversalPrinter<const T*>::Print(a, os);
return;
}
if (N == 0) {
*os << "{}";
} else {
*os << "{ ";
const size_t kThreshold = 18;
const size_t kChunkSize = 8;
// If the array has more than kThreshold elements, we'll have to
// omit some details by printing only the first and the last
// kChunkSize elements.
// TODO(wan): let the user control the threshold using a flag.
if (N <= kThreshold) {
PrintRawArrayTo(a, N, os);
} else {
PrintRawArrayTo(a, kChunkSize, os);
*os << ", ..., ";
PrintRawArrayTo(a + N - kChunkSize, kChunkSize, os);
}
*os << " }";
}
UniversalPrintArray(a, N, os);
}
// A convenient wrapper for Print() that returns the print-out as a
// string.
static string PrintToString(const T (&a)[N]) {
::std::stringstream ss;
Print(a, &ss);
return ss.str();
return UniversalPrintArrayToString(a, N);
}
};
@@ -676,6 +706,15 @@ inline void UniversalTersePrint(char* str, ::std::ostream* os) {
UniversalTersePrint(static_cast<const char*>(str), os);
}
// Prints a value using the type inferred by the compiler. The
// difference between this and UniversalTersePrint() is that for a
// (const) char pointer, this prints both the pointer and the
// NUL-terminated string.
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os) {
UniversalPrinter<T>::Print(value, os);
}
// Prints the fields of a tuple tersely to a string vector, one
// element for each field. See the comment before
// UniversalTersePrint() for how we define "tersely".
+213 -217
Ver Arquivo
@@ -37,16 +37,16 @@
// a mock method. The syntax is:
//
// ON_CALL(mock_object, Method(argument-matchers))
// .WithArguments(multi-argument-matcher)
// .With(multi-argument-matcher)
// .WillByDefault(action);
//
// where the .WithArguments() clause is optional.
// where the .With() clause is optional.
//
// A user can use the EXPECT_CALL() macro to specify an expectation on
// a mock method. The syntax is:
//
// EXPECT_CALL(mock_object, Method(argument-matchers))
// .WithArguments(multi-argument-matchers)
// .With(multi-argument-matchers)
// .Times(cardinality)
// .InSequence(sequences)
// .WillOnce(action)
@@ -93,10 +93,6 @@ class ExpectationTester;
template <typename F>
class FunctionMockerBase;
// Helper class for implementing FunctionMockerBase<F>::InvokeWith().
template <typename Result, typename F>
class InvokeWithHelper;
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
//
@@ -148,20 +144,20 @@ class DefaultActionSpec {
// bug in Symbian's C++ compiler (cannot decide between two
// overloaded constructors of Matcher<const ArgumentTuple&>).
extra_matcher_(A<const ArgumentTuple&>()),
last_clause_(NONE) {
last_clause_(kNone) {
}
// Where in the source file was the default action spec defined?
const char* file() const { return file_; }
int line() const { return line_; }
// Implements the .WithArguments() clause.
DefaultActionSpec& WithArguments(const Matcher<const ArgumentTuple&>& m) {
// Implements the .With() clause.
DefaultActionSpec& With(const Matcher<const ArgumentTuple&>& m) {
// Makes sure this is called at most once.
ExpectSpecProperty(last_clause_ < WITH_ARGUMENTS,
".WithArguments() cannot appear "
ExpectSpecProperty(last_clause_ < kWith,
".With() cannot appear "
"more than once in an ON_CALL().");
last_clause_ = WITH_ARGUMENTS;
last_clause_ = kWith;
extra_matcher_ = m;
return *this;
@@ -169,10 +165,10 @@ class DefaultActionSpec {
// Implements the .WillByDefault() clause.
DefaultActionSpec& WillByDefault(const Action<F>& action) {
ExpectSpecProperty(last_clause_ < WILL_BY_DEFAULT,
ExpectSpecProperty(last_clause_ < kWillByDefault,
".WillByDefault() must appear "
"exactly once in an ON_CALL().");
last_clause_ = WILL_BY_DEFAULT;
last_clause_ = kWillByDefault;
ExpectSpecProperty(!action.IsDoDefault(),
"DoDefault() cannot be used in ON_CALL().");
@@ -187,7 +183,7 @@ class DefaultActionSpec {
// Returns the action specified by the user.
const Action<F>& GetAction() const {
AssertSpecProperty(last_clause_ == WILL_BY_DEFAULT,
AssertSpecProperty(last_clause_ == kWillByDefault,
".WillByDefault() must appear exactly "
"once in an ON_CALL().");
return action_;
@@ -197,9 +193,9 @@ class DefaultActionSpec {
enum Clause {
// Do not change the order of the enum members! The run-time
// syntax checking relies on it.
NONE,
WITH_ARGUMENTS,
WILL_BY_DEFAULT,
kNone,
kWith,
kWillByDefault,
};
// Asserts that the ON_CALL() statement has a certain property.
@@ -215,7 +211,7 @@ class DefaultActionSpec {
// The information in statement
//
// ON_CALL(mock_object, Method(matchers))
// .WithArguments(multi-argument-matcher)
// .With(multi-argument-matcher)
// .WillByDefault(action);
//
// is recorded in the data members like this:
@@ -232,7 +228,7 @@ class DefaultActionSpec {
Action<F> action_;
// The last clause in the ON_CALL() statement as seen so far.
// Initially NONE and changes as the statement is parsed.
// Initially kNone and changes as the statement is parsed.
Clause last_clause_;
}; // class DefaultActionSpec
@@ -269,9 +265,6 @@ class Mock {
template <typename F>
friend class internal::FunctionMockerBase;
template <typename R, typename Args>
friend class internal::InvokeWithHelper;
template <typename M>
friend class NiceMock;
@@ -444,13 +437,13 @@ class ExpectationBase {
enum Clause {
// Don't change the order of the enum members!
NONE,
WITH_ARGUMENTS,
TIMES,
IN_SEQUENCE,
WILL_ONCE,
WILL_REPEATEDLY,
RETIRES_ON_SATURATION,
kNone,
kWith,
kTimes,
kInSequence,
kWillOnce,
kWillRepeatedly,
kRetiresOnSaturation,
};
// Asserts that the EXPECT_CALL() statement has the given property.
@@ -588,7 +581,7 @@ class Expectation : public ExpectationBase {
repeated_action_specified_(false),
repeated_action_(DoDefault()),
retires_on_saturation_(false),
last_clause_(NONE),
last_clause_(kNone),
action_count_checked_(false) {}
virtual ~Expectation() {
@@ -597,18 +590,18 @@ class Expectation : public ExpectationBase {
CheckActionCountIfNotDone();
}
// Implements the .WithArguments() clause.
Expectation& WithArguments(const Matcher<const ArgumentTuple&>& m) {
if (last_clause_ == WITH_ARGUMENTS) {
// Implements the .With() clause.
Expectation& With(const Matcher<const ArgumentTuple&>& m) {
if (last_clause_ == kWith) {
ExpectSpecProperty(false,
".WithArguments() cannot appear "
".With() cannot appear "
"more than once in an EXPECT_CALL().");
} else {
ExpectSpecProperty(last_clause_ < WITH_ARGUMENTS,
".WithArguments() must be the first "
ExpectSpecProperty(last_clause_ < kWith,
".With() must be the first "
"clause in an EXPECT_CALL().");
}
last_clause_ = WITH_ARGUMENTS;
last_clause_ = kWith;
extra_matcher_ = m;
return *this;
@@ -616,17 +609,17 @@ class Expectation : public ExpectationBase {
// Implements the .Times() clause.
Expectation& Times(const Cardinality& cardinality) {
if (last_clause_ ==TIMES) {
if (last_clause_ ==kTimes) {
ExpectSpecProperty(false,
".Times() cannot appear "
"more than once in an EXPECT_CALL().");
} else {
ExpectSpecProperty(last_clause_ < TIMES,
ExpectSpecProperty(last_clause_ < kTimes,
".Times() cannot appear after "
".InSequence(), .WillOnce(), .WillRepeatedly(), "
"or .RetiresOnSaturation().");
}
last_clause_ = TIMES;
last_clause_ = kTimes;
ExpectationBase::SpecifyCardinality(cardinality);
return *this;
@@ -639,11 +632,11 @@ class Expectation : public ExpectationBase {
// Implements the .InSequence() clause.
Expectation& InSequence(const Sequence& s) {
ExpectSpecProperty(last_clause_ <= IN_SEQUENCE,
ExpectSpecProperty(last_clause_ <= kInSequence,
".InSequence() cannot appear after .WillOnce(),"
" .WillRepeatedly(), or "
".RetiresOnSaturation().");
last_clause_ = IN_SEQUENCE;
last_clause_ = kInSequence;
s.AddExpectation(owner_->GetLinkedExpectationBase(this));
return *this;
@@ -667,10 +660,10 @@ class Expectation : public ExpectationBase {
// Implements the .WillOnce() clause.
Expectation& WillOnce(const Action<F>& action) {
ExpectSpecProperty(last_clause_ <= WILL_ONCE,
ExpectSpecProperty(last_clause_ <= kWillOnce,
".WillOnce() cannot appear after "
".WillRepeatedly() or .RetiresOnSaturation().");
last_clause_ = WILL_ONCE;
last_clause_ = kWillOnce;
actions_.push_back(action);
if (!cardinality_specified()) {
@@ -681,16 +674,16 @@ class Expectation : public ExpectationBase {
// Implements the .WillRepeatedly() clause.
Expectation& WillRepeatedly(const Action<F>& action) {
if (last_clause_ == WILL_REPEATEDLY) {
if (last_clause_ == kWillRepeatedly) {
ExpectSpecProperty(false,
".WillRepeatedly() cannot appear "
"more than once in an EXPECT_CALL().");
} else {
ExpectSpecProperty(last_clause_ < WILL_REPEATEDLY,
ExpectSpecProperty(last_clause_ < kWillRepeatedly,
".WillRepeatedly() cannot appear "
"after .RetiresOnSaturation().");
}
last_clause_ = WILL_REPEATEDLY;
last_clause_ = kWillRepeatedly;
repeated_action_specified_ = true;
repeated_action_ = action;
@@ -706,10 +699,10 @@ class Expectation : public ExpectationBase {
// Implements the .RetiresOnSaturation() clause.
Expectation& RetiresOnSaturation() {
ExpectSpecProperty(last_clause_ < RETIRES_ON_SATURATION,
ExpectSpecProperty(last_clause_ < kRetiresOnSaturation,
".RetiresOnSaturation() cannot appear "
"more than once.");
last_clause_ = RETIRES_ON_SATURATION;
last_clause_ = kRetiresOnSaturation;
retires_on_saturation_ = true;
// Now that no more action clauses can be specified, we check
@@ -724,7 +717,7 @@ class Expectation : public ExpectationBase {
return matchers_;
}
// Returns the matcher specified by the .WithArguments() clause.
// Returns the matcher specified by the .With() clause.
const Matcher<const ArgumentTuple&>& extra_matcher() const {
return extra_matcher_;
}
@@ -763,9 +756,6 @@ class Expectation : public ExpectationBase {
template <typename Function>
friend class FunctionMockerBase;
template <typename R, typename Function>
friend class InvokeWithHelper;
// The following methods will be called only after the EXPECT_CALL()
// statement finishes and when the current thread holds
// g_gmock_mutex.
@@ -805,9 +795,9 @@ class Expectation : public ExpectationBase {
DescribeMatchFailureTupleTo(matchers_, args, os);
}
if (!extra_matcher_.Matches(args)) {
*os << " Expected: ";
*os << " Expected args: ";
extra_matcher_.DescribeTo(os);
*os << "\n Actual: false";
*os << "\n Actual: don't match";
internal::ExplainMatchResultAsNeededTo<const ArgumentTuple&>(
extra_matcher_, args, os);
@@ -1042,6 +1032,78 @@ class MockSpec {
#pragma warning(disable:4355) // Temporarily disables warning 4355.
#endif // _MSV_VER
// C++ treats the void type specially. For example, you cannot define
// a void-typed variable or pass a void value to a function.
// ActionResultHolder<T> holds a value of type T, where T must be a
// copyable type or void (T doesn't need to be default-constructable).
// It hides the syntactic difference between void and other types, and
// is used to unify the code for invoking both void-returning and
// non-void-returning mock functions. This generic definition is used
// when T is not void.
template <typename T>
class ActionResultHolder {
public:
explicit ActionResultHolder(T value) : value_(value) {}
// The compiler-generated copy constructor and assignment operator
// are exactly what we need, so we don't need to define them.
T value() const { return value_; }
// Prints the held value as an action's result to os.
void PrintAsActionResult(::std::ostream* os) const {
*os << "\n Returns: ";
UniversalPrinter<T>::Print(value_, os);
}
// Performs the given mock function's default action and returns the
// result in a ActionResultHolder.
template <typename Function, typename Arguments>
static ActionResultHolder PerformDefaultAction(
const FunctionMockerBase<Function>* func_mocker,
const Arguments& args,
const string& call_description) {
return ActionResultHolder(
func_mocker->PerformDefaultAction(args, call_description));
}
// Performs the given action and returns the result in a
// ActionResultHolder.
template <typename Function, typename Arguments>
static ActionResultHolder PerformAction(const Action<Function>& action,
const Arguments& args) {
return ActionResultHolder(action.Perform(args));
}
private:
T value_;
};
// Specialization for T = void.
template <>
class ActionResultHolder<void> {
public:
ActionResultHolder() {}
void value() const {}
void PrintAsActionResult(::std::ostream* /* os */) const {}
template <typename Function, typename Arguments>
static ActionResultHolder PerformDefaultAction(
const FunctionMockerBase<Function>* func_mocker,
const Arguments& args,
const string& call_description) {
func_mocker->PerformDefaultAction(args, call_description);
return ActionResultHolder();
}
template <typename Function, typename Arguments>
static ActionResultHolder PerformAction(const Action<Function>& action,
const Arguments& args) {
action.Perform(args);
return ActionResultHolder();
}
};
// The base of the function mocker class for the given function type.
// We put the methods in this class instead of its child to avoid code
// bloat.
@@ -1167,16 +1229,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
template <typename Function>
friend class MockSpec;
template <typename R, typename Function>
friend class InvokeWithHelper;
// Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple
// threads concurrently.
// L < g_gmock_mutex
Result InvokeWith(const ArgumentTuple& args) {
return InvokeWithHelper<Result, F>::InvokeAndPrintResult(this, args);
}
Result InvokeWith(const ArgumentTuple& args);
// Adds and returns a default action spec for this mock function.
// L < g_gmock_mutex
@@ -1417,170 +1474,109 @@ bool FunctionMockerBase<F>::VerifyAndClearExpectationsLocked() {
// manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const string& msg);
// When an uninteresting or unexpected mock function is called, we
// want to print its return value to assist the user debugging. Since
// there's nothing to print when the function returns void, we need to
// specialize the logic of FunctionMockerBase<F>::InvokeWith() for
// void return values.
//
// C++ doesn't allow us to specialize a member function template
// unless we also specialize its enclosing class, so we had to let
// InvokeWith() delegate its work to a helper class InvokeWithHelper,
// which can then be specialized.
//
// Note that InvokeWithHelper must be a class template (as opposed to
// a function template), as only class templates can be partially
// specialized.
template <typename Result, typename F>
class InvokeWithHelper {
public:
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
// Calculates the result of invoking the function mocked by mocker
// with the given arguments, prints it, and returns it.
// L < g_gmock_mutex
static Result InvokeAndPrintResult(
FunctionMockerBase<F>* mocker,
const ArgumentTuple& args) {
if (mocker->expectations_.size() == 0) {
// No expectation is set on this mock method - we have an
// uninteresting call.
// Warns about the uninteresting call.
::std::stringstream ss;
mocker->DescribeUninterestingCall(args, &ss);
// We must get Google Mock's reaction on uninteresting calls
// made on this mock object BEFORE performing the action,
// because the action may DELETE the mock object and make the
// following expression meaningless.
const CallReaction reaction =
Mock::GetReactionOnUninterestingCalls(mocker->MockObject());
// Calculates the function result.
Result result = mocker->PerformDefaultAction(args, ss.str());
// Prints the function result.
ss << "\n Returns: ";
UniversalPrinter<Result>::Print(result, &ss);
ReportUninterestingCall(reaction, ss.str());
return result;
}
bool is_excessive = false;
::std::stringstream ss;
::std::stringstream why;
::std::stringstream loc;
Action<F> action;
Expectation<F>* exp;
// The FindMatchingExpectationAndAction() function acquires and
// releases g_gmock_mutex.
const bool found = mocker->FindMatchingExpectationAndAction(
args, &exp, &action, &is_excessive, &ss, &why);
ss << " Function call: " << mocker->Name();
UniversalPrinter<ArgumentTuple>::Print(args, &ss);
// In case the action deletes a piece of the expectation, we
// generate the message beforehand.
if (found && !is_excessive) {
exp->DescribeLocationTo(&loc);
}
Result result = action.IsDoDefault() ?
mocker->PerformDefaultAction(args, ss.str())
: action.Perform(args);
ss << "\n Returns: ";
UniversalPrinter<Result>::Print(result, &ss);
ss << "\n" << why.str();
if (found) {
if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, exp->file(), exp->line(), ss.str());
} else {
// We had an expected call and the matching expectation is
// described in ss.
Log(INFO, loc.str() + ss.str(), 3);
}
} else {
// No expectation matches this call - reports a failure.
Expect(false, NULL, -1, ss.str());
}
return result;
}
}; // class InvokeWithHelper
// This specialization helps to implement
// FunctionMockerBase<F>::InvokeWith() for void-returning functions.
// Calculates the result of invoking this mock function with the given
// arguments, prints it, and returns it.
// L < g_gmock_mutex
template <typename F>
class InvokeWithHelper<void, F> {
public:
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typename Function<F>::Result FunctionMockerBase<F>::InvokeWith(
const typename Function<F>::ArgumentTuple& args) {
typedef ActionResultHolder<Result> ResultHolder;
// Invokes the function mocked by mocker with the given arguments.
// L < g_gmock_mutex
static void InvokeAndPrintResult(FunctionMockerBase<F>* mocker,
const ArgumentTuple& args) {
const int count = static_cast<int>(mocker->expectations_.size());
if (count == 0) {
// No expectation is set on this mock method - we have an
// uninteresting call.
::std::stringstream ss;
mocker->DescribeUninterestingCall(args, &ss);
if (expectations_.size() == 0) {
// No expectation is set on this mock method - we have an
// uninteresting call.
// We must get Google Mock's reaction on uninteresting calls
// made on this mock object BEFORE performing the action,
// because the action may DELETE the mock object and make the
// following expression meaningless.
const CallReaction reaction =
Mock::GetReactionOnUninterestingCalls(mocker->MockObject());
// We must get Google Mock's reaction on uninteresting calls
// made on this mock object BEFORE performing the action,
// because the action may DELETE the mock object and make the
// following expression meaningless.
const CallReaction reaction =
Mock::GetReactionOnUninterestingCalls(MockObject());
mocker->PerformDefaultAction(args, ss.str());
ReportUninterestingCall(reaction, ss.str());
return;
// True iff we need to print this call's arguments and return
// value. This definition must be kept in sync with
// the behavior of ReportUninterestingCall().
const bool need_to_report_uninteresting_call =
// If the user allows this uninteresting call, we print it
// only when he wants informational messages.
reaction == ALLOW ? LogIsVisible(INFO) :
// If the user wants this to be a warning, we print it only
// when he wants to see warnings.
reaction == WARN ? LogIsVisible(WARNING) :
// Otherwise, the user wants this to be an error, and we
// should always print detailed information in the error.
true;
if (!need_to_report_uninteresting_call) {
// Perform the action without printing the call information.
return PerformDefaultAction(args, "");
}
bool is_excessive = false;
// Warns about the uninteresting call.
::std::stringstream ss;
::std::stringstream why;
::std::stringstream loc;
Action<F> action;
Expectation<F>* exp;
DescribeUninterestingCall(args, &ss);
// The FindMatchingExpectationAndAction() function acquires and
// releases g_gmock_mutex.
const bool found = mocker->FindMatchingExpectationAndAction(
args, &exp, &action, &is_excessive, &ss, &why);
ss << " Function call: " << mocker->Name();
UniversalPrinter<ArgumentTuple>::Print(args, &ss);
ss << "\n" << why.str();
// In case the action deletes a piece of the expectation, we
// generate the message beforehand.
if (found && !is_excessive) {
exp->DescribeLocationTo(&loc);
}
if (action.IsDoDefault()) {
mocker->PerformDefaultAction(args, ss.str());
} else {
action.Perform(args);
}
// Calculates the function result.
const ResultHolder result =
ResultHolder::PerformDefaultAction(this, args, ss.str());
if (found) {
// A matching expectation and corresponding action were found.
if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, exp->file(), exp->line(), ss.str());
} else {
// We had an expected call and the matching expectation is
// described in ss.
Log(INFO, loc.str() + ss.str(), 3);
}
} else {
// No matching expectation was found - reports an error.
Expect(false, NULL, -1, ss.str());
}
// Prints the function result.
result.PrintAsActionResult(&ss);
ReportUninterestingCall(reaction, ss.str());
return result.value();
}
}; // class InvokeWithHelper<void, F>
bool is_excessive = false;
::std::stringstream ss;
::std::stringstream why;
::std::stringstream loc;
Action<F> action;
Expectation<F>* exp;
// The FindMatchingExpectationAndAction() function acquires and
// releases g_gmock_mutex.
const bool found = FindMatchingExpectationAndAction(
args, &exp, &action, &is_excessive, &ss, &why);
// 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()
// and Log() in this function.
const bool need_to_report_call = !found || is_excessive || LogIsVisible(INFO);
if (!need_to_report_call) {
// Perform the action without printing the call information.
return action.IsDoDefault() ? PerformDefaultAction(args, "") :
action.Perform(args);
}
ss << " Function call: " << Name();
UniversalPrinter<ArgumentTuple>::Print(args, &ss);
// In case the action deletes a piece of the expectation, we
// generate the message beforehand.
if (found && !is_excessive) {
exp->DescribeLocationTo(&loc);
}
const ResultHolder result = action.IsDoDefault() ?
ResultHolder::PerformDefaultAction(this, args, ss.str()) :
ResultHolder::PerformAction(action, args);
result.PrintAsActionResult(&ss);
ss << "\n" << why.str();
if (!found) {
// No expectation matches this call - reports a failure.
Expect(false, NULL, -1, ss.str());
} else if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, exp->file(), exp->line(), ss.str());
} else {
// We had an expected call and the matching expectation is
// described in ss.
Log(INFO, loc.str() + ss.str(), 2);
}
return result.value();
}
} // namespace internal
+4 -4
Ver Arquivo
@@ -39,14 +39,14 @@
// This file implements the following syntax:
//
// ON_CALL(mock_object.Method(...))
// .WithArguments(...) ?
// .With(...) ?
// .WillByDefault(...);
//
// where WithArguments() is optional and WillByDefault() must appear
// exactly once.
// where With() is optional and WillByDefault() must appear exactly
// once.
//
// EXPECT_CALL(mock_object.Method(...))
// .WithArguments(...) ?
// .With(...) ?
// .Times(...) ?
// .InSequence(...) *
// .WillOnce(...) *
@@ -99,6 +99,17 @@ struct RemoveConst { typedef T type; }; // NOLINT
template <typename T>
struct RemoveConst<const T> { typedef T type; }; // NOLINT
// MSVC 8.0 has a bug which causes the above definition to fail to
// remove the const in 'const int[3]'. The following specialization
// works around the bug. However, it causes trouble with gcc and thus
// needs to be conditionally compiled.
#ifdef _MSC_VER
template <typename T, size_t N>
struct RemoveConst<T[N]> {
typedef typename RemoveConst<T>::type type[N];
};
#endif // _MSC_VER
// A handy wrapper around RemoveConst that works when the argument
// T depends on template parameters.
#define GMOCK_REMOVE_CONST_(T) \
@@ -438,6 +449,10 @@ const char kWarningVerbosity[] = "warning";
// No logs are printed.
const char kErrorVerbosity[] = "error";
// Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag.
bool LogIsVisible(LogSeverity severity);
// Prints the given message to stdout iff 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
@@ -447,10 +462,6 @@ const char kErrorVerbosity[] = "error";
// conservative.
void Log(LogSeverity severity, const string& message, int stack_frames_to_skip);
// The universal value printer (public/gmock-printers.h) needs this
// to declare an unused << operator in the global namespace.
struct Unused {};
// TODO(wan@google.com): group all type utilities together.
// Type traits.
@@ -478,6 +489,238 @@ inline T Invalid() {
template <>
inline void Invalid<void>() {}
// Utilities for native arrays.
// ArrayEq() compares two k-dimensional native arrays using the
// elements' operator==, where k can be any integer >= 0. When k is
// 0, ArrayEq() degenerates into comparing a single pair of values.
template <typename T, typename U>
bool ArrayEq(const T* lhs, size_t size, const U* rhs);
// This generic version is used when k is 0.
template <typename T, typename U>
inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; }
// This overload is used when k >= 1.
template <typename T, typename U, size_t N>
inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) {
return internal::ArrayEq(lhs, N, rhs);
}
// This helper reduces code bloat. If we instead put its logic inside
// the previous ArrayEq() function, arrays with different sizes would
// lead to different copies of the template code.
template <typename T, typename U>
bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
for (size_t i = 0; i != size; i++) {
if (!internal::ArrayEq(lhs[i], rhs[i]))
return false;
}
return true;
}
// Finds the first element in the iterator range [begin, end) that
// equals elem. Element may be a native array type itself.
template <typename Iter, typename Element>
Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {
for (Iter it = begin; it != end; ++it) {
if (internal::ArrayEq(*it, elem))
return it;
}
return end;
}
// CopyArray() copies a k-dimensional native array using the elements'
// operator=, where k can be any integer >= 0. When k is 0,
// CopyArray() degenerates into copying a single value.
template <typename T, typename U>
void CopyArray(const T* from, size_t size, U* to);
// This generic version is used when k is 0.
template <typename T, typename U>
inline void CopyArray(const T& from, U* to) { *to = from; }
// This overload is used when k >= 1.
template <typename T, typename U, size_t N>
inline void CopyArray(const T(&from)[N], U(*to)[N]) {
internal::CopyArray(from, N, *to);
}
// This helper reduces code bloat. If we instead put its logic inside
// the previous CopyArray() function, arrays with different sizes
// would lead to different copies of the template code.
template <typename T, typename U>
void CopyArray(const T* from, size_t size, U* to) {
for (size_t i = 0; i != size; i++) {
internal::CopyArray(from[i], to + i);
}
}
// The relation between an NativeArray object (see below) and the
// native array it represents.
enum RelationToSource {
kReference, // The NativeArray references the native array.
kCopy // The NativeArray makes a copy of the native array and
// owns the copy.
};
// Adapts a native array to a read-only STL-style container. Instead
// of the complete STL container concept, this adaptor only implements
// members useful for Google Mock's container matchers. New members
// should be added as needed. To simplify the implementation, we only
// support Element being a raw type (i.e. having no top-level const or
// reference modifier). It's the client's responsibility to satisfy
// this requirement. Element can be an array type itself (hence
// multi-dimensional arrays are supported).
template <typename Element>
class NativeArray {
public:
// STL-style container typedefs.
typedef Element value_type;
typedef const Element* const_iterator;
// Constructs from a native array passed by reference.
template <size_t N>
NativeArray(const Element (&array)[N], RelationToSource relation) {
Init(array, N, relation);
}
// Constructs from a native array passed by a pointer and a size.
// For generality we don't artificially restrict the types of the
// pointer and the size.
template <typename Pointer, typename Size>
NativeArray(const ::std::tr1::tuple<Pointer, Size>& array,
RelationToSource relation) {
Init(internal::GetRawPointer(::std::tr1::get<0>(array)),
::std::tr1::get<1>(array),
relation);
}
// Copy constructor.
NativeArray(const NativeArray& rhs) {
Init(rhs.array_, rhs.size_, rhs.relation_to_source_);
}
~NativeArray() {
// Ensures that the user doesn't instantiate NativeArray with a
// const or reference type.
testing::StaticAssertTypeEq<Element,
GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(Element))>();
if (relation_to_source_ == kCopy)
delete[] array_;
}
// STL-style container methods.
size_t size() const { return size_; }
const_iterator begin() const { return array_; }
const_iterator end() const { return array_ + size_; }
bool operator==(const NativeArray& rhs) const {
return size() == rhs.size() &&
ArrayEq(begin(), size(), rhs.begin());
}
private:
// Not implemented as we don't want to support assignment.
void operator=(const NativeArray& rhs);
// Initializes this object; makes a copy of the input array if
// 'relation' is kCopy.
void Init(const Element* array, size_t size, RelationToSource relation) {
if (relation == kReference) {
array_ = array;
} else {
Element* const copy = new Element[size];
CopyArray(array, size, copy);
array_ = copy;
}
size_ = size;
relation_to_source_ = relation;
}
const Element* array_;
size_t size_;
RelationToSource relation_to_source_;
};
// Given a raw type (i.e. having no top-level reference or const
// modifier) RawContainer that's either an STL-style container or a
// native array, class StlContainerView<RawContainer> has the
// following members:
//
// - type is a type that provides an STL-style container view to
// (i.e. implements the STL container concept for) RawContainer;
// - const_reference is a type that provides a reference to a const
// RawContainer;
// - ConstReference(raw_container) returns a const reference to an STL-style
// container view to raw_container, which is a RawContainer.
// - Copy(raw_container) returns an STL-style container view of a
// copy of raw_container, which is a RawContainer.
//
// This generic version is used when RawContainer itself is already an
// STL-style container.
template <class RawContainer>
class StlContainerView {
public:
typedef RawContainer type;
typedef const type& const_reference;
static const_reference ConstReference(const RawContainer& container) {
// Ensures that RawContainer is not a const type.
testing::StaticAssertTypeEq<RawContainer,
GMOCK_REMOVE_CONST_(RawContainer)>();
return container;
}
static type Copy(const RawContainer& container) { return container; }
};
// This specialization is used when RawContainer is a native array type.
template <typename Element, size_t N>
class StlContainerView<Element[N]> {
public:
typedef GMOCK_REMOVE_CONST_(Element) RawElement;
typedef internal::NativeArray<RawElement> type;
// NativeArray<T> can represent a native array either by value or by
// reference (selected by a constructor argument), so 'const type'
// can be used to reference a const native array. We cannot
// 'typedef const type& const_reference' here, as that would mean
// ConstReference() has to return a reference to a local variable.
typedef const type const_reference;
static const_reference ConstReference(const Element (&array)[N]) {
// Ensures that Element is not a const type.
testing::StaticAssertTypeEq<Element, RawElement>();
return type(array, kReference);
}
static type Copy(const Element (&array)[N]) {
return type(array, kCopy);
}
};
// This specialization is used when RawContainer is a native array
// represented as a (pointer, size) tuple.
template <typename ElementPointer, typename Size>
class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
public:
typedef GMOCK_REMOVE_CONST_(
typename internal::PointeeOf<ElementPointer>::type) RawElement;
typedef internal::NativeArray<RawElement> type;
typedef const type const_reference;
static const_reference ConstReference(
const ::std::tr1::tuple<ElementPointer, Size>& array) {
return type(array, kReference);
}
static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) {
return type(array, kCopy);
}
};
// The following specialization prevents the user from instantiating
// StlContainer with a reference type.
template <typename T> class StlContainerView<T&>;
} // namespace internal
} // namespace testing
@@ -47,23 +47,8 @@
// To avoid conditional compilation everywhere, we make it
// gmock-port.h's responsibility to #include the header implementing
// tr1/tuple.
#if defined(__GNUC__) && GTEST_GCC_VER_ >= 40000
// GTEST_GCC_VER_ is defined in gtest-port.h and 40000 corresponds to
// version 4.0.0.
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
// not conform to the TR1 spec, which requires the header to be <tuple>.
#include <tr1/tuple>
#elif defined(_MSC_VER) && _MSC_VER < 1500
// For Visual Studio older than 2008, we redirect directly to boost tuple
// searching from boost's root. This is to avoid extra dirtying of the
// compiler include paths.
#include "boost/tr1/tr1/tuple"
#else
// If the compiler is neither GCC 4.0+, nor Visual Studio 2008, we assume the
// user is using a spec-conforming TR1 implementation.
#include <tuple>
#endif // __GNUC__
// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
// guaranteed to pull in the tuple header.
#if GTEST_OS_LINUX
@@ -1,326 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vadimb@google.com (Vadim Berman)
//
// Low-level types and utilities for porting Google Mock to various
// platforms. They are subject to change without notice. DO NOT USE
// THEM IN USER CODE.
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#include <assert.h>
#include <stdlib.h>
#include <iostream>
// Most of the types needed for porting Google Mock are also required
// for Google Test and are defined in gtest-port.h.
#include <gtest/internal/gtest-linked_ptr.h>
#include <gtest/internal/gtest-port.h>
// To avoid conditional compilation everywhere, we make it
// gmock-port.h's responsibility to #include the header implementing
// tr1/tuple.
#if defined(__GNUC__) && GTEST_GCC_VER_ >= 40000
// GTEST_GCC_VER_ is defined in gtest-port.h and 40000 corresponds to
// version 4.0.0.
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
// not conform to the TR1 spec, which requires the header to be <tuple>.
#include <tr1/tuple>
#elif defined(_MSC_VER) && _MSC_VER < 1500
// For Visual Studio older than 2008, we redirect directly to boost tuple
// searching from boost's root. This is to avoid extra dirtying of the
// compiler include paths.
#include "boost/tr1/tr1/tuple"
#else
// If the compiler is not GCC 4.0+, or Visual Studio 2008, we assume the
// user is using a spec-conforming TR1 implementation.
#include <tuple>
#endif // __GNUC__
#if GTEST_OS_LINUX
// On some platforms, <regex.h> needs someone to define size_t, and
// won't compile otherwise. We can #include it here as we already
// included <stdlib.h>, which is guaranteed to define size_t through
// <stddef.h>.
#include <regex.h> // NOLINT
// Defines this iff Google Mock uses the enhanced POSIX regular
// expression syntax. This is public as it affects how a user uses
// regular expression matchers.
#define GMOCK_USES_POSIX_RE 1
#endif // GTEST_OS_LINUX
#if defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
// Defines this iff regular expression matchers are supported. This
// is public as it tells a user whether he can use regular expression
// matchers.
#define GMOCK_HAS_REGEX 1
#endif // defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
namespace testing {
namespace internal {
// For Windows, check the compiler version. At least VS 2005 SP1 is
// required to compile Google Mock.
#if GTEST_OS_WINDOWS
#if _MSC_VER < 1400
#error "At least Visual Studio 2005 SP1 is required to compile Google Mock."
#elif _MSC_VER == 1400
// Unfortunately there is no unique _MSC_VER number for SP1. So for VS 2005
// we have to check if it has SP1 by checking whether a bug fixed in SP1
// is present. The bug in question is
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702
// where the compiler incorrectly reports sizeof(poiter to an array).
class TestForSP1 {
private: // GCC complains if x_ is used by sizeof before defining it.
static char x_[100];
// VS 2005 RTM incorrectly reports sizeof(&x) as 100, and that value
// is used to trigger 'invalid negative array size' error. If you
// see this error, upgrade to VS 2005 SP1 since Google Mock will not
// compile in VS 2005 RTM.
static char Google_Mock_requires_Visual_Studio_2005_SP1_or_later_to_compile_[
sizeof(&x_) != 100 ? 1 : -1];
};
#endif // _MSC_VER
#endif // GTEST_OS_WINDOWS
// Use implicit_cast as a safe version of static_cast or const_cast
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
// a const pointer to Foo).
// When you use implicit_cast, the compiler checks that the cast is safe.
// Such explicit implicit_casts are necessary in surprisingly many
// situations where C++ demands an exact type match instead of an
// argument type convertable to a target type.
//
// The From type can be inferred, so the preferred syntax for using
// implicit_cast is the same as for static_cast etc.:
//
// implicit_cast<ToType>(expr)
//
// implicit_cast would have been part of the C++ standard library,
// but the proposal was submitted too late. It will probably make
// its way into the language in the future.
template<typename To, typename From>
inline To implicit_cast(From const &f) {
return f;
}
// When you upcast (that is, cast a pointer from type Foo to type
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
// always succeed. When you downcast (that is, cast a pointer from
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
// how do you know the pointer is really of type SubclassOfFoo? It
// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
// when you downcast, you should use this macro. In debug mode, we
// use dynamic_cast<> to double-check the downcast is legal (we die
// if it's not). In normal mode, we do the efficient static_cast<>
// instead. Thus, it's important to test in debug mode to make sure
// the cast is legal!
// This is the only place in the code we should use dynamic_cast<>.
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
// do RTTI (eg code like this:
// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
// You should design the code some other way not to need this.
template<typename To, typename From> // use like this: down_cast<T*>(foo);
inline To down_cast(From* f) { // so we only accept pointers
// Ensures that To is a sub-type of From *. This test is here only
// for compile-time type checking, and has no overhead in an
// optimized build at run-time, as it will be optimized away
// completely.
if (false) {
implicit_cast<From*, To>(0);
}
#if GTEST_HAS_RTTI
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
#endif
return static_cast<To>(f);
}
// The GMOCK_COMPILE_ASSERT_ macro can be used to verify that a compile time
// expression is true. For example, you could use it to verify the
// size of a static array:
//
// GMOCK_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
// content_type_names_incorrect_size);
//
// or to make sure a struct is smaller than a certain size:
//
// GMOCK_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);
//
// The second argument to the macro is the name of the variable. If
// the expression is false, most compilers will issue a warning/error
// containing the name of the variable.
template <bool>
struct CompileAssert {
};
#define GMOCK_COMPILE_ASSERT_(expr, msg) \
typedef ::testing::internal::CompileAssert<(bool(expr))> \
msg[bool(expr) ? 1 : -1]
// Implementation details of GMOCK_COMPILE_ASSERT_:
//
// - GMOCK_COMPILE_ASSERT_ works by defining an array type that has -1
// elements (and thus is invalid) when the expression is false.
//
// - The simpler definition
//
// #define GMOCK_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]
//
// does not work, as gcc supports variable-length arrays whose sizes
// are determined at run-time (this is gcc's extension and not part
// of the C++ standard). As a result, gcc fails to reject the
// following code with the simple definition:
//
// int foo;
// GMOCK_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is
// // not a compile-time constant.
//
// - By using the type CompileAssert<(bool(expr))>, we ensures that
// expr is a compile-time constant. (Template arguments must be
// determined at compile-time.)
//
// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
//
// CompileAssert<bool(expr)>
//
// instead, these compilers will refuse to compile
//
// GMOCK_COMPILE_ASSERT_(5 > 0, some_message);
//
// (They seem to think the ">" in "5 > 0" marks the end of the
// template argument list.)
//
// - The array size is (bool(expr) ? 1 : -1), instead of simply
//
// ((expr) ? 1 : -1).
//
// This is to avoid running into a bug in MS VC 7.1, which
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
#if GTEST_HAS_GLOBAL_STRING
typedef ::string string;
#elif GTEST_HAS_STD_STRING
typedef ::std::string string;
#else
#error "Google Mock requires ::std::string to compile."
#endif // GTEST_HAS_GLOBAL_STRING
#if GTEST_HAS_GLOBAL_WSTRING
typedef ::wstring wstring;
#elif GTEST_HAS_STD_WSTRING
typedef ::std::wstring wstring;
#endif // GTEST_HAS_GLOBAL_WSTRING
// Prints the file location in the format native to the compiler.
inline void FormatFileLocation(const char* file, int line, ::std::ostream* os) {
if (file == NULL)
file = "unknown file";
if (line < 0) {
*os << file << ":";
} else {
#if _MSC_VER
*os << file << "(" << line << "):";
#else
*os << file << ":" << line << ":";
#endif
}
}
// INTERNAL IMPLEMENTATION - DO NOT USE.
//
// GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
// is not satisfied.
// Synopsys:
// GMOCK_CHECK_(boolean_condition);
// or
// GMOCK_CHECK_(boolean_condition) << "Additional message";
//
// This checks the condition and if the condition is not satisfied
// it prints message about the condition violation, including the
// condition itself, plus additional message streamed into it, if any,
// and then it aborts the program. It aborts the program irrespective of
// whether it is built in the debug mode or not.
class GMockCheckProvider {
public:
GMockCheckProvider(const char* condition, const char* file, int line) {
FormatFileLocation(file, line, &::std::cerr);
::std::cerr << " ERROR: Condition " << condition << " failed. ";
}
~GMockCheckProvider() {
::std::cerr << ::std::endl;
abort();
}
::std::ostream& GetStream() { return ::std::cerr; }
};
#define GMOCK_CHECK_(condition) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (condition) \
; \
else \
::testing::internal::GMockCheckProvider(\
#condition, __FILE__, __LINE__).GetStream()
} // namespace internal
} // namespace testing
// Macro for referencing flags. This is public as we want the user to
// use this syntax to reference Google Mock flags.
#define GMOCK_FLAG(name) FLAGS_gmock_##name
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) extern bool GMOCK_FLAG(name)
#define GMOCK_DECLARE_int32_(name) \
extern ::testing::internal::Int32 GMOCK_FLAG(name)
#define GMOCK_DECLARE_string_(name) \
extern ::testing::internal::String GMOCK_FLAG(name)
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
bool GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_string_(name, default_val, doc) \
::testing::internal::String GMOCK_FLAG(name) = (default_val)
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
+1 -6
Ver Arquivo
@@ -6,15 +6,10 @@
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(BoostDir)/boost/tr1/tr1&quot;;&quot;$(BoostDir)&quot;;&quot;$(GTestDir)/include&quot;"
PreprocessorDefinitions="GTEST_HAS_TR1_TUPLE=1"
AdditionalIncludeDirectories="&quot;$(GTestDir)/include&quot;"
/>
<UserMacro
Name="GTestDir"
Value="../gtest"
/>
<UserMacro
Name="BoostDir"
Value="../boost"
/>
</VisualStudioPropertySheet>
+1 -1
Ver Arquivo
@@ -23,7 +23,7 @@ the environment. For example to use an indent of 4 spaces:
INDENT=4 gmock_gen.py header-file.h ClassName
This version was made from SVN revision 279 in the cppclean repository.
This version was made from SVN revision 281 in the cppclean repository.
Known Limitations
-----------------
+9 -5
Ver Arquivo
@@ -782,7 +782,7 @@ class AstBuilder(object):
parts = self.converter.DeclarationToParts(temp_tokens, True)
(name, type_name, templated_types, modifiers, default,
unused_other_tokens) = parts
t0 = temp_tokens[0]
names = [t.name for t in temp_tokens]
if templated_types:
@@ -1551,18 +1551,22 @@ class AstBuilder(object):
token = self._GetNextToken()
self.namespace_stack.append(name)
assert token.token_type == tokenize.SYNTAX, token
# Create an internal token that denotes when the namespace is complete.
internal_token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP,
None, None)
internal_token.whence = token.whence
if token.name == '=':
# TODO(nnorwitz): handle aliasing namespaces.
name, next_token = self.GetName()
assert next_token.name == ';', next_token
self._AddBackToken(internal_token)
else:
assert token.name == '{', token
tokens = list(self.GetScope())
del tokens[-1] # Remove trailing '}'.
# Replace the trailing } with the internal namespace pop token.
tokens[-1] = internal_token
# Handle namespace with nothing in it.
self._AddBackTokens(tokens)
token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP, None, None)
self._AddBackToken(token)
return None
def handle_using(self):
@@ -1672,7 +1676,7 @@ def PrintIndentifiers(filename, should_print):
if should_print(node):
print(node.name)
except KeyboardInterrupt:
return
return
except:
pass
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# Copyright 2008 Google Inc.
# Copyright 2008 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -73,7 +73,13 @@ def _GenerateMethods(output_lines, source, class_node):
# of the first parameter to the end of the last parameter.
start = node.parameters[0].start
end = node.parameters[-1].end
args = re.sub(' +', ' ', source[start:end].replace('\n', ''))
# 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 prototype.
indent = ' ' * _INDENT
@@ -120,8 +126,6 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
lines.append('} // namespace %s' % class_node.namespace[i])
lines.append('') # Add an extra newline.
sys.stdout.write('\n'.join(lines))
if desired_class_names:
missing_class_name_list = list(desired_class_names - processed_class_names)
if missing_class_name_list:
@@ -129,7 +133,9 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names):
sys.stderr.write('Class(es) not found in %s: %s\n' %
(filename, ', '.join(missing_class_name_list)))
elif not processed_class_names:
sys.stderr.write('No class found in %s\n' % filename)
sys.stderr.write('No class found in %s\n' % filename)
return lines
def main(argv=sys.argv):
@@ -164,7 +170,8 @@ def main(argv=sys.argv):
# An error message was already printed since we couldn't parse.
pass
else:
_GenerateMocks(filename, source, entire_ast, desired_class_names)
lines = _GenerateMocks(filename, source, entire_ast, desired_class_names)
sys.stdout.write('\n'.join(lines))
if __name__ == '__main__':
+137
Ver Arquivo
@@ -0,0 +1,137 @@
#!/usr/bin/env python
#
# Copyright 2009 Neal Norwitz All Rights Reserved.
# Portions Copyright 2009 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for gmock.scripts.generator.cpp.gmock_class."""
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
import os
import sys
import unittest
# Allow the cpp imports below to work when run as a standalone script.
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from cpp import ast
from cpp import gmock_class
class TestCase(unittest.TestCase):
"""Helper class that adds assert methods."""
def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines):
"""Specialized assert that ignores the indent level."""
stripped_lines = '\n'.join([s.lstrip() for s in lines.split('\n')])
self.assertEqual(expected_lines, stripped_lines)
class GenerateMethodsTest(TestCase):
def GenerateMethodSource(self, cpp_source):
"""Helper method to convert C++ source to gMock output source lines."""
method_source_lines = []
# <test> is a pseudo-filename, it is not read or written.
builder = ast.BuilderFromSource(cpp_source, '<test>')
ast_list = list(builder.Generate())
gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0])
return ''.join(method_source_lines)
def testStrangeNewlineInParameter(self):
source = """
class Foo {
public:
virtual void Bar(int
a) = 0;
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD1(Bar,\nvoid(int a));',
self.GenerateMethodSource(source))
def testDoubleSlashCommentsInParameterListAreRemoved(self):
source = """
class Foo {
public:
virtual void Bar(int a, // inline comments should be elided.
int b // inline comments should be elided.
) const = 0;
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_CONST_METHOD2(Bar,\nvoid(int a, int b));',
self.GenerateMethodSource(source))
def testCStyleCommentsInParameterListAreNotRemoved(self):
# NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these
# comments. Also note that C style comments after the last parameter
# are still elided.
source = """
class Foo {
public:
virtual const string& Bar(int /* keeper */, int b);
};
"""
self.assertEqualIgnoreLeadingWhitespace(
'MOCK_METHOD2(Bar,\nconst string&(int /* keeper */, int b));',
self.GenerateMethodSource(source))
class GenerateMocksTest(TestCase):
def GenerateMocks(self, cpp_source):
"""Helper method to convert C++ source to complete gMock output source."""
# <test> is a pseudo-filename, it is not read or written.
filename = '<test>'
builder = ast.BuilderFromSource(cpp_source, filename)
ast_list = list(builder.Generate())
lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None)
return '\n'.join(lines)
def testNamespaces(self):
source = """
namespace Foo {
namespace Bar { class Forward; }
namespace Baz {
class Test {
public:
virtual void Foo();
};
} // namespace Baz
} // namespace Foo
"""
expected = """\
namespace Foo {
namespace Baz {
class MockTest : public Test {
public:
MOCK_METHOD0(Foo,
void());
};
} // namespace Baz
} // namespace Foo
"""
self.assertEqualIgnoreLeadingWhitespace(
expected, self.GenerateMocks(source))
if __name__ == '__main__':
unittest.main()
+1 -1
Ver Arquivo
@@ -259,7 +259,7 @@ fi
# Add the necessary Google Test bits into the various flag variables
gmock_cppflags="${gmock_cppflags} `${gtest_config} --cppflags`"
gmock_cxxflags="${gmock_cxxflags} `${gtest_config} --cxxflags`"
gmock_ldflags="${gmock_ldflags}`${gtest_config} --ldflags`"
gmock_ldflags="${gmock_ldflags} `${gtest_config} --ldflags`"
gmock_libs="${gmock_libs} `${gtest_config} --libs`"
# Do an installation query if requested.
+124 -32
Ver Arquivo
@@ -36,7 +36,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import re
import sys
_VERSION = '1.0.0'
_VERSION = '1.0.3'
_COMMON_GMOCK_SYMBOLS = [
# Matchers
@@ -46,8 +46,12 @@ _COMMON_GMOCK_SYMBOLS = [
'AllOf',
'An',
'AnyOf',
'ContainerEq',
'Contains',
'ContainsRegex',
'DoubleEq',
'ElementsAre',
'ElementsAreArray',
'EndsWith',
'Eq',
'Field',
@@ -59,7 +63,10 @@ _COMMON_GMOCK_SYMBOLS = [
'Le',
'Lt',
'MatcherCast',
'Matches',
'MatchesRegex',
'NanSensitiveDoubleEq',
'NanSensitiveFloatEq',
'Ne',
'Not',
'NotNull',
@@ -67,6 +74,8 @@ _COMMON_GMOCK_SYMBOLS = [
'PointeeIsInitializedProto',
'Property',
'Ref',
'ResultOf',
'SafeMatcherCast',
'StartsWith',
'StrCaseEq',
'StrCaseNe',
@@ -74,9 +83,12 @@ _COMMON_GMOCK_SYMBOLS = [
'StrNe',
'Truly',
'TypedEq',
'Value',
# Actions
'Assign',
'ByRef',
'DeleteArg',
'DoAll',
'DoDefault',
'IgnoreResult',
@@ -84,11 +96,18 @@ _COMMON_GMOCK_SYMBOLS = [
'InvokeArgument',
'InvokeWithoutArgs',
'Return',
'ReturnNew',
'ReturnNull',
'ReturnRef',
'SaveArg',
'SetArgReferee',
'SetArgumentPointee',
'SetArrayArgument',
'SetErrnoAndReturn',
'Throw',
'WithArg',
'WithArgs',
'WithoutArgs',
# Cardinalities
'AnyNumber',
@@ -106,6 +125,9 @@ _COMMON_GMOCK_SYMBOLS = [
'Mock',
]
# Regex for matching source file path and line number in gcc's errors.
_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):\s+'
def _FindAllMatches(regex, s):
"""Generates all matches of regex in string s."""
@@ -128,6 +150,7 @@ def _GenericDiagnoser(short_name, long_name, regex, diagnosis, msg):
(short name of disease, long name of disease, diagnosis).
"""
diagnosis = '%(file)s:%(line)s:' + diagnosis
for m in _FindAllMatches(regex, msg):
yield (short_name, long_name, diagnosis % m.groupdict())
@@ -136,9 +159,9 @@ def _NeedToReturnReferenceDiagnoser(msg):
"""Diagnoses the NRR disease, given the error messages by gcc."""
regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
+ _FILE_LINE_RE + r'instantiated from here\n'
r'.*gmock-actions\.h.*error: creating array with negative size')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
You are using an Return() action in a function that returns a reference.
Please use ReturnRef() instead."""
return _GenericDiagnoser('NRR', 'Need to Return Reference',
@@ -148,11 +171,11 @@ Please use ReturnRef() instead."""
def _NeedToReturnSomethingDiagnoser(msg):
"""Diagnoses the NRS disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+):\s+'
regex = (_FILE_LINE_RE +
r'(instantiated from here\n.'
r'*gmock-actions\.h.*error: void value not ignored)'
r'*gmock.*actions\.h.*error: void value not ignored)'
r'|(error: control reaches end of non-void function)')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
You are using an action that returns void, but it needs to return
*something*. Please tell it *what* to return. Perhaps you can use
the pattern DoAll(some_action, Return(some_value))?"""
@@ -163,10 +186,10 @@ the pattern DoAll(some_action, Return(some_value))?"""
def _NeedToReturnNothingDiagnoser(msg):
"""Diagnoses the NRN disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
regex = (_FILE_LINE_RE + r'instantiated from here\n'
r'.*gmock-actions\.h.*error: return-statement with a value, '
r'in function returning \'void\'')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
You are using an action that returns *something*, but it needs to return
void. Please use a void-returning action instead.
@@ -179,10 +202,10 @@ to re-arrange the order of actions in a DoAll(), if you are using one?"""
def _IncompleteByReferenceArgumentDiagnoser(msg):
"""Diagnoses the IBRA disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
regex = (_FILE_LINE_RE + r'instantiated from here\n'
r'.*gmock-printers\.h.*error: invalid application of '
r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
In order to mock this function, Google Mock needs to see the definition
of type "%(type)s" - declaration alone is not enough. Either #include
the header that defines it, or change the argument to be passed
@@ -194,9 +217,9 @@ by pointer."""
def _OverloadedFunctionMatcherDiagnoser(msg):
"""Diagnoses the OFM disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+): error: no matching function for '
regex = (_FILE_LINE_RE + r'error: no matching function for '
r'call to \'Truly\(<unresolved overloaded function type>\)')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
The argument you gave to Truly() is an overloaded function. Please tell
gcc which overloaded version you want to use.
@@ -211,10 +234,9 @@ you should write
def _OverloadedFunctionActionDiagnoser(msg):
"""Diagnoses the OFA disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+): error: '
r'no matching function for call to \'Invoke\('
regex = (_FILE_LINE_RE + r'error: no matching function for call to \'Invoke\('
r'<unresolved overloaded function type>')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
You are passing an overloaded function to Invoke(). Please tell gcc
which overloaded version you want to use.
@@ -229,10 +251,10 @@ you should write something like
def _OverloadedMethodActionDiagnoser1(msg):
"""Diagnoses the OMA disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+): error: '
regex = (_FILE_LINE_RE + r'error: '
r'.*no matching function for call to \'Invoke\(.*, '
r'unresolved overloaded function type>')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
The second argument you gave to Invoke() is an overloaded method. Please
tell gcc which overloaded version you want to use.
@@ -250,10 +272,10 @@ you should write something like
def _MockObjectPointerDiagnoser(msg):
"""Diagnoses the MOP disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+): error: request for member '
regex = (_FILE_LINE_RE + r'error: request for member '
r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*,
not a *pointer* to it. Please write '*(%(mock_object)s)' instead of
'%(mock_object)s' as your first argument.
@@ -279,9 +301,9 @@ you should use the EXPECT_CALL like this:
def _OverloadedMethodActionDiagnoser2(msg):
"""Diagnoses the OMA disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+): error: no matching function for '
regex = (_FILE_LINE_RE + r'error: no matching function for '
r'call to \'Invoke\(.+, <unresolved overloaded function type>\)')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
The second argument you gave to Invoke() is an overloaded method. Please
tell gcc which overloaded version you want to use.
@@ -299,9 +321,9 @@ you should write something like
def _NeedToUseSymbolDiagnoser(msg):
"""Diagnoses the NUS disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+): error: \'(?P<symbol>.+)\' '
regex = (_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' '
r'(was not declared in this scope|has not been declared)')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
'%(symbol)s' is defined by Google Mock in the testing namespace.
Did you forget to write
using testing::%(symbol)s;
@@ -315,11 +337,10 @@ Did you forget to write
def _NeedToUseReturnNullDiagnoser(msg):
"""Diagnoses the NRNULL disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
regex = (_FILE_LINE_RE + r'instantiated from here\n'
r'.*gmock-actions\.h.*error: invalid conversion from '
r'\'long int\' to \'(?P<type>.+\*)')
diagnosis = """%(file)s:%(line)s:
diagnosis = """
You are probably calling Return(NULL) and the compiler isn't sure how to turn
NULL into a %(type)s*. Use ReturnNull() instead.
Note: the line number may be off; please fix all instances of Return(NULL)."""
@@ -327,23 +348,90 @@ Note: the line number may be off; please fix all instances of Return(NULL)."""
regex, diagnosis, msg)
_TTB_DIAGNOSIS = """
In a mock class template, types or typedefs defined in the base class
template are *not* automatically visible. This is how C++ works. Before
you can use a type or typedef named %(type)s defined in base class Base<T>, you
need to make it visible. One way to do it is:
typedef typename Base<T>::%(type)s %(type)s;"""
def _TypeInTemplatedBaseDiagnoser1(msg):
"""Diagnoses the TTB disease, given the error messages by gcc.
This version works when the type is used as the mock function's return
type.
"""
regex = (r'In member function \'int .*\n' + _FILE_LINE_RE +
r'error: a function call cannot appear in a constant-expression')
diagnosis = _TTB_DIAGNOSIS % {'type': 'Foo'}
return _GenericDiagnoser('TTB', 'Type in Template Base',
regex, diagnosis, msg)
def _TypeInTemplatedBaseDiagnoser2(msg):
"""Diagnoses the TTB disease, given the error messages by gcc.
This version works when the type is used as the mock function's sole
parameter type.
"""
regex = (r'In member function \'int .*\n'
+ _FILE_LINE_RE +
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
r'.*error: template argument 1 is invalid\n')
return _GenericDiagnoser('TTB', 'Type in Template Base',
regex, _TTB_DIAGNOSIS, msg)
def _TypeInTemplatedBaseDiagnoser3(msg):
"""Diagnoses the TTB disease, given the error messages by gcc.
This version works when the type is used as a parameter of a mock
function that has multiple parameters.
"""
regex = (r'error: expected `;\' before \'::\' token\n'
+ _FILE_LINE_RE +
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
r'.*error: template argument 1 is invalid\n'
r'.*error: \'.+\' was not declared in this scope')
return _GenericDiagnoser('TTB', 'Type in Template Base',
regex, _TTB_DIAGNOSIS, msg)
def _WrongMockMethodMacroDiagnoser(msg):
"""Diagnoses the WMM disease, given the error messages by gcc."""
regex = (r'(?P<file>.*):(?P<line>\d+):\s+'
regex = (_FILE_LINE_RE +
r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
r'.*\n'
r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>'
)
diagnosis = """%(file)s:%(line)s:
r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>')
diagnosis = """
You are using MOCK_METHOD%(wrong_args)s to define a mock method that has
%(args)s arguments. Use MOCK_METHOD%(args)s (or MOCK_CONST_METHOD%(args)s,
MOCK_METHOD%(args)s_T, MOCK_CONST_METHOD%(args)s_T as appropriate) instead."""
return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn macro',
return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn Macro',
regex, diagnosis, msg)
def _WrongParenPositionDiagnoser(msg):
"""Diagnoses the WPP disease, given the error messages by gcc."""
regex = (_FILE_LINE_RE +
r'error:.*testing::internal::MockSpec<.* has no member named \''
r'(?P<method>\w+)\'')
diagnosis = """
The closing parenthesis of ON_CALL or EXPECT_CALL should be *before*
".%(method)s". For example, you should write:
EXPECT_CALL(my_mock, Foo(_)).%(method)s(...);
instead of:
EXPECT_CALL(my_mock, Foo(_).%(method)s(...));"""
return _GenericDiagnoser('WPP', 'Wrong Parenthesis Position',
regex, diagnosis, msg)
_DIAGNOSERS = [
_IncompleteByReferenceArgumentDiagnoser,
@@ -357,7 +445,11 @@ _DIAGNOSERS = [
_OverloadedFunctionMatcherDiagnoser,
_OverloadedMethodActionDiagnoser1,
_OverloadedMethodActionDiagnoser2,
_TypeInTemplatedBaseDiagnoser1,
_TypeInTemplatedBaseDiagnoser2,
_TypeInTemplatedBaseDiagnoser3,
_WrongMockMethodMacroDiagnoser,
_WrongParenPositionDiagnoser,
]
+27 -17
Ver Arquivo
@@ -101,6 +101,22 @@ FailureReporterInterface* GetFailureReporter() {
// Protects global resources (stdout in particular) used by Log().
static Mutex g_log_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
// Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag.
bool LogIsVisible(LogSeverity severity) {
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
// Always show the log if --gmock_verbose=info.
return true;
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
// Always hide it if --gmock_verbose=error.
return false;
} else {
// If --gmock_verbose is neither "info" nor "error", we treat it
// as "warning" (its default value).
return severity == WARNING;
}
}
// Prints the given message to stdout iff 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
@@ -110,30 +126,24 @@ static Mutex g_log_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
// conservative.
void Log(LogSeverity severity, const string& message,
int stack_frames_to_skip) {
if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
// The user is not interested in logs.
if (!LogIsVisible(severity))
return;
} else if (GMOCK_FLAG(verbose) != kInfoVerbosity) {
// The user is interested in warnings but not informational logs.
// Note that invalid values of GMOCK_FLAG(verbose) are treated as
// "warning", which is the default value of the flag.
if (severity == INFO) {
return;
}
}
// Ensures that logs from different threads don't interleave.
MutexLock l(&g_log_mutex);
using ::std::cout;
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
// macro.
if (severity == WARNING) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
cout << "\nGMOCK WARNING:";
std::cout << "\nGMOCK WARNING:";
}
// Pre-pends a new-line to message if it doesn't start with one.
if (message.empty() || message[0] != '\n') {
cout << "\n";
std::cout << "\n";
}
cout << message;
std::cout << message;
if (stack_frames_to_skip >= 0) {
#ifdef NDEBUG
// In opt mode, we have to be conservative and skip no stack frame.
@@ -146,13 +156,13 @@ void Log(LogSeverity severity, const string& message,
// Appends a new-line to message if it doesn't end with one.
if (!message.empty() && *message.rbegin() != '\n') {
cout << "\n";
std::cout << "\n";
}
cout << "Stack trace:\n"
std::cout << "Stack trace:\n"
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
::testing::UnitTest::GetInstance(), actual_to_skip);
}
cout << ::std::flush;
std::cout << ::std::flush;
}
} // namespace internal
+5
Ver Arquivo
@@ -242,6 +242,11 @@ static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
*os << "\"";
}
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
PrintCharsAsStringTo(begin, len, os);
}
// Prints the given array of wide characters to the ostream.
// The array starts at *begin, the length is len, it may include L'\0'
// characters and may not be null-terminated.
+2 -2
Ver Arquivo
@@ -139,10 +139,10 @@ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
switch (reaction) {
case ALLOW:
Log(INFO, msg, 4);
Log(INFO, msg, 3);
break;
case WARN:
Log(WARNING, msg, 4);
Log(WARNING, msg, 3);
break;
default: // FAIL
Expect(false, NULL, -1, msg);
+65 -31
Ver Arquivo
@@ -269,13 +269,19 @@ TEST(InvokeTest, FunctionThatTakes6Arguments) {
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
}
// A helper that turns the type of a C-string literal from const
// char[N] to const char*.
inline const char* CharPtr(const char* s) { return s; }
// Tests using Invoke() with a 7-argument function.
TEST(InvokeTest, FunctionThatTakes7Arguments) {
Action<string(const char*, const char*, const char*, const char*,
const char*, const char*, const char*)> a =
Invoke(Concat7);
EXPECT_EQ("1234567",
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7")));
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"))));
}
// Tests using Invoke() with a 8-argument function.
@@ -284,7 +290,9 @@ TEST(InvokeTest, FunctionThatTakes8Arguments) {
const char*, const char*, const char*, const char*)> a =
Invoke(Concat8);
EXPECT_EQ("12345678",
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8")));
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"), CharPtr("8"))));
}
// Tests using Invoke() with a 9-argument function.
@@ -293,7 +301,9 @@ TEST(InvokeTest, FunctionThatTakes9Arguments) {
const char*, const char*, const char*, const char*,
const char*)> a = Invoke(Concat9);
EXPECT_EQ("123456789",
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8", "9")));
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"), CharPtr("8"), CharPtr("9"))));
}
// Tests using Invoke() with a 10-argument function.
@@ -301,15 +311,18 @@ TEST(InvokeTest, FunctionThatTakes10Arguments) {
Action<string(const char*, const char*, const char*, const char*,
const char*, const char*, const char*, const char*,
const char*, const char*)> a = Invoke(Concat10);
EXPECT_EQ("1234567890", a.Perform(make_tuple("1", "2", "3", "4", "5", "6",
"7", "8", "9", "0")));
EXPECT_EQ("1234567890",
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"), CharPtr("8"), CharPtr("9"),
CharPtr("0"))));
}
// Tests using Invoke() with functions with parameters declared as Unused.
TEST(InvokeTest, FunctionWithUnusedParameters) {
Action<int(int, int, double, const string&)> a1 =
Invoke(SumOfFirst2);
EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, "hi")));
EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
Action<int(int, int, bool, int*)> a2 =
Invoke(SumOfFirst2);
@@ -321,7 +334,7 @@ TEST(InvokeTest, MethodWithUnusedParameters) {
Foo foo;
Action<int(string, bool, int, int)> a1 =
Invoke(&foo, &Foo::SumOfLast2);
EXPECT_EQ(12, a1.Perform(make_tuple("hi", true, 10, 2)));
EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
Action<int(char, double, int, int)> a2 =
Invoke(&foo, &Foo::SumOfLast2);
@@ -400,7 +413,9 @@ TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
const char*, const char*, const char*)> a =
Invoke(&foo, &Foo::Concat7);
EXPECT_EQ("1234567",
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7")));
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"))));
}
// Tests using Invoke() with a 8-argument method.
@@ -410,7 +425,9 @@ TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
const char*, const char*, const char*, const char*)> a =
Invoke(&foo, &Foo::Concat8);
EXPECT_EQ("12345678",
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8")));
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"), CharPtr("8"))));
}
// Tests using Invoke() with a 9-argument method.
@@ -420,7 +437,9 @@ TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
const char*, const char*, const char*, const char*,
const char*)> a = Invoke(&foo, &Foo::Concat9);
EXPECT_EQ("123456789",
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8", "9")));
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"), CharPtr("8"), CharPtr("9"))));
}
// Tests using Invoke() with a 10-argument method.
@@ -429,8 +448,11 @@ TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
Action<string(const char*, const char*, const char*, const char*,
const char*, const char*, const char*, const char*,
const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
EXPECT_EQ("1234567890", a.Perform(make_tuple("1", "2", "3", "4", "5", "6",
"7", "8", "9", "0")));
EXPECT_EQ("1234567890",
a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
CharPtr("4"), CharPtr("5"), CharPtr("6"),
CharPtr("7"), CharPtr("8"), CharPtr("9"),
CharPtr("0"))));
}
// Tests using Invoke(f) as an action of a compatible type.
@@ -665,7 +687,7 @@ TEST(WithArgsTest, TwoArgs) {
Action<const char*(const char* s, double x, int n)> a =
WithArgs<0, 2>(Invoke(Binary));
const char s[] = "Hello";
EXPECT_EQ(s + 2, a.Perform(make_tuple(s, 0.5, 2)));
EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, 2)));
}
// Tests using WithArgs with an action that takes 3 arguments.
@@ -679,7 +701,8 @@ TEST(WithArgsTest, ThreeArgs) {
TEST(WithArgsTest, FourArgs) {
Action<string(const char*, const char*, double, const char*, const char*)> a =
WithArgs<4, 3, 1, 0>(Invoke(Concat4));
EXPECT_EQ("4310", a.Perform(make_tuple("0", "1", 2.5, "3", "4")));
EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5,
CharPtr("3"), CharPtr("4"))));
}
// Tests using WithArgs with an action that takes 5 arguments.
@@ -687,42 +710,53 @@ TEST(WithArgsTest, FiveArgs) {
Action<string(const char*, const char*, const char*,
const char*, const char*)> a =
WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5));
EXPECT_EQ("43210", a.Perform(make_tuple("0", "1", "2", "3", "4")));
EXPECT_EQ("43210",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"), CharPtr("4"))));
}
// Tests using WithArgs with an action that takes 6 arguments.
TEST(WithArgsTest, SixArgs) {
Action<string(const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6));
EXPECT_EQ("012210", a.Perform(make_tuple("0", "1", "2")));
EXPECT_EQ("012210",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"))));
}
// Tests using WithArgs with an action that takes 7 arguments.
TEST(WithArgsTest, SevenArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7));
EXPECT_EQ("0123210", a.Perform(make_tuple("0", "1", "2", "3")));
EXPECT_EQ("0123210",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that takes 8 arguments.
TEST(WithArgsTest, EightArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8));
EXPECT_EQ("01230123", a.Perform(make_tuple("0", "1", "2", "3")));
EXPECT_EQ("01230123",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that takes 9 arguments.
TEST(WithArgsTest, NineArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9));
EXPECT_EQ("012312323", a.Perform(make_tuple("0", "1", "2", "3")));
EXPECT_EQ("012312323",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that takes 10 arguments.
TEST(WithArgsTest, TenArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10));
EXPECT_EQ("0123210123", a.Perform(make_tuple("0", "1", "2", "3")));
EXPECT_EQ("0123210123",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that is not Invoke().
@@ -736,7 +770,7 @@ class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT
TEST(WithArgsTest, NonInvokeAction) {
Action<int(const string&, int, int)> a = // NOLINT
WithArgs<2, 1>(MakeAction(new SubstractAction));
EXPECT_EQ(8, a.Perform(make_tuple("hi", 2, 10)));
EXPECT_EQ(8, a.Perform(make_tuple(CharPtr("hi"), 2, 10)));
}
// Tests using WithArgs to pass all original arguments in the original order.
@@ -758,7 +792,7 @@ TEST(WithArgsTest, ReversedArgumentOrder) {
Action<const char*(short n, const char* input)> a = // NOLINT
WithArgs<1, 0>(Invoke(Binary));
const char s[] = "Hello";
EXPECT_EQ(s + 2, a.Perform(make_tuple(2, s)));
EXPECT_EQ(s + 2, a.Perform(make_tuple(2, CharPtr(s))));
}
// Tests using WithArgs with compatible, but not identical, argument types.
@@ -1123,16 +1157,16 @@ TEST(ActionMacroTest, CanDefineOverloadedActions) {
typedef Action<const char*(bool, const char*)> MyAction;
const MyAction a1 = OverloadedAction();
EXPECT_STREQ("hello", a1.Perform(make_tuple(false, "world")));
EXPECT_STREQ("world", a1.Perform(make_tuple(true, "world")));
EXPECT_STREQ("hello", a1.Perform(make_tuple(false, CharPtr("world"))));
EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world"))));
const MyAction a2 = OverloadedAction("hi");
EXPECT_STREQ("hi", a2.Perform(make_tuple(false, "world")));
EXPECT_STREQ("world", a2.Perform(make_tuple(true, "world")));
EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world"))));
EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world"))));
const MyAction a3 = OverloadedAction("hi", "you");
EXPECT_STREQ("hi", a3.Perform(make_tuple(true, "world")));
EXPECT_STREQ("you", a3.Perform(make_tuple(false, "world")));
EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world"))));
EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world"))));
}
// Tests ACTION_Pn where n >= 3.
@@ -1224,8 +1258,8 @@ TEST(ActionPnMacroTest, SimpleTypePromotion) {
PadArgument(std::string("foo"), 'r');
Action<std::string(const char*)> promo =
PadArgument("foo", static_cast<int>('r'));
EXPECT_EQ("foobar", no_promo.Perform(make_tuple("ba")));
EXPECT_EQ("foobar", promo.Perform(make_tuple("ba")));
EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba"))));
EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba"))));
}
// Tests that we can partially restrict parameter types using a
@@ -1470,7 +1504,7 @@ TEST(DeleteArgActionTest, TenArgs) {
const Action<void(bool, int, int, const char*, bool,
int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
EXPECT_FALSE(is_deleted);
a1.Perform(make_tuple(true, 5, 6, "hi", false, 7, 8, 9, 10, t));
a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
EXPECT_TRUE(is_deleted);
}
@@ -53,13 +53,18 @@ using std::pair;
using std::set;
using std::stringstream;
using std::vector;
using std::tr1::get;
using std::tr1::make_tuple;
using std::tr1::tuple;
using testing::_;
using testing::Args;
using testing::Contains;
using testing::ElementsAre;
using testing::ElementsAreArray;
using testing::Eq;
using testing::Ge;
using testing::Gt;
using testing::Lt;
using testing::MakeMatcher;
using testing::Matcher;
using testing::MatcherInterface;
@@ -69,6 +74,7 @@ using testing::Pointee;
using testing::Ref;
using testing::StaticAssertTypeEq;
using testing::StrEq;
using testing::Value;
using testing::internal::string;
// Returns the description of the given matcher.
@@ -95,6 +101,107 @@ string Explain(const MatcherType& m, const Value& x) {
return ss.str();
}
// Tests Args<k0, ..., kn>(m).
TEST(ArgsTest, AcceptsZeroTemplateArg) {
const tuple<int, bool> t(5, true);
EXPECT_THAT(t, Args<>(Eq(tuple<>())));
EXPECT_THAT(t, Not(Args<>(Ne(tuple<>()))));
}
TEST(ArgsTest, AcceptsOneTemplateArg) {
const tuple<int, bool> t(5, true);
EXPECT_THAT(t, Args<0>(Eq(make_tuple(5))));
EXPECT_THAT(t, Args<1>(Eq(make_tuple(true))));
EXPECT_THAT(t, Not(Args<1>(Eq(make_tuple(false)))));
}
TEST(ArgsTest, AcceptsTwoTemplateArgs) {
const tuple<short, int, long> t(4, 5, 6L); // NOLINT
EXPECT_THAT(t, (Args<0, 1>(Lt())));
EXPECT_THAT(t, (Args<1, 2>(Lt())));
EXPECT_THAT(t, Not(Args<0, 2>(Gt())));
}
TEST(ArgsTest, AcceptsRepeatedTemplateArgs) {
const tuple<short, int, long> t(4, 5, 6L); // NOLINT
EXPECT_THAT(t, (Args<0, 0>(Eq())));
EXPECT_THAT(t, Not(Args<1, 1>(Ne())));
}
TEST(ArgsTest, AcceptsDecreasingTemplateArgs) {
const tuple<short, int, long> t(4, 5, 6L); // NOLINT
EXPECT_THAT(t, (Args<2, 0>(Gt())));
EXPECT_THAT(t, Not(Args<2, 1>(Lt())));
}
MATCHER(SumIsZero, "") {
return get<0>(arg) + get<1>(arg) + get<2>(arg) == 0;
}
TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) {
EXPECT_THAT(make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero())));
EXPECT_THAT(make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero())));
}
TEST(ArgsTest, CanBeNested) {
const tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT
EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq()))));
EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt()))));
}
TEST(ArgsTest, CanMatchTupleByValue) {
typedef tuple<char, int, int> Tuple3;
const Matcher<Tuple3> m = Args<1, 2>(Lt());
EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2)));
EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2)));
}
TEST(ArgsTest, CanMatchTupleByReference) {
typedef tuple<char, char, int> Tuple3;
const Matcher<const Tuple3&> m = Args<0, 1>(Lt());
EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2)));
EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2)));
}
// Validates that arg is printed as str.
MATCHER_P(PrintsAs, str, "") {
typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(arg_type)) RawTuple;
return
testing::internal::UniversalPrinter<RawTuple>::PrintToString(arg) == str;
}
TEST(ArgsTest, AcceptsTenTemplateArgs) {
EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9),
(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>(
PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)"))));
EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9),
Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>(
PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)"))));
}
TEST(ArgsTest, DescirbesSelfCorrectly) {
const Matcher<tuple<int, bool, char> > m = Args<2, 0>(Lt());
EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair (x, y) where x < y",
Describe(m));
}
TEST(ArgsTest, DescirbesNestedArgsCorrectly) {
const Matcher<const tuple<int, bool, char, int>&> m =
Args<0, 2, 3>(Args<2, 0>(Lt()));
EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple "
"whose fields (#2, #0) are a pair (x, y) where x < y",
Describe(m));
}
TEST(ArgsTest, DescribesNegationCorrectly) {
const Matcher<tuple<int, char> > m = Args<1, 0>(Gt());
EXPECT_EQ("are a tuple whose fields (#1, #0) are a pair (x, y) "
"where x > y is false",
DescribeNegation(m));
}
// For testing ExplainMatchResultTo().
class GreaterThanMatcher : public MatcherInterface<int> {
public:
@@ -330,6 +437,39 @@ TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
}
TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) {
int array[] = { 0, 1, 2 };
EXPECT_THAT(array, ElementsAre(0, 1, _));
EXPECT_THAT(array, Not(ElementsAre(1, _, _)));
EXPECT_THAT(array, Not(ElementsAre(0, _)));
}
class NativeArrayPassedAsPointerAndSize {
public:
MOCK_METHOD2(Helper, void(int* array, int size));
};
TEST(ElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) {
int array[] = { 0, 1 };
::std::tr1::tuple<int*, size_t> array_as_tuple(array, 2);
EXPECT_THAT(array_as_tuple, ElementsAre(0, 1));
EXPECT_THAT(array_as_tuple, Not(ElementsAre(0)));
NativeArrayPassedAsPointerAndSize helper;
EXPECT_CALL(helper, Helper(_, _))
.With(ElementsAre(0, 1));
helper.Helper(array, 2);
}
TEST(ElementsAreTest, WorksWithTwoDimensionalNativeArray) {
const char a2[][3] = { "hi", "lo" };
EXPECT_THAT(a2, ElementsAre(ElementsAre('h', 'i', '\0'),
ElementsAre('l', 'o', '\0')));
EXPECT_THAT(a2, ElementsAre(StrEq("hi"), StrEq("lo")));
EXPECT_THAT(a2, ElementsAre(Not(ElementsAre('h', 'o', '\0')),
ElementsAre('l', 'o', '\0')));
}
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most
// of the implementation with ElementsAre(), we don't test it as
// thoroughly here.
@@ -379,6 +519,17 @@ TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
}
// Since ElementsAre() and ElementsAreArray() share much of the
// implementation, we only do a sanity test for native arrays here.
TEST(ElementsAreArrayTest, WorksWithNativeArray) {
::std::string a[] = { "hi", "ho" };
::std::string b[] = { "hi", "ho" };
EXPECT_THAT(a, ElementsAreArray(b));
EXPECT_THAT(a, ElementsAreArray(b, 2));
EXPECT_THAT(a, Not(ElementsAreArray(b, 1)));
}
// Tests for the MATCHER*() macro family.
// Tests that a simple MATCHER() definition works.
@@ -443,12 +594,23 @@ namespace matcher_test {
MATCHER(IsOdd, "") { return (arg % 2) != 0; }
} // namespace matcher_test
TEST(MatcherTest, WorksInNamespace) {
TEST(MatcherMacroTest, WorksInNamespace) {
Matcher<int> m = matcher_test::IsOdd();
EXPECT_FALSE(m.Matches(4));
EXPECT_TRUE(m.Matches(5));
}
// Tests that Value() can be used to compose matchers.
MATCHER(IsPositiveOdd, "") {
return Value(arg, matcher_test::IsOdd()) && arg > 0;
}
TEST(MatcherMacroTest, CanBeComposedUsingValue) {
EXPECT_THAT(3, IsPositiveOdd());
EXPECT_THAT(4, Not(IsPositiveOdd()));
EXPECT_THAT(-1, Not(IsPositiveOdd()));
}
// Tests that a simple MATCHER_P() definition works.
MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; }
@@ -742,14 +904,31 @@ TEST(MatcherPnMacroTest, TypesAreCorrect) {
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
}
// Tests that matcher-typed parameters can be used in Value() inside a
// MATCHER_Pn definition.
// Succeeds if arg matches exactly 2 of the 3 matchers.
MATCHER_P3(TwoOf, m1, m2, m3, "") {
const int count = static_cast<int>(Value(arg, m1))
+ static_cast<int>(Value(arg, m2)) + static_cast<int>(Value(arg, m3));
return count == 2;
}
TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) {
EXPECT_THAT(42, TwoOf(Gt(0), Lt(50), Eq(10)));
EXPECT_THAT(0, Not(TwoOf(Gt(-1), Lt(1), Eq(0))));
}
// Tests Contains().
TEST(ContainsTest, ListMatchesWhenElementIsInContainer) {
list<int> some_list;
some_list.push_back(3);
some_list.push_back(1);
some_list.push_back(2);
EXPECT_THAT(some_list, Contains(1));
EXPECT_THAT(some_list, Contains(3.0));
EXPECT_THAT(some_list, Contains(2.0f));
EXPECT_THAT(some_list, Contains(Gt(2.5)));
EXPECT_THAT(some_list, Contains(Eq(2.0f)));
list<string> another_list;
another_list.push_back("fee");
@@ -771,8 +950,8 @@ TEST(ContainsTest, SetMatchesWhenElementIsInContainer) {
some_set.insert(3);
some_set.insert(1);
some_set.insert(2);
EXPECT_THAT(some_set, Contains(1.0));
EXPECT_THAT(some_set, Contains(3.0f));
EXPECT_THAT(some_set, Contains(Eq(1.0)));
EXPECT_THAT(some_set, Contains(Eq(3.0f)));
EXPECT_THAT(some_set, Contains(2));
set<const char*> another_set;
@@ -780,7 +959,7 @@ TEST(ContainsTest, SetMatchesWhenElementIsInContainer) {
another_set.insert("fie");
another_set.insert("foe");
another_set.insert("fum");
EXPECT_THAT(another_set, Contains(string("fum")));
EXPECT_THAT(another_set, Contains(Eq(string("fum"))));
}
TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
@@ -795,8 +974,20 @@ TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
}
TEST(ContainsTest, DescribesItselfCorrectly) {
const int a[2] = { 1, 2 };
Matcher<const int(&)[2]> m = Contains(2);
EXPECT_EQ("element 1 matches", Explain(m, a));
m = Contains(3);
EXPECT_EQ("", Explain(m, a));
}
TEST(ContainsTest, ExplainsMatchResultCorrectly) {
Matcher<vector<int> > m = Contains(1);
EXPECT_EQ("contains 1", Describe(m));
EXPECT_EQ("contains at least one element that is equal to 1", Describe(m));
Matcher<vector<int> > m2 = Not(m);
EXPECT_EQ("doesn't contain any element that is equal to 1", Describe(m2));
}
TEST(ContainsTest, MapMatchesWhenElementIsInContainer) {
@@ -823,7 +1014,7 @@ TEST(ContainsTest, MapDoesNotMatchWhenElementIsNotInContainer) {
TEST(ContainsTest, ArrayMatchesWhenElementIsInContainer) {
const char* string_array[] = { "fee", "fie", "foe", "fum" };
EXPECT_THAT(string_array, Contains(string("fum")));
EXPECT_THAT(string_array, Contains(Eq(string("fum"))));
}
TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) {
@@ -831,4 +1022,25 @@ TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) {
EXPECT_THAT(int_array, Not(Contains(5)));
}
TEST(ContainsTest, AcceptsMatcher) {
const int a[] = { 1, 2, 3 };
EXPECT_THAT(a, Contains(Gt(2)));
EXPECT_THAT(a, Not(Contains(Gt(4))));
}
TEST(ContainsTest, WorksForNativeArrayAsTuple) {
const int a[] = { 1, 2 };
const int* const pointer = a;
EXPECT_THAT(make_tuple(pointer, 2), Contains(1));
EXPECT_THAT(make_tuple(pointer, 2), Not(Contains(Gt(3))));
}
TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
int a[][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
EXPECT_THAT(a, Contains(ElementsAre(4, 5, 6)));
EXPECT_THAT(a, Contains(Contains(5)));
EXPECT_THAT(a, Not(Contains(ElementsAre(3, 4, 5))));
EXPECT_THAT(a, Contains(Not(Contains(5))));
}
} // namespace
@@ -53,6 +53,7 @@ namespace internal {
namespace {
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) {
@@ -130,6 +131,8 @@ TEST(RemoveConstTest, DoesNotAffectNonConstType) {
// Tests that RemoveConst removes const from const types.
TEST(RemoveConstTest, RemovesConst) {
CompileAssertTypesEqual<int, RemoveConst<const int>::type>();
CompileAssertTypesEqual<char[2], RemoveConst<const char[2]>::type>();
CompileAssertTypesEqual<char[2][3], RemoveConst<const char[2][3]>::type>();
}
// Tests GMOCK_REMOVE_CONST_.
@@ -494,6 +497,34 @@ TEST(ExpectTest, FailsNonfatallyOnFalse) {
}, "Expectation failed");
}
// Tests LogIsVisible().
class LogIsVisibleTest : public ::testing::Test {
protected:
virtual void SetUp() { original_verbose_ = GMOCK_FLAG(verbose); }
virtual void TearDown() { GMOCK_FLAG(verbose) = original_verbose_; }
string original_verbose_;
};
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
GMOCK_FLAG(verbose) = kInfoVerbosity;
EXPECT_TRUE(LogIsVisible(INFO));
EXPECT_TRUE(LogIsVisible(WARNING));
}
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
GMOCK_FLAG(verbose) = kErrorVerbosity;
EXPECT_FALSE(LogIsVisible(INFO));
EXPECT_FALSE(LogIsVisible(WARNING));
}
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
GMOCK_FLAG(verbose) = kWarningVerbosity;
EXPECT_FALSE(LogIsVisible(INFO));
EXPECT_TRUE(LogIsVisible(WARNING));
}
// TODO(wan@google.com): find a way to re-enable these tests.
#if 0
@@ -693,6 +724,236 @@ TEST(OnCallTest, LogsAnythingArgument) {
#endif // 0
// Tests ArrayEq().
TEST(ArrayEqTest, WorksForDegeneratedArrays) {
EXPECT_TRUE(ArrayEq(5, 5L));
EXPECT_FALSE(ArrayEq('a', 0));
}
TEST(ArrayEqTest, WorksForOneDimensionalArrays) {
const int a[] = { 0, 1 };
long b[] = { 0, 1 };
EXPECT_TRUE(ArrayEq(a, b));
EXPECT_TRUE(ArrayEq(a, 2, b));
b[0] = 2;
EXPECT_FALSE(ArrayEq(a, b));
EXPECT_FALSE(ArrayEq(a, 1, b));
}
TEST(ArrayEqTest, WorksForTwoDimensionalArrays) {
const char a[][3] = { "hi", "lo" };
const char b[][3] = { "hi", "lo" };
const char c[][3] = { "hi", "li" };
EXPECT_TRUE(ArrayEq(a, b));
EXPECT_TRUE(ArrayEq(a, 2, b));
EXPECT_FALSE(ArrayEq(a, c));
EXPECT_FALSE(ArrayEq(a, 2, c));
}
// Tests ArrayAwareFind().
TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) {
const char a[] = "hello";
EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o'));
EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x'));
}
TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) {
int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
const int b[2] = { 2, 3 };
EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b));
const int c[2] = { 6, 7 };
EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c));
}
// Tests CopyArray().
TEST(CopyArrayTest, WorksForDegeneratedArrays) {
int n = 0;
CopyArray('a', &n);
EXPECT_EQ('a', n);
}
TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
const char a[3] = "hi";
int b[3];
CopyArray(a, &b);
EXPECT_TRUE(ArrayEq(a, b));
int c[3];
CopyArray(a, 3, c);
EXPECT_TRUE(ArrayEq(a, c));
}
TEST(CopyArrayTest, WorksForTwoDimensionalArrays) {
const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
int b[2][3];
CopyArray(a, &b);
EXPECT_TRUE(ArrayEq(a, b));
int c[2][3];
CopyArray(a, 2, c);
EXPECT_TRUE(ArrayEq(a, c));
}
// Tests NativeArray.
TEST(NativeArrayTest, ConstructorFromArrayReferenceWorks) {
const int a[3] = { 0, 1, 2 };
NativeArray<int> na(a, kReference);
EXPECT_EQ(3, na.size());
EXPECT_EQ(a, na.begin());
}
TEST(NativeArrayTest, ConstructorFromTupleWorks) {
int a[3] = { 0, 1, 2 };
int* const p = a;
// Tests with a plain pointer.
NativeArray<int> na(make_tuple(p, 3U), kReference);
EXPECT_EQ(a, na.begin());
const linked_ptr<char> b(new char);
*b = 'a';
// Tests with a smart pointer.
NativeArray<char> nb(make_tuple(b, 1), kCopy);
EXPECT_NE(b.get(), nb.begin());
EXPECT_EQ('a', nb.begin()[0]);
}
TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) {
typedef int Array[2];
Array* a = new Array[1];
(*a)[0] = 0;
(*a)[1] = 1;
NativeArray<int> na(*a, kCopy);
EXPECT_NE(*a, na.begin());
delete[] a;
EXPECT_EQ(0, na.begin()[0]);
EXPECT_EQ(1, na.begin()[1]);
// We rely on the heap checker to verify that na deletes the copy of
// array.
}
TEST(NativeArrayTest, TypeMembersAreCorrect) {
StaticAssertTypeEq<char, NativeArray<char>::value_type>();
StaticAssertTypeEq<int[2], NativeArray<int[2]>::value_type>();
StaticAssertTypeEq<const char*, NativeArray<char>::const_iterator>();
StaticAssertTypeEq<const bool(*)[2], NativeArray<bool[2]>::const_iterator>();
}
TEST(NativeArrayTest, MethodsWork) {
const int a[] = { 0, 1, 2 };
NativeArray<int> na(a, kCopy);
ASSERT_EQ(3, na.size());
EXPECT_EQ(3, na.end() - na.begin());
NativeArray<int>::const_iterator it = na.begin();
EXPECT_EQ(0, *it);
++it;
EXPECT_EQ(1, *it);
it++;
EXPECT_EQ(2, *it);
++it;
EXPECT_EQ(na.end(), it);
EXPECT_THAT(na, Eq(na));
NativeArray<int> na2(a, kReference);
EXPECT_THAT(na, Eq(na2));
const int b1[] = { 0, 1, 1 };
const int b2[] = { 0, 1, 2, 3 };
EXPECT_THAT(na, Not(Eq(NativeArray<int>(b1, kReference))));
EXPECT_THAT(na, Not(Eq(NativeArray<int>(b2, kCopy))));
}
TEST(NativeArrayTest, WorksForTwoDimensionalArray) {
const char a[2][3] = { "hi", "lo" };
NativeArray<char[3]> na(a, kReference);
ASSERT_EQ(2, na.size());
EXPECT_EQ(a, na.begin());
}
// Tests StlContainerView.
TEST(StlContainerViewTest, WorksForStlContainer) {
StaticAssertTypeEq<std::vector<int>,
StlContainerView<std::vector<int> >::type>();
StaticAssertTypeEq<const std::vector<double>&,
StlContainerView<std::vector<double> >::const_reference>();
typedef std::vector<char> Chars;
Chars v1;
const Chars& v2(StlContainerView<Chars>::ConstReference(v1));
EXPECT_EQ(&v1, &v2);
v1.push_back('a');
Chars v3 = StlContainerView<Chars>::Copy(v1);
EXPECT_THAT(v3, Eq(v3));
}
TEST(StlContainerViewTest, WorksForStaticNativeArray) {
StaticAssertTypeEq<NativeArray<int>,
StlContainerView<int[3]>::type>();
StaticAssertTypeEq<NativeArray<double>,
StlContainerView<const double[4]>::type>();
StaticAssertTypeEq<NativeArray<char[3]>,
StlContainerView<const char[2][3]>::type>();
StaticAssertTypeEq<const NativeArray<int>,
StlContainerView<int[2]>::const_reference>();
int a1[3] = { 0, 1, 2 };
NativeArray<int> a2 = StlContainerView<int[3]>::ConstReference(a1);
EXPECT_EQ(3, a2.size());
EXPECT_EQ(a1, a2.begin());
const NativeArray<int> a3 = StlContainerView<int[3]>::Copy(a1);
ASSERT_EQ(3, a3.size());
EXPECT_EQ(0, a3.begin()[0]);
EXPECT_EQ(1, a3.begin()[1]);
EXPECT_EQ(2, a3.begin()[2]);
// Makes sure a1 and a3 aren't aliases.
a1[0] = 3;
EXPECT_EQ(0, a3.begin()[0]);
}
TEST(StlContainerViewTest, WorksForDynamicNativeArray) {
StaticAssertTypeEq<NativeArray<int>,
StlContainerView<tuple<const int*, size_t> >::type>();
StaticAssertTypeEq<NativeArray<double>,
StlContainerView<tuple<linked_ptr<double>, int> >::type>();
StaticAssertTypeEq<const NativeArray<int>,
StlContainerView<tuple<const int*, int> >::const_reference>();
int a1[3] = { 0, 1, 2 };
const int* const p1 = a1;
NativeArray<int> a2 = StlContainerView<tuple<const int*, int> >::
ConstReference(make_tuple(p1, 3));
EXPECT_EQ(3, a2.size());
EXPECT_EQ(a1, a2.begin());
const NativeArray<int> a3 = StlContainerView<tuple<int*, size_t> >::
Copy(make_tuple(static_cast<int*>(a1), 3));
ASSERT_EQ(3, a3.size());
EXPECT_EQ(0, a3.begin()[0]);
EXPECT_EQ(1, a3.begin()[1]);
EXPECT_EQ(2, a3.begin()[2]);
// Makes sure a1 and a3 aren't aliases.
a1[0] = 3;
EXPECT_EQ(0, a3.begin()[0]);
}
} // namespace
} // namespace internal
} // namespace testing
+112 -11
Ver Arquivo
@@ -60,7 +60,9 @@ bool SkipPrefix(const char* prefix, const char** pstr);
namespace gmock_matchers_test {
using std::stringstream;
using std::tr1::make_tuple;
using testing::A;
using testing::AllArgs;
using testing::AllOf;
using testing::An;
using testing::AnyOf;
@@ -98,6 +100,7 @@ using testing::StrEq;
using testing::StrNe;
using testing::Truly;
using testing::TypedEq;
using testing::Value;
using testing::_;
using testing::internal::FloatingEqMatcher;
using testing::internal::FormatMatcherDescriptionSyntaxError;
@@ -1333,7 +1336,7 @@ TEST(Eq2Test, MatchesEqualArguments) {
// Tests that Eq() describes itself properly.
TEST(Eq2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Eq();
EXPECT_EQ("argument #0 is equal to argument #1", Describe(m));
EXPECT_EQ("are a pair (x, y) where x == y", Describe(m));
}
// Tests that Ge() matches a 2-tuple where the first field >= the
@@ -1348,8 +1351,7 @@ TEST(Ge2Test, MatchesGreaterThanOrEqualArguments) {
// Tests that Ge() describes itself properly.
TEST(Ge2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Ge();
EXPECT_EQ("argument #0 is greater than or equal to argument #1",
Describe(m));
EXPECT_EQ("are a pair (x, y) where x >= y", Describe(m));
}
// Tests that Gt() matches a 2-tuple where the first field > the
@@ -1364,7 +1366,7 @@ TEST(Gt2Test, MatchesGreaterThanArguments) {
// Tests that Gt() describes itself properly.
TEST(Gt2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Gt();
EXPECT_EQ("argument #0 is greater than argument #1", Describe(m));
EXPECT_EQ("are a pair (x, y) where x > y", Describe(m));
}
// Tests that Le() matches a 2-tuple where the first field <= the
@@ -1379,8 +1381,7 @@ TEST(Le2Test, MatchesLessThanOrEqualArguments) {
// Tests that Le() describes itself properly.
TEST(Le2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Le();
EXPECT_EQ("argument #0 is less than or equal to argument #1",
Describe(m));
EXPECT_EQ("are a pair (x, y) where x <= y", Describe(m));
}
// Tests that Lt() matches a 2-tuple where the first field < the
@@ -1395,7 +1396,7 @@ TEST(Lt2Test, MatchesLessThanArguments) {
// Tests that Lt() describes itself properly.
TEST(Lt2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Lt();
EXPECT_EQ("argument #0 is less than argument #1", Describe(m));
EXPECT_EQ("are a pair (x, y) where x < y", Describe(m));
}
// Tests that Ne() matches a 2-tuple where the first field != the
@@ -1410,7 +1411,7 @@ TEST(Ne2Test, MatchesUnequalArguments) {
// Tests that Ne() describes itself properly.
TEST(Ne2Test, CanDescribeSelf) {
Matcher<const Tuple2&> m = Ne();
EXPECT_EQ("argument #0 is not equal to argument #1", Describe(m));
EXPECT_EQ("are a pair (x, y) where x != y", Describe(m));
}
// Tests that Not(m) matches any value that doesn't match m.
@@ -1670,6 +1671,54 @@ TEST(MatchesTest, WorksWithMatcherOnNonRefType) {
EXPECT_FALSE(Matches(eq5)(2));
}
// Tests Value(value, matcher). Since Value() is a simple wrapper for
// Matches(), which has been tested already, we don't spend a lot of
// effort on testing Value().
TEST(ValueTest, WorksWithPolymorphicMatcher) {
EXPECT_TRUE(Value("hi", StartsWith("h")));
EXPECT_FALSE(Value(5, Gt(10)));
}
TEST(ValueTest, WorksWithMonomorphicMatcher) {
const Matcher<int> is_zero = Eq(0);
EXPECT_TRUE(Value(0, is_zero));
EXPECT_FALSE(Value('a', is_zero));
int n = 0;
const Matcher<const int&> ref_n = Ref(n);
EXPECT_TRUE(Value(n, ref_n));
EXPECT_FALSE(Value(1, ref_n));
}
TEST(AllArgsTest, WorksForTuple) {
EXPECT_THAT(make_tuple(1, 2L), AllArgs(Lt()));
EXPECT_THAT(make_tuple(2L, 1), Not(AllArgs(Lt())));
}
TEST(AllArgsTest, WorksForNonTuple) {
EXPECT_THAT(42, AllArgs(Gt(0)));
EXPECT_THAT('a', Not(AllArgs(Eq('b'))));
}
class AllArgsHelper {
public:
MOCK_METHOD2(Helper, int(char x, int y));
};
TEST(AllArgsTest, WorksInWithClause) {
AllArgsHelper helper;
ON_CALL(helper, Helper(_, _))
.With(AllArgs(Lt()))
.WillByDefault(Return(1));
EXPECT_CALL(helper, Helper(_, _));
EXPECT_CALL(helper, Helper(_, _))
.With(AllArgs(Gt()))
.WillOnce(Return(2));
EXPECT_EQ(1, helper.Helper('\1', 2));
EXPECT_EQ(2, helper.Helper('a', 1));
}
// Tests that ASSERT_THAT() and EXPECT_THAT() work when the value
// matches the matcher.
TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) {
@@ -2765,9 +2814,7 @@ TEST(ByRefTest, AllowsNotCopyableValueInMatchers) {
// different element types.
template <typename T>
class ContainerEqTest : public testing::Test {
public:
};
class ContainerEqTest : public testing::Test {};
typedef testing::Types<
std::set<int>,
@@ -2901,6 +2948,60 @@ TEST(ContainerEqExtraTest, WorksForMaps) {
Explain(m, test_map));
}
TEST(ContainerEqExtraTest, WorksForNativeArray) {
int a1[] = { 1, 2, 3 };
int a2[] = { 1, 2, 3 };
int b[] = { 1, 2, 4 };
EXPECT_THAT(a1, ContainerEq(a2));
EXPECT_THAT(a1, Not(ContainerEq(b)));
}
TEST(ContainerEqExtraTest, WorksForTwoDimensionalNativeArray) {
const char a1[][3] = { "hi", "lo" };
const char a2[][3] = { "hi", "lo" };
const char b[][3] = { "lo", "hi" };
// Tests using ContainerEq() in the first dimension.
EXPECT_THAT(a1, ContainerEq(a2));
EXPECT_THAT(a1, Not(ContainerEq(b)));
// Tests using ContainerEq() in the second dimension.
EXPECT_THAT(a1, ElementsAre(ContainerEq(a2[0]), ContainerEq(a2[1])));
EXPECT_THAT(a1, ElementsAre(Not(ContainerEq(b[0])), ContainerEq(a2[1])));
}
TEST(ContainerEqExtraTest, WorksForNativeArrayAsTuple) {
const int a1[] = { 1, 2, 3 };
const int a2[] = { 1, 2, 3 };
const int b[] = { 1, 2, 3, 4 };
const int* const p1 = a1;
EXPECT_THAT(make_tuple(p1, 3), ContainerEq(a2));
EXPECT_THAT(make_tuple(p1, 3), Not(ContainerEq(b)));
const int c[] = { 1, 3, 2 };
EXPECT_THAT(make_tuple(p1, 3), Not(ContainerEq(c)));
}
TEST(ContainerEqExtraTest, CopiesNativeArrayParameter) {
std::string a1[][3] = {
{ "hi", "hello", "ciao" },
{ "bye", "see you", "ciao" }
};
std::string a2[][3] = {
{ "hi", "hello", "ciao" },
{ "bye", "see you", "ciao" }
};
const Matcher<const std::string(&)[2][3]> m = ContainerEq(a2);
EXPECT_THAT(a1, m);
a2[0][0] = "ha";
EXPECT_THAT(a1, m);
}
// Tests GetParamIndex().
TEST(GetParamIndexTest, WorksForEmptyParamList) {
+66 -33
Ver Arquivo
@@ -154,10 +154,13 @@ using ::std::tr1::tuple;
using ::std::vector;
using ::testing::ElementsAre;
using ::testing::StartsWith;
using ::testing::internal::NativeArray;
using ::testing::internal::Strings;
using ::testing::internal::UniversalTersePrint;
using ::testing::internal::UniversalPrint;
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
using ::testing::internal::UniversalPrinter;
using ::testing::internal::kReference;
using ::testing::internal::string;
#if GTEST_OS_WINDOWS
@@ -485,75 +488,58 @@ TEST(PrintPointerTest, MemberFunctionPointer) {
// Tests printing C arrays.
// One-dimensional array.
void ArrayHelper1(int (&a)[5]) { // NOLINT
EXPECT_EQ("{ 1, 2, 3, 4, 5 }", Print(a));
// The difference between this and Print() is that it ensures that the
// argument is a reference to an array.
template <typename T, size_t N>
string PrintArrayHelper(T (&a)[N]) {
return Print(a);
}
// One-dimensional array.
TEST(PrintArrayTest, OneDimensionalArray) {
int a[5] = { 1, 2, 3, 4, 5 };
ArrayHelper1(a);
EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a));
}
// Two-dimensional array.
void ArrayHelper2(int (&a)[2][5]) { // NOLINT
EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", Print(a));
}
TEST(PrintArrayTest, TwoDimensionalArray) {
int a[2][5] = {
{ 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 0 }
};
ArrayHelper2(a);
EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a));
}
// Array of const elements.
void ArrayHelper3(const bool (&a)[1]) { // NOLINT
EXPECT_EQ("{ false }", Print(a));
}
TEST(PrintArrayTest, ConstArray) {
const bool a[1] = { false };
ArrayHelper3(a);
EXPECT_EQ("{ false }", PrintArrayHelper(a));
}
// Char array.
void ArrayHelper4(char (&a)[3]) { // NOLINT
EXPECT_EQ(PrintPointer(a) + " pointing to \"Hi\"", Print(a));
}
TEST(PrintArrayTest, CharArray) {
char a[3] = "Hi";
ArrayHelper4(a);
// Array a contains '\0' in the middle and doesn't end with '\0'.
char a[3] = { 'H', '\0', 'i' };
EXPECT_EQ("\"H\\0i\"", PrintArrayHelper(a));
}
// Const char array.
void ArrayHelper5(const char (&a)[3]) { // NOLINT
EXPECT_EQ(Print(a), PrintPointer(a) + " pointing to \"Hi\"");
}
TEST(PrintArrayTest, ConstCharArray) {
const char a[3] = "Hi";
ArrayHelper5(a);
const char a[4] = "\0Hi";
EXPECT_EQ("\"\\0Hi\\0\"", PrintArrayHelper(a));
}
// Array of objects.
TEST(PrintArrayTest, ObjectArray) {
string a[3] = { "Hi", "Hello", "Ni hao" };
EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", Print(a));
EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a));
}
// Array with many elements.
TEST(PrintArrayTest, BigArray) {
int a[100] = { 1, 2, 3 };
EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }",
Print(a));
PrintArrayHelper(a));
}
// Tests printing ::string and ::std::string.
@@ -803,6 +789,17 @@ TEST(PrintStlContainerTest, NestedContainer) {
EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v));
}
TEST(PrintStlContainerTest, OneDimensionalNativeArray) {
const int a[] = { 1, 2, 3 };
NativeArray<int> b(a, kReference);
EXPECT_EQ("{ 1, 2, 3 }", Print(b));
}
TEST(PrintStlContainerTest, TwoDimensionalNativeArray) {
const int a[][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
NativeArray<int[3]> b(a, kReference);
EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b));
}
// Tests printing tuples.
@@ -995,6 +992,11 @@ TEST(PrintToStringTest, WorksForReference) {
UniversalPrinter<const int&>::PrintToString(n));
}
TEST(PrintToStringTest, WorksForArray) {
int n[3] = { 1, 2, 3 };
EXPECT_EQ("{ 1, 2, 3 }", UniversalPrinter<int[3]>::PrintToString(n));
}
TEST(UniversalTersePrintTest, WorksForNonReference) {
::std::stringstream ss;
UniversalTersePrint(123, &ss);
@@ -1025,6 +1027,37 @@ TEST(UniversalTersePrintTest, WorksForCString) {
EXPECT_EQ("NULL", ss3.str());
}
TEST(UniversalPrintTest, WorksForNonReference) {
::std::stringstream ss;
UniversalPrint(123, &ss);
EXPECT_EQ("123", ss.str());
}
TEST(UniversalPrintTest, WorksForReference) {
const int& n = 123;
::std::stringstream ss;
UniversalPrint(n, &ss);
EXPECT_EQ("123", ss.str());
}
TEST(UniversalPrintTest, WorksForCString) {
const char* s1 = "abc";
::std::stringstream ss1;
UniversalPrint(s1, &ss1);
EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", string(ss1.str()));
char* s2 = const_cast<char*>(s1);
::std::stringstream ss2;
UniversalPrint(s2, &ss2);
EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", string(ss2.str()));
const char* s3 = NULL;
::std::stringstream ss3;
UniversalPrint(s3, &ss3);
EXPECT_EQ("NULL", ss3.str());
}
TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) {
EXPECT_THAT(UniversalTersePrintTupleFieldsToStrings(make_tuple()),
ElementsAre());
+66 -20
Ver Arquivo
@@ -72,6 +72,7 @@ using testing::Const;
using testing::DoAll;
using testing::DoDefault;
using testing::GMOCK_FLAG(verbose);
using testing::Gt;
using testing::InSequence;
using testing::Invoke;
using testing::InvokeWithoutArgs;
@@ -96,6 +97,7 @@ class MockA {
MOCK_METHOD1(DoA, void(int n)); // NOLINT
MOCK_METHOD1(ReturnResult, Result(int n)); // NOLINT
MOCK_METHOD2(Binary, bool(int x, int y)); // NOLINT
MOCK_METHOD2(ReturnInt, int(int x, int y)); // NOLINT
};
class MockB {
@@ -171,25 +173,25 @@ TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) {
// Tests that the syntax of ON_CALL() is enforced at run time.
TEST(OnCallSyntaxTest, WithArgumentsIsOptional) {
TEST(OnCallSyntaxTest, WithIsOptional) {
MockA a;
ON_CALL(a, DoA(5))
.WillByDefault(Return());
ON_CALL(a, DoA(_))
.WithArguments(_)
.With(_)
.WillByDefault(Return());
}
TEST(OnCallSyntaxTest, WithArgumentsCanAppearAtMostOnce) {
TEST(OnCallSyntaxTest, WithCanAppearAtMostOnce) {
MockA a;
EXPECT_NONFATAL_FAILURE({ // NOLINT
ON_CALL(a, ReturnResult(_))
.WithArguments(_)
.WithArguments(_)
.With(_)
.With(_)
.WillByDefault(Return(Result()));
}, ".WithArguments() cannot appear more than once in an ON_CALL()");
}, ".With() cannot appear more than once in an ON_CALL()");
}
#if GTEST_HAS_DEATH_TEST
@@ -237,47 +239,44 @@ TEST(ExpectCallSyntaxTest, EvaluatesSecondArgumentOnce) {
// Tests that the syntax of EXPECT_CALL() is enforced at run time.
TEST(ExpectCallSyntaxTest, WithArgumentsIsOptional) {
TEST(ExpectCallSyntaxTest, WithIsOptional) {
MockA a;
EXPECT_CALL(a, DoA(5))
.Times(0);
EXPECT_CALL(a, DoA(6))
.WithArguments(_)
.With(_)
.Times(0);
}
TEST(ExpectCallSyntaxTest, WithArgumentsCanAppearAtMostOnce) {
TEST(ExpectCallSyntaxTest, WithCanAppearAtMostOnce) {
MockA a;
EXPECT_NONFATAL_FAILURE({ // NOLINT
EXPECT_CALL(a, DoA(6))
.WithArguments(_)
.WithArguments(_);
}, ".WithArguments() cannot appear more than once in "
"an EXPECT_CALL()");
.With(_)
.With(_);
}, ".With() cannot appear more than once in an EXPECT_CALL()");
a.DoA(6);
}
TEST(ExpectCallSyntaxTest, WithArgumentsMustBeFirstClause) {
TEST(ExpectCallSyntaxTest, WithMustBeFirstClause) {
MockA a;
EXPECT_NONFATAL_FAILURE({ // NOLINT
EXPECT_CALL(a, DoA(1))
.Times(1)
.WithArguments(_);
}, ".WithArguments() must be the first clause in an "
"EXPECT_CALL()");
.With(_);
}, ".With() must be the first clause in an EXPECT_CALL()");
a.DoA(1);
EXPECT_NONFATAL_FAILURE({ // NOLINT
EXPECT_CALL(a, DoA(2))
.WillOnce(Return())
.WithArguments(_);
}, ".WithArguments() must be the first clause in an "
"EXPECT_CALL()");
.With(_);
}, ".With() must be the first clause in an EXPECT_CALL()");
a.DoA(2);
}
@@ -1612,6 +1611,53 @@ TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
#endif // 0
// A helper class that generates a failure when printed. We use it to
// ensure that Google Mock doesn't print a value (even to an internal
// buffer) when it is not supposed to do so.
class PrintMeNot {};
void PrintTo(PrintMeNot /* dummy */, ::std::ostream* /* os */) {
ADD_FAILURE() << "Google Mock is printing a value that shouldn't be "
<< "printed even to an internal buffer.";
}
class LogTestHelper {
public:
MOCK_METHOD1(Foo, PrintMeNot(PrintMeNot));
};
class GMockLogTest : public ::testing::Test {
protected:
virtual void SetUp() { original_verbose_ = GMOCK_FLAG(verbose); }
virtual void TearDown() { GMOCK_FLAG(verbose) = original_verbose_; }
LogTestHelper helper_;
string original_verbose_;
};
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) {
GMOCK_FLAG(verbose) = kWarningVerbosity;
EXPECT_CALL(helper_, Foo(_))
.WillOnce(Return(PrintMeNot()));
helper_.Foo(PrintMeNot()); // This is an expected call.
}
TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) {
GMOCK_FLAG(verbose) = kErrorVerbosity;
EXPECT_CALL(helper_, Foo(_))
.WillOnce(Return(PrintMeNot()));
helper_.Foo(PrintMeNot()); // This is an expected call.
}
TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) {
GMOCK_FLAG(verbose) = kErrorVerbosity;
ON_CALL(helper_, Foo(_))
.WillByDefault(Return(PrintMeNot()));
helper_.Foo(PrintMeNot()); // This should generate a warning.
}
// Tests Mock::AllowLeak().
TEST(AllowLeakTest, AllowsLeakingUnusedMockObject) {
MockA* a = new MockA;
Mock::AllowLeak(a);
+1
Ver Arquivo
@@ -120,6 +120,7 @@
#include <errno.h>
#endif
#include <gmock/internal/gmock-port.h>
#include <gtest/gtest.h>
#include <iostream>
#include <vector>
+6 -6
Ver Arquivo
@@ -177,19 +177,19 @@ TEST_F(GMockOutputTest, MismatchArguments) {
foo_.Bar(s, 0, 0);
}
TEST_F(GMockOutputTest, MismatchWithArguments) {
TEST_F(GMockOutputTest, MismatchWith) {
EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
.WithArguments(Ge());
.With(Ge());
foo_.Bar2(2, 3); // Mismatch WithArguments()
foo_.Bar2(2, 3); // Mismatch With()
foo_.Bar2(2, 1);
}
TEST_F(GMockOutputTest, MismatchArgumentsAndWithArguments) {
TEST_F(GMockOutputTest, MismatchArgumentsAndWith) {
EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
.WithArguments(Ge());
.With(Ge());
foo_.Bar2(1, 3); // Mismatch arguments and mismatch WithArguments()
foo_.Bar2(1, 3); // Mismatch arguments and mismatch With()
foo_.Bar2(2, 1);
}
+10 -10
Ver Arquivo
@@ -174,7 +174,7 @@ FILE:#:
Expected: to be called once
Actual: never called - unsatisfied and active
[ FAILED ] GMockOutputTest.MismatchArguments
[ RUN ] GMockOutputTest.MismatchWithArguments
[ RUN ] GMockOutputTest.MismatchWith
unknown file: Failure
Unexpected mock function call - returning default value.
@@ -183,12 +183,12 @@ Unexpected mock function call - returning default value.
Google Mock tried the following 1 expectation, but it didn't match:
FILE:#:
Expected: argument #0 is greater than or equal to argument #1
Actual: false
Expected args: are a pair (x, y) where x >= y
Actual: don't match
Expected: to be called once
Actual: never called - unsatisfied and active
[ FAILED ] GMockOutputTest.MismatchWithArguments
[ RUN ] GMockOutputTest.MismatchArgumentsAndWithArguments
[ FAILED ] GMockOutputTest.MismatchWith
[ RUN ] GMockOutputTest.MismatchArgumentsAndWith
unknown file: Failure
Unexpected mock function call - returning default value.
@@ -199,11 +199,11 @@ Google Mock tried the following 1 expectation, but it didn't match:
FILE:#:
Expected arg #0: is greater than or equal to 2
Actual: 1
Expected: argument #0 is greater than or equal to argument #1
Actual: false
Expected args: are a pair (x, y) where x >= y
Actual: don't match
Expected: to be called once
Actual: never called - unsatisfied and active
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith
[ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction
unknown file: Failure
@@ -290,8 +290,8 @@ Stack trace:
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
[ FAILED ] GMockOutputTest.MismatchArguments
[ FAILED ] GMockOutputTest.MismatchWithArguments
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
[ FAILED ] GMockOutputTest.MismatchWith
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
+17 -11
Ver Arquivo
@@ -12,15 +12,7 @@
'type': '<(library)',
'msvs_guid': 'BFE8E2A7-3B3B-43B0-A994-3058B852DB8B',
'sources': [
'gtest/include/gtest/internal/gtest-death-test-internal.h',
'gtest/include/gtest/internal/gtest-filepath.h',
'gtest/include/gtest/internal/gtest-internal.h',
'gtest/include/gtest/internal/gtest-linked_ptr.h',
'gtest/include/gtest/internal/gtest-param-util-generated.h',
'gtest/include/gtest/internal/gtest-param-util.h',
'gtest/include/gtest/internal/gtest-port.h',
'gtest/include/gtest/internal/gtest-string.h',
'gtest/include/gtest/internal/gtest-type-util.h',
# Sources based on files in r267 of gmock.
'gtest/include/gtest/gtest-death-test.h',
'gtest/include/gtest/gtest-message.h',
'gtest/include/gtest/gtest-param-test.h',
@@ -30,17 +22,31 @@
'gtest/include/gtest/gtest.h',
'gtest/include/gtest/gtest_pred_impl.h',
'gtest/include/gtest/gtest_prod.h',
'gtest/src/gtest-test-part.cc',
'gtest/src/gtest-typed-test.cc',
'gtest/include/gtest/internal/gtest-death-test-internal.h',
'gtest/include/gtest/internal/gtest-filepath.h',
'gtest/include/gtest/internal/gtest-internal.h',
'gtest/include/gtest/internal/gtest-linked_ptr.h',
'gtest/include/gtest/internal/gtest-param-util-generated.h',
'gtest/include/gtest/internal/gtest-param-util.h',
'gtest/include/gtest/internal/gtest-port.h',
'gtest/include/gtest/internal/gtest-string.h',
'gtest/include/gtest/internal/gtest-tuple.h',
'gtest/include/gtest/internal/gtest-type-util.h',
'gtest/src/gtest-all.cc',
'gtest/src/gtest-death-test.cc',
'gtest/src/gtest-filepath.cc',
'gtest/src/gtest-internal-inl.h',
'gtest/src/gtest-port.cc',
'gtest/src/gtest-test-part.cc',
'gtest/src/gtest-typed-test.cc',
'gtest/src/gtest.cc',
'multiprocess_func_list.cc',
'multiprocess_func_list.h',
'platform_test.h',
],
'sources!': [
'gtest/src/gtest-all.cc', # Not needed by our build.
],
'include_dirs': [
'gtest',
'gtest/include',