aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--CONTRIBUTORS37
-rw-r--r--COPYING28
-rw-r--r--Makefile.am181
-rw-r--r--README242
-rw-r--r--build-aux/.keep0
-rw-r--r--configure.ac115
-rw-r--r--include/gmock/gmock-actions.h900
-rw-r--r--include/gmock/gmock-cardinalities.h146
-rw-r--r--include/gmock/gmock-generated-actions.h1329
-rw-r--r--include/gmock/gmock-generated-actions.h.pump567
-rw-r--r--include/gmock/gmock-generated-function-mockers.h706
-rw-r--r--include/gmock/gmock-generated-function-mockers.h.pump200
-rw-r--r--include/gmock/gmock-generated-matchers.h650
-rw-r--r--include/gmock/gmock-generated-matchers.h.pump303
-rw-r--r--include/gmock/gmock-generated-nice-strict.h244
-rw-r--r--include/gmock/gmock-generated-nice-strict.h.pump146
-rw-r--r--include/gmock/gmock-matchers.h2094
-rw-r--r--include/gmock/gmock-printers.h514
-rw-r--r--include/gmock/gmock-spec-builders.h1568
-rw-r--r--include/gmock/gmock.h92
-rw-r--r--include/gmock/internal/gmock-generated-internal-utils.h277
-rw-r--r--include/gmock/internal/gmock-generated-internal-utils.h.pump136
-rw-r--r--include/gmock/internal/gmock-internal-utils.h339
-rw-r--r--include/gmock/internal/gmock-port.h314
-rw-r--r--make/Makefile109
-rw-r--r--scripts/generator/COPYING203
-rw-r--r--scripts/generator/README33
-rw-r--r--scripts/generator/README.cppclean115
-rwxr-xr-xscripts/generator/cpp/__init__.py0
-rwxr-xr-xscripts/generator/cpp/ast.py1713
-rwxr-xr-xscripts/generator/cpp/gmock_class.py148
-rwxr-xr-xscripts/generator/cpp/keywords.py58
-rwxr-xr-xscripts/generator/cpp/tokenize.py287
-rwxr-xr-xscripts/generator/cpp/utils.py41
-rwxr-xr-xscripts/generator/gmock_gen.py31
-rwxr-xr-xscripts/gmock_doctor.py376
-rw-r--r--src/gmock-all.cc43
-rw-r--r--src/gmock-cardinalities.cc155
-rw-r--r--src/gmock-internal-utils.cc135
-rw-r--r--src/gmock-matchers.cc61
-rw-r--r--src/gmock-printers.cc309
-rw-r--r--src/gmock-spec-builders.cc337
-rw-r--r--src/gmock.cc155
-rw-r--r--src/gmock_main.cc43
-rw-r--r--test/gmock-actions_test.cc902
-rw-r--r--test/gmock-cardinalities_test.cc422
-rw-r--r--test/gmock-generated-actions_test.cc946
-rw-r--r--test/gmock-generated-function-mockers_test.cc426
-rw-r--r--test/gmock-generated-internal-utils_test.cc127
-rw-r--r--test/gmock-generated-matchers_test.cc373
-rw-r--r--test/gmock-internal-utils_test.cc521
-rw-r--r--test/gmock-matchers_test.cc2629
-rw-r--r--test/gmock-nice-strict_test.cc228
-rw-r--r--test/gmock-port_test.cc95
-rw-r--r--test/gmock-printers_test.cc903
-rw-r--r--test/gmock-sample.cc32
-rw-r--r--test/gmock-sample.h49
-rw-r--r--test/gmock-spec-builders_test.cc1889
-rw-r--r--test/gmock_link_test.cc37
-rwxr-xr-xtest/gmock_output_test.py200
-rw-r--r--test/gmock_output_test_.cc241
-rw-r--r--test/gmock_output_test_golden.txt296
-rw-r--r--test/gmock_test.cc248
-rwxr-xr-xtest/gmock_test_utils.py126
65 files changed, 26173 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 00000000..be9b0ac2
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,3 @@
+Changes for 1.0.0:
+
+ * Initial Open Source release of Google Mock
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 00000000..50209471
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,37 @@
+# This file contains a list of people who've made non-trivial
+# contribution to the Google C++ Mocking Framework project. People
+# who commit code to the project are encouraged to add their names
+# here. Please keep the list sorted by first names.
+
+Benoit Sigoure <tsuna@google.com>
+Bogdan Piloca <boo@google.com>
+Chandler Carruth <chandlerc@google.com>
+Dave MacLachlan <dmaclach@gmail.com>
+David Anderson <danderson@google.com>
+Dean Sturtevant
+Gene Volovich <gv@cite.com>
+Hal Burch <gmock@hburch.com>
+Jeffrey Yasskin <jyasskin@google.com>
+Jim Keller <jimkeller@google.com>
+Joe Walnes <joe@truemesh.com>
+Jon Wray <jwray@google.com>
+Keir Mierle <mierle@gmail.com>
+Keith Ray <keith.ray@gmail.com>
+Kostya Serebryany <kcc@google.com>
+Lev Makhlis
+Mario Tanev <radix@google.com>
+Mark Paskin
+Markus Heule <markus.heule@gmail.com>
+Matthew Simmons <simmonmt@acm.org>
+Mike Bland <mbland@google.com>
+Neal Norwitz <nnorwitz@gmail.com>
+Owen Carlsen <ocarlsen@google.com>
+Paneendra Ba <paneendra@google.com>
+Paul Menage <menage@google.com>
+Piotr Kaminski <piotrk@google.com>
+Russ Rufer <russ@pentad.com>
+Takeshi Yoshino <tyoshino@google.com>
+Vadim Berman <vadimb@google.com>
+Vlad Losev <vladl@google.com>
+Wolfgang Klier <wklier@google.com>
+Zhanyong Wan <wan@google.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 00000000..1941a11f
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,28 @@
+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.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 00000000..6e6b6ec2
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,181 @@
+# Nonstandard package files for distribution.
+EXTRA_DIST =
+
+# Scripts and utilities to be installed by 'make install'.
+dist_bin_SCRIPTS = scripts/gmock_doctor.py
+
+# We define the global AM_CPPFLAGS as everything we compile includes from these
+# directories.
+AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I$(srcdir)/include
+
+# Build rules for libraries.
+lib_LTLIBRARIES = lib/libgmock.la lib/libgmock_main.la
+
+lib_libgmock_la_SOURCES = src/gmock.cc \
+ src/gmock-cardinalities.cc \
+ src/gmock-internal-utils.cc \
+ src/gmock-matchers.cc \
+ src/gmock-printers.cc \
+ src/gmock-spec-builders.cc
+
+pkginclude_HEADERS = include/gmock/gmock.h \
+ include/gmock/gmock-actions.h \
+ include/gmock/gmock-cardinalities.h \
+ include/gmock/gmock-generated-actions.h \
+ include/gmock/gmock-generated-function-mockers.h \
+ include/gmock/gmock-generated-matchers.h \
+ include/gmock/gmock-generated-nice-strict.h \
+ include/gmock/gmock-matchers.h \
+ include/gmock/gmock-printers.h \
+ include/gmock/gmock-spec-builders.h
+
+pkginclude_internaldir = $(pkgincludedir)/internal
+pkginclude_internal_HEADERS = \
+ include/gmock/internal/gmock-generated-internal-utils.h \
+ include/gmock/internal/gmock-internal-utils.h \
+ include/gmock/internal/gmock-port.h
+
+lib_libgmock_main_la_SOURCES = src/gmock_main.cc
+lib_libgmock_main_la_LIBADD = lib/libgmock.la
+
+# Build rules for tests. Automake's naming for some of these variables isn't
+# terribly obvious, so this is a brief reference:
+#
+# TESTS -- Programs run automatically by "make check"
+# check_PROGRAMS -- Programs built by "make check" but not necessarily run
+
+TESTS=
+TESTS_ENVIRONMENT = GMOCK_SOURCE_DIR="$(srcdir)/test" \
+ GMOCK_BUILD_DIR="$(top_builddir)/test"
+check_PROGRAMS=
+AM_LDFLAGS = $(GTEST_LDFLAGS)
+
+TESTS += test/gmock-actions_test
+check_PROGRAMS += test/gmock-actions_test
+test_gmock_actions_test_SOURCES = test/gmock-actions_test.cc
+test_gmock_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-cardinalities_test
+check_PROGRAMS += test/gmock-cardinalities_test
+test_gmock_cardinalities_test_SOURCES = test/gmock-cardinalities_test.cc
+test_gmock_cardinalities_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-generated-actions_test
+check_PROGRAMS += test/gmock-generated-actions_test
+test_gmock_generated_actions_test_SOURCES = test/gmock-generated-actions_test.cc
+test_gmock_generated_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-generated-function-mockers_test
+check_PROGRAMS += test/gmock-generated-function-mockers_test
+test_gmock_generated_function_mockers_test_SOURCES = \
+ test/gmock-generated-function-mockers_test.cc
+test_gmock_generated_function_mockers_test_LDADD = $(GTEST_LIBS) \
+ lib/libgmock_main.la
+
+TESTS += test/gmock-generated-internal-utils_test
+check_PROGRAMS += test/gmock-generated-internal-utils_test
+test_gmock_generated_internal_utils_test_SOURCES = \
+ test/gmock-generated-internal-utils_test.cc
+test_gmock_generated_internal_utils_test_LDADD = $(GTEST_LIBS) \
+ lib/libgmock_main.la
+
+TESTS += test/gmock-generated-matchers_test
+check_PROGRAMS += test/gmock-generated-matchers_test
+test_gmock_generated_matchers_test_SOURCES = \
+ test/gmock-generated-matchers_test.cc
+test_gmock_generated_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-internal-utils_test
+check_PROGRAMS += test/gmock-internal-utils_test
+test_gmock_internal_utils_test_SOURCES = test/gmock-internal-utils_test.cc
+test_gmock_internal_utils_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock_link_test
+check_PROGRAMS += test/gmock_link_test
+test_gmock_link_test_SOURCES = test/gmock_link_test.cc \
+ test/gmock-sample.cc \
+ test/gmock-sample.h
+test_gmock_link_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-matchers_test
+check_PROGRAMS += test/gmock-matchers_test
+test_gmock_matchers_test_SOURCES = test/gmock-matchers_test.cc
+test_gmock_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-nice-strict_test
+check_PROGRAMS += test/gmock-nice-strict_test
+test_gmock_nice_strict_test_SOURCES = test/gmock-nice-strict_test.cc
+test_gmock_nice_strict_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-port_test
+check_PROGRAMS += test/gmock-port_test
+test_gmock_port_test_SOURCES = test/gmock-port_test.cc
+test_gmock_port_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-printers_test
+check_PROGRAMS += test/gmock-printers_test
+test_gmock_printers_test_SOURCES = test/gmock-printers_test.cc
+test_gmock_printers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock-spec-builders_test
+check_PROGRAMS += test/gmock-spec-builders_test
+test_gmock_spec_builders_test_SOURCES = test/gmock-spec-builders_test.cc
+test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+TESTS += test/gmock_test
+check_PROGRAMS += test/gmock_test
+test_gmock_test_SOURCES = test/gmock_test.cc
+test_gmock_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
+# 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
+# attempt to build and execute these tests if Autoconf has found Python v2.3 on
+# the system, we don't use the PYTHON variable it specified as the valid
+# interpreter. The problem is that TESTS_ENVIRONMENT is a global variable, and
+# thus we cannot distinguish between C++ unit tests and Python unit tests.
+dist_check_SCRIPTS =
+
+# Python modules used by multiple Python tests below.
+dist_check_SCRIPTS += test/gmock_test_utils.py
+
+check_PROGRAMS += test/gmock_output_test_
+test_gmock_output_test__SOURCES = test/gmock_output_test_.cc
+test_gmock_output_test__LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+dist_check_SCRIPTS += test/gmock_output_test.py
+EXTRA_DIST += test/gmock_output_test_golden.txt
+
+# Enable all the python driven tests when we can run them.
+if HAVE_PYTHON
+TESTS += test/gmock_output_test.py
+endif
+
+# Nonstandard package files for distribution.
+EXTRA_DIST += \
+ CHANGES \
+ CONTRIBUTORS \
+ make/Makefile \
+ src/gmock-all.cc
+
+# Pump scripts for generating Google Mock headers.
+# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
+EXTRA_DIST += include/gmock/gmock-generated-actions.h.pump \
+ include/gmock/gmock-generated-function-mockers.h.pump \
+ include/gmock/gmock-generated-matchers.h.pump \
+ include/gmock/gmock-generated-nice-strict.h.pump \
+ include/gmock/internal/gmock-generated-internal-utils.h.pump
+
+# The Google Mock Generator tool from the cppclean project.
+EXTRA_DIST += \
+ scripts/generator/COPYING \
+ scripts/generator/README \
+ scripts/generator/README.cppclean \
+ scripts/generator/cpp/__init__.py \
+ scripts/generator/cpp/ast.py \
+ scripts/generator/cpp/gmock_class.py \
+ scripts/generator/cpp/keywords.py \
+ scripts/generator/cpp/tokenize.py \
+ scripts/generator/cpp/utils.py \
+ scripts/generator/gmock_gen.py
+
+# TODO(wan@google.com): add the MSVC projects to EXTRA_DIST.
diff --git a/README b/README
new file mode 100644
index 00000000..0f382147
--- /dev/null
+++ b/README
@@ -0,0 +1,242 @@
+Google C++ Mocking Framework
+============================
+http://code.google.com/p/googlemock/
+
+Overview
+--------
+Google's framework for writing and using C++ mock classes on Linux,
+Mac OS X, and Windows. Inspired by jMock, EasyMock, and Hamcrest, and
+designed with C++'s specifics in mind, it can help you derive better
+designs of your system and write better tests.
+
+Google Mock:
+
+- provides a declarative syntax for defining mocks,
+- can easily define partial (hybrid) mocks, which are a cross of real
+ and mock objects,
+- handles functions of arbitrary types and overloaded functions,
+- comes with a rich set of matchers for validating function arguments,
+- uses an intuitive syntax for controlling the behavior of a mock,
+- does automatic verification of expectations (no record-and-replay
+ needed),
+- allows arbitrary (partial) ordering constraints on
+ function calls to be expressed,
+- lets a user extend it by defining new matchers and actions.
+- does not use exceptions, and
+- is easy to learn and use.
+
+Please see the project page above for more information as well as mailing lists
+for questions, discussions, and development. There is also an IRC channel on
+OFTC (irc.oftc.net) #gtest available. Please join us!
+
+Please note that code under scripts/generator/ is from the cppclean
+project (http://code.google.com/p/cppclean/) and under the Apache
+License.
+
+Requirements
+------------
+Google Mock is not a testing framework itself. Instead, it needs a
+testing framework for writing tests. Currently Google Mock only works
+with Google Test (http://code.google.com/p/googletest/), although
+eventually we plan to support other C++ testing frameworks. You can
+use either the copy of Google Test that comes with Google Mock, or a
+compatible version you already have.
+
+TODO(wan@google.com): describe which Google Test versions are
+compatible with the latest Google Mock release.
+
+Google Mock depends on advanced C++ features and thus requires a more
+modern compiler. The following are needed to use Google Mock:
+
+### Linux Requirements ###
+These are the base requirements to build and use Google Mock from a source
+package (as described below):
+ * GNU-compatible Make or "gmake"
+ * POSIX-standard shell
+ * POSIX(-2) Regular Expressions (regex.h)
+ * gcc 4.0 or newer
+
+Furthermore, if you are building Google Mock from a VCS Checkout (also
+described below), there are further requirements:
+ * Automake version 1.9 or newer
+ * Autoconf version 2.59 or newer
+ * Libtool / Libtoolize
+ * Python version 2.3 or newer
+
+### Windows Requirements ###
+ * Microsoft Visual C++ 8.0 SP1 or newer
+ * An implementation of the tr1 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
+ * Developer Tools Installed
+
+Getting the Source
+------------------
+There are two primary ways of getting Google Mock's source code: you can
+download a source release in your preferred archive format, or directly check
+out the source from a Version Control System (VCS, we use Google Code's
+Subversion hosting). The VCS checkout requires a few extra steps and some extra
+software packages on your system, but lets you track development, and make
+patches to contribute much more easily, so we highly encourage it.
+
+### VCS Checkout: ###
+The first step is to select whether you want to check out the main line of
+development on Google Mock, or one of the released branches. The former will be
+much more active and have the latest features, but the latter provides much
+more stability and predictability. Choose whichever fits your needs best, and
+proceed with the following Subversion commands:
+
+ $ svn checkout http://googlemock.googlecode.com/svn/trunk/ gmock-svn
+
+or for a release version X.Y.*'s branch:
+
+ $ svn checkout http://googlemock.googlecode.com/svn/branches/release-X.Y/ \
+ gmock-X.Y-svn
+
+Next you will need to prepare the GNU Autotools build system, if you
+are using Linux or Mac OS X. Enter the target directory of the
+checkout command you used ('gmock-svn' or 'gmock-X.Y-svn' above) and
+proceed with the following commands:
+
+ $ aclocal-1.9 # Where "1.9" must match the following automake command.
+ $ libtoolize -c # Use "glibtoolize -c" instead on Mac OS X.
+ $ autoheader
+ $ automake-1.9 -ac # See Automake version requirements above.
+ $ autoconf
+
+While this is a bit complicated, it will most often be automatically re-run by
+your "make" invocations, so in practice you shouldn't need to worry too much.
+Once you have completed these steps, you are ready to build the library.
+
+TODO(chandlerc@google.com): Update the above with instructions on
+preparing the build system for Google Test.
+
+### Source Package: ###
+Google Mock is also released in source packages which can be downloaded from
+its Google Code download page[1]. Several different archive formats are
+provided, but the only difference is the tools used to manipulate them, and the
+size of the resulting file. Download whichever you are most comfortable with.
+
+ [1] Google Mock Downloads: http://code.google.com/p/googlemock/downloads/list
+
+Once downloaded expand the archive using whichever tools you prefer for that
+type. This will always result in a new directory with the name "gmock-X.Y.Z"
+which contains all of the source code. Here are some examples in Linux:
+
+ $ tar -xvzf gmock-X.Y.Z.tar.gz
+ $ tar -xvjf gmock-X.Y.Z.tar.bz2
+ $ unzip gmock-X.Y.Z.zip
+
+Building the Source
+-------------------
+### Linux and Mac OS X (without Xcode) ###
+There are two primary options for building the source at this point: build it
+inside the source code tree, or in a separate directory. We recommend building
+in a separate directory as that tends to produce both more consistent results
+and be easier to clean up should anything go wrong, but both patterns are
+supported. The only hard restriction is that while the build directory can be
+a subdirectory of the source directory, the opposite is not possible and will
+result in errors. Once you have selected where you wish to build Google Mock,
+create the directory if necessary, and enter it. The following steps apply for
+either approach by simply substituting the shell variable SRCDIR with "." for
+building inside the source directory, and the relative path to the source
+directory otherwise.
+
+ $ ${SRCDIR}/configure # Standard GNU configure script, --help for more info
+ $ make # Standard makefile following GNU conventions
+ $ make check # Builds and runs all tests - all should pass
+
+Other programs will only be able to use Google Mock's functionality if you
+install it in a location which they can access, in Linux this is typically
+under '/usr/local'. The following command will install all of the Google Mock
+libraries, public headers, and utilities necessary for other programs and
+libraries to leverage it:
+
+ $ sudo make install # Not necessary, but allows use by other programs
+
+TODO(chandlerc@google.com): This section needs to be expanded when the
+'gmock-config' script is finished and Autoconf macro's are provided (or not
+provided) in order to properly reflect the process for other programs to
+locate, include, and link against Google Mock.
+
+Finally, should you need to remove Google Mock from your system after having
+installed it, run the following command, and it will back out its changes.
+However, note carefully that you must run this command on the *same* Google
+Mock build that you ran the install from, or the results are not predictable.
+If you install Google Mock on your system, and are working from a VCS checkout,
+make sure you run this *before* updating your checkout of the source in order
+to uninstall the same version which you installed.
+
+ $ sudo make uninstall # Must be run against the exact same build as "install"
+
+TODO(chandlerc@google.com): Fixes the above instructions to match the
+actual implementation.
+
+### Windows ###
+We don't have the Visual Studio project files for Google Mock ready
+yet. Please see the next two sections on how you can integrate Google
+Mock into your project's build system.
+
+### Using GNU Make ###
+The make/ directory contains a Makefile that you can use to build
+Google Mock on systems where GNU make is available (e.g. Linux and Mac
+OS X). It doesn't try to build Google Mock's own tests. Instead, it
+just builds the Google Mock libraries and some sample tests. You can
+use it as a starting point for your own Makefile.
+
+If the default settings are correct for your environment, the
+following commands should succeed:
+
+ $ cd ${SRCDIR}/make
+ $ make
+ $ ./gmock_test
+
+If you see errors, try to tweak the contents of make/Makefile to make
+them go away. There are instructions in make/Makefile on how to do
+it.
+
+### Using Your Own Build System ###
+If none of the build solutions we provide works for you, or if you
+prefer your own build system, you just need to compile
+${GTEST_SRCDIR}/src/gtest-all.cc (where GTEST_SRCDIR is the root of
+the Google Test source tree) and src/gmock-all.cc into a library and
+link your tests with it. Assuming a Linux-like system and gcc,
+something like the following will do:
+
+ $ cd ${SRCDIR}
+ $ g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
+ -c {GTEST_SRCDIR}/src/gtest-all.cc
+ $ g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
+ -c src/gmock-all.cc
+ $ ar -rv libgmock.a gtest-all.o gmock-all.o
+ $ 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
+in the C++ sense) using a script. A template file is named FOO.pump,
+where FOO is the name of the file it will generate. For example, the
+file include/gmock/gmock-generated-actions.h.pump is used to generate
+gmock-generated-actions.h in the same directory.
+
+Normally you don't need to worry about regenerating the source files,
+unless you need to modify them (e.g. if you are working on a patch for
+Google Mock). In that case, you should modify the corresponding .pump
+files instead and run the 'pump' script (for Pump is Useful for Meta
+Programming) to regenerate them. We are still working on releasing
+the script and its documentation. If you need it now, please email
+googlemock@googlegroups.com such that we know to make it happen
+sooner.
+
+Happy testing!
diff --git a/build-aux/.keep b/build-aux/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/build-aux/.keep
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 00000000..daacfdd8
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,115 @@
+AC_INIT([Google C++ Mocking Framework],
+ [1.0.0],
+ [googlemock@googlegroups.com],
+ [gmock])
+
+# Provide various options to initialize the Autoconf and configure processes.
+AC_PREREQ([2.59])
+AC_CONFIG_SRCDIR([./COPYING])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_HEADERS([build-aux/config.h])
+AC_CONFIG_FILES([Makefile])
+
+# Initialize Automake with various options. We require at least v1.9, prevent
+# pedantic complaints about package files, and enable various distribution
+# targets.
+AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects])
+
+# Check for programs used in building Google Test.
+AC_PROG_CC
+AC_PROG_CXX
+AC_LANG([C++])
+AC_PROG_LIBTOOL
+
+# TODO(chandlerc@google.com): Currently we aren't running the Python tests
+# against the interpreter detected by AM_PATH_PYTHON, and so we condition
+# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's
+# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env"
+# hashbang.
+PYTHON= # We *do not* allow the user to specify a python interpreter
+AC_PATH_PROG([PYTHON],[python],[:])
+AS_IF([test "$PYTHON" != ":"],
+ [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
+AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
+
+# TODO(chandlerc@google.com) Check for the necessary system headers.
+
+# GoogleMock currently has hard dependencies upon GoogleTest above and beyond
+# running its own test suite, so we both provide our own version in
+# a subdirectory and provide some logic to use a custom version or a system
+# installed version.
+AC_ARG_WITH([gtest],
+ [AS_HELP_STRING([--with-gtest],
+ [Specifies how to find the gtest package. If no
+ arguments are given, the default behavior, a
+ system installed gtest will be used if present,
+ and an internal version built otherwise. If a
+ path is provided, the gtest built or installed at
+ that prefix will be used.])],
+ [],
+ [with_gtest=yes])
+AS_IF([test "x$with_gtest" == "xno"],
+ [AC_MSG_ERROR([
+Support for GoogleTest was explicitly disabled. Currently GoogleMock has a hard
+dependency upon GoogleTest to build, please provide a version, or allow
+GoogleMock to use any installed version and fall back upon its internal
+version.])])
+
+# Setup various GTEST variables. TODO(chandlerc@google.com): When these are
+# used below, they should be used such that any pre-existing values always
+# trump values we set them to, so that they can be used to selectively override
+# details of the detection process.
+AC_ARG_VAR([GTEST_CONFIG],
+ [The exact path of Google Test's 'gtest-config' script.])
+AC_ARG_VAR([GTEST_CPPFLAGS],
+ [C-like preprocessor flags for Google Test.])
+AC_ARG_VAR([GTEST_CXXFLAGS],
+ [C++ compile flags for Google Test.])
+AC_ARG_VAR([GTEST_LDFLAGS],
+ [Linker path and option flags for Google Test.])
+AC_ARG_VAR([GTEST_LIBS],
+ [Library linking flags for Google Test.])
+AC_ARG_VAR([GTEST_VERSION],
+ [The version of Google Test available.])
+HAVE_BUILT_GTEST="no"
+
+# TODO(chandlerc@google.com): This is arbitrary, but we will need to introduce
+# some features to the GoogleTest build system to help support GoogleMock, and
+# at that point it will become more meaningful.
+GTEST_MIN_VERSION="1.0.0"
+
+# Begin filling in variables as we are able.
+AS_IF([test "x${with_gtest}" != "xyes"],
+ [AS_IF([test -x "${with_gtest}/scripts/gtest-config"],
+ [GTEST_CONFIG="${with_gtest}/scripts/gtest-config"],
+ [GTEST_CONFIG="${with_gtest}/bin/gtest-config"])
+ AS_IF([test -x "${GTEST_CONFIG}"], [],
+ [AC_MSG_ERROR([
+Unable to locate either a built or installed Google Test at '${with_gtest}'.])
+ ])])
+
+AS_IF([test -x "${GTEST_CONFIG}"], [],
+ [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])
+AS_IF([test -x "${GTEST_CONFIG}"],
+ [AC_MSG_CHECKING([for Google Test with version >= ${GTEST_MIN_VERSION}])
+ AS_IF([${GTEST_CONFIG} --min-version=${GTEST_MIN_VERSION}],
+ [AC_MSG_RESULT([yes])
+ HAVE_BUILT_GTEST="yes"],
+ [AC_MSG_RESULT([no])])])
+
+# TODO(chandlerc@google.com): Need to add support for passing a custom prefix
+# into the gtest-config script..
+AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"],
+ [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`
+ GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`
+ GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
+ GTEST_LIBS=`${GTEST_CONFIG} --libs`
+ GTEST_VERSION=`${GTEST_CONFIG} --version`],
+ [AC_MSG_ERROR([TODO(chandlerc@google.com): Need to add support for
+ building the internal gtest.])])
+
+# TODO(chandlerc@google.com) Check the types, structures, and other compiler
+# and architecture characteristics.
+
+# Output the generated files. No further autoconf macros may be used.
+AC_OUTPUT
diff --git a/include/gmock/gmock-actions.h b/include/gmock/gmock-actions.h
new file mode 100644
index 00000000..a4327588
--- /dev/null
+++ b/include/gmock/gmock-actions.h
@@ -0,0 +1,900 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used actions.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
+
+#include <algorithm>
+#include <string>
+#include <errno.h>
+#include <gmock/internal/gmock-internal-utils.h>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+// To implement an action Foo, define:
+// 1. a class FooAction that implements the ActionInterface interface, and
+// 2. a factory function that creates an Action object from a
+// const FooAction*.
+//
+// The two-level delegation design follows that of Matcher, providing
+// consistency for extension developers. It also eases ownership
+// management as Action objects can now be copied like plain values.
+
+namespace internal {
+
+template <typename F>
+class MonomorphicDoDefaultActionImpl;
+
+template <typename F1, typename F2>
+class ActionAdaptor;
+
+// BuiltInDefaultValue<T>::Get() returns the "built-in" default
+// value for type T, which is NULL when T is a pointer type, 0 when T
+// is a numeric type, false when T is bool, or "" when T is string or
+// std::string. For any other type T, this value is undefined and the
+// function will abort the process.
+template <typename T>
+class BuiltInDefaultValue {
+ public:
+ static T Get() {
+ Assert(false, __FILE__, __LINE__,
+ "Default action undefined for the function return type.");
+ return internal::Invalid<T>();
+ // The above statement will never be reached, but is required in
+ // order for this function to compile.
+ }
+};
+
+// This partial specialization says that we use the same built-in
+// default value for T and const T.
+template <typename T>
+class BuiltInDefaultValue<const T> {
+ public:
+ static T Get() { return BuiltInDefaultValue<T>::Get(); }
+};
+
+// This partial specialization defines the default values for pointer
+// types.
+template <typename T>
+class BuiltInDefaultValue<T*> {
+ public:
+ static T* Get() { return NULL; }
+};
+
+// The following specializations define the default values for
+// specific types we care about.
+#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(type, value) \
+ template <> \
+ class BuiltInDefaultValue<type> { \
+ public: \
+ static type Get() { return value; } \
+ }
+
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(void, ); // NOLINT
+#if GTEST_HAS_GLOBAL_STRING
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(::string, "");
+#endif // GTEST_HAS_GLOBAL_STRING
+#if GTEST_HAS_STD_STRING
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(::std::string, "");
+#endif // GTEST_HAS_STD_STRING
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(bool, false);
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned char, '\0');
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed char, '\0');
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(char, '\0');
+
+// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
+// Using them is a bad practice and not portable. So don't use them.
+//
+// Still, Google Mock is designed to work even if the user uses signed
+// wchar_t or unsigned wchar_t (obviously, assuming the compiler
+// supports them).
+//
+// To gcc,
+//
+// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
+//
+// MSVC does not recognize signed wchar_t or unsigned wchar_t. It
+// treats wchar_t as a native type usually, but treats it as the same
+// as unsigned short when the compiler option /Zc:wchar_t- is
+// specified.
+//
+// Therefore we provide a default action for wchar_t when compiled
+// with gcc or _NATIVE_WCHAR_T_DEFINED is defined.
+//
+// There's no need for a default action for signed wchar_t, as that
+// type is the same as wchar_t for gcc, and invalid for MSVC.
+//
+// There's also no need for a default action for unsigned wchar_t, as
+// that type is the same as unsigned int for gcc, and invalid for
+// MSVC.
+#if defined(__GNUC__) || defined(_NATIVE_WCHAR_T_DEFINED)
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(wchar_t, 0U); // NOLINT
+#endif
+
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned short, 0U); // NOLINT
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed short, 0); // NOLINT
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned int, 0U);
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed int, 0);
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned long, 0UL); // NOLINT
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed long, 0L); // NOLINT
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(UInt64, 0);
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(Int64, 0);
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(float, 0);
+GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(double, 0);
+
+#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE
+
+} // namespace internal
+
+// When an unexpected function call is encountered, Google Mock will
+// let it return a default value if the user has specified one for its
+// return type, or if the return type has a built-in default value;
+// otherwise Google Mock won't know what value to return and will have
+// to abort the process.
+//
+// The DefaultValue<T> class allows a user to specify the
+// default value for a type T that is both copyable and publicly
+// destructible (i.e. anything that can be used as a function return
+// type). The usage is:
+//
+// // Sets the default value for type T to be foo.
+// DefaultValue<T>::Set(foo);
+template <typename T>
+class DefaultValue {
+ public:
+ // Sets the default value for type T; requires T to be
+ // copy-constructable and have a public destructor.
+ static void Set(T x) {
+ delete value_;
+ value_ = new T(x);
+ }
+
+ // Unsets the default value for type T.
+ static void Clear() {
+ delete value_;
+ value_ = NULL;
+ }
+
+ // Returns true iff the user has set the default value for type T.
+ static bool IsSet() { return value_ != NULL; }
+
+ // Returns the default value for type T if the user has set one;
+ // otherwise returns the built-in default value if there is one;
+ // otherwise aborts the process.
+ static T Get() {
+ return value_ == NULL ?
+ internal::BuiltInDefaultValue<T>::Get() : *value_;
+ }
+ private:
+ static const T* value_;
+};
+
+// This partial specialization allows a user to set default values for
+// reference types.
+template <typename T>
+class DefaultValue<T&> {
+ public:
+ // Sets the default value for type T&.
+ static void Set(T& x) { // NOLINT
+ address_ = &x;
+ }
+
+ // Unsets the default value for type T&.
+ static void Clear() {
+ address_ = NULL;
+ }
+
+ // Returns true iff the user has set the default value for type T&.
+ static bool IsSet() { return address_ != NULL; }
+
+ // Returns the default value for type T& if the user has set one;
+ // otherwise returns the built-in default value if there is one;
+ // otherwise aborts the process.
+ static T& Get() {
+ return address_ == NULL ?
+ internal::BuiltInDefaultValue<T&>::Get() : *address_;
+ }
+ private:
+ static T* address_;
+};
+
+// This specialization allows DefaultValue<void>::Get() to
+// compile.
+template <>
+class DefaultValue<void> {
+ public:
+ static void Get() {}
+};
+
+// Points to the user-set default value for type T.
+template <typename T>
+const T* DefaultValue<T>::value_ = NULL;
+
+// Points to the user-set default value for type T&.
+template <typename T>
+T* DefaultValue<T&>::address_ = NULL;
+
+// Implement this interface to define an action for function type F.
+template <typename F>
+class ActionInterface {
+ public:
+ typedef typename internal::Function<F>::Result Result;
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ ActionInterface() : is_do_default_(false) {}
+
+ virtual ~ActionInterface() {}
+
+ // Performs the action. This method is not const, as in general an
+ // action can have side effects and be stateful. For example, a
+ // get-the-next-element-from-the-collection action will need to
+ // remember the current element.
+ virtual Result Perform(const ArgumentTuple& args) = 0;
+
+ // Returns true iff this is the DoDefault() action.
+ bool IsDoDefault() const { return is_do_default_; }
+ private:
+ template <typename Function>
+ friend class internal::MonomorphicDoDefaultActionImpl;
+
+ // This private constructor is reserved for implementing
+ // DoDefault(), the default action for a given mock function.
+ explicit ActionInterface(bool is_do_default)
+ : is_do_default_(is_do_default) {}
+
+ // True iff this action is DoDefault().
+ const bool is_do_default_;
+};
+
+// An Action<F> is a copyable and IMMUTABLE (except by assignment)
+// object that represents an action to be taken when a mock function
+// of type F is called. The implementation of Action<T> is just a
+// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
+// Don't inherit from Action!
+//
+// You can view an object implementing ActionInterface<F> as a
+// concrete action (including its current state), and an Action<F>
+// object as a handle to it.
+template <typename F>
+class Action {
+ public:
+ typedef typename internal::Function<F>::Result Result;
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ // Constructs a null Action. Needed for storing Action objects in
+ // STL containers.
+ Action() : impl_(NULL) {}
+
+ // Constructs an Action from its implementation.
+ explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
+
+ // Copy constructor.
+ Action(const Action& action) : impl_(action.impl_) {}
+
+ // This constructor allows us to turn an Action<Func> object into an
+ // Action<F>, as long as F's arguments can be implicitly converted
+ // to Func's and Func's return type cann be implicitly converted to
+ // F's.
+ template <typename Func>
+ explicit Action(const Action<Func>& action);
+
+ // Returns true iff this is the DoDefault() action.
+ bool IsDoDefault() const { return impl_->IsDoDefault(); }
+
+ // Performs the action. Note that this method is const even though
+ // the corresponding method in ActionInterface is not. The reason
+ // is that a const Action<F> means that it cannot be re-bound to
+ // another concrete action, not that the concrete action it binds to
+ // cannot change state. (Think of the difference between a const
+ // pointer and a pointer to const.)
+ Result Perform(const ArgumentTuple& args) const {
+ return impl_->Perform(args);
+ }
+ private:
+ template <typename F1, typename F2>
+ friend class internal::ActionAdaptor;
+
+ internal::linked_ptr<ActionInterface<F> > impl_;
+};
+
+// The PolymorphicAction class template makes it easy to implement a
+// polymorphic action (i.e. an action that can be used in mock
+// functions of than one type, e.g. Return()).
+//
+// To define a polymorphic action, a user first provides a COPYABLE
+// implementation class that has a Perform() method template:
+//
+// class FooAction {
+// public:
+// template <typename Result, typename ArgumentTuple>
+// Result Perform(const ArgumentTuple& args) const {
+// // Processes the arguments and returns a result, using
+// // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
+// }
+// ...
+// };
+//
+// Then the user creates the polymorphic action using
+// MakePolymorphicAction(object) where object has type FooAction. See
+// the definition of Return(void) and SetArgumentPointee<N>(value) for
+// complete examples.
+template <typename Impl>
+class PolymorphicAction {
+ public:
+ explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
+
+ template <typename F>
+ operator Action<F>() const {
+ return Action<F>(new MonomorphicImpl<F>(impl_));
+ }
+ private:
+ template <typename F>
+ class MonomorphicImpl : public ActionInterface<F> {
+ public:
+ typedef typename internal::Function<F>::Result Result;
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ return impl_.template Perform<Result>(args);
+ }
+
+ private:
+ Impl impl_;
+ };
+
+ Impl impl_;
+};
+
+// Creates an Action from its implementation and returns it. The
+// created Action object owns the implementation.
+template <typename F>
+Action<F> MakeAction(ActionInterface<F>* impl) {
+ return Action<F>(impl);
+}
+
+// Creates a polymorphic action from its implementation. This is
+// easier to use than the PolymorphicAction<Impl> constructor as it
+// doesn't require you to explicitly write the template argument, e.g.
+//
+// MakePolymorphicAction(foo);
+// vs
+// PolymorphicAction<TypeOfFoo>(foo);
+template <typename Impl>
+inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
+ return PolymorphicAction<Impl>(impl);
+}
+
+namespace internal {
+
+// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
+// and F1 are compatible.
+template <typename F1, typename F2>
+class ActionAdaptor : public ActionInterface<F1> {
+ public:
+ typedef typename internal::Function<F1>::Result Result;
+ typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
+
+ explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ return impl_->Perform(args);
+ }
+ private:
+ const internal::linked_ptr<ActionInterface<F2> > impl_;
+};
+
+// Implements the polymorphic Return(x) action, which can be used in
+// any function that returns the type of x, regardless of the argument
+// types.
+template <typename R>
+class ReturnAction {
+ public:
+ // Constructs a ReturnAction object from the value to be returned.
+ // 'value' is passed by value instead of by const reference in order
+ // to allow Return("string literal") to compile.
+ explicit ReturnAction(R value) : value_(value) {}
+
+ // This template type conversion operator allows Return(x) to be
+ // used in ANY function that returns x's type.
+ template <typename F>
+ operator Action<F>() const {
+ // Assert statement belongs here because this is the best place to verify
+ // conditions on F. It produces the clearest error messages
+ // in most compilers.
+ // Impl really belongs in this scope as a local class but can't
+ // because MSVC produces duplicate symbols in different translation units
+ // in this case. Until MS fixes that bug we put Impl into the class scope
+ // and put the typedef both here (for use in assert statement) and
+ // in the Impl class. But both definitions must be the same.
+ typedef typename Function<F>::Result Result;
+ GMOCK_COMPILE_ASSERT(!internal::is_reference<Result>::value,
+ use_ReturnRef_instead_of_Return_to_return_a_reference);
+ return Action<F>(new Impl<F>(value_));
+ }
+ private:
+ // Implements the Return(x) action for a particular function type F.
+ template <typename F>
+ class Impl : public ActionInterface<F> {
+ public:
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+
+ explicit Impl(R value) : value_(value) {}
+
+ virtual Result Perform(const ArgumentTuple&) { return value_; }
+
+ private:
+ R value_;
+ };
+
+ R value_;
+};
+
+// Implements the ReturnNull() action.
+class ReturnNullAction {
+ public:
+ // Allows ReturnNull() to be used in any pointer-returning function.
+ template <typename Result, typename ArgumentTuple>
+ static Result Perform(const ArgumentTuple&) {
+ GMOCK_COMPILE_ASSERT(internal::is_pointer<Result>::value,
+ ReturnNull_can_be_used_to_return_a_pointer_only);
+ return NULL;
+ }
+};
+
+// Implements the Return() action.
+class ReturnVoidAction {
+ public:
+ // Allows Return() to be used in any void-returning function.
+ template <typename Result, typename ArgumentTuple>
+ static void Perform(const ArgumentTuple&) {
+ CompileAssertTypesEqual<void, Result>();
+ }
+};
+
+// Implements the polymorphic ReturnRef(x) action, which can be used
+// in any function that returns a reference to the type of x,
+// regardless of the argument types.
+template <typename T>
+class ReturnRefAction {
+ public:
+ // Constructs a ReturnRefAction object from the reference to be returned.
+ explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
+
+ // This template type conversion operator allows ReturnRef(x) to be
+ // used in ANY function that returns a reference to x's type.
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ // Asserts that the function return type is a reference. This
+ // catches the user error of using ReturnRef(x) when Return(x)
+ // should be used, and generates some helpful error message.
+ GMOCK_COMPILE_ASSERT(internal::is_reference<Result>::value,
+ use_Return_instead_of_ReturnRef_to_return_a_value);
+ return Action<F>(new Impl<F>(ref_));
+ }
+ private:
+ // Implements the ReturnRef(x) action for a particular function type F.
+ template <typename F>
+ class Impl : public ActionInterface<F> {
+ public:
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+
+ explicit Impl(T& ref) : ref_(ref) {} // NOLINT
+
+ virtual Result Perform(const ArgumentTuple&) {
+ return ref_;
+ }
+ private:
+ T& ref_;
+ };
+
+ T& ref_;
+};
+
+// Implements the DoDefault() action for a particular function type F.
+template <typename F>
+class MonomorphicDoDefaultActionImpl : public ActionInterface<F> {
+ public:
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+
+ MonomorphicDoDefaultActionImpl() : ActionInterface<F>(true) {}
+
+ // For technical reasons, DoDefault() cannot be used inside a
+ // composite action (e.g. DoAll(...)). It can only be used at the
+ // top level in an EXPECT_CALL(). If this function is called, the
+ // user must be using DoDefault() inside a composite action, and we
+ // have to generate a run-time error.
+ virtual Result Perform(const ArgumentTuple&) {
+ Assert(false, __FILE__, __LINE__,
+ "You are using DoDefault() inside a composite action like "
+ "DoAll() or WithArgs(). This is not supported for technical "
+ "reasons. Please instead spell out the default action, or "
+ "assign the default action to an Action variable and use "
+ "the variable in various places.");
+ return internal::Invalid<Result>();
+ // The above statement will never be reached, but is required in
+ // order for this function to compile.
+ }
+};
+
+// Implements the polymorphic DoDefault() action.
+class DoDefaultAction {
+ public:
+ // This template type conversion operator allows DoDefault() to be
+ // used in any function.
+ template <typename F>
+ operator Action<F>() const {
+ return Action<F>(new MonomorphicDoDefaultActionImpl<F>);
+ }
+};
+
+// Implements the Assign action to set a given pointer referent to a
+// particular value.
+template <typename T1, typename T2>
+class AssignAction {
+ public:
+ AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
+
+ template <typename Result, typename ArgumentTuple>
+ void Perform(const ArgumentTuple &args) const {
+ *ptr_ = value_;
+ }
+ private:
+ T1* const ptr_;
+ const T2 value_;
+};
+
+// Implements the SetErrnoAndReturn action to simulate return from
+// various system calls and libc functions.
+template <typename T>
+class SetErrnoAndReturnAction {
+ public:
+ SetErrnoAndReturnAction(int errno_value, T result)
+ : errno_(errno_value),
+ result_(result) {}
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple &args) const {
+ errno = errno_;
+ return result_;
+ }
+ private:
+ const int errno_;
+ const T result_;
+};
+
+// Implements the SetArgumentPointee<N>(x) action for any function
+// whose N-th argument (0-based) is a pointer to x's type. The
+// template parameter kIsProto is true iff type A is ProtocolMessage,
+// proto2::Message, or a sub-class of those.
+template <size_t N, typename A, bool kIsProto>
+class SetArgumentPointeeAction {
+ public:
+ // Constructs an action that sets the variable pointed to by the
+ // N-th function argument to 'value'.
+ explicit SetArgumentPointeeAction(const A& value) : value_(value) {}
+
+ template <typename Result, typename ArgumentTuple>
+ void Perform(const ArgumentTuple& args) const {
+ CompileAssertTypesEqual<void, Result>();
+ *::std::tr1::get<N>(args) = value_;
+ }
+
+ private:
+ const A value_;
+};
+
+template <size_t N, typename Proto>
+class SetArgumentPointeeAction<N, Proto, true> {
+ public:
+ // Constructs an action that sets the variable pointed to by the
+ // N-th function argument to 'proto'. Both ProtocolMessage and
+ // proto2::Message have the CopyFrom() method, so the same
+ // implementation works for both.
+ explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) {
+ proto_->CopyFrom(proto);
+ }
+
+ template <typename Result, typename ArgumentTuple>
+ void Perform(const ArgumentTuple& args) const {
+ CompileAssertTypesEqual<void, Result>();
+ ::std::tr1::get<N>(args)->CopyFrom(*proto_);
+ }
+ private:
+ const internal::linked_ptr<Proto> proto_;
+};
+
+// Implements the SetArrayArgument<N>(first, last) action for any function
+// whose N-th argument (0-based) is a pointer or iterator to a type that can be
+// implicitly converted from *first.
+template <size_t N, typename InputIterator>
+class SetArrayArgumentAction {
+ public:
+ // Constructs an action that sets the variable pointed to by the
+ // N-th function argument to 'value'.
+ explicit SetArrayArgumentAction(InputIterator first, InputIterator last)
+ : first_(first), last_(last) {
+ }
+
+ template <typename Result, typename ArgumentTuple>
+ void Perform(const ArgumentTuple& args) const {
+ CompileAssertTypesEqual<void, Result>();
+
+ // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
+ // 4996 (Function call with parameters that may be unsafe) there.
+#ifdef GTEST_OS_WINDOWS
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4996) // Temporarily disables warning 4996.
+#endif // GTEST_OS_WINDOWS
+ ::std::copy(first_, last_, ::std::tr1::get<N>(args));
+#ifdef GTEST_OS_WINDOWS
+#pragma warning(pop) // Restores the warning state.
+#endif // GTEST_OS_WINDOWS
+ }
+
+ private:
+ const InputIterator first_;
+ const InputIterator last_;
+};
+
+// Implements the InvokeWithoutArgs(f) action. The template argument
+// FunctionImpl is the implementation type of f, which can be either a
+// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
+// Action<F> as long as f's type is compatible with F (i.e. f can be
+// assigned to a tr1::function<F>).
+template <typename FunctionImpl>
+class InvokeWithoutArgsAction {
+ public:
+ // The c'tor makes a copy of function_impl (either a function
+ // pointer or a functor).
+ explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
+ : function_impl_(function_impl) {}
+
+ // Allows InvokeWithoutArgs(f) to be used as any action whose type is
+ // compatible with f.
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple&) { return function_impl_(); }
+ private:
+ FunctionImpl function_impl_;
+};
+
+// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+class InvokeMethodWithoutArgsAction {
+ public:
+ InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
+ : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple&) const {
+ return (obj_ptr_->*method_ptr_)();
+ }
+ private:
+ Class* const obj_ptr_;
+ const MethodPtr method_ptr_;
+};
+
+// Implements the IgnoreResult(action) action.
+template <typename A>
+class IgnoreResultAction {
+ public:
+ explicit IgnoreResultAction(const A& action) : action_(action) {}
+
+ template <typename F>
+ operator Action<F>() const {
+ // Assert statement belongs here because this is the best place to verify
+ // conditions on F. It produces the clearest error messages
+ // in most compilers.
+ // Impl really belongs in this scope as a local class but can't
+ // because MSVC produces duplicate symbols in different translation units
+ // in this case. Until MS fixes that bug we put Impl into the class scope
+ // and put the typedef both here (for use in assert statement) and
+ // in the Impl class. But both definitions must be the same.
+ typedef typename internal::Function<F>::Result Result;
+
+ // Asserts at compile time that F returns void.
+ CompileAssertTypesEqual<void, Result>();
+
+ return Action<F>(new Impl<F>(action_));
+ }
+ private:
+ template <typename F>
+ class Impl : public ActionInterface<F> {
+ public:
+ typedef typename internal::Function<F>::Result Result;
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ explicit Impl(const A& action) : action_(action) {}
+
+ virtual void Perform(const ArgumentTuple& args) {
+ // Performs the action and ignores its result.
+ action_.Perform(args);
+ }
+
+ private:
+ // Type OriginalFunction is the same as F except that its return
+ // type is IgnoredValue.
+ typedef typename internal::Function<F>::MakeResultIgnoredValue
+ OriginalFunction;
+
+ const Action<OriginalFunction> action_;
+ };
+
+ const A action_;
+};
+
+} // namespace internal
+
+// An Unused object can be implicitly constructed from ANY value.
+// This is handy when defining actions that ignore some or all of the
+// mock function arguments. For example, given
+//
+// MOCK_METHOD3(Foo, double(const string& label, double x, double y));
+// MOCK_METHOD3(Bar, double(int index, double x, double y));
+//
+// instead of
+//
+// double DistanceToOriginWithLabel(const string& label, double x, double y) {
+// return sqrt(x*x + y*y);
+// }
+// double DistanceToOriginWithIndex(int index, double x, double y) {
+// return sqrt(x*x + y*y);
+// }
+// ...
+// EXEPCT_CALL(mock, Foo("abc", _, _))
+// .WillOnce(Invoke(DistanceToOriginWithLabel));
+// EXEPCT_CALL(mock, Bar(5, _, _))
+// .WillOnce(Invoke(DistanceToOriginWithIndex));
+//
+// you could write
+//
+// // We can declare any uninteresting argument as Unused.
+// double DistanceToOrigin(Unused, double x, double y) {
+// return sqrt(x*x + y*y);
+// }
+// ...
+// EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
+// EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
+typedef internal::IgnoredValue Unused;
+
+// This constructor allows us to turn an Action<From> object into an
+// Action<To>, as long as To's arguments can be implicitly converted
+// to From's and From's return type cann be implicitly converted to
+// To's.
+template <typename To>
+template <typename From>
+Action<To>::Action(const Action<From>& from)
+ : impl_(new internal::ActionAdaptor<To, From>(from)) {}
+
+// Creates an action that returns 'value'. 'value' is passed by value
+// instead of const reference - otherwise Return("string literal")
+// will trigger a compiler error about using array as initializer.
+template <typename R>
+internal::ReturnAction<R> Return(R value) {
+ return internal::ReturnAction<R>(value);
+}
+
+// Creates an action that returns NULL.
+inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {
+ return MakePolymorphicAction(internal::ReturnNullAction());
+}
+
+// Creates an action that returns from a void function.
+inline PolymorphicAction<internal::ReturnVoidAction> Return() {
+ return MakePolymorphicAction(internal::ReturnVoidAction());
+}
+
+// Creates an action that returns the reference to a variable.
+template <typename R>
+inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
+ return internal::ReturnRefAction<R>(x);
+}
+
+// Creates an action that does the default action for the give mock function.
+inline internal::DoDefaultAction DoDefault() {
+ return internal::DoDefaultAction();
+}
+
+// Creates an action that sets the variable pointed by the N-th
+// (0-based) function argument to 'value'.
+template <size_t N, typename T>
+PolymorphicAction<
+ internal::SetArgumentPointeeAction<
+ N, T, internal::IsAProtocolMessage<T>::value> >
+SetArgumentPointee(const T& x) {
+ return MakePolymorphicAction(internal::SetArgumentPointeeAction<
+ N, T, internal::IsAProtocolMessage<T>::value>(x));
+}
+
+// Creates an action that sets the elements of the array pointed to by the N-th
+// (0-based) function argument, which can be either a pointer or an iterator,
+// to the values of the elements in the source range [first, last).
+template <size_t N, typename InputIterator>
+PolymorphicAction<internal::SetArrayArgumentAction<N, InputIterator> >
+SetArrayArgument(InputIterator first, InputIterator last) {
+ return MakePolymorphicAction(internal::SetArrayArgumentAction<
+ N, InputIterator>(first, last));
+}
+
+// Creates an action that sets a pointer referent to a given value.
+template <typename T1, typename T2>
+PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) {
+ return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
+}
+
+// Creates an action that sets errno and returns the appropriate error.
+template <typename T>
+PolymorphicAction<internal::SetErrnoAndReturnAction<T> >
+SetErrnoAndReturn(int errval, T result) {
+ return MakePolymorphicAction(
+ internal::SetErrnoAndReturnAction<T>(errval, result));
+}
+
+// Various overloads for InvokeWithoutArgs().
+
+// Creates an action that invokes 'function_impl' with no argument.
+template <typename FunctionImpl>
+PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
+InvokeWithoutArgs(FunctionImpl function_impl) {
+ return MakePolymorphicAction(
+ internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
+}
+
+// Creates an action that invokes the given method on the given object
+// with no argument.
+template <class Class, typename MethodPtr>
+PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
+InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
+ return MakePolymorphicAction(
+ internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
+ obj_ptr, method_ptr));
+}
+
+// Creates an action that performs an_action and throws away its
+// result. In other words, it changes the return type of an_action to
+// void. an_action MUST NOT return void, or the code won't compile.
+template <typename A>
+inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
+ return internal::IgnoreResultAction<A>(an_action);
+}
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
diff --git a/include/gmock/gmock-cardinalities.h b/include/gmock/gmock-cardinalities.h
new file mode 100644
index 00000000..ae4cb641
--- /dev/null
+++ b/include/gmock/gmock-cardinalities.h
@@ -0,0 +1,146 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used cardinalities. More
+// cardinalities can be defined by the user implementing the
+// CardinalityInterface interface if necessary.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
+
+#include <limits.h>
+#include <ostream> // NOLINT
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+
+// To implement a cardinality Foo, define:
+// 1. a class FooCardinality that implements the
+// CardinalityInterface interface, and
+// 2. a factory function that creates a Cardinality object from a
+// const FooCardinality*.
+//
+// The two-level delegation design follows that of Matcher, providing
+// consistency for extension developers. It also eases ownership
+// management as Cardinality objects can now be copied like plain values.
+
+// The implementation of a cardinality.
+class CardinalityInterface {
+ public:
+ virtual ~CardinalityInterface() {}
+
+ // Conservative estimate on the lower/upper bound of the number of
+ // calls allowed.
+ virtual int ConservativeLowerBound() const { return 0; }
+ virtual int ConservativeUpperBound() const { return INT_MAX; }
+
+ // Returns true iff call_count calls will satisfy this cardinality.
+ virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
+
+ // Returns true iff call_count calls will saturate this cardinality.
+ virtual bool IsSaturatedByCallCount(int call_count) const = 0;
+
+ // Describes self to an ostream.
+ virtual void DescribeTo(::std::ostream* os) const = 0;
+};
+
+// A Cardinality is a copyable and IMMUTABLE (except by assignment)
+// object that specifies how many times a mock function is expected to
+// be called. The implementation of Cardinality is just a linked_ptr
+// to const CardinalityInterface, so copying is fairly cheap.
+// Don't inherit from Cardinality!
+class Cardinality {
+ public:
+ // Constructs a null cardinality. Needed for storing Cardinality
+ // objects in STL containers.
+ Cardinality() {}
+
+ // Constructs a Cardinality from its implementation.
+ explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
+
+ // Conservative estimate on the lower/upper bound of the number of
+ // calls allowed.
+ int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
+ int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
+
+ // Returns true iff call_count calls will satisfy this cardinality.
+ bool IsSatisfiedByCallCount(int call_count) const {
+ return impl_->IsSatisfiedByCallCount(call_count);
+ }
+
+ // Returns true iff call_count calls will saturate this cardinality.
+ bool IsSaturatedByCallCount(int call_count) const {
+ return impl_->IsSaturatedByCallCount(call_count);
+ }
+
+ // Returns true iff call_count calls will over-saturate this
+ // cardinality, i.e. exceed the maximum number of allowed calls.
+ bool IsOverSaturatedByCallCount(int call_count) const {
+ return impl_->IsSaturatedByCallCount(call_count) &&
+ !impl_->IsSatisfiedByCallCount(call_count);
+ }
+
+ // Describes self to an ostream
+ void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
+
+ // Describes the given actual call count to an ostream.
+ static void DescribeActualCallCountTo(int actual_call_count,
+ ::std::ostream* os);
+ private:
+ internal::linked_ptr<const CardinalityInterface> impl_;
+};
+
+// Creates a cardinality that allows at least n calls.
+Cardinality AtLeast(int n);
+
+// Creates a cardinality that allows at most n calls.
+Cardinality AtMost(int n);
+
+// Creates a cardinality that allows any number of calls.
+Cardinality AnyNumber();
+
+// Creates a cardinality that allows between min and max calls.
+Cardinality Between(int min, int max);
+
+// Creates a cardinality that allows exactly n calls.
+Cardinality Exactly(int n);
+
+// Creates a cardinality from its implementation.
+inline Cardinality MakeCardinality(const CardinalityInterface* c) {
+ return Cardinality(c);
+}
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
diff --git a/include/gmock/gmock-generated-actions.h b/include/gmock/gmock-generated-actions.h
new file mode 100644
index 00000000..ec696b30
--- /dev/null
+++ b/include/gmock/gmock-generated-actions.h
@@ -0,0 +1,1329 @@
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used variadic actions.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+
+#include <gmock/gmock-actions.h>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+namespace internal {
+
+// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
+// function or method with the unpacked values, where F is a function
+// type that takes N arguments.
+template <typename Result, typename ArgumentTuple>
+class InvokeHelper;
+
+template <typename R>
+class InvokeHelper<R, ::std::tr1::tuple<> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<>&) {
+ return function();
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<>&) {
+ return (obj_ptr->*method_ptr)();
+ }
+};
+
+template <typename R, typename A1>
+class InvokeHelper<R, ::std::tr1::tuple<A1> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2,
+ A3>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3,
+ A4>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4,
+ A5>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args),
+ get<4>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4, A5>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4,
+ A5, A6>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args),
+ get<4>(args), get<5>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args), get<5>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4,
+ A5, A6, A7>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args),
+ get<4>(args), get<5>(args), get<6>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6,
+ A7>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args), get<5>(args), get<6>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4,
+ A5, A6, A7, A8>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args),
+ get<4>(args), get<5>(args), get<6>(args), get<7>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7,
+ A8>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4,
+ A5, A6, A7, A8, A9>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args),
+ get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
+ A9>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args),
+ get<8>(args));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9,
+ typename A10>
+class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
+ A10> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4,
+ A5, A6, A7, A8, A9, A10>& args) {
+ using ::std::tr1::get;
+ return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args),
+ get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
+ get<9>(args));
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
+ A9, A10>& args) {
+ using ::std::tr1::get;
+ return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args),
+ get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args),
+ get<8>(args), get<9>(args));
+ }
+};
+
+
+// Implements the Invoke(f) action. The template argument
+// FunctionImpl is the implementation type of f, which can be either a
+// function pointer or a functor. Invoke(f) can be used as an
+// Action<F> as long as f's type is compatible with F (i.e. f can be
+// assigned to a tr1::function<F>).
+template <typename FunctionImpl>
+class InvokeAction {
+ public:
+ // The c'tor makes a copy of function_impl (either a function
+ // pointer or a functor).
+ explicit InvokeAction(FunctionImpl function_impl)
+ : function_impl_(function_impl) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
+ }
+ private:
+ FunctionImpl function_impl_;
+};
+
+// Implements the Invoke(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+class InvokeMethodAction {
+ public:
+ InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
+ : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) const {
+ return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
+ obj_ptr_, method_ptr_, args);
+ }
+ private:
+ Class* const obj_ptr_;
+ const MethodPtr method_ptr_;
+};
+
+// A ReferenceWrapper<T> object represents a reference to type T,
+// which can be either const or not. It can be explicitly converted
+// from, and implicitly converted to, a T&. Unlike a reference,
+// ReferenceWrapper<T> can be copied and can survive template type
+// inference. This is used to support by-reference arguments in the
+// InvokeArgument<N>(...) action. The idea was from "reference
+// wrappers" in tr1, which we don't have in our source tree yet.
+template <typename T>
+class ReferenceWrapper {
+ public:
+ // Constructs a ReferenceWrapper<T> object from a T&.
+ explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
+
+ // Allows a ReferenceWrapper<T> object to be implicitly converted to
+ // a T&.
+ operator T&() const { return *pointer_; }
+ private:
+ T* pointer_;
+};
+
+// CallableHelper has static methods for invoking "callables",
+// i.e. function pointers and functors. It uses overloading to
+// provide a uniform interface for invoking different kinds of
+// callables. In particular, you can use:
+//
+// CallableHelper<R>::Call(callable, a1, a2, ..., an)
+//
+// to invoke an n-ary callable, where R is its return type. If an
+// argument, say a2, needs to be passed by reference, you should write
+// ByRef(a2) instead of a2 in the above expression.
+template <typename R>
+class CallableHelper {
+ public:
+ // Calls a nullary callable.
+ template <typename Function>
+ static R Call(Function function) { return function(); }
+
+ // Calls a unary callable.
+
+ // We deliberately pass a1 by value instead of const reference here
+ // in case it is a C-string literal. If we had declared the
+ // parameter as 'const A1& a1' and write Call(function, "Hi"), the
+ // compiler would've thought A1 is 'char[3]', which causes trouble
+ // when you need to copy a value of type A1. By declaring the
+ // parameter as 'A1 a1', the compiler will correctly infer that A1
+ // is 'const char*' when it sees Call(function, "Hi").
+ //
+ // Since this function is defined inline, the compiler can get rid
+ // of the copying of the arguments. Therefore the performance won't
+ // be hurt.
+ template <typename Function, typename A1>
+ static R Call(Function function, A1 a1) { return function(a1); }
+
+ // Calls a binary callable.
+ template <typename Function, typename A1, typename A2>
+ static R Call(Function function, A1 a1, A2 a2) {
+ return function(a1, a2);
+ }
+
+ // Calls a ternary callable.
+ template <typename Function, typename A1, typename A2, typename A3>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3) {
+ return function(a1, a2, a3);
+ }
+
+ // Calls a 4-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return function(a1, a2, a3, a4);
+ }
+
+ // Calls a 5-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4, typename A5>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+ return function(a1, a2, a3, a4, a5);
+ }
+
+ // Calls a 6-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
+ return function(a1, a2, a3, a4, a5, a6);
+ }
+
+ // Calls a 7-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
+ A7 a7) {
+ return function(a1, a2, a3, a4, a5, a6, a7);
+ }
+
+ // Calls a 8-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
+ A7 a7, A8 a8) {
+ return function(a1, a2, a3, a4, a5, a6, a7, a8);
+ }
+
+ // Calls a 9-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8,
+ typename A9>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
+ A7 a7, A8 a8, A9 a9) {
+ return function(a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ }
+
+ // Calls a 10-ary callable.
+ template <typename Function, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8,
+ typename A9, typename A10>
+ static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
+ A7 a7, A8 a8, A9 a9, A10 a10) {
+ return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+ }
+
+}; // class CallableHelper
+
+// Invokes a nullary callable argument.
+template <size_t N>
+class InvokeArgumentAction0 {
+ public:
+ template <typename Result, typename ArgumentTuple>
+ static Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args));
+ }
+};
+
+// Invokes a unary callable argument with the given argument.
+template <size_t N, typename A1>
+class InvokeArgumentAction1 {
+ public:
+ // We deliberately pass a1 by value instead of const reference here
+ // in case it is a C-string literal.
+ //
+ // Since this function is defined inline, the compiler can get rid
+ // of the copying of the arguments. Therefore the performance won't
+ // be hurt.
+ explicit InvokeArgumentAction1(A1 a1) : arg1_(a1) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_);
+ }
+ private:
+ const A1 arg1_;
+};
+
+// Invokes a binary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2>
+class InvokeArgumentAction2 {
+ public:
+ InvokeArgumentAction2(A1 a1, A2 a2) :
+ arg1_(a1), arg2_(a2) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_, arg2_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+};
+
+// Invokes a ternary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3>
+class InvokeArgumentAction3 {
+ public:
+ InvokeArgumentAction3(A1 a1, A2 a2, A3 a3) :
+ arg1_(a1), arg2_(a2), arg3_(a3) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_, arg2_,
+ arg3_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+};
+
+// Invokes a 4-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4>
+class InvokeArgumentAction4 {
+ public:
+ InvokeArgumentAction4(A1 a1, A2 a2, A3 a3, A4 a4) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_, arg2_,
+ arg3_, arg4_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+};
+
+// Invokes a 5-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+class InvokeArgumentAction5 {
+ public:
+ InvokeArgumentAction5(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function(arg1_, arg2_, arg3_, arg4_, arg5_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+ const A5 arg5_;
+};
+
+// Invokes a 6-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+class InvokeArgumentAction6 {
+ public:
+ InvokeArgumentAction6(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+ const A5 arg5_;
+ const A6 arg6_;
+};
+
+// Invokes a 7-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7>
+class InvokeArgumentAction7 {
+ public:
+ InvokeArgumentAction7(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
+ arg7_(a7) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+ const A5 arg5_;
+ const A6 arg6_;
+ const A7 arg7_;
+};
+
+// Invokes a 8-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8>
+class InvokeArgumentAction8 {
+ public:
+ InvokeArgumentAction8(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
+ A8 a8) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
+ arg7_(a7), arg8_(a8) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+ const A5 arg5_;
+ const A6 arg6_;
+ const A7 arg7_;
+ const A8 arg8_;
+};
+
+// Invokes a 9-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9>
+class InvokeArgumentAction9 {
+ public:
+ InvokeArgumentAction9(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8,
+ A9 a9) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
+ arg7_(a7), arg8_(a8), arg9_(a9) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_,
+ arg9_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+ const A5 arg5_;
+ const A6 arg6_;
+ const A7 arg7_;
+ const A8 arg8_;
+ const A9 arg9_;
+};
+
+// Invokes a 10-ary callable argument with the given arguments.
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9,
+ typename A10>
+class InvokeArgumentAction10 {
+ public:
+ InvokeArgumentAction10(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
+ A8 a8, A9 a9, A10 a10) :
+ arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
+ arg7_(a7), arg8_(a8), arg9_(a9), arg10_(a10) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_,
+ arg9_, arg10_);
+ }
+ private:
+ const A1 arg1_;
+ const A2 arg2_;
+ const A3 arg3_;
+ const A4 arg4_;
+ const A5 arg5_;
+ const A6 arg6_;
+ const A7 arg7_;
+ const A8 arg8_;
+ const A9 arg9_;
+ const A10 arg10_;
+};
+
+// An INTERNAL macro for extracting the type of a tuple field. It's
+// subject to change without notice - DO NOT USE IN USER CODE!
+#define GMOCK_FIELD(Tuple, N) \
+ typename ::std::tr1::tuple_element<N, Tuple>::type
+
+// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
+// type of an n-ary function whose i-th (1-based) argument type is the
+// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
+// type, and whose return type is Result. For example,
+// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
+// is int(bool, long).
+//
+// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
+// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
+// For example,
+// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
+// ::std::tr1::make_tuple(true, 'a', 2.5))
+// returns ::std::tr1::tuple (2.5, true).
+//
+// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
+// in the range [0, 10]. Duplicates are allowed and they don't have
+// to be in an ascending or descending order.
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4, int k5, int k6, int k7, int k8, int k9, int k10>
+class SelectArgs {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4), GMOCK_FIELD(ArgumentTuple, k5),
+ GMOCK_FIELD(ArgumentTuple, k6), GMOCK_FIELD(ArgumentTuple, k7),
+ GMOCK_FIELD(ArgumentTuple, k8), GMOCK_FIELD(ArgumentTuple, k9),
+ GMOCK_FIELD(ArgumentTuple, k10));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
+ get<k8>(args), get<k9>(args), get<k10>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple>
+class SelectArgs<Result, ArgumentTuple,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
+ public:
+ typedef Result type();
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs();
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1>
+class SelectArgs<Result, ArgumentTuple,
+ k1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, -1, -1, -1, -1, -1, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, -1, -1, -1, -1, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, -1, -1, -1, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4, int k5>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, k5, -1, -1, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4), GMOCK_FIELD(ArgumentTuple, k5));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args), get<k5>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4, int k5, int k6>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, k5, k6, -1, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4), GMOCK_FIELD(ArgumentTuple, k5),
+ GMOCK_FIELD(ArgumentTuple, k6));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args), get<k5>(args), get<k6>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4, int k5, int k6, int k7>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, k5, k6, k7, -1, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4), GMOCK_FIELD(ArgumentTuple, k5),
+ GMOCK_FIELD(ArgumentTuple, k6), GMOCK_FIELD(ArgumentTuple, k7));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4, int k5, int k6, int k7, int k8>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, k5, k6, k7, k8, -1, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4), GMOCK_FIELD(ArgumentTuple, k5),
+ GMOCK_FIELD(ArgumentTuple, k6), GMOCK_FIELD(ArgumentTuple, k7),
+ GMOCK_FIELD(ArgumentTuple, k8));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
+ get<k8>(args));
+ }
+};
+
+template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
+ int k4, int k5, int k6, int k7, int k8, int k9>
+class SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, k5, k6, k7, k8, k9, -1> {
+ public:
+ typedef Result type(GMOCK_FIELD(ArgumentTuple, k1),
+ GMOCK_FIELD(ArgumentTuple, k2), GMOCK_FIELD(ArgumentTuple, k3),
+ GMOCK_FIELD(ArgumentTuple, k4), GMOCK_FIELD(ArgumentTuple, k5),
+ GMOCK_FIELD(ArgumentTuple, k6), GMOCK_FIELD(ArgumentTuple, k7),
+ GMOCK_FIELD(ArgumentTuple, k8), GMOCK_FIELD(ArgumentTuple, k9));
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
+ get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
+ get<k8>(args), get<k9>(args));
+ }
+};
+
+#undef GMOCK_FIELD
+
+// Implements the WithArgs action.
+template <typename InnerAction, 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, int k10 = -1>
+class WithArgsAction {
+ public:
+ explicit WithArgsAction(const InnerAction& action) : action_(action) {}
+
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename SelectArgs<Result, ArgumentTuple,
+ k1, k2, k3, k4, k5, k6, k7, k8, k9, k10>::type
+ InnerFunctionType;
+
+ class Impl : public ActionInterface<F> {
+ public:
+ explicit Impl(const InnerAction& action) : action_(action) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ return action_.Perform(SelectArgs<Result, ArgumentTuple, k1, k2, k3,
+ k4, k5, k6, k7, k8, k9, k10>::Select(args));
+ }
+ private:
+ Action<InnerFunctionType> action_;
+ };
+
+ return MakeAction(new Impl(action_));
+ }
+ private:
+ const InnerAction action_;
+};
+
+// Does two actions sequentially. Used for implementing the DoAll(a1,
+// a2, ...) action.
+template <typename Action1, typename Action2>
+class DoBothAction {
+ public:
+ DoBothAction(Action1 action1, Action2 action2)
+ : action1_(action1), action2_(action2) {}
+
+ // This template type conversion operator allows DoAll(a1, ..., a_n)
+ // to be used in ANY function of compatible type.
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename Function<F>::MakeResultVoid VoidResult;
+
+ // Implements the DoAll(...) action for a particular function type F.
+ class Impl : public ActionInterface<F> {
+ public:
+ Impl(const Action<VoidResult>& action1, const Action<F>& action2)
+ : action1_(action1), action2_(action2) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ action1_.Perform(args);
+ return action2_.Perform(args);
+ }
+ private:
+ const Action<VoidResult> action1_;
+ const Action<F> action2_;
+ };
+
+ return Action<F>(new Impl(action1_, action2_));
+ }
+ private:
+ Action1 action1_;
+ Action2 action2_;
+};
+
+} // namespace internal
+
+// Various overloads for Invoke().
+
+// Creates an action that invokes 'function_impl' with the mock
+// function's arguments.
+template <typename FunctionImpl>
+PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
+ FunctionImpl function_impl) {
+ return MakePolymorphicAction(
+ internal::InvokeAction<FunctionImpl>(function_impl));
+}
+
+// Creates an action that invokes the given method on the given object
+// with the mock function's arguments.
+template <class Class, typename MethodPtr>
+PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
+ Class* obj_ptr, MethodPtr method_ptr) {
+ return MakePolymorphicAction(
+ internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
+}
+
+// Creates a reference wrapper for the given L-value. If necessary,
+// you can explicitly specify the type of the reference. For example,
+// suppose 'derived' is an object of type Derived, ByRef(derived)
+// would wrap a Derived&. If you want to wrap a const Base& instead,
+// where Base is a base class of Derived, just write:
+//
+// ByRef<const Base>(derived)
+template <typename T>
+inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
+ return internal::ReferenceWrapper<T>(l_value);
+}
+
+// Various overloads for InvokeArgument<N>().
+//
+// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
+// (0-based) argument, which must be a k-ary callable, of the mock
+// function, with arguments a1, a2, ..., a_k.
+//
+// Notes:
+//
+// 1. The arguments are passed by value by default. If you need to
+// pass an argument by reference, wrap it inside ByRef(). For
+// example,
+//
+// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
+//
+// passes 5 and string("Hello") by value, and passes foo by
+// reference.
+//
+// 2. If the callable takes an argument by reference but ByRef() is
+// not used, it will receive the reference to a copy of the value,
+// instead of the original value. For example, when the 0-th
+// argument of the mock function takes a const string&, the action
+//
+// InvokeArgument<0>(string("Hello"))
+//
+// makes a copy of the temporary string("Hello") object and passes a
+// reference of the copy, instead of the original temporary object,
+// to the callable. This makes it easy for a user to define an
+// InvokeArgument action from temporary values and have it performed
+// later.
+template <size_t N>
+inline PolymorphicAction<internal::InvokeArgumentAction0<N> > InvokeArgument() {
+ return MakePolymorphicAction(internal::InvokeArgumentAction0<N>());
+}
+
+// We deliberately pass a1 by value instead of const reference here in
+// case it is a C-string literal. If we had declared the parameter as
+// 'const A1& a1' and write InvokeArgument<0>("Hi"), the compiler
+// would've thought A1 is 'char[3]', which causes trouble as the
+// implementation needs to copy a value of type A1. By declaring the
+// parameter as 'A1 a1', the compiler will correctly infer that A1 is
+// 'const char*' when it sees InvokeArgument<0>("Hi").
+//
+// Since this function is defined inline, the compiler can get rid of
+// the copying of the arguments. Therefore the performance won't be
+// hurt.
+template <size_t N, typename A1>
+inline PolymorphicAction<internal::InvokeArgumentAction1<N, A1> >
+InvokeArgument(A1 a1) {
+ return MakePolymorphicAction(internal::InvokeArgumentAction1<N, A1>(a1));
+}
+
+template <size_t N, typename A1, typename A2>
+inline PolymorphicAction<internal::InvokeArgumentAction2<N, A1, A2> >
+InvokeArgument(A1 a1, A2 a2) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction2<N, A1, A2>(a1, a2));
+}
+
+template <size_t N, typename A1, typename A2, typename A3>
+inline PolymorphicAction<internal::InvokeArgumentAction3<N, A1, A2, A3> >
+InvokeArgument(A1 a1, A2 a2, A3 a3) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction3<N, A1, A2, A3>(a1, a2, a3));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4>
+inline PolymorphicAction<internal::InvokeArgumentAction4<N, A1, A2, A3, A4> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction4<N, A1, A2, A3, A4>(a1, a2, a3, a4));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+inline PolymorphicAction<internal::InvokeArgumentAction5<N, A1, A2, A3, A4,
+ A5> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction5<N, A1, A2, A3, A4, A5>(a1, a2, a3, a4,
+ a5));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+inline PolymorphicAction<internal::InvokeArgumentAction6<N, A1, A2, A3, A4, A5,
+ A6> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction6<N, A1, A2, A3, A4, A5, A6>(a1, a2, a3,
+ a4, a5, a6));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7>
+inline PolymorphicAction<internal::InvokeArgumentAction7<N, A1, A2, A3, A4, A5,
+ A6, A7> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction7<N, A1, A2, A3, A4, A5, A6, A7>(a1, a2,
+ a3, a4, a5, a6, a7));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8>
+inline PolymorphicAction<internal::InvokeArgumentAction8<N, A1, A2, A3, A4, A5,
+ A6, A7, A8> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction8<N, A1, A2, A3, A4, A5, A6, A7, A8>(a1,
+ a2, a3, a4, a5, a6, a7, a8));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9>
+inline PolymorphicAction<internal::InvokeArgumentAction9<N, A1, A2, A3, A4, A5,
+ A6, A7, A8, A9> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction9<N, A1, A2, A3, A4, A5, A6, A7, A8,
+ A9>(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template <size_t N, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9,
+ typename A10>
+inline PolymorphicAction<internal::InvokeArgumentAction10<N, A1, A2, A3, A4,
+ A5, A6, A7, A8, A9, A10> >
+InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
+ A10 a10) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction10<N, A1, A2, A3, A4, A5, A6, A7, A8, A9,
+ A10>(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
+}
+
+// WithoutArgs(inner_action) can be used in a mock function with a
+// non-empty argument list to perform inner_action, which takes no
+// argument. In other words, it adapts an action accepting no
+// argument to one that accepts (and ignores) arguments.
+template <typename InnerAction>
+inline internal::WithArgsAction<InnerAction>
+WithoutArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction>(action);
+}
+
+// WithArg<k>(an_action) creates an action that passes the k-th
+// (0-based) argument of the mock function to an_action and performs
+// it. It adapts an action accepting one argument to one that accepts
+// multiple arguments. For convenience, we also provide
+// WithArgs<k>(an_action) (defined below) as a synonym.
+template <int k, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k>
+WithArg(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k>(action);
+}
+
+// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
+// the selected arguments of the mock function to an_action and
+// performs it. It serves as an adaptor between actions with
+// different argument lists. C++ doesn't support default arguments for
+// function templates, so we have to overload it.
+template <int k1, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1>(action);
+}
+
+template <int k1, int k2, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2>(action);
+}
+
+template <int k1, int k2, int k3, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3>(action);
+}
+
+template <int k1, int k2, int k3, int k4, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4>(action);
+}
+
+template <int k1, int k2, int k3, int k4, int k5, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>(action);
+}
+
+template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>(action);
+}
+
+template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
+ typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6,
+ k7>(action);
+}
+
+template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
+ typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7,
+ k8>(action);
+}
+
+template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
+ int k9, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, k9>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
+ k9>(action);
+}
+
+template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
+ int k9, int k10, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
+ k9, k10>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
+ k9, k10>(action);
+}
+
+// Creates an action that does actions a1, a2, ..., sequentially in
+// each invocation.
+template <typename Action1, typename Action2>
+inline internal::DoBothAction<Action1, Action2>
+DoAll(Action1 a1, Action2 a2) {
+ return internal::DoBothAction<Action1, Action2>(a1, a2);
+}
+
+template <typename Action1, typename Action2, typename Action3>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ Action3> >
+DoAll(Action1 a1, Action2 a2, Action3 a3) {
+ return DoAll(a1, DoAll(a2, a3));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, Action4> > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) {
+ return DoAll(a1, DoAll(a2, a3, a4));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4, typename Action5>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, internal::DoBothAction<Action4,
+ Action5> > > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) {
+ return DoAll(a1, DoAll(a2, a3, a4, a5));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4, typename Action5, typename Action6>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, internal::DoBothAction<Action4,
+ internal::DoBothAction<Action5, Action6> > > > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) {
+ return DoAll(a1, DoAll(a2, a3, a4, a5, a6));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4, typename Action5, typename Action6, typename Action7>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, internal::DoBothAction<Action4,
+ internal::DoBothAction<Action5, internal::DoBothAction<Action6,
+ Action7> > > > > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
+ Action7 a7) {
+ return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4, typename Action5, typename Action6, typename Action7,
+ typename Action8>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, internal::DoBothAction<Action4,
+ internal::DoBothAction<Action5, internal::DoBothAction<Action6,
+ internal::DoBothAction<Action7, Action8> > > > > > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
+ Action7 a7, Action8 a8) {
+ return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4, typename Action5, typename Action6, typename Action7,
+ typename Action8, typename Action9>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, internal::DoBothAction<Action4,
+ internal::DoBothAction<Action5, internal::DoBothAction<Action6,
+ internal::DoBothAction<Action7, internal::DoBothAction<Action8,
+ Action9> > > > > > > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
+ Action7 a7, Action8 a8, Action9 a9) {
+ return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template <typename Action1, typename Action2, typename Action3,
+ typename Action4, typename Action5, typename Action6, typename Action7,
+ typename Action8, typename Action9, typename Action10>
+inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
+ internal::DoBothAction<Action3, internal::DoBothAction<Action4,
+ internal::DoBothAction<Action5, internal::DoBothAction<Action6,
+ internal::DoBothAction<Action7, internal::DoBothAction<Action8,
+ internal::DoBothAction<Action9, Action10> > > > > > > > >
+DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
+ Action7 a7, Action8 a8, Action9 a9, Action10 a10) {
+ return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10));
+}
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/include/gmock/gmock-generated-actions.h.pump b/include/gmock/gmock-generated-actions.h.pump
new file mode 100644
index 00000000..d3dfac09
--- /dev/null
+++ b/include/gmock/gmock-generated-actions.h.pump
@@ -0,0 +1,567 @@
+$$ -*- mode: c++; -*-
+$$ 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.
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used variadic actions.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+
+#include <gmock/gmock-actions.h>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+namespace internal {
+
+// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
+// function or method with the unpacked values, where F is a function
+// type that takes N arguments.
+template <typename Result, typename ArgumentTuple>
+class InvokeHelper;
+
+
+$range i 0..n
+$for i [[
+$range j 1..i
+$var types = [[$for j [[, typename A$j]]]]
+$var as = [[$for j, [[A$j]]]]
+$var args = [[$if i==0 [[]] $else [[ args]]]]
+$var import = [[$if i==0 [[]] $else [[
+ using ::std::tr1::get;
+
+]]]]
+$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
+template <typename R$types>
+class InvokeHelper<R, ::std::tr1::tuple<$as> > {
+ public:
+ template <typename Function>
+ static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
+$import return function($gets);
+ }
+
+ template <class Class, typename MethodPtr>
+ static R InvokeMethod(Class* obj_ptr,
+ MethodPtr method_ptr,
+ const ::std::tr1::tuple<$as>&$args) {
+$import return (obj_ptr->*method_ptr)($gets);
+ }
+};
+
+
+]]
+
+// Implements the Invoke(f) action. The template argument
+// FunctionImpl is the implementation type of f, which can be either a
+// function pointer or a functor. Invoke(f) can be used as an
+// Action<F> as long as f's type is compatible with F (i.e. f can be
+// assigned to a tr1::function<F>).
+template <typename FunctionImpl>
+class InvokeAction {
+ public:
+ // The c'tor makes a copy of function_impl (either a function
+ // pointer or a functor).
+ explicit InvokeAction(FunctionImpl function_impl)
+ : function_impl_(function_impl) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
+ }
+ private:
+ FunctionImpl function_impl_;
+};
+
+// Implements the Invoke(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+class InvokeMethodAction {
+ public:
+ InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
+ : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) const {
+ return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
+ obj_ptr_, method_ptr_, args);
+ }
+ private:
+ Class* const obj_ptr_;
+ const MethodPtr method_ptr_;
+};
+
+// A ReferenceWrapper<T> object represents a reference to type T,
+// which can be either const or not. It can be explicitly converted
+// from, and implicitly converted to, a T&. Unlike a reference,
+// ReferenceWrapper<T> can be copied and can survive template type
+// inference. This is used to support by-reference arguments in the
+// InvokeArgument<N>(...) action. The idea was from "reference
+// wrappers" in tr1, which we don't have in our source tree yet.
+template <typename T>
+class ReferenceWrapper {
+ public:
+ // Constructs a ReferenceWrapper<T> object from a T&.
+ explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
+
+ // Allows a ReferenceWrapper<T> object to be implicitly converted to
+ // a T&.
+ operator T&() const { return *pointer_; }
+ private:
+ T* pointer_;
+};
+
+// CallableHelper has static methods for invoking "callables",
+// i.e. function pointers and functors. It uses overloading to
+// provide a uniform interface for invoking different kinds of
+// callables. In particular, you can use:
+//
+// CallableHelper<R>::Call(callable, a1, a2, ..., an)
+//
+// to invoke an n-ary callable, where R is its return type. If an
+// argument, say a2, needs to be passed by reference, you should write
+// ByRef(a2) instead of a2 in the above expression.
+template <typename R>
+class CallableHelper {
+ public:
+ // Calls a nullary callable.
+ template <typename Function>
+ static R Call(Function function) { return function(); }
+
+ // Calls a unary callable.
+
+ // We deliberately pass a1 by value instead of const reference here
+ // in case it is a C-string literal. If we had declared the
+ // parameter as 'const A1& a1' and write Call(function, "Hi"), the
+ // compiler would've thought A1 is 'char[3]', which causes trouble
+ // when you need to copy a value of type A1. By declaring the
+ // parameter as 'A1 a1', the compiler will correctly infer that A1
+ // is 'const char*' when it sees Call(function, "Hi").
+ //
+ // Since this function is defined inline, the compiler can get rid
+ // of the copying of the arguments. Therefore the performance won't
+ // be hurt.
+ template <typename Function, typename A1>
+ static R Call(Function function, A1 a1) { return function(a1); }
+
+$range i 2..n
+$for i
+[[
+$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
+
+ // Calls a $arity callable.
+
+$range j 1..i
+$var typename_As = [[$for j, [[typename A$j]]]]
+$var Aas = [[$for j, [[A$j a$j]]]]
+$var as = [[$for j, [[a$j]]]]
+$var typename_Ts = [[$for j, [[typename T$j]]]]
+$var Ts = [[$for j, [[T$j]]]]
+ template <typename Function, $typename_As>
+ static R Call(Function function, $Aas) {
+ return function($as);
+ }
+
+]]
+
+}; // class CallableHelper
+
+// Invokes a nullary callable argument.
+template <size_t N>
+class InvokeArgumentAction0 {
+ public:
+ template <typename Result, typename ArgumentTuple>
+ static Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args));
+ }
+};
+
+// Invokes a unary callable argument with the given argument.
+template <size_t N, typename A1>
+class InvokeArgumentAction1 {
+ public:
+ // We deliberately pass a1 by value instead of const reference here
+ // in case it is a C-string literal.
+ //
+ // Since this function is defined inline, the compiler can get rid
+ // of the copying of the arguments. Therefore the performance won't
+ // be hurt.
+ explicit InvokeArgumentAction1(A1 a1) : arg1_(a1) {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_);
+ }
+ private:
+ const A1 arg1_;
+};
+
+$range i 2..n
+$for i [[
+$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
+$range j 1..i
+$var typename_As = [[$for j, [[typename A$j]]]]
+$var args_ = [[$for j, [[arg$j[[]]_]]]]
+
+// Invokes a $arity callable argument with the given arguments.
+template <size_t N, $typename_As>
+class InvokeArgumentAction$i {
+ public:
+ InvokeArgumentAction$i($for j, [[A$j a$j]]) :
+ $for j, [[arg$j[[]]_(a$j)]] {}
+
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) {
+$if i <= 4 [[
+
+ return CallableHelper<Result>::Call(::std::tr1::get<N>(args), $args_);
+
+]] $else [[
+
+ // We extract the callable to a variable before invoking it, in
+ // case it is a functor passed by value and its operator() is not
+ // const.
+ typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
+ ::std::tr1::get<N>(args);
+ return function($args_);
+
+]]
+ }
+ private:
+$for j [[
+
+ const A$j arg$j[[]]_;
+]]
+
+};
+
+]]
+
+// An INTERNAL macro for extracting the type of a tuple field. It's
+// subject to change without notice - DO NOT USE IN USER CODE!
+#define GMOCK_FIELD(Tuple, N) \
+ typename ::std::tr1::tuple_element<N, Tuple>::type
+
+$range i 1..n
+
+// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
+// type of an n-ary function whose i-th (1-based) argument type is the
+// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
+// type, and whose return type is Result. For example,
+// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
+// is int(bool, long).
+//
+// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
+// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
+// For example,
+// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
+// ::std::tr1::make_tuple(true, 'a', 2.5))
+// returns ::std::tr1::tuple (2.5, true).
+//
+// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
+// in the range [0, $n]. Duplicates are allowed and they don't have
+// to be in an ascending or descending order.
+
+template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
+class SelectArgs {
+ public:
+ typedef Result type($for i, [[GMOCK_FIELD(ArgumentTuple, k$i)]]);
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs($for i, [[get<k$i>(args)]]);
+ }
+};
+
+
+$for i [[
+$range j 1..n
+$range j1 1..i-1
+template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
+class SelectArgs<Result, ArgumentTuple,
+ $for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
+ public:
+ typedef Result type($for j1, [[GMOCK_FIELD(ArgumentTuple, k$j1)]]);
+ typedef typename Function<type>::ArgumentTuple SelectedArgs;
+ static SelectedArgs Select(const ArgumentTuple& args) {
+ using ::std::tr1::get;
+ return SelectedArgs($for j1, [[get<k$j1>(args)]]);
+ }
+};
+
+
+]]
+#undef GMOCK_FIELD
+
+$var ks = [[$for i, [[k$i]]]]
+
+// Implements the WithArgs action.
+template <typename InnerAction, $for i, [[int k$i = -1]]>
+class WithArgsAction {
+ public:
+ explicit WithArgsAction(const InnerAction& action) : action_(action) {}
+
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename SelectArgs<Result, ArgumentTuple,
+ $ks>::type
+ InnerFunctionType;
+
+ class Impl : public ActionInterface<F> {
+ public:
+ explicit Impl(const InnerAction& action) : action_(action) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
+ }
+ private:
+ Action<InnerFunctionType> action_;
+ };
+
+ return MakeAction(new Impl(action_));
+ }
+ private:
+ const InnerAction action_;
+};
+
+// Does two actions sequentially. Used for implementing the DoAll(a1,
+// a2, ...) action.
+template <typename Action1, typename Action2>
+class DoBothAction {
+ public:
+ DoBothAction(Action1 action1, Action2 action2)
+ : action1_(action1), action2_(action2) {}
+
+ // This template type conversion operator allows DoAll(a1, ..., a_n)
+ // to be used in ANY function of compatible type.
+ template <typename F>
+ operator Action<F>() const {
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename Function<F>::MakeResultVoid VoidResult;
+
+ // Implements the DoAll(...) action for a particular function type F.
+ class Impl : public ActionInterface<F> {
+ public:
+ Impl(const Action<VoidResult>& action1, const Action<F>& action2)
+ : action1_(action1), action2_(action2) {}
+
+ virtual Result Perform(const ArgumentTuple& args) {
+ action1_.Perform(args);
+ return action2_.Perform(args);
+ }
+ private:
+ const Action<VoidResult> action1_;
+ const Action<F> action2_;
+ };
+
+ return Action<F>(new Impl(action1_, action2_));
+ }
+ private:
+ Action1 action1_;
+ Action2 action2_;
+};
+
+} // namespace internal
+
+// Various overloads for Invoke().
+
+// Creates an action that invokes 'function_impl' with the mock
+// function's arguments.
+template <typename FunctionImpl>
+PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
+ FunctionImpl function_impl) {
+ return MakePolymorphicAction(
+ internal::InvokeAction<FunctionImpl>(function_impl));
+}
+
+// Creates an action that invokes the given method on the given object
+// with the mock function's arguments.
+template <class Class, typename MethodPtr>
+PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
+ Class* obj_ptr, MethodPtr method_ptr) {
+ return MakePolymorphicAction(
+ internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
+}
+
+// Creates a reference wrapper for the given L-value. If necessary,
+// you can explicitly specify the type of the reference. For example,
+// suppose 'derived' is an object of type Derived, ByRef(derived)
+// would wrap a Derived&. If you want to wrap a const Base& instead,
+// where Base is a base class of Derived, just write:
+//
+// ByRef<const Base>(derived)
+template <typename T>
+inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
+ return internal::ReferenceWrapper<T>(l_value);
+}
+
+// Various overloads for InvokeArgument<N>().
+//
+// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
+// (0-based) argument, which must be a k-ary callable, of the mock
+// function, with arguments a1, a2, ..., a_k.
+//
+// Notes:
+//
+// 1. The arguments are passed by value by default. If you need to
+// pass an argument by reference, wrap it inside ByRef(). For
+// example,
+//
+// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
+//
+// passes 5 and string("Hello") by value, and passes foo by
+// reference.
+//
+// 2. If the callable takes an argument by reference but ByRef() is
+// not used, it will receive the reference to a copy of the value,
+// instead of the original value. For example, when the 0-th
+// argument of the mock function takes a const string&, the action
+//
+// InvokeArgument<0>(string("Hello"))
+//
+// makes a copy of the temporary string("Hello") object and passes a
+// reference of the copy, instead of the original temporary object,
+// to the callable. This makes it easy for a user to define an
+// InvokeArgument action from temporary values and have it performed
+// later.
+template <size_t N>
+inline PolymorphicAction<internal::InvokeArgumentAction0<N> > InvokeArgument() {
+ return MakePolymorphicAction(internal::InvokeArgumentAction0<N>());
+}
+
+// We deliberately pass a1 by value instead of const reference here in
+// case it is a C-string literal. If we had declared the parameter as
+// 'const A1& a1' and write InvokeArgument<0>("Hi"), the compiler
+// would've thought A1 is 'char[3]', which causes trouble as the
+// implementation needs to copy a value of type A1. By declaring the
+// parameter as 'A1 a1', the compiler will correctly infer that A1 is
+// 'const char*' when it sees InvokeArgument<0>("Hi").
+//
+// Since this function is defined inline, the compiler can get rid of
+// the copying of the arguments. Therefore the performance won't be
+// hurt.
+template <size_t N, typename A1>
+inline PolymorphicAction<internal::InvokeArgumentAction1<N, A1> >
+InvokeArgument(A1 a1) {
+ return MakePolymorphicAction(internal::InvokeArgumentAction1<N, A1>(a1));
+}
+
+$range i 2..n
+$for i [[
+$range j 1..i
+$var typename_As = [[$for j, [[typename A$j]]]]
+$var As = [[$for j, [[A$j]]]]
+$var Aas = [[$for j, [[A$j a$j]]]]
+$var as = [[$for j, [[a$j]]]]
+
+template <size_t N, $typename_As>
+inline PolymorphicAction<internal::InvokeArgumentAction$i<N, $As> >
+InvokeArgument($Aas) {
+ return MakePolymorphicAction(
+ internal::InvokeArgumentAction$i<N, $As>($as));
+}
+
+]]
+
+// WithoutArgs(inner_action) can be used in a mock function with a
+// non-empty argument list to perform inner_action, which takes no
+// argument. In other words, it adapts an action accepting no
+// argument to one that accepts (and ignores) arguments.
+template <typename InnerAction>
+inline internal::WithArgsAction<InnerAction>
+WithoutArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction>(action);
+}
+
+// WithArg<k>(an_action) creates an action that passes the k-th
+// (0-based) argument of the mock function to an_action and performs
+// it. It adapts an action accepting one argument to one that accepts
+// multiple arguments. For convenience, we also provide
+// WithArgs<k>(an_action) (defined below) as a synonym.
+template <int k, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k>
+WithArg(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction, k>(action);
+}
+
+// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
+// the selected arguments of the mock function to an_action and
+// performs it. It serves as an adaptor between actions with
+// different argument lists. C++ doesn't support default arguments for
+// function templates, so we have to overload it.
+
+$range i 1..n
+$for i [[
+$range j 1..i
+template <$for j [[int k$j, ]]typename InnerAction>
+inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
+WithArgs(const InnerAction& action) {
+ return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
+}
+
+
+]]
+// Creates an action that does actions a1, a2, ..., sequentially in
+// each invocation.
+$range i 2..n
+$for i [[
+$range j 2..i
+$var types = [[$for j, [[typename Action$j]]]]
+$var Aas = [[$for j [[, Action$j a$j]]]]
+
+template <typename Action1, $types>
+$range k 1..i-1
+
+inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
+
+DoAll(Action1 a1$Aas) {
+$if i==2 [[
+
+ return internal::DoBothAction<Action1, Action2>(a1, a2);
+]] $else [[
+$range j2 2..i
+
+ return DoAll(a1, DoAll($for j2, [[a$j2]]));
+]]
+
+}
+
+]]
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/include/gmock/gmock-generated-function-mockers.h b/include/gmock/gmock-generated-function-mockers.h
new file mode 100644
index 00000000..abdfc9e0
--- /dev/null
+++ b/include/gmock/gmock-generated-function-mockers.h
@@ -0,0 +1,706 @@
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements function mockers of various arities.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+
+#include <gmock/gmock-spec-builders.h>
+#include <gmock/internal/gmock-internal-utils.h>
+
+namespace testing {
+
+template <typename F>
+class MockSpec;
+
+namespace internal {
+
+template <typename F>
+class FunctionMockerBase;
+
+// Note: class FunctionMocker really belongs to the ::testing
+// namespace. However if we define it in ::testing, MSVC will
+// complain when classes in ::testing::internal declare it as a
+// friend class template. To workaround this compiler bug, we define
+// FunctionMocker in ::testing::internal and import it into ::testing.
+template <typename F>
+class FunctionMocker;
+
+template <typename R>
+class FunctionMocker<R()> : public
+ internal::FunctionMockerBase<R()> {
+ public:
+ typedef R F();
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With() {
+ return this->current_spec();
+ }
+
+ R Invoke() {
+ return InvokeWith(ArgumentTuple());
+ }
+};
+
+template <typename R, typename A1>
+class FunctionMocker<R(A1)> : public
+ internal::FunctionMockerBase<R(A1)> {
+ public:
+ typedef R F(A1);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1) {
+ return InvokeWith(ArgumentTuple(a1));
+ }
+};
+
+template <typename R, typename A1, typename A2>
+class FunctionMocker<R(A1, A2)> : public
+ internal::FunctionMockerBase<R(A1, A2)> {
+ public:
+ typedef R F(A1, A2);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2) {
+ return InvokeWith(ArgumentTuple(a1, a2));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3>
+class FunctionMocker<R(A1, A2, A3)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3)> {
+ public:
+ typedef R F(A1, A2, A3);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+class FunctionMocker<R(A1, A2, A3, A4)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
+ public:
+ typedef R F(A1, A2, A3, A4);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
+ public:
+ typedef R F(A1, A2, A3, A4, A5);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4,
+ m5));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
+ public:
+ typedef R F(A1, A2, A3, A4, A5, A6);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
+ const Matcher<A6>& m6) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
+ m6));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7>
+class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
+ public:
+ typedef R F(A1, A2, A3, A4, A5, A6, A7);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
+ const Matcher<A6>& m6, const Matcher<A7>& m7) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
+ m6, m7));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8>
+class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
+ public:
+ typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
+ const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
+ m6, m7, m8));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9>
+class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
+ public:
+ typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
+ const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
+ const Matcher<A9>& m9) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
+ m6, m7, m8, m9));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+ }
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9,
+ typename A10>
+class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
+ internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
+ public:
+ typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
+ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
+ const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
+ const Matcher<A9>& m9, const Matcher<A10>& m10) {
+ this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
+ m6, m7, m8, m9, m10));
+ return this->current_spec();
+ }
+
+ R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
+ A10 a10) {
+ return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
+ }
+};
+
+} // namespace internal
+
+// The style guide prohibits "using" statements in a namespace scope
+// inside a header file. However, the FunctionMocker class template
+// is meant to be defined in the ::testing namespace. The following
+// line is just a trick for working around a bug in MSVC 8.0, which
+// cannot handle it if we define FunctionMocker in ::testing.
+using internal::FunctionMocker;
+
+// The result type of function type F.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_RESULT(tn, F) tn ::testing::internal::Function<F>::Result
+
+// The type of argument N of function type F.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_ARG(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
+
+// The matcher type for argument N of function type F.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_MATCHER(tn, F, N) const ::testing::Matcher<GMOCK_ARG(tn, F, N)>&
+
+// The variable for mocking the given method.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_MOCKER(Method) GMOCK_CONCAT_TOKEN(gmock_##Method##_, __LINE__)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD0(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method() constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 0, \
+ this_method_does_not_take_0_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method() constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD1(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 1, \
+ this_method_does_not_take_1_argument); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD2(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 2, \
+ this_method_does_not_take_2_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD3(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 3, \
+ this_method_does_not_take_3_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD4(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 4, \
+ this_method_does_not_take_4_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD5(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4, \
+ GMOCK_ARG(tn, F, 5) gmock_a5) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 5, \
+ this_method_does_not_take_5_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4, gmock_a5); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4, \
+ GMOCK_MATCHER(tn, F, 5) gmock_a5) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD6(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4, \
+ GMOCK_ARG(tn, F, 5) gmock_a5, \
+ GMOCK_ARG(tn, F, 6) gmock_a6) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 6, \
+ this_method_does_not_take_6_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4, gmock_a5, gmock_a6); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4, \
+ GMOCK_MATCHER(tn, F, 5) gmock_a5, \
+ GMOCK_MATCHER(tn, F, 6) gmock_a6) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD7(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4, \
+ GMOCK_ARG(tn, F, 5) gmock_a5, \
+ GMOCK_ARG(tn, F, 6) gmock_a6, \
+ GMOCK_ARG(tn, F, 7) gmock_a7) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 7, \
+ this_method_does_not_take_7_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4, \
+ GMOCK_MATCHER(tn, F, 5) gmock_a5, \
+ GMOCK_MATCHER(tn, F, 6) gmock_a6, \
+ GMOCK_MATCHER(tn, F, 7) gmock_a7) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD8(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4, \
+ GMOCK_ARG(tn, F, 5) gmock_a5, \
+ GMOCK_ARG(tn, F, 6) gmock_a6, \
+ GMOCK_ARG(tn, F, 7) gmock_a7, \
+ GMOCK_ARG(tn, F, 8) gmock_a8) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 8, \
+ this_method_does_not_take_8_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4, \
+ GMOCK_MATCHER(tn, F, 5) gmock_a5, \
+ GMOCK_MATCHER(tn, F, 6) gmock_a6, \
+ GMOCK_MATCHER(tn, F, 7) gmock_a7, \
+ GMOCK_MATCHER(tn, F, 8) gmock_a8) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD9(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4, \
+ GMOCK_ARG(tn, F, 5) gmock_a5, \
+ GMOCK_ARG(tn, F, 6) gmock_a6, \
+ GMOCK_ARG(tn, F, 7) gmock_a7, \
+ GMOCK_ARG(tn, F, 8) gmock_a8, \
+ GMOCK_ARG(tn, F, 9) gmock_a9) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 9, \
+ this_method_does_not_take_9_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4, \
+ GMOCK_MATCHER(tn, F, 5) gmock_a5, \
+ GMOCK_MATCHER(tn, F, 6) gmock_a6, \
+ GMOCK_MATCHER(tn, F, 7) gmock_a7, \
+ GMOCK_MATCHER(tn, F, 8) gmock_a8, \
+ GMOCK_MATCHER(tn, F, 9) gmock_a9) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
+ gmock_a9); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD10(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
+ GMOCK_ARG(tn, F, 2) gmock_a2, \
+ GMOCK_ARG(tn, F, 3) gmock_a3, \
+ GMOCK_ARG(tn, F, 4) gmock_a4, \
+ GMOCK_ARG(tn, F, 5) gmock_a5, \
+ GMOCK_ARG(tn, F, 6) gmock_a6, \
+ GMOCK_ARG(tn, F, 7) gmock_a7, \
+ GMOCK_ARG(tn, F, 8) gmock_a8, \
+ GMOCK_ARG(tn, F, 9) gmock_a9, \
+ GMOCK_ARG(tn, F, 10) gmock_a10) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == 10, \
+ this_method_does_not_take_10_arguments); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
+ gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
+ gmock_a10); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
+ GMOCK_MATCHER(tn, F, 2) gmock_a2, \
+ GMOCK_MATCHER(tn, F, 3) gmock_a3, \
+ GMOCK_MATCHER(tn, F, 4) gmock_a4, \
+ GMOCK_MATCHER(tn, F, 5) gmock_a5, \
+ GMOCK_MATCHER(tn, F, 6) gmock_a6, \
+ GMOCK_MATCHER(tn, F, 7) gmock_a7, \
+ GMOCK_MATCHER(tn, F, 8) gmock_a8, \
+ GMOCK_MATCHER(tn, F, 9) gmock_a9, \
+ GMOCK_MATCHER(tn, F, 10) gmock_a10) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
+ gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
+ gmock_a10); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+#define MOCK_METHOD0(m, F) GMOCK_METHOD0(, , , m, F)
+#define MOCK_METHOD1(m, F) GMOCK_METHOD1(, , , m, F)
+#define MOCK_METHOD2(m, F) GMOCK_METHOD2(, , , m, F)
+#define MOCK_METHOD3(m, F) GMOCK_METHOD3(, , , m, F)
+#define MOCK_METHOD4(m, F) GMOCK_METHOD4(, , , m, F)
+#define MOCK_METHOD5(m, F) GMOCK_METHOD5(, , , m, F)
+#define MOCK_METHOD6(m, F) GMOCK_METHOD6(, , , m, F)
+#define MOCK_METHOD7(m, F) GMOCK_METHOD7(, , , m, F)
+#define MOCK_METHOD8(m, F) GMOCK_METHOD8(, , , m, F)
+#define MOCK_METHOD9(m, F) GMOCK_METHOD9(, , , m, F)
+#define MOCK_METHOD10(m, F) GMOCK_METHOD10(, , , m, F)
+
+#define MOCK_CONST_METHOD0(m, F) GMOCK_METHOD0(, const, , m, F)
+#define MOCK_CONST_METHOD1(m, F) GMOCK_METHOD1(, const, , m, F)
+#define MOCK_CONST_METHOD2(m, F) GMOCK_METHOD2(, const, , m, F)
+#define MOCK_CONST_METHOD3(m, F) GMOCK_METHOD3(, const, , m, F)
+#define MOCK_CONST_METHOD4(m, F) GMOCK_METHOD4(, const, , m, F)
+#define MOCK_CONST_METHOD5(m, F) GMOCK_METHOD5(, const, , m, F)
+#define MOCK_CONST_METHOD6(m, F) GMOCK_METHOD6(, const, , m, F)
+#define MOCK_CONST_METHOD7(m, F) GMOCK_METHOD7(, const, , m, F)
+#define MOCK_CONST_METHOD8(m, F) GMOCK_METHOD8(, const, , m, F)
+#define MOCK_CONST_METHOD9(m, F) GMOCK_METHOD9(, const, , m, F)
+#define MOCK_CONST_METHOD10(m, F) GMOCK_METHOD10(, const, , m, F)
+
+#define MOCK_METHOD0_T(m, F) GMOCK_METHOD0(typename, , , m, F)
+#define MOCK_METHOD1_T(m, F) GMOCK_METHOD1(typename, , , m, F)
+#define MOCK_METHOD2_T(m, F) GMOCK_METHOD2(typename, , , m, F)
+#define MOCK_METHOD3_T(m, F) GMOCK_METHOD3(typename, , , m, F)
+#define MOCK_METHOD4_T(m, F) GMOCK_METHOD4(typename, , , m, F)
+#define MOCK_METHOD5_T(m, F) GMOCK_METHOD5(typename, , , m, F)
+#define MOCK_METHOD6_T(m, F) GMOCK_METHOD6(typename, , , m, F)
+#define MOCK_METHOD7_T(m, F) GMOCK_METHOD7(typename, , , m, F)
+#define MOCK_METHOD8_T(m, F) GMOCK_METHOD8(typename, , , m, F)
+#define MOCK_METHOD9_T(m, F) GMOCK_METHOD9(typename, , , m, F)
+#define MOCK_METHOD10_T(m, F) GMOCK_METHOD10(typename, , , m, F)
+
+#define MOCK_CONST_METHOD0_T(m, F) GMOCK_METHOD0(typename, const, , m, F)
+#define MOCK_CONST_METHOD1_T(m, F) GMOCK_METHOD1(typename, const, , m, F)
+#define MOCK_CONST_METHOD2_T(m, F) GMOCK_METHOD2(typename, const, , m, F)
+#define MOCK_CONST_METHOD3_T(m, F) GMOCK_METHOD3(typename, const, , m, F)
+#define MOCK_CONST_METHOD4_T(m, F) GMOCK_METHOD4(typename, const, , m, F)
+#define MOCK_CONST_METHOD5_T(m, F) GMOCK_METHOD5(typename, const, , m, F)
+#define MOCK_CONST_METHOD6_T(m, F) GMOCK_METHOD6(typename, const, , m, F)
+#define MOCK_CONST_METHOD7_T(m, F) GMOCK_METHOD7(typename, const, , m, F)
+#define MOCK_CONST_METHOD8_T(m, F) GMOCK_METHOD8(typename, const, , m, F)
+#define MOCK_CONST_METHOD9_T(m, F) GMOCK_METHOD9(typename, const, , m, F)
+#define MOCK_CONST_METHOD10_T(m, F) GMOCK_METHOD10(typename, const, , m, F)
+
+#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD0(, , ct, m, F)
+#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD1(, , ct, m, F)
+#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD2(, , ct, m, F)
+#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD3(, , ct, m, F)
+#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD4(, , ct, m, F)
+#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD5(, , ct, m, F)
+#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD6(, , ct, m, F)
+#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD7(, , ct, m, F)
+#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD8(, , ct, m, F)
+#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD9(, , ct, m, F)
+#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD10(, , ct, m, F)
+
+#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD0(, const, ct, m, F)
+#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD1(, const, ct, m, F)
+#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD2(, const, ct, m, F)
+#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD3(, const, ct, m, F)
+#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD4(, const, ct, m, F)
+#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD5(, const, ct, m, F)
+#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD6(, const, ct, m, F)
+#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD7(, const, ct, m, F)
+#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD8(, const, ct, m, F)
+#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD9(, const, ct, m, F)
+#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD10(, const, ct, m, F)
+
+#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD0(typename, , ct, m, F)
+#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD1(typename, , ct, m, F)
+#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD2(typename, , ct, m, F)
+#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD3(typename, , ct, m, F)
+#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD4(typename, , ct, m, F)
+#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD5(typename, , ct, m, F)
+#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD6(typename, , ct, m, F)
+#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD7(typename, , ct, m, F)
+#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD8(typename, , ct, m, F)
+#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD9(typename, , ct, m, F)
+#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD10(typename, , ct, m, F)
+
+#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD0(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD1(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD2(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD3(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD4(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD5(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD6(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD7(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD8(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD9(typename, const, ct, m, F)
+#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD10(typename, const, ct, m, F)
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/include/gmock/gmock-generated-function-mockers.h.pump b/include/gmock/gmock-generated-function-mockers.h.pump
new file mode 100644
index 00000000..4f7fdc16
--- /dev/null
+++ b/include/gmock/gmock-generated-function-mockers.h.pump
@@ -0,0 +1,200 @@
+$$ -*- mode: c++; -*-
+$$ This is a Pump source file. Please use Pump to convert it to
+$$ gmock-generated-function-mockers.h.
+$$
+$var n = 10 $$ The maximum arity we support.
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements function mockers of various arities.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+
+#include <gmock/gmock-spec-builders.h>
+#include <gmock/internal/gmock-internal-utils.h>
+
+namespace testing {
+
+template <typename F>
+class MockSpec;
+
+namespace internal {
+
+template <typename F>
+class FunctionMockerBase;
+
+// Note: class FunctionMocker really belongs to the ::testing
+// namespace. However if we define it in ::testing, MSVC will
+// complain when classes in ::testing::internal declare it as a
+// friend class template. To workaround this compiler bug, we define
+// FunctionMocker in ::testing::internal and import it into ::testing.
+template <typename F>
+class FunctionMocker;
+
+
+$range i 0..n
+$for i [[
+$range j 1..i
+$var typename_As = [[$for j [[, typename A$j]]]]
+$var As = [[$for j, [[A$j]]]]
+$var as = [[$for j, [[a$j]]]]
+$var Aas = [[$for j, [[A$j a$j]]]]
+$var ms = [[$for j, [[m$j]]]]
+$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
+template <typename R$typename_As>
+class FunctionMocker<R($As)> : public
+ internal::FunctionMockerBase<R($As)> {
+ public:
+ typedef R F($As);
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+
+ MockSpec<F>& With($matchers) {
+
+$if i >= 1 [[
+ this->current_spec().SetMatchers(::std::tr1::make_tuple($ms));
+
+]]
+ return this->current_spec();
+ }
+
+ R Invoke($Aas) {
+ return InvokeWith(ArgumentTuple($as));
+ }
+};
+
+
+]]
+} // namespace internal
+
+// The style guide prohibits "using" statements in a namespace scope
+// inside a header file. However, the FunctionMocker class template
+// is meant to be defined in the ::testing namespace. The following
+// line is just a trick for working around a bug in MSVC 8.0, which
+// cannot handle it if we define FunctionMocker in ::testing.
+using internal::FunctionMocker;
+
+// The result type of function type F.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_RESULT(tn, F) tn ::testing::internal::Function<F>::Result
+
+// The type of argument N of function type F.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_ARG(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
+
+// The matcher type for argument N of function type F.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_MATCHER(tn, F, N) const ::testing::Matcher<GMOCK_ARG(tn, F, N)>&
+
+// The variable for mocking the given method.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_MOCKER(Method) GMOCK_CONCAT_TOKEN(gmock_##Method##_, __LINE__)
+
+
+$for i [[
+$range j 1..i
+$var arg_as = [[$for j, \
+ [[GMOCK_ARG(tn, F, $j) gmock_a$j]]]]
+$var as = [[$for j, [[gmock_a$j]]]]
+$var matcher_as = [[$for j, \
+ [[GMOCK_MATCHER(tn, F, $j) gmock_a$j]]]]
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD$i(tn, constness, ct, Method, F) \
+ GMOCK_RESULT(tn, F) ct Method($arg_as) constness { \
+ GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
+ tn ::testing::internal::Function<F>::ArgumentTuple>::value == $i, \
+ this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
+ GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
+ return GMOCK_MOCKER(Method).Invoke($as); \
+ } \
+ ::testing::MockSpec<F>& \
+ gmock_##Method($matcher_as) constness { \
+ return GMOCK_MOCKER(Method).RegisterOwner(this).With($as); \
+ } \
+ mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
+
+
+]]
+$for i [[
+#define MOCK_METHOD$i(m, F) GMOCK_METHOD$i(, , , m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_CONST_METHOD$i(m, F) GMOCK_METHOD$i(, const, , m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i(typename, , , m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_CONST_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i(typename, const, , m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD$i(, , ct, m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD$i(, const, ct, m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD$i(typename, , ct, m, F)
+
+]]
+
+
+$for i [[
+#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
+ GMOCK_METHOD$i(typename, const, ct, m, F)
+
+]]
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/include/gmock/gmock-generated-matchers.h b/include/gmock/gmock-generated-matchers.h
new file mode 100644
index 00000000..09ccc9c3
--- /dev/null
+++ b/include/gmock/gmock-generated-matchers.h
@@ -0,0 +1,650 @@
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used variadic matchers.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <gmock/gmock-matchers.h>
+
+namespace testing {
+namespace internal {
+
+// 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;
+
+ // Constructs the matcher from a sequence of element values or
+ // element matchers.
+ template <typename InputIter>
+ ElementsAreMatcherImpl(InputIter first, size_t count) {
+ matchers_.reserve(count);
+ InputIter it = first;
+ for (size_t i = 0; i != count; ++i, ++it) {
+ matchers_.push_back(MatcherCast<const Element&>(*it));
+ }
+ }
+
+ // Returns true iff 'container' matches.
+ virtual bool Matches(Container container) const {
+ if (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))
+ return false;
+ }
+
+ return true;
+ }
+
+ // Describes what this matcher does.
+ virtual void DescribeTo(::std::ostream* os) const {
+ if (count() == 0) {
+ *os << "is empty";
+ } else if (count() == 1) {
+ *os << "has 1 element that ";
+ matchers_[0].DescribeTo(os);
+ } else {
+ *os << "has " << Elements(count()) << " where\n";
+ for (size_t i = 0; i != count(); ++i) {
+ *os << "element " << i << " ";
+ matchers_[i].DescribeTo(os);
+ if (i + 1 < count()) {
+ *os << ",\n";
+ }
+ }
+ }
+ }
+
+ // Describes what the negation of this matcher does.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ if (count() == 0) {
+ *os << "is not empty";
+ return;
+ }
+
+ *os << "does not have " << Elements(count()) << ", or\n";
+ for (size_t i = 0; i != count(); ++i) {
+ *os << "element " << i << " ";
+ matchers_[i].DescribeNegationTo(os);
+ if (i + 1 < count()) {
+ *os << ", or\n";
+ }
+ }
+ }
+
+ // Explains why 'container' matches, or doesn't match, this matcher.
+ virtual void ExplainMatchResultTo(Container container,
+ ::std::ostream* os) const {
+ 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) {
+ ::std::stringstream ss;
+ matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
+
+ const string s = ss.str();
+ if (!s.empty()) {
+ if (reason_printed) {
+ *os << ",\n";
+ }
+ *os << "element " << i << " " << s;
+ reason_printed = true;
+ }
+ }
+ } else {
+ // We need to explain why the container doesn't match.
+ const size_t actual_count = container.size();
+ if (actual_count != count()) {
+ // The element count doesn't match. If the container is
+ // empty, there's no need to explain anything as Google Mock
+ // already prints the empty container. Otherwise we just need
+ // to show how many elements there actually are.
+ if (actual_count != 0) {
+ *os << "has " << Elements(actual_count);
+ }
+ return;
+ }
+
+ // The container has the right size but at least one element
+ // doesn't match expectation. We need to find this element and
+ // explain why it doesn't match.
+ typename RawContainer::const_iterator container_iter = container.begin();
+ for (size_t i = 0; i != count(); ++container_iter, ++i) {
+ if (matchers_[i].Matches(*container_iter)) {
+ continue;
+ }
+
+ *os << "element " << i << " doesn't match";
+
+ ::std::stringstream ss;
+ matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
+ const string s = ss.str();
+ if (!s.empty()) {
+ *os << " (" << s << ")";
+ }
+ return;
+ }
+ }
+ }
+
+ private:
+ static Message Elements(size_t count) {
+ return Message() << count << (count == 1 ? " element" : " elements");
+ }
+
+ size_t count() const { return matchers_.size(); }
+ std::vector<Matcher<const Element&> > matchers_;
+};
+
+// Implements ElementsAre() of 0-10 arguments.
+
+class ElementsAreMatcher0 {
+ public:
+ ElementsAreMatcher0() {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&>* const matchers = NULL;
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
+ }
+};
+
+template <typename T1>
+class ElementsAreMatcher1 {
+ public:
+ explicit ElementsAreMatcher1(const T1& e1) : e1_(e1) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 1));
+ }
+
+ private:
+ const T1& e1_;
+};
+
+template <typename T1, typename T2>
+class ElementsAreMatcher2 {
+ public:
+ ElementsAreMatcher2(const T1& e1, const T2& e2) : e1_(e1), e2_(e2) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 2));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+};
+
+template <typename T1, typename T2, typename T3>
+class ElementsAreMatcher3 {
+ public:
+ ElementsAreMatcher3(const T1& e1, const T2& e2, const T3& e3) : e1_(e1),
+ e2_(e2), e3_(e3) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 3));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class ElementsAreMatcher4 {
+ public:
+ ElementsAreMatcher4(const T1& e1, const T2& e2, const T3& e3,
+ const T4& e4) : e1_(e1), e2_(e2), e3_(e3), e4_(e4) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 4));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class ElementsAreMatcher5 {
+ public:
+ ElementsAreMatcher5(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ MatcherCast<const Element&>(e5_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 5));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+ const T5& e5_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+class ElementsAreMatcher6 {
+ public:
+ ElementsAreMatcher6(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6) : e1_(e1), e2_(e2), e3_(e3), e4_(e4),
+ e5_(e5), e6_(e6) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ MatcherCast<const Element&>(e5_),
+ MatcherCast<const Element&>(e6_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 6));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+ const T5& e5_;
+ const T6& e6_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+class ElementsAreMatcher7 {
+ public:
+ ElementsAreMatcher7(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7) : e1_(e1), e2_(e2), e3_(e3),
+ e4_(e4), e5_(e5), e6_(e6), e7_(e7) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ MatcherCast<const Element&>(e5_),
+ MatcherCast<const Element&>(e6_),
+ MatcherCast<const Element&>(e7_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 7));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+ const T5& e5_;
+ const T6& e6_;
+ const T7& e7_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+class ElementsAreMatcher8 {
+ public:
+ ElementsAreMatcher8(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7, const T8& e8) : e1_(e1),
+ e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6), e7_(e7), e8_(e8) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ MatcherCast<const Element&>(e5_),
+ MatcherCast<const Element&>(e6_),
+ MatcherCast<const Element&>(e7_),
+ MatcherCast<const Element&>(e8_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 8));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+ const T5& e5_;
+ const T6& e6_;
+ const T7& e7_;
+ const T8& e8_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+class ElementsAreMatcher9 {
+ public:
+ ElementsAreMatcher9(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7, const T8& e8,
+ const T9& e9) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6),
+ e7_(e7), e8_(e8), e9_(e9) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ MatcherCast<const Element&>(e5_),
+ MatcherCast<const Element&>(e6_),
+ MatcherCast<const Element&>(e7_),
+ MatcherCast<const Element&>(e8_),
+ MatcherCast<const Element&>(e9_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 9));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+ const T5& e5_;
+ const T6& e6_;
+ const T7& e7_;
+ const T8& e8_;
+ const T9& e9_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+class ElementsAreMatcher10 {
+ public:
+ ElementsAreMatcher10(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
+ const T10& e10) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6),
+ e7_(e7), e8_(e8), e9_(e9), e10_(e10) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+ MatcherCast<const Element&>(e1_),
+ MatcherCast<const Element&>(e2_),
+ MatcherCast<const Element&>(e3_),
+ MatcherCast<const Element&>(e4_),
+ MatcherCast<const Element&>(e5_),
+ MatcherCast<const Element&>(e6_),
+ MatcherCast<const Element&>(e7_),
+ MatcherCast<const Element&>(e8_),
+ MatcherCast<const Element&>(e9_),
+ MatcherCast<const Element&>(e10_),
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 10));
+ }
+
+ private:
+ const T1& e1_;
+ const T2& e2_;
+ const T3& e3_;
+ const T4& e4_;
+ const T5& e5_;
+ const T6& e6_;
+ const T7& e7_;
+ const T8& e8_;
+ const T9& e9_;
+ const T10& e10_;
+};
+
+// Implements ElementsAreArray().
+template <typename T>
+class ElementsAreArrayMatcher {
+ public:
+ ElementsAreArrayMatcher(const T* first, size_t count) :
+ first_(first), count_(count) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
+ }
+
+ private:
+ const T* const first_;
+ const size_t count_;
+};
+
+} // namespace internal
+
+// 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
+// ElementsAre() can be either a value or a matcher. We support up to
+// 10 arguments.
+//
+// NOTE: Since ElementsAre() cares about the order of the elements, it
+// must not be used with containers whose elements's order is
+// undefined (e.g. hash_map).
+
+inline internal::ElementsAreMatcher0 ElementsAre() {
+ return internal::ElementsAreMatcher0();
+}
+
+template <typename T1>
+inline internal::ElementsAreMatcher1<T1> ElementsAre(const T1& e1) {
+ return internal::ElementsAreMatcher1<T1>(e1);
+}
+
+template <typename T1, typename T2>
+inline internal::ElementsAreMatcher2<T1, T2> ElementsAre(const T1& e1,
+ const T2& e2) {
+ return internal::ElementsAreMatcher2<T1, T2>(e1, e2);
+}
+
+template <typename T1, typename T2, typename T3>
+inline internal::ElementsAreMatcher3<T1, T2, T3> ElementsAre(const T1& e1,
+ const T2& e2, const T3& e3) {
+ return internal::ElementsAreMatcher3<T1, T2, T3>(e1, e2, e3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+inline internal::ElementsAreMatcher4<T1, T2, T3, T4> ElementsAre(const T1& e1,
+ const T2& e2, const T3& e3, const T4& e4) {
+ return internal::ElementsAreMatcher4<T1, T2, T3, T4>(e1, e2, e3, e4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+inline internal::ElementsAreMatcher5<T1, T2, T3, T4,
+ T5> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5) {
+ return internal::ElementsAreMatcher5<T1, T2, T3, T4, T5>(e1, e2, e3, e4, e5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+inline internal::ElementsAreMatcher6<T1, T2, T3, T4, T5,
+ T6> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6) {
+ return internal::ElementsAreMatcher6<T1, T2, T3, T4, T5, T6>(e1, e2, e3, e4,
+ e5, e6);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+inline internal::ElementsAreMatcher7<T1, T2, T3, T4, T5, T6,
+ T7> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7) {
+ return internal::ElementsAreMatcher7<T1, T2, T3, T4, T5, T6, T7>(e1, e2, e3,
+ e4, e5, e6, e7);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+inline internal::ElementsAreMatcher8<T1, T2, T3, T4, T5, T6, T7,
+ T8> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
+ return internal::ElementsAreMatcher8<T1, T2, T3, T4, T5, T6, T7, T8>(e1, e2,
+ e3, e4, e5, e6, e7, e8);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+inline internal::ElementsAreMatcher9<T1, T2, T3, T4, T5, T6, T7, T8,
+ T9> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
+ return internal::ElementsAreMatcher9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(e1,
+ e2, e3, e4, e5, e6, e7, e8, e9);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+inline internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+ T10> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
+ const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
+ const T10& e10) {
+ return internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+ T10>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
+}
+
+// ElementsAreArray(array) and ElementAreArray(array, count) are like
+// ElementsAre(), except that they take an array of values or
+// matchers. The former form infers the size of 'array', which must
+// be a static C-style array. In the latter form, 'array' can either
+// be a static array or a pointer to a dynamically created array.
+
+template <typename T>
+inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
+ const T* first, size_t count) {
+ return internal::ElementsAreArrayMatcher<T>(first, count);
+}
+
+template <typename T, size_t N>
+inline internal::ElementsAreArrayMatcher<T>
+ElementsAreArray(const T (&array)[N]) {
+ return internal::ElementsAreArrayMatcher<T>(array, N);
+}
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
diff --git a/include/gmock/gmock-generated-matchers.h.pump b/include/gmock/gmock-generated-matchers.h.pump
new file mode 100644
index 00000000..b45028ae
--- /dev/null
+++ b/include/gmock/gmock-generated-matchers.h.pump
@@ -0,0 +1,303 @@
+$$ -*- mode: c++; -*-
+$$ 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.
+// 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.
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used variadic matchers.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <gmock/gmock-matchers.h>
+
+namespace testing {
+namespace internal {
+
+// 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;
+
+ // Constructs the matcher from a sequence of element values or
+ // element matchers.
+ template <typename InputIter>
+ ElementsAreMatcherImpl(InputIter first, size_t count) {
+ matchers_.reserve(count);
+ InputIter it = first;
+ for (size_t i = 0; i != count; ++i, ++it) {
+ matchers_.push_back(MatcherCast<const Element&>(*it));
+ }
+ }
+
+ // Returns true iff 'container' matches.
+ virtual bool Matches(Container container) const {
+ if (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))
+ return false;
+ }
+
+ return true;
+ }
+
+ // Describes what this matcher does.
+ virtual void DescribeTo(::std::ostream* os) const {
+ if (count() == 0) {
+ *os << "is empty";
+ } else if (count() == 1) {
+ *os << "has 1 element that ";
+ matchers_[0].DescribeTo(os);
+ } else {
+ *os << "has " << Elements(count()) << " where\n";
+ for (size_t i = 0; i != count(); ++i) {
+ *os << "element " << i << " ";
+ matchers_[i].DescribeTo(os);
+ if (i + 1 < count()) {
+ *os << ",\n";
+ }
+ }
+ }
+ }
+
+ // Describes what the negation of this matcher does.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ if (count() == 0) {
+ *os << "is not empty";
+ return;
+ }
+
+ *os << "does not have " << Elements(count()) << ", or\n";
+ for (size_t i = 0; i != count(); ++i) {
+ *os << "element " << i << " ";
+ matchers_[i].DescribeNegationTo(os);
+ if (i + 1 < count()) {
+ *os << ", or\n";
+ }
+ }
+ }
+
+ // Explains why 'container' matches, or doesn't match, this matcher.
+ virtual void ExplainMatchResultTo(Container container,
+ ::std::ostream* os) const {
+ 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) {
+ ::std::stringstream ss;
+ matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
+
+ const string s = ss.str();
+ if (!s.empty()) {
+ if (reason_printed) {
+ *os << ",\n";
+ }
+ *os << "element " << i << " " << s;
+ reason_printed = true;
+ }
+ }
+ } else {
+ // We need to explain why the container doesn't match.
+ const size_t actual_count = container.size();
+ if (actual_count != count()) {
+ // The element count doesn't match. If the container is
+ // empty, there's no need to explain anything as Google Mock
+ // already prints the empty container. Otherwise we just need
+ // to show how many elements there actually are.
+ if (actual_count != 0) {
+ *os << "has " << Elements(actual_count);
+ }
+ return;
+ }
+
+ // The container has the right size but at least one element
+ // doesn't match expectation. We need to find this element and
+ // explain why it doesn't match.
+ typename RawContainer::const_iterator container_iter = container.begin();
+ for (size_t i = 0; i != count(); ++container_iter, ++i) {
+ if (matchers_[i].Matches(*container_iter)) {
+ continue;
+ }
+
+ *os << "element " << i << " doesn't match";
+
+ ::std::stringstream ss;
+ matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
+ const string s = ss.str();
+ if (!s.empty()) {
+ *os << " (" << s << ")";
+ }
+ return;
+ }
+ }
+ }
+
+ private:
+ static Message Elements(size_t count) {
+ return Message() << count << (count == 1 ? " element" : " elements");
+ }
+
+ size_t count() const { return matchers_.size(); }
+ std::vector<Matcher<const Element&> > matchers_;
+};
+
+// Implements ElementsAre() of 0-10 arguments.
+
+class ElementsAreMatcher0 {
+ public:
+ ElementsAreMatcher0() {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&>* const matchers = NULL;
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
+ }
+};
+
+
+$range i 1..n
+$for i [[
+$range j 1..i
+template <$for j, [[typename T$j]]>
+class ElementsAreMatcher$i {
+ public:
+ $if i==1 [[explicit ]]ElementsAreMatcher$i($for j, [[const T$j& e$j]])$if i > 0 [[ : ]]
+ $for j, [[e$j[[]]_(e$j)]] {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ const Matcher<const Element&> matchers[] = {
+
+$for j [[
+ MatcherCast<const Element&>(e$j[[]]_),
+
+]]
+ };
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i));
+ }
+
+ private:
+
+$for j [[
+ const T$j& e$j[[]]_;
+
+]]
+};
+
+
+]]
+// Implements ElementsAreArray().
+template <typename T>
+class ElementsAreArrayMatcher {
+ public:
+ ElementsAreArrayMatcher(const T* first, size_t count) :
+ first_(first), count_(count) {}
+
+ template <typename Container>
+ operator Matcher<Container>() const {
+ typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
+ typedef typename RawContainer::value_type Element;
+
+ return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
+ }
+
+ private:
+ const T* const first_;
+ const size_t count_;
+};
+
+} // namespace internal
+
+// 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
+// ElementsAre() can be either a value or a matcher. We support up to
+// $n arguments.
+//
+// NOTE: Since ElementsAre() cares about the order of the elements, it
+// must not be used with containers whose elements's order is
+// undefined (e.g. hash_map).
+
+inline internal::ElementsAreMatcher0 ElementsAre() {
+ return internal::ElementsAreMatcher0();
+}
+
+$for i [[
+$range j 1..i
+
+template <$for j, [[typename T$j]]>
+inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[const T$j& e$j]]) {
+ return internal::ElementsAreMatcher$i<$for j, [[T$j]]>($for j, [[e$j]]);
+}
+
+]]
+
+// ElementsAreArray(array) and ElementAreArray(array, count) are like
+// ElementsAre(), except that they take an array of values or
+// matchers. The former form infers the size of 'array', which must
+// be a static C-style array. In the latter form, 'array' can either
+// be a static array or a pointer to a dynamically created array.
+
+template <typename T>
+inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
+ const T* first, size_t count) {
+ return internal::ElementsAreArrayMatcher<T>(first, count);
+}
+
+template <typename T, size_t N>
+inline internal::ElementsAreArrayMatcher<T>
+ElementsAreArray(const T (&array)[N]) {
+ return internal::ElementsAreArrayMatcher<T>(array, N);
+}
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
diff --git a/include/gmock/gmock-generated-nice-strict.h b/include/gmock/gmock-generated-nice-strict.h
new file mode 100644
index 00000000..f961d796
--- /dev/null
+++ b/include/gmock/gmock-generated-nice-strict.h
@@ -0,0 +1,244 @@
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Implements class templates NiceMock and StrictMock.
+//
+// Given a mock class MockFoo that is created using Google Mock,
+// NiceMock<MockFoo> is a subclass of MockFoo that allows
+// uninteresting calls (i.e. calls to mock methods that have no
+// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of
+// MockFoo that treats all uninteresting calls as errors.
+//
+// NiceMock and StrictMock "inherits" the constructors of their
+// respective base class, with up-to 10 arguments. Therefore you can
+// write NiceMock<MockFoo>(5, "a") to construct a nice mock where
+// MockFoo has a constructor that accepts (int, const char*), for
+// example.
+//
+// A known limitation is that NiceMock<MockFoo> and
+// StrictMock<MockFoo> only works for mock methods defined using the
+// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a
+// mock method is defined in a base class of MockFoo, the "nice" or
+// "strict" modifier may not affect it, depending on the compiler. In
+// particular, nesting NiceMock and StrictMock is NOT supported.
+//
+// Another known limitation is that the constructors of the base mock
+// cannot have arguments passed by non-const reference, which are
+// banned by the Google C++ style guide anyway.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
+
+#include <gmock/gmock-spec-builders.h>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+template <class MockClass>
+class NiceMock : public MockClass {
+ public:
+ // We don't factor out the constructor body to a common method, as
+ // we have to avoid a possible clash with members of MockClass.
+ NiceMock() {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ // C++ doesn't (yet) allow inheritance of constructors, so we have
+ // to define it for each arity.
+ template <typename A1>
+ explicit NiceMock(const A1& a1) : MockClass(a1) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+ template <typename A1, typename A2>
+ NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4) : MockClass(a1, a2, a3, a4) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
+ a6, a7) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
+ a2, a3, a4, a5, a6, a7, a8) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8, typename A9>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7, const A8& a8,
+ const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8, typename A9, typename A10>
+ NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
+ const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ virtual ~NiceMock() {
+ Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ }
+};
+
+template <class MockClass>
+class StrictMock : public MockClass {
+ public:
+ // We don't factor out the constructor body to a common method, as
+ // we have to avoid a possible clash with members of MockClass.
+ StrictMock() {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1>
+ explicit StrictMock(const A1& a1) : MockClass(a1) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+ template <typename A1, typename A2>
+ StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4) : MockClass(a1, a2, a3, a4) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
+ a6, a7) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
+ a2, a3, a4, a5, a6, a7, a8) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8, typename A9>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7, const A8& a8,
+ const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8, typename A9, typename A10>
+ StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
+ const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ virtual ~StrictMock() {
+ Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ }
+};
+
+// The following specializations catch some (relatively more common)
+// user errors of nesting nice and strict mocks. They do NOT catch
+// all possible errors.
+
+// These specializations are declared but not defined, as NiceMock and
+// StrictMock cannot be nested.
+template <typename MockClass>
+class NiceMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class NiceMock<StrictMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<StrictMock<MockClass> >;
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
diff --git a/include/gmock/gmock-generated-nice-strict.h.pump b/include/gmock/gmock-generated-nice-strict.h.pump
new file mode 100644
index 00000000..580e79f0
--- /dev/null
+++ b/include/gmock/gmock-generated-nice-strict.h.pump
@@ -0,0 +1,146 @@
+$$ -*- mode: c++; -*-
+$$ This is a Pump source file. Please use Pump to convert it to
+$$ gmock-generated-nice-strict.h.
+$$
+$var n = 10 $$ The maximum arity we support.
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Implements class templates NiceMock and StrictMock.
+//
+// Given a mock class MockFoo that is created using Google Mock,
+// NiceMock<MockFoo> is a subclass of MockFoo that allows
+// uninteresting calls (i.e. calls to mock methods that have no
+// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of
+// MockFoo that treats all uninteresting calls as errors.
+//
+// NiceMock and StrictMock "inherits" the constructors of their
+// respective base class, with up-to $n arguments. Therefore you can
+// write NiceMock<MockFoo>(5, "a") to construct a nice mock where
+// MockFoo has a constructor that accepts (int, const char*), for
+// example.
+//
+// A known limitation is that NiceMock<MockFoo> and
+// StrictMock<MockFoo> only works for mock methods defined using the
+// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a
+// mock method is defined in a base class of MockFoo, the "nice" or
+// "strict" modifier may not affect it, depending on the compiler. In
+// particular, nesting NiceMock and StrictMock is NOT supported.
+//
+// Another known limitation is that the constructors of the base mock
+// cannot have arguments passed by non-const reference, which are
+// banned by the Google C++ style guide anyway.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
+
+#include <gmock/gmock-spec-builders.h>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+template <class MockClass>
+class NiceMock : public MockClass {
+ public:
+ // We don't factor out the constructor body to a common method, as
+ // we have to avoid a possible clash with members of MockClass.
+ NiceMock() {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ // C++ doesn't (yet) allow inheritance of constructors, so we have
+ // to define it for each arity.
+ template <typename A1>
+ explicit NiceMock(const A1& a1) : MockClass(a1) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+$range i 2..n
+$for i [[
+$range j 1..i
+ template <$for j, [[typename A$j]]>
+ NiceMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
+ Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+
+]]
+ virtual ~NiceMock() {
+ Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ }
+};
+
+template <class MockClass>
+class StrictMock : public MockClass {
+ public:
+ // We don't factor out the constructor body to a common method, as
+ // we have to avoid a possible clash with members of MockClass.
+ StrictMock() {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+ template <typename A1>
+ explicit StrictMock(const A1& a1) : MockClass(a1) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+$for i [[
+$range j 1..i
+ template <$for j, [[typename A$j]]>
+ StrictMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
+ Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
+ }
+
+
+]]
+ virtual ~StrictMock() {
+ Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
+ }
+};
+
+// The following specializations catch some (relatively more common)
+// user errors of nesting nice and strict mocks. They do NOT catch
+// all possible errors.
+
+// These specializations are declared but not defined, as NiceMock and
+// StrictMock cannot be nested.
+template <typename MockClass>
+class NiceMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class NiceMock<StrictMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<StrictMock<MockClass> >;
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h
new file mode 100644
index 00000000..69879a48
--- /dev/null
+++ b/include/gmock/gmock-matchers.h
@@ -0,0 +1,2094 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used argument matchers. More
+// matchers can be defined by the user implementing the
+// MatcherInterface<T> interface if necessary.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
+
+#include <ostream> // NOLINT
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <gmock/gmock-printers.h>
+#include <gmock/internal/gmock-internal-utils.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+
+// To implement a matcher Foo for type T, define:
+// 1. a class FooMatcherImpl that implements the
+// MatcherInterface<T> interface, and
+// 2. a factory function that creates a Matcher<T> object from a
+// FooMatcherImpl*.
+//
+// The two-level delegation design makes it possible to allow a user
+// to write "v" instead of "Eq(v)" where a Matcher is expected, which
+// is impossible if we pass matchers by pointers. It also eases
+// ownership management as Matcher objects can now be copied like
+// plain values.
+
+// The implementation of a matcher.
+template <typename T>
+class MatcherInterface {
+ public:
+ virtual ~MatcherInterface() {}
+
+ // Returns true iff the matcher matches x.
+ virtual bool Matches(T x) const = 0;
+
+ // Describes this matcher to an ostream.
+ virtual void DescribeTo(::std::ostream* os) const = 0;
+
+ // Describes the negation of this matcher to an ostream. For
+ // example, if the description of this matcher is "is greater than
+ // 7", the negated description could be "is not greater than 7".
+ // You are not required to override this when implementing
+ // MatcherInterface, but it is highly advised so that your matcher
+ // can produce good error messages.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "not (";
+ DescribeTo(os);
+ *os << ")";
+ }
+
+ // Explains why x matches, or doesn't match, the matcher. Override
+ // this to provide any additional information that helps a user
+ // understand the match result.
+ virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ // By default, nothing more needs to be explained, as Google Mock
+ // has already printed the value of x when this function is
+ // called.
+ }
+};
+
+namespace internal {
+
+// An internal class for implementing Matcher<T>, which will derive
+// from it. We put functionalities common to all Matcher<T>
+// specializations here to avoid code duplication.
+template <typename T>
+class MatcherBase {
+ public:
+ // Returns true iff this matcher matches x.
+ bool Matches(T x) const { return impl_->Matches(x); }
+
+ // Describes this matcher to an ostream.
+ void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
+
+ // Describes the negation of this matcher to an ostream.
+ void DescribeNegationTo(::std::ostream* os) const {
+ impl_->DescribeNegationTo(os);
+ }
+
+ // Explains why x matches, or doesn't match, the matcher.
+ void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ impl_->ExplainMatchResultTo(x, os);
+ }
+ protected:
+ MatcherBase() {}
+
+ // Constructs a matcher from its implementation.
+ explicit MatcherBase(const MatcherInterface<T>* impl)
+ : impl_(impl) {}
+
+ virtual ~MatcherBase() {}
+ private:
+ // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar
+ // interfaces. The former dynamically allocates a chunk of memory
+ // to hold the reference count, while the latter tracks all
+ // references using a circular linked list without allocating
+ // memory. It has been observed that linked_ptr performs better in
+ // typical scenarios. However, shared_ptr can out-perform
+ // linked_ptr when there are many more uses of the copy constructor
+ // than the default constructor.
+ //
+ // If performance becomes a problem, we should see if using
+ // shared_ptr helps.
+ ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_;
+};
+
+// The default implementation of ExplainMatchResultTo() for
+// polymorphic matchers.
+template <typename PolymorphicMatcherImpl, typename T>
+inline void ExplainMatchResultTo(const PolymorphicMatcherImpl& impl, const T& x,
+ ::std::ostream* os) {
+ // By default, nothing more needs to be said, as Google Mock already
+ // prints the value of x elsewhere.
+}
+
+} // namespace internal
+
+// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
+// object that can check whether a value of type T matches. The
+// implementation of Matcher<T> is just a linked_ptr to const
+// MatcherInterface<T>, so copying is fairly cheap. Don't inherit
+// from Matcher!
+template <typename T>
+class Matcher : public internal::MatcherBase<T> {
+ public:
+ // Constructs a null matcher. Needed for storing Matcher objects in
+ // STL containers.
+ Matcher() {}
+
+ // Constructs a matcher from its implementation.
+ explicit Matcher(const MatcherInterface<T>* impl)
+ : internal::MatcherBase<T>(impl) {}
+
+ // Implicit constructor here allows ipeople to write
+ // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
+ Matcher(T value); // NOLINT
+};
+
+// The following two specializations allow the user to write str
+// instead of Eq(str) and "foo" instead of Eq("foo") when a string
+// matcher is expected.
+template <>
+class Matcher<const internal::string&>
+ : public internal::MatcherBase<const internal::string&> {
+ public:
+ Matcher() {}
+
+ explicit Matcher(const MatcherInterface<const internal::string&>* impl)
+ : internal::MatcherBase<const internal::string&>(impl) {}
+
+ // Allows the user to write str instead of Eq(str) sometimes, where
+ // str is a string object.
+ Matcher(const internal::string& s); // NOLINT
+
+ // Allows the user to write "foo" instead of Eq("foo") sometimes.
+ Matcher(const char* s); // NOLINT
+};
+
+template <>
+class Matcher<internal::string>
+ : public internal::MatcherBase<internal::string> {
+ public:
+ Matcher() {}
+
+ explicit Matcher(const MatcherInterface<internal::string>* impl)
+ : internal::MatcherBase<internal::string>(impl) {}
+
+ // Allows the user to write str instead of Eq(str) sometimes, where
+ // str is a string object.
+ Matcher(const internal::string& s); // NOLINT
+
+ // Allows the user to write "foo" instead of Eq("foo") sometimes.
+ Matcher(const char* s); // NOLINT
+};
+
+// The PolymorphicMatcher class template makes it easy to implement a
+// polymorphic matcher (i.e. a matcher that can match values of more
+// than one type, e.g. Eq(n) and NotNull()).
+//
+// To define a polymorphic matcher, a user first provides a Impl class
+// that has a Matches() method, a DescribeTo() method, and a
+// DescribeNegationTo() method. The Matches() method is usually a
+// method template (such that it works with multiple types). Then the
+// user creates the polymorphic matcher using
+// MakePolymorphicMatcher(). To provide additional explanation to the
+// match result, define a FREE function (or function template)
+//
+// void ExplainMatchResultTo(const Impl& matcher, const Value& value,
+// ::std::ostream* os);
+//
+// in the SAME NAME SPACE where Impl is defined. See the definition
+// of NotNull() for a complete example.
+template <class Impl>
+class PolymorphicMatcher {
+ public:
+ explicit PolymorphicMatcher(const Impl& impl) : impl_(impl) {}
+
+ template <typename T>
+ operator Matcher<T>() const {
+ return Matcher<T>(new MonomorphicImpl<T>(impl_));
+ }
+ private:
+ template <typename T>
+ class MonomorphicImpl : public MatcherInterface<T> {
+ public:
+ explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
+
+ virtual bool Matches(T x) const { return impl_.Matches(x); }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ impl_.DescribeTo(os);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ impl_.DescribeNegationTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ using ::testing::internal::ExplainMatchResultTo;
+
+ // C++ uses Argument-Dependent Look-up (aka Koenig Look-up) to
+ // resolve the call to ExplainMatchResultTo() here. This
+ // means that if there's a ExplainMatchResultTo() function
+ // defined in the name space where class Impl is defined, it
+ // will be picked by the compiler as the better match.
+ // Otherwise the default implementation of it in
+ // ::testing::internal will be picked.
+ //
+ // This look-up rule lets a writer of a polymorphic matcher
+ // customize the behavior of ExplainMatchResultTo() when he
+ // cares to. Nothing needs to be done by the writer if he
+ // doesn't need to customize it.
+ ExplainMatchResultTo(impl_, x, os);
+ }
+ private:
+ const Impl impl_;
+ };
+
+ const Impl impl_;
+};
+
+// Creates a matcher from its implementation. This is easier to use
+// than the Matcher<T> constructor as it doesn't require you to
+// explicitly write the template argument, e.g.
+//
+// MakeMatcher(foo);
+// vs
+// Matcher<const string&>(foo);
+template <typename T>
+inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
+ return Matcher<T>(impl);
+};
+
+// Creates a polymorphic matcher from its implementation. This is
+// easier to use than the PolymorphicMatcher<Impl> constructor as it
+// doesn't require you to explicitly write the template argument, e.g.
+//
+// MakePolymorphicMatcher(foo);
+// vs
+// PolymorphicMatcher<TypeOfFoo>(foo);
+template <class Impl>
+inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
+ return PolymorphicMatcher<Impl>(impl);
+}
+
+// In order to be safe and clear, casting between different matcher
+// types is done explicitly via MatcherCast<T>(m), which takes a
+// matcher m and returns a Matcher<T>. It compiles only when T can be
+// statically converted to the argument type of m.
+template <typename T, typename M>
+Matcher<T> MatcherCast(M m);
+
+// A<T>() returns a matcher that matches any value of type T.
+template <typename T>
+Matcher<T> A();
+
+// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
+// and MUST NOT BE USED IN USER CODE!!!
+namespace internal {
+
+// Appends the explanation on the result of matcher.Matches(value) to
+// os iff the explanation is not empty.
+template <typename T>
+void ExplainMatchResultAsNeededTo(const Matcher<T>& matcher, T value,
+ ::std::ostream* os) {
+ ::std::stringstream reason;
+ matcher.ExplainMatchResultTo(value, &reason);
+ const internal::string s = reason.str();
+ if (s != "") {
+ *os << " (" << s << ")";
+ }
+}
+
+// An internal helper class for doing compile-time loop on a tuple's
+// fields.
+template <size_t N>
+class TuplePrefix {
+ public:
+ // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true
+ // iff the first N fields of matcher_tuple matches the first N
+ // fields of value_tuple, respectively.
+ template <typename MatcherTuple, typename ValueTuple>
+ static bool Matches(const MatcherTuple& matcher_tuple,
+ const ValueTuple& value_tuple) {
+ using ::std::tr1::get;
+ return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple)
+ && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple));
+ }
+
+ // TuplePrefix<N>::DescribeMatchFailuresTo(matchers, values, os)
+ // describes failures in matching the first N fields of matchers
+ // against the first N fields of values. If there is no failure,
+ // nothing will be streamed to os.
+ template <typename MatcherTuple, typename ValueTuple>
+ static void DescribeMatchFailuresTo(const MatcherTuple& matchers,
+ const ValueTuple& values,
+ ::std::ostream* os) {
+ using ::std::tr1::tuple_element;
+ using ::std::tr1::get;
+
+ // First, describes failures in the first N - 1 fields.
+ TuplePrefix<N - 1>::DescribeMatchFailuresTo(matchers, values, os);
+
+ // Then describes the failure (if any) in the (N - 1)-th (0-based)
+ // field.
+ typename tuple_element<N - 1, MatcherTuple>::type matcher =
+ get<N - 1>(matchers);
+ typedef typename tuple_element<N - 1, ValueTuple>::type Value;
+ Value value = get<N - 1>(values);
+ if (!matcher.Matches(value)) {
+ // TODO(wan): include in the message the name of the parameter
+ // as used in MOCK_METHOD*() when possible.
+ *os << " Expected arg #" << N - 1 << ": ";
+ get<N - 1>(matchers).DescribeTo(os);
+ *os << "\n Actual: ";
+ // We remove the reference in type Value to prevent the
+ // universal printer from printing the address of value, which
+ // isn't interesting to the user most of the time. The
+ // matcher's ExplainMatchResultTo() method handles the case when
+ // the address is interesting.
+ internal::UniversalPrinter<GMOCK_REMOVE_REFERENCE(Value)>::
+ Print(value, os);
+ ExplainMatchResultAsNeededTo<Value>(matcher, value, os);
+ *os << "\n";
+ }
+ }
+};
+
+// The base case.
+template <>
+class TuplePrefix<0> {
+ public:
+ template <typename MatcherTuple, typename ValueTuple>
+ static bool Matches(const MatcherTuple& matcher_tuple,
+ const ValueTuple& value_tuple) {
+ return true;
+ }
+
+ template <typename MatcherTuple, typename ValueTuple>
+ static void DescribeMatchFailuresTo(const MatcherTuple& matchers,
+ const ValueTuple& values,
+ ::std::ostream* os) {}
+};
+
+// TupleMatches(matcher_tuple, value_tuple) returns true iff all
+// matchers in matcher_tuple match the corresponding fields in
+// value_tuple. It is a compiler error if matcher_tuple and
+// value_tuple have different number of fields or incompatible field
+// types.
+template <typename MatcherTuple, typename ValueTuple>
+bool TupleMatches(const MatcherTuple& matcher_tuple,
+ const ValueTuple& value_tuple) {
+ using ::std::tr1::tuple_size;
+ // Makes sure that matcher_tuple and value_tuple have the same
+ // number of fields.
+ GMOCK_COMPILE_ASSERT(tuple_size<MatcherTuple>::value ==
+ tuple_size<ValueTuple>::value,
+ matcher_and_value_have_different_numbers_of_fields);
+ return TuplePrefix<tuple_size<ValueTuple>::value>::
+ Matches(matcher_tuple, value_tuple);
+}
+
+// Describes failures in matching matchers against values. If there
+// is no failure, nothing will be streamed to os.
+template <typename MatcherTuple, typename ValueTuple>
+void DescribeMatchFailureTupleTo(const MatcherTuple& matchers,
+ const ValueTuple& values,
+ ::std::ostream* os) {
+ using ::std::tr1::tuple_size;
+ TuplePrefix<tuple_size<MatcherTuple>::value>::DescribeMatchFailuresTo(
+ matchers, values, os);
+}
+
+// The MatcherCastImpl class template is a helper for implementing
+// MatcherCast(). We need this helper in order to partially
+// specialize the implementation of MatcherCast() (C++ allows
+// class/struct templates to be partially specialized, but not
+// function templates.).
+
+// This general version is used when MatcherCast()'s argument is a
+// polymorphic matcher (i.e. something that can be converted to a
+// Matcher but is not one yet; for example, Eq(value)).
+template <typename T, typename M>
+class MatcherCastImpl {
+ public:
+ static Matcher<T> Cast(M polymorphic_matcher) {
+ return Matcher<T>(polymorphic_matcher);
+ }
+};
+
+// This more specialized version is used when MatcherCast()'s argument
+// is already a Matcher. This only compiles when type T can be
+// statically converted to type U.
+template <typename T, typename U>
+class MatcherCastImpl<T, Matcher<U> > {
+ public:
+ static Matcher<T> Cast(const Matcher<U>& source_matcher) {
+ return Matcher<T>(new Impl(source_matcher));
+ }
+ private:
+ class Impl : public MatcherInterface<T> {
+ public:
+ explicit Impl(const Matcher<U>& source_matcher)
+ : source_matcher_(source_matcher) {}
+
+ // We delegate the matching logic to the source matcher.
+ virtual bool Matches(T x) const {
+ return source_matcher_.Matches(static_cast<U>(x));
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ source_matcher_.DescribeTo(os);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ source_matcher_.DescribeNegationTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ source_matcher_.ExplainMatchResultTo(static_cast<U>(x), os);
+ }
+ private:
+ const Matcher<U> source_matcher_;
+ };
+};
+
+// This even more specialized version is used for efficiently casting
+// a matcher to its own type.
+template <typename T>
+class MatcherCastImpl<T, Matcher<T> > {
+ public:
+ static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
+};
+
+// Implements A<T>().
+template <typename T>
+class AnyMatcherImpl : public MatcherInterface<T> {
+ public:
+ virtual bool Matches(T x) const { return true; }
+ virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; }
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ // This is mostly for completeness' safe, as it's not very useful
+ // to write Not(A<bool>()). However we cannot completely rule out
+ // such a possibility, and it doesn't hurt to be prepared.
+ *os << "never matches";
+ }
+};
+
+// Implements _, a matcher that matches any value of any
+// type. This is a polymorphic matcher, so we need a template type
+// conversion operator to make it appearing as a Matcher<T> for any
+// type T.
+class AnythingMatcher {
+ public:
+ template <typename T>
+ operator Matcher<T>() const { return A<T>(); }
+};
+
+// Implements a matcher that compares a given value with a
+// pre-supplied value using one of the ==, <=, <, etc, operators. The
+// two values being compared don't have to have the same type.
+//
+// The matcher defined here is polymorphic (for example, Eq(5) can be
+// used to match an int, a short, a double, etc). Therefore we use
+// a template type conversion operator in the implementation.
+//
+// We define this as a macro in order to eliminate duplicated source
+// code.
+//
+// The following template definition assumes that the Rhs parameter is
+// a "bare" type (i.e. neither 'const T' nor 'T&').
+#define GMOCK_IMPLEMENT_COMPARISON_MATCHER(name, op, relation) \
+ template <typename Rhs> class name##Matcher { \
+ public: \
+ explicit name##Matcher(const Rhs& rhs) : rhs_(rhs) {} \
+ template <typename Lhs> \
+ operator Matcher<Lhs>() const { \
+ return MakeMatcher(new Impl<Lhs>(rhs_)); \
+ } \
+ private: \
+ template <typename Lhs> \
+ class Impl : public MatcherInterface<Lhs> { \
+ public: \
+ explicit Impl(const Rhs& rhs) : rhs_(rhs) {} \
+ virtual bool Matches(Lhs lhs) const { return lhs op rhs_; } \
+ virtual void DescribeTo(::std::ostream* os) const { \
+ *os << "is " relation " "; \
+ UniversalPrinter<Rhs>::Print(rhs_, os); \
+ } \
+ virtual void DescribeNegationTo(::std::ostream* os) const { \
+ *os << "is not " relation " "; \
+ UniversalPrinter<Rhs>::Print(rhs_, os); \
+ } \
+ private: \
+ Rhs rhs_; \
+ }; \
+ Rhs rhs_; \
+ }
+
+// Implements Eq(v), Ge(v), Gt(v), Le(v), Lt(v), and Ne(v)
+// respectively.
+GMOCK_IMPLEMENT_COMPARISON_MATCHER(Eq, ==, "equal to");
+GMOCK_IMPLEMENT_COMPARISON_MATCHER(Ge, >=, "greater than or equal to");
+GMOCK_IMPLEMENT_COMPARISON_MATCHER(Gt, >, "greater than");
+GMOCK_IMPLEMENT_COMPARISON_MATCHER(Le, <=, "less than or equal to");
+GMOCK_IMPLEMENT_COMPARISON_MATCHER(Lt, <, "less than");
+GMOCK_IMPLEMENT_COMPARISON_MATCHER(Ne, !=, "not equal to");
+
+#undef GMOCK_IMPLEMENT_COMPARISON_MATCHER
+
+// Implements the polymorphic NotNull() matcher, which matches any
+// pointer that is not NULL.
+class NotNullMatcher {
+ public:
+ template <typename T>
+ bool Matches(T* p) const { return p != NULL; }
+
+ void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; }
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "is NULL";
+ }
+};
+
+// Ref(variable) matches any argument that is a reference to
+// 'variable'. This matcher is polymorphic as it can match any
+// super type of the type of 'variable'.
+//
+// The RefMatcher template class implements Ref(variable). It can
+// only be instantiated with a reference type. This prevents a user
+// from mistakenly using Ref(x) to match a non-reference function
+// argument. For example, the following will righteously cause a
+// compiler error:
+//
+// int n;
+// Matcher<int> m1 = Ref(n); // This won't compile.
+// Matcher<int&> m2 = Ref(n); // This will compile.
+template <typename T>
+class RefMatcher;
+
+template <typename T>
+class RefMatcher<T&> {
+ // Google Mock is a generic framework and thus needs to support
+ // mocking any function types, including those that take non-const
+ // reference arguments. Therefore the template parameter T (and
+ // Super below) can be instantiated to either a const type or a
+ // non-const type.
+ public:
+ // RefMatcher() takes a T& instead of const T&, as we want the
+ // compiler to catch using Ref(const_value) as a matcher for a
+ // non-const reference.
+ explicit RefMatcher(T& x) : object_(x) {} // NOLINT
+
+ template <typename Super>
+ operator Matcher<Super&>() const {
+ // By passing object_ (type T&) to Impl(), which expects a Super&,
+ // we make sure that Super is a super type of T. In particular,
+ // this catches using Ref(const_value) as a matcher for a
+ // non-const reference, as you cannot implicitly convert a const
+ // reference to a non-const reference.
+ return MakeMatcher(new Impl<Super>(object_));
+ }
+ private:
+ template <typename Super>
+ class Impl : public MatcherInterface<Super&> {
+ public:
+ explicit Impl(Super& x) : object_(x) {} // NOLINT
+
+ // Matches() takes a Super& (as opposed to const Super&) in
+ // order to match the interface MatcherInterface<Super&>.
+ virtual bool Matches(Super& x) const { return &x == &object_; } // NOLINT
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "references the variable ";
+ UniversalPrinter<Super&>::Print(object_, os);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "does not reference the variable ";
+ UniversalPrinter<Super&>::Print(object_, os);
+ }
+
+ virtual void ExplainMatchResultTo(Super& x, // NOLINT
+ ::std::ostream* os) const {
+ *os << "is located @" << static_cast<const void*>(&x);
+ }
+ private:
+ const Super& object_;
+ };
+
+ T& object_;
+};
+
+// Polymorphic helper functions for narrow and wide string matchers.
+inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {
+ return String::CaseInsensitiveCStringEquals(lhs, rhs);
+}
+
+inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,
+ const wchar_t* rhs) {
+ return String::CaseInsensitiveWideCStringEquals(lhs, rhs);
+}
+
+// String comparison for narrow or wide strings that can have embedded NUL
+// characters.
+template <typename StringType>
+bool CaseInsensitiveStringEquals(const StringType& s1,
+ const StringType& s2) {
+ // Are the heads equal?
+ if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) {
+ return false;
+ }
+
+ // Skip the equal heads.
+ const typename StringType::value_type nul = 0;
+ const size_t i1 = s1.find(nul), i2 = s2.find(nul);
+
+ // Are we at the end of either s1 or s2?
+ if (i1 == StringType::npos || i2 == StringType::npos) {
+ return i1 == i2;
+ }
+
+ // Are the tails equal?
+ return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));
+}
+
+// String matchers.
+
+// Implements equality-based string matchers like StrEq, StrCaseNe, and etc.
+template <typename StringType>
+class StrEqualityMatcher {
+ public:
+ typedef typename StringType::const_pointer ConstCharPointer;
+
+ StrEqualityMatcher(const StringType& str, bool expect_eq,
+ bool case_sensitive)
+ : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
+
+ // When expect_eq_ is true, returns true iff s is equal to string_;
+ // otherwise returns true iff s is not equal to string_.
+ bool Matches(ConstCharPointer s) const {
+ if (s == NULL) {
+ return !expect_eq_;
+ }
+ return Matches(StringType(s));
+ }
+
+ bool Matches(const StringType& s) const {
+ const bool eq = case_sensitive_ ? s == string_ :
+ CaseInsensitiveStringEquals(s, string_);
+ return expect_eq_ == eq;
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ DescribeToHelper(expect_eq_, os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ DescribeToHelper(!expect_eq_, os);
+ }
+ private:
+ void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {
+ *os << "is ";
+ if (!expect_eq) {
+ *os << "not ";
+ }
+ *os << "equal to ";
+ if (!case_sensitive_) {
+ *os << "(ignoring case) ";
+ }
+ UniversalPrinter<StringType>::Print(string_, os);
+ }
+
+ const StringType string_;
+ const bool expect_eq_;
+ const bool case_sensitive_;
+};
+
+// Implements the polymorphic HasSubstr(substring) matcher, which
+// can be used as a Matcher<T> as long as T can be converted to a
+// string.
+template <typename StringType>
+class HasSubstrMatcher {
+ public:
+ typedef typename StringType::const_pointer ConstCharPointer;
+
+ explicit HasSubstrMatcher(const StringType& substring)
+ : substring_(substring) {}
+
+ // These overloaded methods allow HasSubstr(substring) to be used as a
+ // Matcher<T> as long as T can be converted to string. Returns true
+ // iff s contains substring_ as a substring.
+ bool Matches(ConstCharPointer s) const {
+ return s != NULL && Matches(StringType(s));
+ }
+
+ bool Matches(const StringType& s) const {
+ return s.find(substring_) != StringType::npos;
+ }
+
+ // Describes what this matcher matches.
+ void DescribeTo(::std::ostream* os) const {
+ *os << "has substring ";
+ UniversalPrinter<StringType>::Print(substring_, os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "has no substring ";
+ UniversalPrinter<StringType>::Print(substring_, os);
+ }
+ private:
+ const StringType substring_;
+};
+
+// Implements the polymorphic StartsWith(substring) matcher, which
+// can be used as a Matcher<T> as long as T can be converted to a
+// string.
+template <typename StringType>
+class StartsWithMatcher {
+ public:
+ typedef typename StringType::const_pointer ConstCharPointer;
+
+ explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
+ }
+
+ // These overloaded methods allow StartsWith(prefix) to be used as a
+ // Matcher<T> as long as T can be converted to string. Returns true
+ // iff s starts with prefix_.
+ bool Matches(ConstCharPointer s) const {
+ return s != NULL && Matches(StringType(s));
+ }
+
+ bool Matches(const StringType& s) const {
+ return s.length() >= prefix_.length() &&
+ s.substr(0, prefix_.length()) == prefix_;
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << "starts with ";
+ UniversalPrinter<StringType>::Print(prefix_, os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't start with ";
+ UniversalPrinter<StringType>::Print(prefix_, os);
+ }
+ private:
+ const StringType prefix_;
+};
+
+// Implements the polymorphic EndsWith(substring) matcher, which
+// can be used as a Matcher<T> as long as T can be converted to a
+// string.
+template <typename StringType>
+class EndsWithMatcher {
+ public:
+ typedef typename StringType::const_pointer ConstCharPointer;
+
+ explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
+
+ // These overloaded methods allow EndsWith(suffix) to be used as a
+ // Matcher<T> as long as T can be converted to string. Returns true
+ // iff s ends with suffix_.
+ bool Matches(ConstCharPointer s) const {
+ return s != NULL && Matches(StringType(s));
+ }
+
+ bool Matches(const StringType& s) const {
+ return s.length() >= suffix_.length() &&
+ s.substr(s.length() - suffix_.length()) == suffix_;
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << "ends with ";
+ UniversalPrinter<StringType>::Print(suffix_, os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't end with ";
+ UniversalPrinter<StringType>::Print(suffix_, os);
+ }
+ private:
+ const StringType suffix_;
+};
+
+#if GMOCK_HAS_REGEX
+
+// Implements polymorphic matchers MatchesRegex(regex) and
+// ContainsRegex(regex), which can be used as a Matcher<T> as long as
+// T can be converted to a string.
+class MatchesRegexMatcher {
+ public:
+ MatchesRegexMatcher(const RE* regex, bool full_match)
+ : regex_(regex), full_match_(full_match) {}
+
+ // These overloaded methods allow MatchesRegex(regex) to be used as
+ // a Matcher<T> as long as T can be converted to string. Returns
+ // true iff s matches regular expression regex. When full_match_ is
+ // true, a full match is done; otherwise a partial match is done.
+ bool Matches(const char* s) const {
+ return s != NULL && Matches(internal::string(s));
+ }
+
+ bool Matches(const internal::string& s) const {
+ return full_match_ ? RE::FullMatch(s, *regex_) :
+ RE::PartialMatch(s, *regex_);
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << (full_match_ ? "matches" : "contains")
+ << " regular expression ";
+ UniversalPrinter<internal::string>::Print(regex_->pattern(), os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't " << (full_match_ ? "match" : "contain")
+ << " regular expression ";
+ UniversalPrinter<internal::string>::Print(regex_->pattern(), os);
+ }
+ private:
+ const internal::linked_ptr<const RE> regex_;
+ const bool full_match_;
+};
+
+#endif // GMOCK_HAS_REGEX
+
+// Implements a matcher that compares the two fields of a 2-tuple
+// using one of the ==, <=, <, etc, operators. The two fields being
+// compared don't have to have the same type.
+//
+// The matcher defined here is polymorphic (for example, Eq() can be
+// used to match a tuple<int, short>, a tuple<const long&, double>,
+// etc). Therefore we use a template type conversion operator in the
+// implementation.
+//
+// We define this as a macro in order to eliminate duplicated source
+// code.
+#define GMOCK_IMPLEMENT_COMPARISON2_MATCHER(name, op, relation) \
+ class name##2Matcher { \
+ public: \
+ template <typename T1, typename T2> \
+ operator Matcher<const ::std::tr1::tuple<T1, T2>&>() const { \
+ return MakeMatcher(new Impl<T1, T2>); \
+ } \
+ private: \
+ template <typename T1, typename T2> \
+ class Impl : public MatcherInterface<const ::std::tr1::tuple<T1, T2>&> { \
+ public: \
+ virtual bool Matches(const ::std::tr1::tuple<T1, T2>& args) const { \
+ 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"; \
+ } \
+ virtual void DescribeNegationTo(::std::ostream* os) const { \
+ *os << "argument #0 is not " relation " argument #1"; \
+ } \
+ }; \
+ }
+
+// 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");
+
+#undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER
+
+// Implements the Not(m) matcher, which matches a value that doesn't
+// match matcher m.
+template <typename InnerMatcher>
+class NotMatcher {
+ public:
+ explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
+
+ // This template type conversion operator allows Not(m) to be used
+ // to match any type m can match.
+ template <typename T>
+ operator Matcher<T>() const {
+ return Matcher<T>(new Impl<T>(matcher_));
+ }
+ private:
+ // Implements the Not(...) matcher for a particular argument type T.
+ template <typename T>
+ class Impl : public MatcherInterface<T> {
+ public:
+ explicit Impl(const Matcher<T>& matcher) : matcher_(matcher) {}
+
+ virtual bool Matches(T x) const {
+ return !matcher_.Matches(x);
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ matcher_.DescribeNegationTo(os);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ matcher_.DescribeTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ matcher_.ExplainMatchResultTo(x, os);
+ }
+ private:
+ const Matcher<T> matcher_;
+ };
+
+ InnerMatcher matcher_;
+};
+
+// Used for implementing the AllOf(m_1, ..., m_n) matcher, which
+// matches a value that matches all of the matchers m_1, ..., and m_n.
+template <typename Matcher1, typename Matcher2>
+class BothOfMatcher {
+ public:
+ BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
+ : matcher1_(matcher1), matcher2_(matcher2) {}
+
+ // This template type conversion operator allows a
+ // BothOfMatcher<Matcher1, Matcher2> object to match any type that
+ // both Matcher1 and Matcher2 can match.
+ template <typename T>
+ operator Matcher<T>() const {
+ return Matcher<T>(new Impl<T>(matcher1_, matcher2_));
+ }
+ private:
+ // Implements the AllOf(m1, m2) matcher for a particular argument
+ // type T.
+ template <typename T>
+ class Impl : public MatcherInterface<T> {
+ public:
+ Impl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
+ : matcher1_(matcher1), matcher2_(matcher2) {}
+
+ virtual bool Matches(T x) const {
+ return matcher1_.Matches(x) && matcher2_.Matches(x);
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "(";
+ matcher1_.DescribeTo(os);
+ *os << ") and (";
+ matcher2_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "not ";
+ DescribeTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ if (Matches(x)) {
+ // When both matcher1_ and matcher2_ match x, we need to
+ // explain why *both* of them match.
+ ::std::stringstream ss1;
+ matcher1_.ExplainMatchResultTo(x, &ss1);
+ const internal::string s1 = ss1.str();
+
+ ::std::stringstream ss2;
+ matcher2_.ExplainMatchResultTo(x, &ss2);
+ const internal::string s2 = ss2.str();
+
+ if (s1 == "") {
+ *os << s2;
+ } else {
+ *os << s1;
+ if (s2 != "") {
+ *os << "; " << s2;
+ }
+ }
+ } else {
+ // Otherwise we only need to explain why *one* of them fails
+ // to match.
+ if (!matcher1_.Matches(x)) {
+ matcher1_.ExplainMatchResultTo(x, os);
+ } else {
+ matcher2_.ExplainMatchResultTo(x, os);
+ }
+ }
+ }
+ private:
+ const Matcher<T> matcher1_;
+ const Matcher<T> matcher2_;
+ };
+
+ Matcher1 matcher1_;
+ Matcher2 matcher2_;
+};
+
+// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which
+// matches a value that matches at least one of the matchers m_1, ...,
+// and m_n.
+template <typename Matcher1, typename Matcher2>
+class EitherOfMatcher {
+ public:
+ EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
+ : matcher1_(matcher1), matcher2_(matcher2) {}
+
+ // This template type conversion operator allows a
+ // EitherOfMatcher<Matcher1, Matcher2> object to match any type that
+ // both Matcher1 and Matcher2 can match.
+ template <typename T>
+ operator Matcher<T>() const {
+ return Matcher<T>(new Impl<T>(matcher1_, matcher2_));
+ }
+ private:
+ // Implements the AnyOf(m1, m2) matcher for a particular argument
+ // type T.
+ template <typename T>
+ class Impl : public MatcherInterface<T> {
+ public:
+ Impl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
+ : matcher1_(matcher1), matcher2_(matcher2) {}
+
+ virtual bool Matches(T x) const {
+ return matcher1_.Matches(x) || matcher2_.Matches(x);
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "(";
+ matcher1_.DescribeTo(os);
+ *os << ") or (";
+ matcher2_.DescribeTo(os);
+ *os << ")";
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "not ";
+ DescribeTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const {
+ if (Matches(x)) {
+ // If either matcher1_ or matcher2_ matches x, we just need
+ // to explain why *one* of them matches.
+ if (matcher1_.Matches(x)) {
+ matcher1_.ExplainMatchResultTo(x, os);
+ } else {
+ matcher2_.ExplainMatchResultTo(x, os);
+ }
+ } else {
+ // Otherwise we need to explain why *neither* matches.
+ ::std::stringstream ss1;
+ matcher1_.ExplainMatchResultTo(x, &ss1);
+ const internal::string s1 = ss1.str();
+
+ ::std::stringstream ss2;
+ matcher2_.ExplainMatchResultTo(x, &ss2);
+ const internal::string s2 = ss2.str();
+
+ if (s1 == "") {
+ *os << s2;
+ } else {
+ *os << s1;
+ if (s2 != "") {
+ *os << "; " << s2;
+ }
+ }
+ }
+ }
+ private:
+ const Matcher<T> matcher1_;
+ const Matcher<T> matcher2_;
+ };
+
+ Matcher1 matcher1_;
+ Matcher2 matcher2_;
+};
+
+// Used for implementing Truly(pred), which turns a predicate into a
+// matcher.
+template <typename Predicate>
+class TrulyMatcher {
+ public:
+ explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}
+
+ // This method template allows Truly(pred) to be used as a matcher
+ // for type T where T is the argument type of predicate 'pred'. The
+ // argument is passed by reference as the predicate may be
+ // interested in the address of the argument.
+ template <typename T>
+ bool Matches(T& x) const {
+#ifdef GTEST_OS_WINDOWS
+ // MSVC warns about converting a value into bool (warning 4800).
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4800) // Temporarily disables warning 4800.
+#endif // GTEST_OS_WINDOWS
+ return predicate_(x);
+#ifdef GTEST_OS_WINDOWS
+#pragma warning(pop) // Restores the warning state.
+#endif // GTEST_OS_WINDOWS
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << "satisfies the given predicate";
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't satisfy the given predicate";
+ }
+ private:
+ Predicate predicate_;
+};
+
+// Used for implementing Matches(matcher), which turns a matcher into
+// a predicate.
+template <typename M>
+class MatcherAsPredicate {
+ public:
+ explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}
+
+ // This template operator() allows Matches(m) to be used as a
+ // predicate on type T where m is a matcher on type T.
+ //
+ // The argument x is passed by reference instead of by value, as
+ // some matcher may be interested in its address (e.g. as in
+ // Matches(Ref(n))(x)).
+ template <typename T>
+ bool operator()(const T& x) const {
+ // We let matcher_ commit to a particular type here instead of
+ // when the MatcherAsPredicate object was constructed. This
+ // allows us to write Matches(m) where m is a polymorphic matcher
+ // (e.g. Eq(5)).
+ //
+ // If we write Matcher<T>(matcher_).Matches(x) here, it won't
+ // compile when matcher_ has type Matcher<const T&>; if we write
+ // Matcher<const T&>(matcher_).Matches(x) here, it won't compile
+ // when matcher_ has type Matcher<T>; if we just write
+ // matcher_.Matches(x), it won't compile when matcher_ is
+ // polymorphic, e.g. Eq(5).
+ //
+ // MatcherCast<const T&>() is necessary for making the code work
+ // in all of the above situations.
+ return MatcherCast<const T&>(matcher_).Matches(x);
+ }
+ private:
+ M matcher_;
+};
+
+// For implementing ASSERT_THAT() and EXPECT_THAT(). The template
+// argument M must be a type that can be converted to a matcher.
+template <typename M>
+class PredicateFormatterFromMatcher {
+ public:
+ explicit PredicateFormatterFromMatcher(const M& m) : matcher_(m) {}
+
+ // This template () operator allows a PredicateFormatterFromMatcher
+ // object to act as a predicate-formatter suitable for using with
+ // Google Test's EXPECT_PRED_FORMAT1() macro.
+ template <typename T>
+ AssertionResult operator()(const char* value_text, const T& x) const {
+ // We convert matcher_ to a Matcher<const T&> *now* instead of
+ // when the PredicateFormatterFromMatcher object was constructed,
+ // as matcher_ may be polymorphic (e.g. NotNull()) and we won't
+ // know which type to instantiate it to until we actually see the
+ // type of x here.
+ //
+ // We write MatcherCast<const T&>(matcher_) instead of
+ // Matcher<const T&>(matcher_), as the latter won't compile when
+ // matcher_ has type Matcher<T> (e.g. An<int>()).
+ const Matcher<const T&> matcher = MatcherCast<const T&>(matcher_);
+ if (matcher.Matches(x)) {
+ return AssertionSuccess();
+ } else {
+ ::std::stringstream ss;
+ ss << "Value of: " << value_text << "\n"
+ << "Expected: ";
+ matcher.DescribeTo(&ss);
+ ss << "\n Actual: ";
+ UniversalPrinter<T>::Print(x, &ss);
+ ExplainMatchResultAsNeededTo<const T&>(matcher, x, &ss);
+ return AssertionFailure(Message() << ss.str());
+ }
+ }
+ private:
+ const M matcher_;
+};
+
+// A helper function for converting a matcher to a predicate-formatter
+// without the user needing to explicitly write the type. This is
+// used for implementing ASSERT_THAT() and EXPECT_THAT().
+template <typename M>
+inline PredicateFormatterFromMatcher<M>
+MakePredicateFormatterFromMatcher(const M& matcher) {
+ return PredicateFormatterFromMatcher<M>(matcher);
+}
+
+// Implements the polymorphic floating point equality matcher, which
+// matches two float values using ULP-based approximation. The
+// template is meant to be instantiated with FloatType being either
+// float or double.
+template <typename FloatType>
+class FloatingEqMatcher {
+ public:
+ // Constructor for FloatingEqMatcher.
+ // The matcher's input will be compared with rhs. The matcher treats two
+ // NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards,
+ // equality comparisons between NANs will always return false.
+ FloatingEqMatcher(FloatType rhs, bool nan_eq_nan) :
+ rhs_(rhs), nan_eq_nan_(nan_eq_nan) {}
+
+ // Implements floating point equality matcher as a Matcher<T>.
+ template <typename T>
+ class Impl : public MatcherInterface<T> {
+ public:
+ Impl(FloatType rhs, bool nan_eq_nan) :
+ rhs_(rhs), nan_eq_nan_(nan_eq_nan) {}
+
+ virtual bool Matches(T value) const {
+ const FloatingPoint<FloatType> lhs(value), rhs(rhs_);
+
+ // Compares NaNs first, if nan_eq_nan_ is true.
+ if (nan_eq_nan_ && lhs.is_nan()) {
+ return rhs.is_nan();
+ }
+
+ return lhs.AlmostEquals(rhs);
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ // os->precision() returns the previously set precision, which we
+ // store to restore the ostream to its original configuration
+ // after outputting.
+ const ::std::streamsize old_precision = os->precision(
+ ::std::numeric_limits<FloatType>::digits10 + 2);
+ if (FloatingPoint<FloatType>(rhs_).is_nan()) {
+ if (nan_eq_nan_) {
+ *os << "is NaN";
+ } else {
+ *os << "never matches";
+ }
+ } else {
+ *os << "is approximately " << rhs_;
+ }
+ os->precision(old_precision);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ // As before, get original precision.
+ const ::std::streamsize old_precision = os->precision(
+ ::std::numeric_limits<FloatType>::digits10 + 2);
+ if (FloatingPoint<FloatType>(rhs_).is_nan()) {
+ if (nan_eq_nan_) {
+ *os << "is not NaN";
+ } else {
+ *os << "is anything";
+ }
+ } else {
+ *os << "is not approximately " << rhs_;
+ }
+ // Restore original precision.
+ os->precision(old_precision);
+ }
+
+ private:
+ const FloatType rhs_;
+ const bool nan_eq_nan_;
+ };
+
+ // The following 3 type conversion operators allow FloatEq(rhs) and
+ // NanSensitiveFloatEq(rhs) to be used as a Matcher<float>, a
+ // Matcher<const float&>, or a Matcher<float&>, but nothing else.
+ // (While Google's C++ coding style doesn't allow arguments passed
+ // by non-const reference, we may see them in code not conforming to
+ // the style. Therefore Google Mock needs to support them.)
+ operator Matcher<FloatType>() const {
+ return MakeMatcher(new Impl<FloatType>(rhs_, nan_eq_nan_));
+ }
+
+ operator Matcher<const FloatType&>() const {
+ return MakeMatcher(new Impl<const FloatType&>(rhs_, nan_eq_nan_));
+ }
+
+ operator Matcher<FloatType&>() const {
+ return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_));
+ }
+ private:
+ const FloatType rhs_;
+ const bool nan_eq_nan_;
+};
+
+// Implements the Pointee(m) matcher for matching a pointer whose
+// pointee matches matcher m. The pointer can be either raw or smart.
+template <typename InnerMatcher>
+class PointeeMatcher {
+ public:
+ explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
+
+ // This type conversion operator template allows Pointee(m) to be
+ // used as a matcher for any pointer type whose pointee type is
+ // compatible with the inner matcher, where type Pointer can be
+ // either a raw pointer or a smart pointer.
+ //
+ // The reason we do this instead of relying on
+ // MakePolymorphicMatcher() is that the latter is not flexible
+ // enough for implementing the DescribeTo() method of Pointee().
+ template <typename Pointer>
+ operator Matcher<Pointer>() const {
+ return MakeMatcher(new Impl<Pointer>(matcher_));
+ }
+ private:
+ // The monomorphic implementation that works for a particular pointer type.
+ template <typename Pointer>
+ class Impl : public MatcherInterface<Pointer> {
+ public:
+ typedef typename PointeeOf<GMOCK_REMOVE_CONST( // NOLINT
+ GMOCK_REMOVE_REFERENCE(Pointer))>::type Pointee;
+
+ explicit Impl(const InnerMatcher& matcher)
+ : matcher_(MatcherCast<const Pointee&>(matcher)) {}
+
+ virtual bool Matches(Pointer p) const {
+ return GetRawPointer(p) != NULL && matcher_.Matches(*p);
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "points to a value that ";
+ matcher_.DescribeTo(os);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "does not point to a value that ";
+ matcher_.DescribeTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(Pointer pointer,
+ ::std::ostream* os) const {
+ if (GetRawPointer(pointer) == NULL)
+ return;
+
+ ::std::stringstream ss;
+ matcher_.ExplainMatchResultTo(*pointer, &ss);
+ const internal::string s = ss.str();
+ if (s != "") {
+ *os << "points to a value that " << s;
+ }
+ }
+ private:
+ const Matcher<const Pointee&> matcher_;
+ };
+
+ const InnerMatcher matcher_;
+};
+
+// Implements the Field() matcher for matching a field (i.e. member
+// variable) of an object.
+template <typename Class, typename FieldType>
+class FieldMatcher {
+ public:
+ FieldMatcher(FieldType Class::*field,
+ const Matcher<const FieldType&>& matcher)
+ : field_(field), matcher_(matcher) {}
+
+ // Returns true iff the inner matcher matches obj.field.
+ bool Matches(const Class& obj) const {
+ return matcher_.Matches(obj.*field_);
+ }
+
+ // Returns true iff the inner matcher matches obj->field.
+ bool Matches(const Class* p) const {
+ return (p != NULL) && matcher_.Matches(p->*field_);
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << "the given field ";
+ matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "the given field ";
+ matcher_.DescribeNegationTo(os);
+ }
+
+ void ExplainMatchResultTo(const Class& obj, ::std::ostream* os) const {
+ ::std::stringstream ss;
+ matcher_.ExplainMatchResultTo(obj.*field_, &ss);
+ const internal::string s = ss.str();
+ if (s != "") {
+ *os << "the given field " << s;
+ }
+ }
+
+ void ExplainMatchResultTo(const Class* p, ::std::ostream* os) const {
+ if (p != NULL) {
+ ExplainMatchResultTo(*p, os);
+ }
+ }
+ private:
+ const FieldType Class::*field_;
+ const Matcher<const FieldType&> matcher_;
+};
+
+// Explains the result of matching an object against a field matcher.
+template <typename Class, typename FieldType>
+void ExplainMatchResultTo(const FieldMatcher<Class, FieldType>& matcher,
+ const Class& obj, ::std::ostream* os) {
+ matcher.ExplainMatchResultTo(obj, os);
+}
+
+// Explains the result of matching a pointer against a field matcher.
+template <typename Class, typename FieldType>
+void ExplainMatchResultTo(const FieldMatcher<Class, FieldType>& matcher,
+ const Class* p, ::std::ostream* os) {
+ matcher.ExplainMatchResultTo(p, os);
+}
+
+// Implements the Property() matcher for matching a property
+// (i.e. return value of a getter method) of an object.
+template <typename Class, typename PropertyType>
+class PropertyMatcher {
+ public:
+ // The property may have a reference type, so 'const PropertyType&'
+ // may cause double references and fail to compile. That's why we
+ // need GMOCK_REFERENCE_TO_CONST, which works regardless of
+ // PropertyType being a reference or not.
+ typedef GMOCK_REFERENCE_TO_CONST(PropertyType) RefToConstProperty;
+
+ PropertyMatcher(PropertyType (Class::*property)() const,
+ const Matcher<RefToConstProperty>& matcher)
+ : property_(property), matcher_(matcher) {}
+
+ // Returns true iff obj.property() matches the inner matcher.
+ bool Matches(const Class& obj) const {
+ return matcher_.Matches((obj.*property_)());
+ }
+
+ // Returns true iff p->property() matches the inner matcher.
+ bool Matches(const Class* p) const {
+ return (p != NULL) && matcher_.Matches((p->*property_)());
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << "the given property ";
+ matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "the given property ";
+ matcher_.DescribeNegationTo(os);
+ }
+
+ void ExplainMatchResultTo(const Class& obj, ::std::ostream* os) const {
+ ::std::stringstream ss;
+ matcher_.ExplainMatchResultTo((obj.*property_)(), &ss);
+ const internal::string s = ss.str();
+ if (s != "") {
+ *os << "the given property " << s;
+ }
+ }
+
+ void ExplainMatchResultTo(const Class* p, ::std::ostream* os) const {
+ if (p != NULL) {
+ ExplainMatchResultTo(*p, os);
+ }
+ }
+ private:
+ PropertyType (Class::*property_)() const;
+ const Matcher<RefToConstProperty> matcher_;
+};
+
+// Explains the result of matching an object against a property matcher.
+template <typename Class, typename PropertyType>
+void ExplainMatchResultTo(const PropertyMatcher<Class, PropertyType>& matcher,
+ const Class& obj, ::std::ostream* os) {
+ matcher.ExplainMatchResultTo(obj, os);
+}
+
+// Explains the result of matching a pointer against a property matcher.
+template <typename Class, typename PropertyType>
+void ExplainMatchResultTo(const PropertyMatcher<Class, PropertyType>& matcher,
+ const Class* p, ::std::ostream* os) {
+ matcher.ExplainMatchResultTo(p, os);
+}
+
+// Type traits specifying various features of different functors for ResultOf.
+// The default template specifies features for functor objects.
+// Functor classes have to typedef argument_type and result_type
+// to be compatible with ResultOf.
+template <typename Functor>
+struct CallableTraits {
+ typedef typename Functor::result_type ResultType;
+ typedef Functor StorageType;
+
+ static void CheckIsValid(Functor functor) {}
+ template <typename T>
+ static ResultType Invoke(Functor f, T arg) { return f(arg); }
+};
+
+// Specialization for function pointers.
+template <typename ArgType, typename ResType>
+struct CallableTraits<ResType(*)(ArgType)> {
+ typedef ResType ResultType;
+ typedef ResType(*StorageType)(ArgType);
+
+ static void CheckIsValid(ResType(*f)(ArgType)) {
+ GMOCK_CHECK_(f != NULL)
+ << "NULL function pointer is passed into ResultOf().";
+ }
+ template <typename T>
+ static ResType Invoke(ResType(*f)(ArgType), T arg) {
+ return (*f)(arg);
+ }
+};
+
+// Implements the ResultOf() matcher for matching a return value of a
+// unary function of an object.
+template <typename Callable>
+class ResultOfMatcher {
+ public:
+ typedef typename CallableTraits<Callable>::ResultType ResultType;
+
+ ResultOfMatcher(Callable callable, const Matcher<ResultType>& matcher)
+ : callable_(callable), matcher_(matcher) {
+ CallableTraits<Callable>::CheckIsValid(callable_);
+ }
+
+ template <typename T>
+ operator Matcher<T>() const {
+ return Matcher<T>(new Impl<T>(callable_, matcher_));
+ }
+
+ private:
+ typedef typename CallableTraits<Callable>::StorageType CallableStorageType;
+
+ template <typename T>
+ class Impl : public MatcherInterface<T> {
+ public:
+ Impl(CallableStorageType callable, const Matcher<ResultType>& matcher)
+ : callable_(callable), matcher_(matcher) {}
+ // Returns true iff callable_(obj) matches the inner matcher.
+ // The calling syntax is different for different types of callables
+ // so we abstract it in CallableTraits<Callable>::Invoke().
+ virtual bool Matches(T obj) const {
+ return matcher_.Matches(
+ CallableTraits<Callable>::template Invoke<T>(callable_, obj));
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "result of the given callable ";
+ matcher_.DescribeTo(os);
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "result of the given callable ";
+ matcher_.DescribeNegationTo(os);
+ }
+
+ virtual void ExplainMatchResultTo(T obj, ::std::ostream* os) const {
+ ::std::stringstream ss;
+ matcher_.ExplainMatchResultTo(
+ CallableTraits<Callable>::template Invoke<T>(callable_, obj),
+ &ss);
+ const internal::string s = ss.str();
+ if (s != "")
+ *os << "result of the given callable " << s;
+ }
+ private:
+ // Functors often define operator() as non-const method even though
+ // they are actualy stateless. But we need to use them even when
+ // 'this' is a const pointer. It's the user's responsibility not to
+ // use stateful callables with ResultOf(), which does't guarantee
+ // how many times the callable will be invoked.
+ mutable CallableStorageType callable_;
+ const Matcher<ResultType> matcher_;
+ }; // class Impl
+
+ const CallableStorageType callable_;
+ const Matcher<ResultType> matcher_;
+};
+
+// Explains the result of matching a value against a functor matcher.
+template <typename T, typename Callable>
+void ExplainMatchResultTo(const ResultOfMatcher<Callable>& matcher,
+ T obj, ::std::ostream* os) {
+ matcher.ExplainMatchResultTo(obj, os);
+}
+
+} // namespace internal
+
+// Implements MatcherCast().
+template <typename T, typename M>
+inline Matcher<T> MatcherCast(M matcher) {
+ return internal::MatcherCastImpl<T, M>::Cast(matcher);
+}
+
+// _ is a matcher that matches anything of any type.
+//
+// This definition is fine as:
+//
+// 1. The C++ standard permits using the name _ in a namespace that
+// is not the global namespace or ::std.
+// 2. The AnythingMatcher class has no data member or constructor,
+// so it's OK to create global variables of this type.
+// 3. c-style has approved of using _ in this case.
+const internal::AnythingMatcher _ = {};
+// Creates a matcher that matches any value of the given type T.
+template <typename T>
+inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); }
+
+// Creates a matcher that matches any value of the given type T.
+template <typename T>
+inline Matcher<T> An() { return A<T>(); }
+
+// Creates a polymorphic matcher that matches anything equal to x.
+// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
+// wouldn't compile.
+template <typename T>
+inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
+
+// Constructs a Matcher<T> from a 'value' of type T. The constructed
+// matcher matches any value that's equal to 'value'.
+template <typename T>
+Matcher<T>::Matcher(T value) { *this = Eq(value); }
+
+// Creates a monomorphic matcher that matches anything with type Lhs
+// and equal to rhs. A user may need to use this instead of Eq(...)
+// in order to resolve an overloading ambiguity.
+//
+// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
+// or Matcher<T>(x), but more readable than the latter.
+//
+// We could define similar monomorphic matchers for other comparison
+// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
+// it yet as those are used much less than Eq() in practice. A user
+// can always write Matcher<T>(Lt(5)) to be explicit about the type,
+// for example.
+template <typename Lhs, typename Rhs>
+inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
+
+// Creates a polymorphic matcher that matches anything >= x.
+template <typename Rhs>
+inline internal::GeMatcher<Rhs> Ge(Rhs x) {
+ return internal::GeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything > x.
+template <typename Rhs>
+inline internal::GtMatcher<Rhs> Gt(Rhs x) {
+ return internal::GtMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything <= x.
+template <typename Rhs>
+inline internal::LeMatcher<Rhs> Le(Rhs x) {
+ return internal::LeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything < x.
+template <typename Rhs>
+inline internal::LtMatcher<Rhs> Lt(Rhs x) {
+ return internal::LtMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything != x.
+template <typename Rhs>
+inline internal::NeMatcher<Rhs> Ne(Rhs x) {
+ return internal::NeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches any non-NULL pointer.
+// This is convenient as Not(NULL) doesn't compile (the compiler
+// thinks that that expression is comparing a pointer with an integer).
+inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() {
+ return MakePolymorphicMatcher(internal::NotNullMatcher());
+}
+
+// Creates a polymorphic matcher that matches any argument that
+// references variable x.
+template <typename T>
+inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT
+ return internal::RefMatcher<T&>(x);
+}
+
+// Creates a matcher that matches any double argument approximately
+// equal to rhs, where two NANs are considered unequal.
+inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
+ return internal::FloatingEqMatcher<double>(rhs, false);
+}
+
+// Creates a matcher that matches any double argument approximately
+// equal to rhs, including NaN values when rhs is NaN.
+inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {
+ return internal::FloatingEqMatcher<double>(rhs, true);
+}
+
+// Creates a matcher that matches any float argument approximately
+// equal to rhs, where two NANs are considered unequal.
+inline internal::FloatingEqMatcher<float> FloatEq(float rhs) {
+ return internal::FloatingEqMatcher<float>(rhs, false);
+}
+
+// Creates a matcher that matches any double argument approximately
+// equal to rhs, including NaN values when rhs is NaN.
+inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) {
+ return internal::FloatingEqMatcher<float>(rhs, true);
+}
+
+// Creates a matcher that matches a pointer (raw or smart) that points
+// to a value that matches inner_matcher.
+template <typename InnerMatcher>
+inline internal::PointeeMatcher<InnerMatcher> Pointee(
+ const InnerMatcher& inner_matcher) {
+ return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
+}
+
+// Creates a matcher that matches an object whose given field matches
+// 'matcher'. For example,
+// Field(&Foo::number, Ge(5))
+// matches a Foo object x iff x.number >= 5.
+template <typename Class, typename FieldType, typename FieldMatcher>
+inline PolymorphicMatcher<
+ internal::FieldMatcher<Class, FieldType> > Field(
+ FieldType Class::*field, const FieldMatcher& matcher) {
+ return MakePolymorphicMatcher(
+ internal::FieldMatcher<Class, FieldType>(
+ field, MatcherCast<const FieldType&>(matcher)));
+ // The call to MatcherCast() is required for supporting inner
+ // matchers of compatible types. For example, it allows
+ // Field(&Foo::bar, m)
+ // to compile where bar is an int32 and m is a matcher for int64.
+}
+
+// Creates a matcher that matches an object whose given property
+// matches 'matcher'. For example,
+// Property(&Foo::str, StartsWith("hi"))
+// matches a Foo object x iff x.str() starts with "hi".
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<
+ internal::PropertyMatcher<Class, PropertyType> > Property(
+ PropertyType (Class::*property)() const, const PropertyMatcher& matcher) {
+ return MakePolymorphicMatcher(
+ internal::PropertyMatcher<Class, PropertyType>(
+ property,
+ MatcherCast<GMOCK_REFERENCE_TO_CONST(PropertyType)>(matcher)));
+ // The call to MatcherCast() is required for supporting inner
+ // matchers of compatible types. For example, it allows
+ // Property(&Foo::bar, m)
+ // to compile where bar() returns an int32 and m is a matcher for int64.
+}
+
+// Creates a matcher that matches an object iff the result of applying
+// a callable to x matches 'matcher'.
+// For example,
+// ResultOf(f, StartsWith("hi"))
+// matches a Foo object x iff f(x) starts with "hi".
+// callable parameter can be a function, function pointer, or a functor.
+// Callable has to satisfy the following conditions:
+// * It is required to keep no state affecting the results of
+// the calls on it and make no assumptions about how many calls
+// will be made. Any state it keeps must be protected from the
+// concurrent access.
+// * If it is a function object, it has to define type result_type.
+// We recommend deriving your functor classes from std::unary_function.
+template <typename Callable, typename ResultOfMatcher>
+internal::ResultOfMatcher<Callable> ResultOf(
+ Callable callable, const ResultOfMatcher& matcher) {
+ return internal::ResultOfMatcher<Callable>(
+ callable,
+ MatcherCast<typename internal::CallableTraits<Callable>::ResultType>(
+ matcher));
+ // The call to MatcherCast() is required for supporting inner
+ // matchers of compatible types. For example, it allows
+ // ResultOf(Function, m)
+ // to compile where Function() returns an int32 and m is a matcher for int64.
+}
+
+// String matchers.
+
+// Matches a string equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
+ StrEq(const internal::string& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
+ str, true, true));
+}
+
+// Matches a string not equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
+ StrNe(const internal::string& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
+ str, false, true));
+}
+
+// Matches a string equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
+ StrCaseEq(const internal::string& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
+ str, true, false));
+}
+
+// Matches a string not equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
+ StrCaseNe(const internal::string& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
+ str, false, false));
+}
+
+// Creates a matcher that matches any string, std::string, or C string
+// that contains the given substring.
+inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::string> >
+ HasSubstr(const internal::string& substring) {
+ return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::string>(
+ substring));
+}
+
+// Matches a string that starts with 'prefix' (case-sensitive).
+inline PolymorphicMatcher<internal::StartsWithMatcher<internal::string> >
+ StartsWith(const internal::string& prefix) {
+ return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::string>(
+ prefix));
+}
+
+// Matches a string that ends with 'suffix' (case-sensitive).
+inline PolymorphicMatcher<internal::EndsWithMatcher<internal::string> >
+ EndsWith(const internal::string& suffix) {
+ return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::string>(
+ suffix));
+}
+
+#ifdef GMOCK_HAS_REGEX
+
+// Matches a string that fully matches regular expression 'regex'.
+// The matcher takes ownership of 'regex'.
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
+ const internal::RE* regex) {
+ return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
+}
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
+ const internal::string& regex) {
+ return MatchesRegex(new internal::RE(regex));
+}
+
+// Matches a string that contains regular expression 'regex'.
+// The matcher takes ownership of 'regex'.
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
+ const internal::RE* regex) {
+ return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
+}
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
+ const internal::string& regex) {
+ return ContainsRegex(new internal::RE(regex));
+}
+
+#endif // GMOCK_HAS_REGEX
+
+#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
+// Wide string matchers.
+
+// Matches a string equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
+ StrEq(const internal::wstring& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
+ str, true, true));
+}
+
+// Matches a string not equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
+ StrNe(const internal::wstring& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
+ str, false, true));
+}
+
+// Matches a string equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
+ StrCaseEq(const internal::wstring& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
+ str, true, false));
+}
+
+// Matches a string not equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
+ StrCaseNe(const internal::wstring& str) {
+ return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
+ str, false, false));
+}
+
+// Creates a matcher that matches any wstring, std::wstring, or C wide string
+// that contains the given substring.
+inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> >
+ HasSubstr(const internal::wstring& substring) {
+ return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>(
+ substring));
+}
+
+// Matches a string that starts with 'prefix' (case-sensitive).
+inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> >
+ StartsWith(const internal::wstring& prefix) {
+ return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>(
+ prefix));
+}
+
+// Matches a string that ends with 'suffix' (case-sensitive).
+inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> >
+ EndsWith(const internal::wstring& suffix) {
+ return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>(
+ suffix));
+}
+
+#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field == the second field.
+inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field >= the second field.
+inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field > the second field.
+inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field <= the second field.
+inline internal::Le2Matcher Le() { return internal::Le2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field < the second field.
+inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field != the second field.
+inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
+
+// Creates a matcher that matches any value of type T that m doesn't
+// match.
+template <typename InnerMatcher>
+inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {
+ return internal::NotMatcher<InnerMatcher>(m);
+}
+
+// Creates a matcher that matches any value that matches all of the
+// given matchers.
+//
+// For now we only support up to 5 matchers. Support for more
+// matchers can be added as needed, or the user can use nested
+// AllOf()s.
+template <typename Matcher1, typename Matcher2>
+inline internal::BothOfMatcher<Matcher1, Matcher2>
+AllOf(Matcher1 m1, Matcher2 m2) {
+ return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3>
+inline internal::BothOfMatcher<Matcher1,
+ internal::BothOfMatcher<Matcher2, Matcher3> >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) {
+ return AllOf(m1, AllOf(m2, m3));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4>
+inline internal::BothOfMatcher<Matcher1,
+ internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3, Matcher4> > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) {
+ return AllOf(m1, AllOf(m2, m3, m4));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5>
+inline internal::BothOfMatcher<Matcher1,
+ internal::BothOfMatcher<Matcher2,
+ internal::BothOfMatcher<Matcher3,
+ internal::BothOfMatcher<Matcher4, Matcher5> > > >
+AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) {
+ return AllOf(m1, AllOf(m2, m3, m4, m5));
+}
+
+// Creates a matcher that matches any value that matches at least one
+// of the given matchers.
+//
+// For now we only support up to 5 matchers. Support for more
+// matchers can be added as needed, or the user can use nested
+// AnyOf()s.
+template <typename Matcher1, typename Matcher2>
+inline internal::EitherOfMatcher<Matcher1, Matcher2>
+AnyOf(Matcher1 m1, Matcher2 m2) {
+ return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3>
+inline internal::EitherOfMatcher<Matcher1,
+ internal::EitherOfMatcher<Matcher2, Matcher3> >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) {
+ return AnyOf(m1, AnyOf(m2, m3));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4>
+inline internal::EitherOfMatcher<Matcher1,
+ internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3, Matcher4> > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) {
+ return AnyOf(m1, AnyOf(m2, m3, m4));
+}
+
+template <typename Matcher1, typename Matcher2, typename Matcher3,
+ typename Matcher4, typename Matcher5>
+inline internal::EitherOfMatcher<Matcher1,
+ internal::EitherOfMatcher<Matcher2,
+ internal::EitherOfMatcher<Matcher3,
+ internal::EitherOfMatcher<Matcher4, Matcher5> > > >
+AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) {
+ return AnyOf(m1, AnyOf(m2, m3, m4, m5));
+}
+
+// Returns a matcher that matches anything that satisfies the given
+// predicate. The predicate can be any unary function or functor
+// whose return type can be implicitly converted to bool.
+template <typename Predicate>
+inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> >
+Truly(Predicate pred) {
+ return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred));
+}
+
+// Returns a predicate that is satisfied by anything that matches the
+// given matcher.
+template <typename M>
+inline internal::MatcherAsPredicate<M> Matches(M matcher) {
+ return internal::MatcherAsPredicate<M>(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,
+// the value and the description of the matcher will be printed.
+#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\
+ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
+#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
+ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
diff --git a/include/gmock/gmock-printers.h b/include/gmock/gmock-printers.h
new file mode 100644
index 00000000..628fc744
--- /dev/null
+++ b/include/gmock/gmock-printers.h
@@ -0,0 +1,514 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements a universal value printer that can print a
+// value of any type T:
+//
+// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
+//
+// It uses the << operator when possible, and prints the bytes in the
+// object otherwise. A user can override its behavior for a class
+// type Foo by defining either operator<<(::std::ostream&, const Foo&)
+// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
+// defines Foo. If both are defined, PrintTo() takes precedence.
+// When T is a reference type, the address of the value is also
+// printed.
+//
+// We also provide a convenient wrapper
+//
+// string ::testing::internal::UniversalPrinter<T>::PrintAsString(value);
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
+
+#include <ostream> // NOLINT
+#include <string>
+#include <utility>
+
+#include <gmock/internal/gmock-internal-utils.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+// Makes sure there is at least one << operator declared in the global
+// namespace. This has no implementation and won't be called
+// anywhere. We just need the declaration such that we can say "using
+// ::operator <<;" in the definition of PrintTo() below.
+void operator<<(::testing::internal::Unused, int);
+
+namespace testing {
+
+// Definitions in the 'internal' and 'internal2' name spaces are
+// subject to change without notice. DO NOT USE THEM IN USER CODE!
+namespace internal2 {
+
+// Prints the given number of bytes in the given object to the given
+// ostream.
+void PrintBytesInObjectTo(const unsigned char* obj_bytes,
+ size_t count,
+ ::std::ostream* os);
+
+// TypeWithoutFormatter<T, kIsProto>::PrintValue(value, os) is called
+// by the universal printer to print a value of type T when neither
+// operator<< nor PrintTo() is defined for type T. When T is
+// ProtocolMessage, proto2::Message, or a subclass of those, kIsProto
+// will be true and the short debug string of the protocol message
+// value will be printed; otherwise kIsProto will be false and the
+// bytes in the value will be printed.
+template <typename T, bool kIsProto>
+class TypeWithoutFormatter {
+ public:
+ static void PrintValue(const T& value, ::std::ostream* os) {
+ PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
+ sizeof(value), os);
+ }
+};
+template <typename T>
+class TypeWithoutFormatter<T, true> {
+ public:
+ static void PrintValue(const T& value, ::std::ostream* os) {
+ // Both ProtocolMessage and proto2::Message have the
+ // ShortDebugString() method, so the same implementation works for
+ // both.
+ ::std::operator<<(*os, "<" + value.ShortDebugString() + ">");
+ }
+};
+
+// Prints the given value to the given ostream. If the value is a
+// protocol message, its short debug string is printed; otherwise the
+// bytes in the value are printed. This is what
+// UniversalPrinter<T>::Print() does when it knows nothing about type
+// T and T has no << operator.
+//
+// A user can override this behavior for a class type Foo by defining
+// a << operator in the namespace where Foo is defined.
+//
+// We put this operator in namespace 'internal2' instead of 'internal'
+// to simplify the implementation, as much code in 'internal' needs to
+// use << in STL, which would conflict with our own << were it defined
+// in 'internal'.
+template <typename T>
+::std::ostream& operator<<(::std::ostream& os, const T& x) {
+ TypeWithoutFormatter<T, ::testing::internal::IsAProtocolMessage<T>::value>::
+ PrintValue(x, &os);
+ return os;
+}
+
+} // namespace internal2
+
+namespace internal {
+
+// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
+// value to the given ostream. The caller must ensure that
+// 'ostream_ptr' is not NULL, or the behavior is undefined.
+//
+// We define UniversalPrinter as a class template (as opposed to a
+// function template), as we need to partially specialize it for
+// reference types, which cannot be done with function templates.
+template <typename T>
+class UniversalPrinter;
+
+// Used to print an STL-style container when the user doesn't define
+// a PrintTo() for it.
+template <typename C>
+void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) {
+ const size_t kMaxCount = 32; // The maximum number of elements to print.
+ *os << '{';
+ size_t count = 0;
+ for (typename C::const_iterator it = container.begin();
+ it != container.end(); ++it, ++count) {
+ if (count > 0) {
+ *os << ',';
+ if (count == kMaxCount) { // Enough has been printed.
+ *os << " ...";
+ break;
+ }
+ }
+ *os << ' ';
+ PrintTo(*it, os);
+ }
+
+ if (count > 0) {
+ *os << ' ';
+ }
+ *os << '}';
+}
+
+// Used to print a value when the user doesn't define PrintTo() for it.
+template <typename T>
+void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) {
+ // If T has its << operator defined in the global namespace, which
+ // is not recommended but sometimes unavoidable (as in
+ // util/gtl/stl_logging-inl.h), the following statement makes it
+ // visible in this function.
+ //
+ // Without the statement, << in the global namespace would be hidden
+ // by the one in ::testing::internal2, due to the next using
+ // statement.
+ using ::operator <<;
+
+ // When T doesn't come with a << operator, we want to fall back to
+ // the one defined in ::testing::internal2, which prints the bytes in
+ // the value.
+ using ::testing::internal2::operator <<;
+
+ // Thanks to Koenig look-up, if type T has its own << operator
+ // defined in its namespace, which is the recommended way, that
+ // operator will be visible here. Since it is more specific than
+ // the generic one, it will be picked by the compiler in the
+ // following statement - exactly what we want.
+ *os << value;
+}
+
+// Prints the given value using the << operator if it has one;
+// otherwise prints the bytes in it. This is what
+// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
+// or overloaded for type T.
+//
+// A user can override this behavior for a class type Foo by defining
+// an overload of PrintTo() in the namespace where Foo is defined. We
+// give the user this option as sometimes defining a << operator for
+// Foo is not desirable (e.g. the coding style may prevent doing it,
+// or there is already a << operator but it doesn't do what the user
+// wants).
+template <typename T>
+void PrintTo(const T& value, ::std::ostream* os) {
+ // DefaultPrintTo() is overloaded. The type of its first argument
+ // determines which version will be picked. If T is an STL-style
+ // container, the version for container will be called. Otherwise
+ // the generic version will be called.
+ //
+ // Note that we check for container types here, prior to we check
+ // for protocol message types in our operator<<. The rationale is:
+ //
+ // For protocol messages, we want to give people a chance to
+ // override Google Mock's format by defining a PrintTo() or
+ // operator<<. For STL containers, we believe the Google Mock's
+ // format is superior to what util/gtl/stl-logging.h offers.
+ // Therefore we don't want it to be accidentally overridden by the
+ // latter (even if the user includes stl-logging.h through other
+ // headers indirectly, Google Mock's format will still be used).
+ DefaultPrintTo(IsContainerTest<T>(0), value, os);
+}
+
+// The following list of PrintTo() overloads tells
+// UniversalPrinter<T>::Print() how to print standard types (built-in
+// types, strings, plain arrays, and pointers).
+
+// Overloads for various char types.
+void PrintCharTo(char c, int char_code, ::std::ostream* os);
+inline void PrintTo(unsigned char c, ::std::ostream* os) {
+ PrintCharTo(c, c, os);
+}
+inline void PrintTo(signed char c, ::std::ostream* os) {
+ PrintCharTo(c, c, os);
+}
+inline void PrintTo(char c, ::std::ostream* os) {
+ // When printing a plain char, we always treat it as unsigned. This
+ // way, the output won't be affected by whether the compiler thinks
+ // char is signed or not.
+ PrintTo(static_cast<unsigned char>(c), os);
+}
+
+// Overloads for other simple built-in types.
+inline void PrintTo(bool x, ::std::ostream* os) {
+ *os << (x ? "true" : "false");
+}
+
+// Overload for wchar_t type.
+// Prints a wchar_t as a symbol if it is printable or as its internal
+// code otherwise and also as its decimal code (except for L'\0').
+// The L'\0' char is printed as "L'\\0'". The decimal code is printed
+// as signed integer when wchar_t is implemented by the compiler
+// as a signed type and is printed as an unsigned integer when wchar_t
+// is implemented as an unsigned type.
+void PrintTo(wchar_t wc, ::std::ostream* os);
+
+// Overloads for C strings.
+void PrintTo(const char* s, ::std::ostream* os);
+inline void PrintTo(char* s, ::std::ostream* os) {
+ PrintTo(implicit_cast<const char*>(s), os);
+}
+
+// MSVC compiler can be configured to define whar_t as a typedef
+// of unsigned short. Defining an overload for const wchar_t* in that case
+// would cause pointers to unsigned shorts be printed as wide strings,
+// possibly accessing more memory than intended and causing invalid
+// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
+// wchar_t is implemented as a native type.
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+// Overloads for wide C strings
+void PrintTo(const wchar_t* s, ::std::ostream* os);
+inline void PrintTo(wchar_t* s, ::std::ostream* os) {
+ PrintTo(implicit_cast<const wchar_t*>(s), os);
+}
+#endif
+
+// Overload for pointers that are neither char pointers nor member
+// pointers. (A member variable pointer or member function pointer
+// doesn't really points to a location in the address space. Their
+// representation is implementation-defined. Therefore they will be
+// printed as raw bytes.)
+template <typename T>
+void PrintTo(T* p, ::std::ostream* os) {
+ if (p == NULL) {
+ *os << "NULL";
+ } else {
+ // We cannot use implicit_cast or static_cast here, as they don't
+ // work when p is a function pointer.
+ *os << reinterpret_cast<const void*>(p);
+ }
+}
+
+// Overload for C arrays. Multi-dimensional arrays are printed
+// properly.
+
+// Prints the given number of elements in an array, without printing
+// the curly braces.
+template <typename T>
+void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
+ UniversalPrinter<T>::Print(a[0], os);
+ for (size_t i = 1; i != count; i++) {
+ *os << ", ";
+ UniversalPrinter<T>::Print(a[i], os);
+ }
+}
+
+// Overloads for ::string and ::std::string.
+#if GTEST_HAS_GLOBAL_STRING
+void PrintStringTo(const ::string&s, ::std::ostream* os);
+inline void PrintTo(const ::string& s, ::std::ostream* os) {
+ PrintStringTo(s, os);
+}
+#endif // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_STD_STRING
+void PrintStringTo(const ::std::string&s, ::std::ostream* os);
+inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
+ PrintStringTo(s, os);
+}
+#endif // GTEST_HAS_STD_STRING
+
+// Overloads for ::wstring and ::std::wstring.
+#if GTEST_HAS_GLOBAL_WSTRING
+void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
+inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
+ PrintWideStringTo(s, os);
+}
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+#if GTEST_HAS_STD_WSTRING
+void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
+inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
+ PrintWideStringTo(s, os);
+}
+#endif // GTEST_HAS_STD_WSTRING
+
+// Overload for ::std::tr1::tuple. Needed for printing function
+// arguments, which are packed as tuples.
+
+// This helper template allows PrintTo() for tuples to be defined by
+// induction on the number of tuple fields. The idea is that
+// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
+// fields in tuple t, and can be defined in terms of
+// TuplePrefixPrinter<N - 1>.
+template <size_t N>
+struct TuplePrefixPrinter {
+ template <typename Tuple>
+ static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
+ TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
+ *os << ", ";
+ UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
+ ::Print(::std::tr1::get<N - 1>(t), os);
+ }
+};
+template <>
+struct TuplePrefixPrinter<0> {
+ template <typename Tuple>
+ static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
+};
+template <>
+struct TuplePrefixPrinter<1> {
+ template <typename Tuple>
+ static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
+ UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
+ Print(::std::tr1::get<0>(t), os);
+ }
+};
+
+// We support tuples of up-to 10 fields. Note that an N-tuple type is
+// just an (N + 1)-tuple type where the last field has a special,
+// unused type.
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+void PrintTo(
+ const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
+ ::std::ostream* os) {
+ typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Tuple;
+ *os << "(";
+ TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
+ PrintPrefixTo(t, os);
+ *os << ")";
+}
+
+// Overload for std::pair.
+template <typename T1, typename T2>
+void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
+ *os << '(';
+ UniversalPrinter<T1>::Print(value.first, os);
+ *os << ", ";
+ UniversalPrinter<T2>::Print(value.second, os);
+ *os << ')';
+}
+
+// Implements printing a non-reference type T by letting the compiler
+// pick the right overload of PrintTo() for T.
+template <typename T>
+class UniversalPrinter {
+ public:
+ // MSVC warns about adding const to a function type, so we want to
+ // disable the warning.
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4180) // Temporarily disables warning 4180.
+#endif // _MSC_VER
+
+ // Note: we deliberately don't call this PrintTo(), as that name
+ // conflicts with ::testing::internal::PrintTo in the body of the
+ // function.
+ static void Print(const T& value, ::std::ostream* os) {
+ // By default, ::testing::internal::PrintTo() is used for printing
+ // the value.
+ //
+ // Thanks to Koenig look-up, if T is a class and has its own
+ // PrintTo() function defined in its namespace, that function will
+ // be visible here. Since it is more specific than the generic ones
+ // in ::testing::internal, it will be picked by the compiler in the
+ // following statement - exactly what we want.
+ PrintTo(value, os);
+ }
+
+ // A convenient wrapper for Print() that returns the print-out as a
+ // string.
+ static string PrintAsString(const T& value) {
+ ::std::stringstream ss;
+ Print(value, &ss);
+ return ss.str();
+ }
+
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif // _MSC_VER
+};
+
+// Implements printing an array type T[N].
+template <typename T, size_t N>
+class UniversalPrinter<T[N]> {
+ public:
+ // 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 << " }";
+ }
+ }
+
+ // A convenient wrapper for Print() that returns the print-out as a
+ // string.
+ static string PrintAsString(const T (&a)[N]) {
+ ::std::stringstream ss;
+ Print(a, &ss);
+ return ss.str();
+ }
+};
+
+// Implements printing a reference type T&.
+template <typename T>
+class UniversalPrinter<T&> {
+ public:
+ // MSVC warns about adding const to a function type, so we want to
+ // disable the warning.
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4180) // Temporarily disables warning 4180.
+#endif // _MSC_VER
+
+ static void Print(const T& value, ::std::ostream* os) {
+ // Prints the address of the value. We use reinterpret_cast here
+ // as static_cast doesn't compile when T is a function type.
+ *os << "@" << reinterpret_cast<const void*>(&value) << " ";
+
+ // Then prints the value itself.
+ UniversalPrinter<T>::Print(value, os);
+ }
+
+ // A convenient wrapper for Print() that returns the print-out as a
+ // string.
+ static string PrintAsString(const T& value) {
+ ::std::stringstream ss;
+ Print(value, &ss);
+ return ss.str();
+ }
+
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif // _MSC_VER
+};
+
+} // namespace internal
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
diff --git a/include/gmock/gmock-spec-builders.h b/include/gmock/gmock-spec-builders.h
new file mode 100644
index 00000000..84e0b513
--- /dev/null
+++ b/include/gmock/gmock-spec-builders.h
@@ -0,0 +1,1568 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements the ON_CALL() and EXPECT_CALL() macros.
+//
+// A user can use the ON_CALL() macro to specify the default action of
+// a mock method. The syntax is:
+//
+// ON_CALL(mock_object, Method(argument-matchers))
+// .WithArguments(multi-argument-matcher)
+// .WillByDefault(action);
+//
+// where the .WithArguments() 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)
+// .Times(cardinality)
+// .InSequence(sequences)
+// .WillOnce(action)
+// .WillRepeatedly(action)
+// .RetiresOnSaturation();
+//
+// where all clauses are optional, .InSequence() and .WillOnce() can
+// appear any number of times, and .Times() can be omitted only if
+// .WillOnce() or .WillRepeatedly() is present.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+
+#include <map>
+#include <set>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <gmock/gmock-actions.h>
+#include <gmock/gmock-cardinalities.h>
+#include <gmock/gmock-matchers.h>
+#include <gmock/gmock-printers.h>
+#include <gmock/internal/gmock-internal-utils.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+
+// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
+// and MUST NOT BE USED IN USER CODE!!!
+namespace internal {
+
+template <typename F>
+class FunctionMocker;
+
+// Base class for expectations.
+class ExpectationBase;
+
+// Helper class for testing the Expectation class template.
+class ExpectationTester;
+
+// Base class for function mockers.
+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.
+//
+// The reason we don't use more fine-grained protection is: when a
+// mock function Foo() is called, it needs to consult its expectations
+// to see which one should be picked. If another thread is allowed to
+// call a mock function (either Foo() or a different one) at the same
+// time, it could affect the "retired" attributes of Foo()'s
+// expectations when InSequence() is used, and thus affect which
+// expectation gets picked. Therefore, we sequence all mock function
+// calls to ensure the integrity of the mock objects' states.
+extern Mutex g_gmock_mutex;
+
+// Abstract base class of FunctionMockerBase. This is the
+// type-agnostic part of the function mocker interface. Its pure
+// virtual methods are implemented by FunctionMockerBase.
+class UntypedFunctionMockerBase {
+ public:
+ virtual ~UntypedFunctionMockerBase() {}
+
+ // Verifies that all expectations on this mock function have been
+ // satisfied. Reports one or more Google Test non-fatal failures
+ // and returns false if not.
+ // L >= g_gmock_mutex
+ virtual bool VerifyAndClearExpectationsLocked() = 0;
+
+ // Clears the ON_CALL()s set on this mock function.
+ // L >= g_gmock_mutex
+ virtual void ClearDefaultActionsLocked() = 0;
+}; // class UntypedFunctionMockerBase
+
+// This template class implements a default action spec (i.e. an
+// ON_CALL() statement).
+template <typename F>
+class DefaultActionSpec {
+ public:
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
+
+ // Constructs a DefaultActionSpec object from the information inside
+ // the parenthesis of an ON_CALL() statement.
+ DefaultActionSpec(const char* file, int line,
+ const ArgumentMatcherTuple& matchers)
+ : file_(file),
+ line_(line),
+ matchers_(matchers),
+ extra_matcher_(_),
+ last_clause_(NONE) {
+ }
+
+ // 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) {
+ // Makes sure this is called at most once.
+ ExpectSpecProperty(last_clause_ < WITH_ARGUMENTS,
+ ".WithArguments() cannot appear "
+ "more than once in an ON_CALL().");
+ last_clause_ = WITH_ARGUMENTS;
+
+ extra_matcher_ = m;
+ return *this;
+ }
+
+ // Implements the .WillByDefault() clause.
+ DefaultActionSpec& WillByDefault(const Action<F>& action) {
+ ExpectSpecProperty(last_clause_ < WILL_BY_DEFAULT,
+ ".WillByDefault() must appear "
+ "exactly once in an ON_CALL().");
+ last_clause_ = WILL_BY_DEFAULT;
+
+ ExpectSpecProperty(!action.IsDoDefault(),
+ "DoDefault() cannot be used in ON_CALL().");
+ action_ = action;
+ return *this;
+ }
+
+ // Returns true iff the given arguments match the matchers.
+ bool Matches(const ArgumentTuple& args) const {
+ return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
+ }
+
+ // Returns the action specified by the user.
+ const Action<F>& GetAction() const {
+ AssertSpecProperty(last_clause_ == WILL_BY_DEFAULT,
+ ".WillByDefault() must appear exactly "
+ "once in an ON_CALL().");
+ return action_;
+ }
+ private:
+ // Gives each clause in the ON_CALL() statement a name.
+ 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,
+ };
+
+ // Asserts that the ON_CALL() statement has a certain property.
+ void AssertSpecProperty(bool property, const string& failure_message) const {
+ Assert(property, file_, line_, failure_message);
+ }
+
+ // Expects that the ON_CALL() statement has a certain property.
+ void ExpectSpecProperty(bool property, const string& failure_message) const {
+ Expect(property, file_, line_, failure_message);
+ }
+
+ // The information in statement
+ //
+ // ON_CALL(mock_object, Method(matchers))
+ // .WithArguments(multi-argument-matcher)
+ // .WillByDefault(action);
+ //
+ // is recorded in the data members like this:
+ //
+ // source file that contains the statement => file_
+ // line number of the statement => line_
+ // matchers => matchers_
+ // multi-argument-matcher => extra_matcher_
+ // action => action_
+ const char* file_;
+ int line_;
+ ArgumentMatcherTuple matchers_;
+ Matcher<const ArgumentTuple&> extra_matcher_;
+ Action<F> action_;
+
+ // The last clause in the ON_CALL() statement as seen so far.
+ // Initially NONE and changes as the statement is parsed.
+ Clause last_clause_;
+}; // class DefaultActionSpec
+
+// Possible reactions on uninteresting calls.
+enum CallReaction {
+ ALLOW,
+ WARN,
+ FAIL,
+};
+
+} // namespace internal
+
+// Utilities for manipulating mock objects.
+class Mock {
+ public:
+ // The following public methods can be called concurrently.
+
+ // Verifies and clears all expectations on the given mock object.
+ // If the expectations aren't satisfied, generates one or more
+ // Google Test non-fatal failures and returns false.
+ static bool VerifyAndClearExpectations(void* mock_obj);
+
+ // Verifies all expectations on the given mock object and clears its
+ // default actions and expectations. Returns true iff the
+ // verification was successful.
+ static bool VerifyAndClear(void* mock_obj);
+ private:
+ // Needed for a function mocker to register itself (so that we know
+ // how to clear a mock object).
+ template <typename F>
+ friend class internal::FunctionMockerBase;
+
+ template <typename R, typename Args>
+ friend class internal::InvokeWithHelper;
+
+ template <typename M>
+ friend class NiceMock;
+
+ template <typename M>
+ friend class StrictMock;
+
+ // Tells Google Mock to allow uninteresting calls on the given mock
+ // object.
+ // L < g_gmock_mutex
+ static void AllowUninterestingCalls(const void* mock_obj);
+
+ // Tells Google Mock to warn the user about uninteresting calls on
+ // the given mock object.
+ // L < g_gmock_mutex
+ static void WarnUninterestingCalls(const void* mock_obj);
+
+ // Tells Google Mock to fail uninteresting calls on the given mock
+ // object.
+ // L < g_gmock_mutex
+ static void FailUninterestingCalls(const void* mock_obj);
+
+ // Tells Google Mock the given mock object is being destroyed and
+ // its entry in the call-reaction table should be removed.
+ // L < g_gmock_mutex
+ static void UnregisterCallReaction(const void* mock_obj);
+
+ // Returns the reaction Google Mock will have on uninteresting calls
+ // made on the given mock object.
+ // L < g_gmock_mutex
+ static internal::CallReaction GetReactionOnUninterestingCalls(
+ const void* mock_obj);
+
+ // Verifies that all expectations on the given mock object have been
+ // satisfied. Reports one or more Google Test non-fatal failures
+ // and returns false if not.
+ // L >= g_gmock_mutex
+ static bool VerifyAndClearExpectationsLocked(void* mock_obj);
+
+ // Clears all ON_CALL()s set on the given mock object.
+ // L >= g_gmock_mutex
+ static void ClearDefaultActionsLocked(void* mock_obj);
+
+ // Registers a mock object and a mock method it owns.
+ // L < g_gmock_mutex
+ static void Register(const void* mock_obj,
+ internal::UntypedFunctionMockerBase* mocker);
+
+ // Unregisters a mock method; removes the owning mock object from
+ // the registry when the last mock method associated with it has
+ // been unregistered. This is called only in the destructor of
+ // FunctionMockerBase.
+ // L >= g_gmock_mutex
+ static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker);
+}; // class Mock
+
+// Sequence objects are used by a user to specify the relative order
+// in which the expectations should match. They are copyable (we rely
+// on the compiler-defined copy constructor and assignment operator).
+class Sequence {
+ public:
+ // Constructs an empty sequence.
+ Sequence()
+ : last_expectation_(
+ new internal::linked_ptr<internal::ExpectationBase>(NULL)) {}
+
+ // Adds an expectation to this sequence. The caller must ensure
+ // that no other thread is accessing this Sequence object.
+ void AddExpectation(
+ const internal::linked_ptr<internal::ExpectationBase>& expectation) const;
+ private:
+ // The last expectation in this sequence. We use a nested
+ // linked_ptr here because:
+ // - Sequence objects are copyable, and we want the copies to act
+ // as aliases. The outer linked_ptr allows the copies to co-own
+ // and share the same state.
+ // - An Expectation object is co-owned (via linked_ptr) by its
+ // FunctionMocker and its successors (other Expectation objects).
+ // Hence the inner linked_ptr.
+ internal::linked_ptr<internal::linked_ptr<internal::ExpectationBase> >
+ last_expectation_;
+}; // class Sequence
+
+// An object of this type causes all EXPECT_CALL() statements
+// encountered in its scope to be put in an anonymous sequence. The
+// work is done in the constructor and destructor. You should only
+// create an InSequence object on the stack.
+//
+// The sole purpose for this class is to support easy definition of
+// sequential expectations, e.g.
+//
+// {
+// InSequence dummy; // The name of the object doesn't matter.
+//
+// // The following expectations must match in the order they appear.
+// EXPECT_CALL(a, Bar())...;
+// EXPECT_CALL(a, Baz())...;
+// ...
+// EXPECT_CALL(b, Xyz())...;
+// }
+//
+// You can create InSequence objects in multiple threads, as long as
+// they are used to affect different mock objects. The idea is that
+// each thread can create and set up its own mocks as if it's the only
+// thread. However, for clarity of your tests we recommend you to set
+// up mocks in the main thread unless you have a good reason not to do
+// so.
+class InSequence {
+ public:
+ InSequence();
+ ~InSequence();
+ private:
+ bool sequence_created_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT
+} GMOCK_ATTRIBUTE_UNUSED;
+
+namespace internal {
+
+// Points to the implicit sequence introduced by a living InSequence
+// object (if any) in the current thread or NULL.
+extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;
+
+// Base class for implementing expectations.
+//
+// There are two reasons for having a type-agnostic base class for
+// Expectation:
+//
+// 1. We need to store collections of expectations of different
+// types (e.g. all pre-requisites of a particular expectation, all
+// expectations in a sequence). Therefore these expectation objects
+// must share a common base class.
+//
+// 2. We can avoid binary code bloat by moving methods not depending
+// on the template argument of Expectation to the base class.
+//
+// This class is internal and mustn't be used by user code directly.
+class ExpectationBase {
+ public:
+ ExpectationBase(const char* file, int line);
+
+ virtual ~ExpectationBase();
+
+ // Where in the source file was the expectation spec defined?
+ const char* file() const { return file_; }
+ int line() const { return line_; }
+
+ // Returns the cardinality specified in the expectation spec.
+ const Cardinality& cardinality() const { return cardinality_; }
+
+ // Describes the source file location of this expectation.
+ void DescribeLocationTo(::std::ostream* os) const {
+ *os << file() << ":" << line() << ": ";
+ }
+
+ // Describes how many times a function call matching this
+ // expectation has occurred.
+ // L >= g_gmock_mutex
+ virtual void DescribeCallCountTo(::std::ostream* os) const = 0;
+ protected:
+ typedef std::set<linked_ptr<ExpectationBase>,
+ LinkedPtrLessThan<ExpectationBase> >
+ ExpectationBaseSet;
+
+ enum Clause {
+ // Don't change the order of the enum members!
+ NONE,
+ WITH_ARGUMENTS,
+ TIMES,
+ IN_SEQUENCE,
+ WILL_ONCE,
+ WILL_REPEATEDLY,
+ RETIRES_ON_SATURATION,
+ };
+
+ // Asserts that the EXPECT_CALL() statement has the given property.
+ void AssertSpecProperty(bool property, const string& failure_message) const {
+ Assert(property, file_, line_, failure_message);
+ }
+
+ // Expects that the EXPECT_CALL() statement has the given property.
+ void ExpectSpecProperty(bool property, const string& failure_message) const {
+ Expect(property, file_, line_, failure_message);
+ }
+
+ // Explicitly specifies the cardinality of this expectation. Used
+ // by the subclasses to implement the .Times() clause.
+ void SpecifyCardinality(const Cardinality& cardinality);
+
+ // Returns true iff the user specified the cardinality explicitly
+ // using a .Times().
+ bool cardinality_specified() const { return cardinality_specified_; }
+
+ // Sets the cardinality of this expectation spec.
+ void set_cardinality(const Cardinality& cardinality) {
+ cardinality_ = cardinality;
+ }
+
+ // The following group of methods should only be called after the
+ // EXPECT_CALL() statement, and only when g_gmock_mutex is held by
+ // the current thread.
+
+ // Retires all pre-requisites of this expectation.
+ // L >= g_gmock_mutex
+ void RetireAllPreRequisites();
+
+ // Returns true iff this expectation is retired.
+ // L >= g_gmock_mutex
+ bool is_retired() const {
+ g_gmock_mutex.AssertHeld();
+ return retired_;
+ }
+
+ // Retires this expectation.
+ // L >= g_gmock_mutex
+ void Retire() {
+ g_gmock_mutex.AssertHeld();
+ retired_ = true;
+ }
+
+ // Returns true iff this expectation is satisfied.
+ // L >= g_gmock_mutex
+ bool IsSatisfied() const {
+ g_gmock_mutex.AssertHeld();
+ return cardinality().IsSatisfiedByCallCount(call_count_);
+ }
+
+ // Returns true iff this expectation is saturated.
+ // L >= g_gmock_mutex
+ bool IsSaturated() const {
+ g_gmock_mutex.AssertHeld();
+ return cardinality().IsSaturatedByCallCount(call_count_);
+ }
+
+ // Returns true iff this expectation is over-saturated.
+ // L >= g_gmock_mutex
+ bool IsOverSaturated() const {
+ g_gmock_mutex.AssertHeld();
+ return cardinality().IsOverSaturatedByCallCount(call_count_);
+ }
+
+ // Returns true iff all pre-requisites of this expectation are satisfied.
+ // L >= g_gmock_mutex
+ bool AllPrerequisitesAreSatisfied() const;
+
+ // Adds unsatisfied pre-requisites of this expectation to 'result'.
+ // L >= g_gmock_mutex
+ void FindUnsatisfiedPrerequisites(ExpectationBaseSet* result) const;
+
+ // Returns the number this expectation has been invoked.
+ // L >= g_gmock_mutex
+ int call_count() const {
+ g_gmock_mutex.AssertHeld();
+ return call_count_;
+ }
+
+ // Increments the number this expectation has been invoked.
+ // L >= g_gmock_mutex
+ void IncrementCallCount() {
+ g_gmock_mutex.AssertHeld();
+ call_count_++;
+ }
+
+ private:
+ friend class ::testing::Sequence;
+ friend class ::testing::internal::ExpectationTester;
+
+ template <typename Function>
+ friend class Expectation;
+
+ // This group of fields are part of the spec and won't change after
+ // an EXPECT_CALL() statement finishes.
+ const char* file_; // The file that contains the expectation.
+ int line_; // The line number of the expectation.
+ // True iff the cardinality is specified explicitly.
+ bool cardinality_specified_;
+ Cardinality cardinality_; // The cardinality of the expectation.
+ // The immediate pre-requisites of this expectation. We use
+ // linked_ptr in the set because we want an Expectation object to be
+ // co-owned by its FunctionMocker and its successors. This allows
+ // multiple mock objects to be deleted at different times.
+ ExpectationBaseSet immediate_prerequisites_;
+
+ // This group of fields are the current state of the expectation,
+ // and can change as the mock function is called.
+ int call_count_; // How many times this expectation has been invoked.
+ bool retired_; // True iff this expectation has retired.
+}; // class ExpectationBase
+
+// Impements an expectation for the given function type.
+template <typename F>
+class Expectation : public ExpectationBase {
+ public:
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
+ typedef typename Function<F>::Result Result;
+
+ Expectation(FunctionMockerBase<F>* owner, const char* file, int line,
+ const ArgumentMatcherTuple& m)
+ : ExpectationBase(file, line),
+ owner_(owner),
+ matchers_(m),
+ extra_matcher_(_),
+ repeated_action_specified_(false),
+ repeated_action_(DoDefault()),
+ retires_on_saturation_(false),
+ last_clause_(NONE),
+ action_count_checked_(false) {}
+
+ virtual ~Expectation() {
+ // Check the validity of the action count if it hasn't been done
+ // yet (for example, if the expectation was never used).
+ CheckActionCountIfNotDone();
+ }
+
+ // Implements the .WithArguments() clause.
+ Expectation& WithArguments(const Matcher<const ArgumentTuple&>& m) {
+ if (last_clause_ == WITH_ARGUMENTS) {
+ ExpectSpecProperty(false,
+ ".WithArguments() cannot appear "
+ "more than once in an EXPECT_CALL().");
+ } else {
+ ExpectSpecProperty(last_clause_ < WITH_ARGUMENTS,
+ ".WithArguments() must be the first "
+ "clause in an EXPECT_CALL().");
+ }
+ last_clause_ = WITH_ARGUMENTS;
+
+ extra_matcher_ = m;
+ return *this;
+ }
+
+ // Implements the .Times() clause.
+ Expectation& Times(const Cardinality& cardinality) {
+ if (last_clause_ ==TIMES) {
+ ExpectSpecProperty(false,
+ ".Times() cannot appear "
+ "more than once in an EXPECT_CALL().");
+ } else {
+ ExpectSpecProperty(last_clause_ < TIMES,
+ ".Times() cannot appear after "
+ ".InSequence(), .WillOnce(), .WillRepeatedly(), "
+ "or .RetiresOnSaturation().");
+ }
+ last_clause_ = TIMES;
+
+ ExpectationBase::SpecifyCardinality(cardinality);
+ return *this;
+ }
+
+ // Implements the .Times() clause.
+ Expectation& Times(int n) {
+ return Times(Exactly(n));
+ }
+
+ // Implements the .InSequence() clause.
+ Expectation& InSequence(const Sequence& s) {
+ ExpectSpecProperty(last_clause_ <= IN_SEQUENCE,
+ ".InSequence() cannot appear after .WillOnce(),"
+ " .WillRepeatedly(), or "
+ ".RetiresOnSaturation().");
+ last_clause_ = IN_SEQUENCE;
+
+ s.AddExpectation(owner_->GetLinkedExpectationBase(this));
+ return *this;
+ }
+ Expectation& InSequence(const Sequence& s1, const Sequence& s2) {
+ return InSequence(s1).InSequence(s2);
+ }
+ Expectation& InSequence(const Sequence& s1, const Sequence& s2,
+ const Sequence& s3) {
+ return InSequence(s1, s2).InSequence(s3);
+ }
+ Expectation& InSequence(const Sequence& s1, const Sequence& s2,
+ const Sequence& s3, const Sequence& s4) {
+ return InSequence(s1, s2, s3).InSequence(s4);
+ }
+ Expectation& InSequence(const Sequence& s1, const Sequence& s2,
+ const Sequence& s3, const Sequence& s4,
+ const Sequence& s5) {
+ return InSequence(s1, s2, s3, s4).InSequence(s5);
+ }
+
+ // Implements the .WillOnce() clause.
+ Expectation& WillOnce(const Action<F>& action) {
+ ExpectSpecProperty(last_clause_ <= WILL_ONCE,
+ ".WillOnce() cannot appear after "
+ ".WillRepeatedly() or .RetiresOnSaturation().");
+ last_clause_ = WILL_ONCE;
+
+ actions_.push_back(action);
+ if (!cardinality_specified()) {
+ set_cardinality(Exactly(static_cast<int>(actions_.size())));
+ }
+ return *this;
+ }
+
+ // Implements the .WillRepeatedly() clause.
+ Expectation& WillRepeatedly(const Action<F>& action) {
+ if (last_clause_ == WILL_REPEATEDLY) {
+ ExpectSpecProperty(false,
+ ".WillRepeatedly() cannot appear "
+ "more than once in an EXPECT_CALL().");
+ } else {
+ ExpectSpecProperty(last_clause_ < WILL_REPEATEDLY,
+ ".WillRepeatedly() cannot appear "
+ "after .RetiresOnSaturation().");
+ }
+ last_clause_ = WILL_REPEATEDLY;
+ repeated_action_specified_ = true;
+
+ repeated_action_ = action;
+ if (!cardinality_specified()) {
+ set_cardinality(AtLeast(static_cast<int>(actions_.size())));
+ }
+
+ // Now that no more action clauses can be specified, we check
+ // whether their count makes sense.
+ CheckActionCountIfNotDone();
+ return *this;
+ }
+
+ // Implements the .RetiresOnSaturation() clause.
+ Expectation& RetiresOnSaturation() {
+ ExpectSpecProperty(last_clause_ < RETIRES_ON_SATURATION,
+ ".RetiresOnSaturation() cannot appear "
+ "more than once.");
+ last_clause_ = RETIRES_ON_SATURATION;
+ retires_on_saturation_ = true;
+
+ // Now that no more action clauses can be specified, we check
+ // whether their count makes sense.
+ CheckActionCountIfNotDone();
+ return *this;
+ }
+
+ // Returns the matchers for the arguments as specified inside the
+ // EXPECT_CALL() macro.
+ const ArgumentMatcherTuple& matchers() const {
+ return matchers_;
+ }
+
+ // Returns the matcher specified by the .WithArguments() clause.
+ const Matcher<const ArgumentTuple&>& extra_matcher() const {
+ return extra_matcher_;
+ }
+
+ // Returns the sequence of actions specified by the .WillOnce() clause.
+ const std::vector<Action<F> >& actions() const { return actions_; }
+
+ // Returns the action specified by the .WillRepeatedly() clause.
+ const Action<F>& repeated_action() const { return repeated_action_; }
+
+ // Returns true iff the .RetiresOnSaturation() clause was specified.
+ bool retires_on_saturation() const { return retires_on_saturation_; }
+
+ // Describes how many times a function call matching this
+ // expectation has occurred (implements
+ // ExpectationBase::DescribeCallCountTo()).
+ // L >= g_gmock_mutex
+ virtual void DescribeCallCountTo(::std::ostream* os) const {
+ g_gmock_mutex.AssertHeld();
+
+ // Describes how many times the function is expected to be called.
+ *os << " Expected: to be ";
+ cardinality().DescribeTo(os);
+ *os << "\n Actual: ";
+ Cardinality::DescribeActualCallCountTo(call_count(), os);
+
+ // Describes the state of the expectation (e.g. is it satisfied?
+ // is it active?).
+ *os << " - " << (IsOverSaturated() ? "over-saturated" :
+ IsSaturated() ? "saturated" :
+ IsSatisfied() ? "satisfied" : "unsatisfied")
+ << " and "
+ << (is_retired() ? "retired" : "active");
+ }
+ private:
+ 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.
+
+ // Returns true iff this expectation matches the given arguments.
+ // L >= g_gmock_mutex
+ bool Matches(const ArgumentTuple& args) const {
+ g_gmock_mutex.AssertHeld();
+ return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
+ }
+
+ // Returns true iff this expectation should handle the given arguments.
+ // L >= g_gmock_mutex
+ bool ShouldHandleArguments(const ArgumentTuple& args) const {
+ g_gmock_mutex.AssertHeld();
+
+ // In case the action count wasn't checked when the expectation
+ // was defined (e.g. if this expectation has no WillRepeatedly()
+ // or RetiresOnSaturation() clause), we check it when the
+ // expectation is used for the first time.
+ CheckActionCountIfNotDone();
+ return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args);
+ }
+
+ // Describes the result of matching the arguments against this
+ // expectation to the given ostream.
+ // L >= g_gmock_mutex
+ void DescribeMatchResultTo(const ArgumentTuple& args,
+ ::std::ostream* os) const {
+ g_gmock_mutex.AssertHeld();
+
+ if (is_retired()) {
+ *os << " Expected: the expectation is active\n"
+ << " Actual: it is retired\n";
+ } else if (!Matches(args)) {
+ if (!TupleMatches(matchers_, args)) {
+ DescribeMatchFailureTupleTo(matchers_, args, os);
+ }
+ if (!extra_matcher_.Matches(args)) {
+ *os << " Expected: ";
+ extra_matcher_.DescribeTo(os);
+ *os << "\n Actual: false";
+
+ internal::ExplainMatchResultAsNeededTo<const ArgumentTuple&>(
+ extra_matcher_, args, os);
+ *os << "\n";
+ }
+ } else if (!AllPrerequisitesAreSatisfied()) {
+ *os << " Expected: all pre-requisites are satisfied\n"
+ << " Actual: the following immediate pre-requisites "
+ << "are not satisfied:\n";
+ ExpectationBaseSet unsatisfied_prereqs;
+ FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);
+ int i = 0;
+ for (ExpectationBaseSet::const_iterator it = unsatisfied_prereqs.begin();
+ it != unsatisfied_prereqs.end(); ++it) {
+ (*it)->DescribeLocationTo(os);
+ *os << "pre-requisite #" << i++ << "\n";
+ }
+ *os << " (end of pre-requisites)\n";
+ } else {
+ // This line is here just for completeness' sake. It will never
+ // be executed as currently the DescribeMatchResultTo() function
+ // is called only when the mock function call does NOT match the
+ // expectation.
+ *os << "The call matches the expectation.\n";
+ }
+ }
+
+ // Returns the action that should be taken for the current invocation.
+ // L >= g_gmock_mutex
+ const Action<F>& GetCurrentAction(const FunctionMockerBase<F>* mocker,
+ const ArgumentTuple& args) const {
+ g_gmock_mutex.AssertHeld();
+ const int count = call_count();
+ Assert(count >= 1, __FILE__, __LINE__,
+ "call_count() is <= 0 when GetCurrentAction() is "
+ "called - this should never happen.");
+
+ const int action_count = static_cast<int>(actions().size());
+ if (action_count > 0 && !repeated_action_specified_ &&
+ count > action_count) {
+ // If there is at least one WillOnce() and no WillRepeatedly(),
+ // we warn the user when the WillOnce() clauses ran out.
+ ::std::stringstream ss;
+ DescribeLocationTo(&ss);
+ ss << "Actions ran out.\n"
+ << "Called " << count << " times, but only "
+ << action_count << " WillOnce()"
+ << (action_count == 1 ? " is" : "s are") << " specified - ";
+ mocker->DescribeDefaultActionTo(args, &ss);
+ Log(WARNING, ss.str(), 1);
+ }
+
+ return count <= action_count ? actions()[count - 1] : repeated_action();
+ }
+
+ // Given the arguments of a mock function call, if the call will
+ // over-saturate this expectation, returns the default action;
+ // otherwise, returns the next action in this expectation. Also
+ // describes *what* happened to 'what', and explains *why* Google
+ // Mock does it to 'why'. This method is not const as it calls
+ // IncrementCallCount().
+ // L >= g_gmock_mutex
+ Action<F> GetActionForArguments(const FunctionMockerBase<F>* mocker,
+ const ArgumentTuple& args,
+ ::std::ostream* what,
+ ::std::ostream* why) {
+ g_gmock_mutex.AssertHeld();
+ if (IsSaturated()) {
+ // We have an excessive call.
+ IncrementCallCount();
+ *what << "Mock function called more times than expected - ";
+ mocker->DescribeDefaultActionTo(args, what);
+ DescribeCallCountTo(why);
+
+ // TODO(wan): allow the user to control whether unexpected calls
+ // should fail immediately or continue using a flag
+ // --gmock_unexpected_calls_are_fatal.
+ return DoDefault();
+ }
+
+ IncrementCallCount();
+ RetireAllPreRequisites();
+
+ if (retires_on_saturation() && IsSaturated()) {
+ Retire();
+ }
+
+ // Must be done after IncrementCount()!
+ *what << "Expected mock function call.\n";
+ return GetCurrentAction(mocker, args);
+ }
+
+ // Checks the action count (i.e. the number of WillOnce() and
+ // WillRepeatedly() clauses) against the cardinality if this hasn't
+ // been done before. Prints a warning if there are too many or too
+ // few actions.
+ // L < mutex_
+ void CheckActionCountIfNotDone() const {
+ bool should_check = false;
+ {
+ MutexLock l(&mutex_);
+ if (!action_count_checked_) {
+ action_count_checked_ = true;
+ should_check = true;
+ }
+ }
+
+ if (should_check) {
+ if (!cardinality_specified_) {
+ // The cardinality was inferred - no need to check the action
+ // count against it.
+ return;
+ }
+
+ // The cardinality was explicitly specified.
+ const int action_count = static_cast<int>(actions_.size());
+ const int upper_bound = cardinality().ConservativeUpperBound();
+ const int lower_bound = cardinality().ConservativeLowerBound();
+ bool too_many; // True if there are too many actions, or false
+ // if there are too few.
+ if (action_count > upper_bound ||
+ (action_count == upper_bound && repeated_action_specified_)) {
+ too_many = true;
+ } else if (0 < action_count && action_count < lower_bound &&
+ !repeated_action_specified_) {
+ too_many = false;
+ } else {
+ return;
+ }
+
+ ::std::stringstream ss;
+ DescribeLocationTo(&ss);
+ ss << "Too " << (too_many ? "many" : "few")
+ << " actions specified.\n"
+ << "Expected to be ";
+ cardinality().DescribeTo(&ss);
+ ss << ", but has " << (too_many ? "" : "only ")
+ << action_count << " WillOnce()"
+ << (action_count == 1 ? "" : "s");
+ if (repeated_action_specified_) {
+ ss << " and a WillRepeatedly()";
+ }
+ ss << ".";
+ Log(WARNING, ss.str(), -1); // -1 means "don't print stack trace".
+ }
+ }
+
+ // All the fields below won't change once the EXPECT_CALL()
+ // statement finishes.
+ FunctionMockerBase<F>* const owner_;
+ ArgumentMatcherTuple matchers_;
+ Matcher<const ArgumentTuple&> extra_matcher_;
+ std::vector<Action<F> > actions_;
+ bool repeated_action_specified_; // True if a WillRepeatedly() was specified.
+ Action<F> repeated_action_;
+ bool retires_on_saturation_;
+ Clause last_clause_;
+ mutable bool action_count_checked_; // Under mutex_.
+ mutable Mutex mutex_; // Protects action_count_checked_.
+}; // class Expectation
+
+// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
+// specifying the default behavior of, or expectation on, a mock
+// function.
+
+// Note: class MockSpec really belongs to the ::testing namespace.
+// However if we define it in ::testing, MSVC will complain when
+// classes in ::testing::internal declare it as a friend class
+// template. To workaround this compiler bug, we define MockSpec in
+// ::testing::internal and import it into ::testing.
+
+template <typename F>
+class MockSpec {
+ public:
+ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename internal::Function<F>::ArgumentMatcherTuple
+ ArgumentMatcherTuple;
+
+ // Constructs a MockSpec object, given the function mocker object
+ // that the spec is associated with.
+ explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker)
+ : function_mocker_(function_mocker) {}
+
+ // Adds a new default action spec to the function mocker and returns
+ // the newly created spec.
+ internal::DefaultActionSpec<F>& InternalDefaultActionSetAt(
+ const char* file, int line, const char* obj, const char* call) {
+ LogWithLocation(internal::INFO, file, line,
+ string("ON_CALL(") + obj + ", " + call + ") invoked");
+ return function_mocker_->AddNewDefaultActionSpec(file, line, matchers_);
+ }
+
+ // Adds a new expectation spec to the function mocker and returns
+ // the newly created spec.
+ internal::Expectation<F>& InternalExpectedAt(
+ const char* file, int line, const char* obj, const char* call) {
+ LogWithLocation(internal::INFO, file, line,
+ string("EXPECT_CALL(") + obj + ", " + call + ") invoked");
+ return function_mocker_->AddNewExpectation(file, line, matchers_);
+ }
+
+ private:
+ template <typename Function>
+ friend class internal::FunctionMocker;
+
+ void SetMatchers(const ArgumentMatcherTuple& matchers) {
+ matchers_ = matchers;
+ }
+
+ // Logs a message including file and line number information.
+ void LogWithLocation(testing::internal::LogSeverity severity,
+ const char* file, int line,
+ const string& message) {
+ ::std::ostringstream s;
+ s << file << ":" << line << ": " << message << ::std::endl;
+ Log(severity, s.str(), 0);
+ }
+
+ // The function mocker that owns this spec.
+ internal::FunctionMockerBase<F>* const function_mocker_;
+ // The argument matchers specified in the spec.
+ ArgumentMatcherTuple matchers_;
+}; // class MockSpec
+
+// MSVC warns about using 'this' in base member initializer list, so
+// we need to temporarily disable the warning. We have to do it for
+// the entire class to suppress the warning, even though it's about
+// the constructor only.
+
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4355) // Temporarily disables warning 4355.
+#endif // _MSV_VER
+
+// The base of the function mocker class for the given function type.
+// We put the methods in this class instead of its child to avoid code
+// bloat.
+template <typename F>
+class FunctionMockerBase : public UntypedFunctionMockerBase {
+ public:
+ typedef typename Function<F>::Result Result;
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+ typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
+
+ FunctionMockerBase() : mock_obj_(NULL), name_(""), current_spec_(this) {}
+
+ // The destructor verifies that all expectations on this mock
+ // function have been satisfied. If not, it will report Google Test
+ // non-fatal failures for the violations.
+ // L < g_gmock_mutex
+ virtual ~FunctionMockerBase() {
+ MutexLock l(&g_gmock_mutex);
+ VerifyAndClearExpectationsLocked();
+ Mock::UnregisterLocked(this);
+ }
+
+ // Returns the ON_CALL spec that matches this mock function with the
+ // given arguments; returns NULL if no matching ON_CALL is found.
+ // L = *
+ const DefaultActionSpec<F>* FindDefaultActionSpec(
+ const ArgumentTuple& args) const {
+ for (typename std::vector<DefaultActionSpec<F> >::const_reverse_iterator it
+ = default_actions_.rbegin();
+ it != default_actions_.rend(); ++it) {
+ const DefaultActionSpec<F>& spec = *it;
+ if (spec.Matches(args))
+ return &spec;
+ }
+
+ return NULL;
+ }
+
+ // Performs the default action of this mock function on the given
+ // arguments and returns the result. This method doesn't depend on
+ // the mutable state of this object, and thus can be called
+ // concurrently without locking.
+ // L = *
+ Result PerformDefaultAction(const ArgumentTuple& args) const {
+ const DefaultActionSpec<F>* const spec = FindDefaultActionSpec(args);
+ return (spec != NULL) ? spec->GetAction().Perform(args)
+ : DefaultValue<Result>::Get();
+ }
+
+ // Registers this function mocker and the mock object owning it;
+ // returns a reference to the function mocker object. This is only
+ // called by the ON_CALL() and EXPECT_CALL() macros.
+ FunctionMocker<F>& RegisterOwner(const void* mock_obj) {
+ Mock::Register(mock_obj, this);
+ return *down_cast<FunctionMocker<F>*>(this);
+ }
+
+ // The following two functions are from UntypedFunctionMockerBase.
+
+ // Verifies that all expectations on this mock function have been
+ // satisfied. Reports one or more Google Test non-fatal failures
+ // and returns false if not.
+ // L >= g_gmock_mutex
+ virtual bool VerifyAndClearExpectationsLocked();
+
+ // Clears the ON_CALL()s set on this mock function.
+ // L >= g_gmock_mutex
+ virtual void ClearDefaultActionsLocked() {
+ g_gmock_mutex.AssertHeld();
+ default_actions_.clear();
+ }
+
+ // Sets the name of the function being mocked. Will be called upon
+ // each invocation of this mock function.
+ // L < g_gmock_mutex
+ void SetOwnerAndName(const void* mock_obj, const char* name) {
+ // We protect name_ under g_gmock_mutex in case this mock function
+ // is called from two threads concurrently.
+ MutexLock l(&g_gmock_mutex);
+ mock_obj_ = mock_obj;
+ name_ = name;
+ }
+
+ // Returns the address of the mock object this method belongs to.
+ // Must be called after SetOwnerAndName() has been called.
+ // L < g_gmock_mutex
+ const void* MockObject() const {
+ const void* mock_obj;
+ {
+ // We protect mock_obj_ under g_gmock_mutex in case this mock
+ // function is called from two threads concurrently.
+ MutexLock l(&g_gmock_mutex);
+ mock_obj = mock_obj_;
+ }
+ return mock_obj;
+ }
+
+ // Returns the name of the function being mocked. Must be called
+ // after SetOwnerAndName() has been called.
+ // L < g_gmock_mutex
+ const char* Name() const {
+ const char* name;
+ {
+ // We protect name_ under g_gmock_mutex in case this mock
+ // function is called from two threads concurrently.
+ MutexLock l(&g_gmock_mutex);
+ name = name_;
+ }
+ return name;
+ }
+ protected:
+ 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);
+ }
+
+ // Adds and returns a default action spec for this mock function.
+ DefaultActionSpec<F>& AddNewDefaultActionSpec(
+ const char* file, int line,
+ const ArgumentMatcherTuple& m) {
+ default_actions_.push_back(DefaultActionSpec<F>(file, line, m));
+ return default_actions_.back();
+ }
+
+ // Adds and returns an expectation spec for this mock function.
+ Expectation<F>& AddNewExpectation(
+ const char* file, int line,
+ const ArgumentMatcherTuple& m) {
+ const linked_ptr<Expectation<F> > expectation(
+ new Expectation<F>(this, file, line, m));
+ expectations_.push_back(expectation);
+
+ // Adds this expectation into the implicit sequence if there is one.
+ Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
+ if (implicit_sequence != NULL) {
+ implicit_sequence->AddExpectation(expectation);
+ }
+
+ return *expectation;
+ }
+
+ // The current spec (either default action spec or expectation spec)
+ // being described on this function mocker.
+ MockSpec<F>& current_spec() { return current_spec_; }
+ private:
+ template <typename Func> friend class Expectation;
+
+ typedef std::vector<internal::linked_ptr<Expectation<F> > > Expectations;
+
+ // Gets the internal::linked_ptr<ExpectationBase> object that co-owns 'exp'.
+ internal::linked_ptr<ExpectationBase> GetLinkedExpectationBase(
+ Expectation<F>* exp) {
+ for (typename Expectations::const_iterator it = expectations_.begin();
+ it != expectations_.end(); ++it) {
+ if (it->get() == exp) {
+ return *it;
+ }
+ }
+
+ Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
+ return internal::linked_ptr<ExpectationBase>(NULL);
+ // The above statement is just to make the code compile, and will
+ // never be executed.
+ }
+
+ // Some utilities needed for implementing InvokeWith().
+
+ // Describes what default action will be performed for the given
+ // arguments.
+ // L = *
+ void DescribeDefaultActionTo(const ArgumentTuple& args,
+ ::std::ostream* os) const {
+ const DefaultActionSpec<F>* const spec = FindDefaultActionSpec(args);
+
+ if (spec == NULL) {
+ *os << (internal::type_equals<Result, void>::value ?
+ "returning directly.\n" :
+ "returning default value.\n");
+ } else {
+ *os << "taking default action specified at:\n"
+ << spec->file() << ":" << spec->line() << ":\n";
+ }
+ }
+
+ // Writes a message that the call is uninteresting (i.e. neither
+ // explicitly expected nor explicitly unexpected) to the given
+ // ostream.
+ // L < g_gmock_mutex
+ void DescribeUninterestingCall(const ArgumentTuple& args,
+ ::std::ostream* os) const {
+ *os << "Uninteresting mock function call - ";
+ DescribeDefaultActionTo(args, os);
+ *os << " Function call: " << Name();
+ UniversalPrinter<ArgumentTuple>::Print(args, os);
+ }
+
+ // Critical section: We must find the matching expectation and the
+ // corresponding action that needs to be taken in an ATOMIC
+ // transaction. Otherwise another thread may call this mock
+ // method in the middle and mess up the state.
+ //
+ // However, performing the action has to be left out of the critical
+ // section. The reason is that we have no control on what the
+ // action does (it can invoke an arbitrary user function or even a
+ // mock function) and excessive locking could cause a dead lock.
+ // L < g_gmock_mutex
+ bool FindMatchingExpectationAndAction(
+ const ArgumentTuple& args, Expectation<F>** exp, Action<F>* action,
+ bool* is_excessive, ::std::ostream* what, ::std::ostream* why) {
+ MutexLock l(&g_gmock_mutex);
+ *exp = this->FindMatchingExpectationLocked(args);
+ if (*exp == NULL) { // A match wasn't found.
+ *action = DoDefault();
+ this->FormatUnexpectedCallMessageLocked(args, what, why);
+ return false;
+ }
+
+ // This line must be done before calling GetActionForArguments(),
+ // which will increment the call count for *exp and thus affect
+ // its saturation status.
+ *is_excessive = (*exp)->IsSaturated();
+ *action = (*exp)->GetActionForArguments(this, args, what, why);
+ return true;
+ }
+
+ // Returns the expectation that matches the arguments, or NULL if no
+ // expectation matches them.
+ // L >= g_gmock_mutex
+ Expectation<F>* FindMatchingExpectationLocked(
+ const ArgumentTuple& args) const {
+ g_gmock_mutex.AssertHeld();
+ for (typename Expectations::const_reverse_iterator it =
+ expectations_.rbegin();
+ it != expectations_.rend(); ++it) {
+ Expectation<F>* const exp = it->get();
+ if (exp->ShouldHandleArguments(args)) {
+ return exp;
+ }
+ }
+ return NULL;
+ }
+
+ // Returns a message that the arguments don't match any expectation.
+ // L >= g_gmock_mutex
+ void FormatUnexpectedCallMessageLocked(const ArgumentTuple& args,
+ ::std::ostream* os,
+ ::std::ostream* why) const {
+ g_gmock_mutex.AssertHeld();
+ *os << "\nUnexpected mock function call - ";
+ DescribeDefaultActionTo(args, os);
+ PrintTriedExpectationsLocked(args, why);
+ }
+
+ // Prints a list of expectations that have been tried against the
+ // current mock function call.
+ // L >= g_gmock_mutex
+ void PrintTriedExpectationsLocked(const ArgumentTuple& args,
+ ::std::ostream* why) const {
+ g_gmock_mutex.AssertHeld();
+ const int count = static_cast<int>(expectations_.size());
+ *why << "Google Mock tried the following " << count << " "
+ << (count == 1 ? "expectation, but it didn't match" :
+ "expectations, but none matched")
+ << ":\n";
+ for (int i = 0; i < count; i++) {
+ *why << "\n";
+ expectations_[i]->DescribeLocationTo(why);
+ if (count > 1) {
+ *why << "tried expectation #" << i;
+ }
+ *why << "\n";
+ expectations_[i]->DescribeMatchResultTo(args, why);
+ expectations_[i]->DescribeCallCountTo(why);
+ }
+ }
+
+ // Address of the mock object this mock method belongs to.
+ const void* mock_obj_; // Protected by g_gmock_mutex.
+
+ // Name of the function being mocked.
+ const char* name_; // Protected by g_gmock_mutex.
+
+ // The current spec (either default action spec or expectation spec)
+ // being described on this function mocker.
+ MockSpec<F> current_spec_;
+
+ // All default action specs for this function mocker.
+ std::vector<DefaultActionSpec<F> > default_actions_;
+ // All expectations for this function mocker.
+ Expectations expectations_;
+}; // class FunctionMockerBase
+
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif // _MSV_VER
+
+// Implements methods of FunctionMockerBase.
+
+// Verifies that all expectations on this mock function have been
+// satisfied. Reports one or more Google Test non-fatal failures and
+// returns false if not.
+// L >= g_gmock_mutex
+template <typename F>
+bool FunctionMockerBase<F>::VerifyAndClearExpectationsLocked() {
+ g_gmock_mutex.AssertHeld();
+ bool expectations_met = true;
+ for (typename Expectations::const_iterator it = expectations_.begin();
+ it != expectations_.end(); ++it) {
+ Expectation<F>* const exp = it->get();
+
+ if (exp->IsOverSaturated()) {
+ // There was an upper-bound violation. Since the error was
+ // already reported when it occurred, there is no need to do
+ // anything here.
+ expectations_met = false;
+ } else if (!exp->IsSatisfied()) {
+ expectations_met = false;
+ ::std::stringstream ss;
+ ss << "Actual function call count doesn't match this expectation.\n";
+ // No need to show the source file location of the expectation
+ // in the description, as the Expect() call that follows already
+ // takes care of it.
+ exp->DescribeCallCountTo(&ss);
+ Expect(false, exp->file(), exp->line(), ss.str());
+ }
+ }
+ expectations_.clear();
+ return expectations_met;
+}
+
+// Reports an uninteresting call (whose description is in msg) in the
+// 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);
+
+ // 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;
+ 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);
+ Result result =
+ action.IsDoDefault() ? mocker->PerformDefaultAction(args)
+ : 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.
+ ::std::stringstream loc;
+ exp->DescribeLocationTo(&loc);
+ 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.
+template <typename F>
+class InvokeWithHelper<void, F> {
+ public:
+ typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+
+ // 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);
+
+ // 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());
+
+ mocker->PerformDefaultAction(args);
+ ReportUninterestingCall(reaction, ss.str());
+ return;
+ }
+
+ bool is_excessive = false;
+ ::std::stringstream ss;
+ ::std::stringstream why;
+ 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);
+ ss << "\n" << why.str();
+ if (action.IsDoDefault()) {
+ mocker->PerformDefaultAction(args);
+ } else {
+ action.Perform(args);
+ }
+
+ 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.
+ ::std::stringstream loc;
+ exp->DescribeLocationTo(&loc);
+ Log(INFO, loc.str() + ss.str(), 3);
+ }
+ } else {
+ // No matching expectation was found - reports an error.
+ Expect(false, NULL, -1, ss.str());
+ }
+ }
+}; // class InvokeWithHelper<void, F>
+
+} // namespace internal
+
+// The style guide prohibits "using" statements in a namespace scope
+// inside a header file. However, the MockSpec class template is
+// meant to be defined in the ::testing namespace. The following line
+// is just a trick for working around a bug in MSVC 8.0, which cannot
+// handle it if we define MockSpec in ::testing.
+using internal::MockSpec;
+
+// Const(x) is a convenient function for obtaining a const reference
+// to x. This is useful for setting expectations on an overloaded
+// const mock method, e.g.
+//
+// class MockFoo : public FooInterface {
+// public:
+// MOCK_METHOD0(Bar, int());
+// MOCK_CONST_METHOD0(Bar, int&());
+// };
+//
+// MockFoo foo;
+// // Expects a call to non-const MockFoo::Bar().
+// EXPECT_CALL(foo, Bar());
+// // Expects a call to const MockFoo::Bar().
+// EXPECT_CALL(Const(foo), Bar());
+template <typename T>
+inline const T& Const(const T& x) { return x; }
+
+} // namespace testing
+
+// A separate macro is required to avoid compile errors when the name
+// of the method used in call is a result of macro expansion.
+// See CompilesWithMethodNameExpandedFromMacro tests in
+// internal/gmock-spec-builders_test.cc for more details.
+#define ON_CALL_IMPL_(obj, call) \
+ ((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \
+ #obj, #call)
+#define ON_CALL(obj, call) ON_CALL_IMPL_(obj, call)
+
+#define EXPECT_CALL_IMPL_(obj, call) \
+ ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
+#define EXPECT_CALL(obj, call) EXPECT_CALL_IMPL_(obj, call)
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
diff --git a/include/gmock/gmock.h b/include/gmock/gmock.h
new file mode 100644
index 00000000..9c9cdd91
--- /dev/null
+++ b/include/gmock/gmock.h
@@ -0,0 +1,92 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This is the main header file a user should include.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
+
+// This file implements the following syntax:
+//
+// ON_CALL(mock_object.Method(...))
+// .WithArguments(...) ?
+// .WillByDefault(...);
+//
+// where WithArguments() is optional and WillByDefault() must appear
+// exactly once.
+//
+// EXPECT_CALL(mock_object.Method(...))
+// .WithArguments(...) ?
+// .Times(...) ?
+// .InSequence(...) *
+// .WillOnce(...) *
+// .WillRepeatedly(...) ?
+// .RetiresOnSaturation() ? ;
+//
+// where all clauses are optional and WillOnce() can be repeated.
+
+#include <gmock/gmock-actions.h>
+#include <gmock/gmock-cardinalities.h>
+#include <gmock/gmock-generated-actions.h>
+#include <gmock/gmock-generated-function-mockers.h>
+#include <gmock/gmock-generated-matchers.h>
+#include <gmock/gmock-generated-nice-strict.h>
+#include <gmock/gmock-matchers.h>
+#include <gmock/gmock-printers.h>
+#include <gmock/internal/gmock-internal-utils.h>
+
+namespace testing {
+
+// Declares Google Mock flags that we want a user to use programmatically.
+GMOCK_DECLARE_string(verbose);
+
+// Initializes Google Mock. This must be called before running the
+// tests. In particular, it parses the command line for the flags
+// that Google Mock recognizes. Whenever a Google Mock flag is seen,
+// it is removed from argv, and *argc is decremented.
+//
+// No value is returned. Instead, the Google Mock flag variables are
+// updated.
+//
+// Since Google Test is needed for Google Mock to work, this function
+// also initializes Google Test and parses its flags, if that hasn't
+// been done.
+void InitGoogleMock(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleMock(int* argc, wchar_t** argv);
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
diff --git a/include/gmock/internal/gmock-generated-internal-utils.h b/include/gmock/internal/gmock-generated-internal-utils.h
new file mode 100644
index 00000000..6386b05a
--- /dev/null
+++ b/include/gmock/internal/gmock-generated-internal-utils.h
@@ -0,0 +1,277 @@
+// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file contains template meta-programming utility classes needed
+// for implementing Google Mock.
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
+
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+template <typename T>
+class Matcher;
+
+namespace internal {
+
+// An IgnoredValue object can be implicitly constructed from ANY value.
+// This is used in implementing the IgnoreResult(a) action.
+class IgnoredValue {
+ public:
+ // This constructor template allows any value to be implicitly
+ // converted to IgnoredValue. The object has no data member and
+ // doesn't try to remember anything about the argument. We
+ // deliberately omit the 'explicit' keyword in order to allow the
+ // conversion to be implicit.
+ template <typename T>
+ IgnoredValue(const T&) {}
+};
+
+// MatcherTuple<T>::type is a tuple type where each field is a Matcher
+// for the corresponding field in tuple type T.
+template <typename Tuple>
+struct MatcherTuple;
+
+template <>
+struct MatcherTuple< ::std::tr1::tuple<> > {
+ typedef ::std::tr1::tuple< > type;
+};
+
+template <typename A1>
+struct MatcherTuple< ::std::tr1::tuple<A1> > {
+ typedef ::std::tr1::tuple<Matcher<A1> > type;
+};
+
+template <typename A1, typename A2>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type;
+};
+
+template <typename A1, typename A2, typename A3>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
+ Matcher<A4> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
+ Matcher<A5> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
+ Matcher<A5>, Matcher<A6> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
+ Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
+ Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8, typename A9>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
+ Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename A7, typename A8, typename A9, typename A10>
+struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
+ A10> > {
+ typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
+ Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
+ Matcher<A10> > type;
+};
+
+// Template struct Function<F>, where F must be a function type, contains
+// the following typedefs:
+//
+// Result: the function's return type.
+// ArgumentN: the type of the N-th argument, where N starts with 1.
+// ArgumentTuple: the tuple type consisting of all parameters of F.
+// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
+// parameters of F.
+// MakeResultVoid: the function type obtained by substituting void
+// for the return type of F.
+// MakeResultIgnoredValue:
+// the function type obtained by substituting Something
+// for the return type of F.
+template <typename F>
+struct Function;
+
+template <typename R>
+struct Function<R()> {
+ typedef R Result;
+ typedef ::std::tr1::tuple<> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid();
+ typedef IgnoredValue MakeResultIgnoredValue();
+};
+
+template <typename R, typename A1>
+struct Function<R(A1)>
+ : Function<R()> {
+ typedef A1 Argument1;
+ typedef ::std::tr1::tuple<A1> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1);
+ typedef IgnoredValue MakeResultIgnoredValue(A1);
+};
+
+template <typename R, typename A1, typename A2>
+struct Function<R(A1, A2)>
+ : Function<R(A1)> {
+ typedef A2 Argument2;
+ typedef ::std::tr1::tuple<A1, A2> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
+};
+
+template <typename R, typename A1, typename A2, typename A3>
+struct Function<R(A1, A2, A3)>
+ : Function<R(A1, A2)> {
+ typedef A3 Argument3;
+ typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+struct Function<R(A1, A2, A3, A4)>
+ : Function<R(A1, A2, A3)> {
+ typedef A4 Argument4;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+struct Function<R(A1, A2, A3, A4, A5)>
+ : Function<R(A1, A2, A3, A4)> {
+ typedef A5 Argument5;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4, A5);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+struct Function<R(A1, A2, A3, A4, A5, A6)>
+ : Function<R(A1, A2, A3, A4, A5)> {
+ typedef A6 Argument6;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7>
+struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
+ : Function<R(A1, A2, A3, A4, A5, A6)> {
+ typedef A7 Argument7;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8>
+struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
+ : Function<R(A1, A2, A3, A4, A5, A6, A7)> {
+ typedef A8 Argument8;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9>
+struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
+ : Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
+ typedef A9 Argument9;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
+ A9);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename A7, typename A8, typename A9,
+ typename A10>
+struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
+ : Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
+ typedef A10 Argument10;
+ typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
+ A10> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
+ typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
+ A9, A10);
+};
+
+} // namespace internal
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
diff --git a/include/gmock/internal/gmock-generated-internal-utils.h.pump b/include/gmock/internal/gmock-generated-internal-utils.h.pump
new file mode 100644
index 00000000..f3128b04
--- /dev/null
+++ b/include/gmock/internal/gmock-generated-internal-utils.h.pump
@@ -0,0 +1,136 @@
+$$ -*- mode: c++; -*-
+$$ This is a Pump source file. Please use Pump to convert it to
+$$ gmock-generated-function-mockers.h.
+$$
+$var n = 10 $$ The maximum arity we support.
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file contains template meta-programming utility classes needed
+// for implementing Google Mock.
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
+
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+template <typename T>
+class Matcher;
+
+namespace internal {
+
+// An IgnoredValue object can be implicitly constructed from ANY value.
+// This is used in implementing the IgnoreResult(a) action.
+class IgnoredValue {
+ public:
+ // This constructor template allows any value to be implicitly
+ // converted to IgnoredValue. The object has no data member and
+ // doesn't try to remember anything about the argument. We
+ // deliberately omit the 'explicit' keyword in order to allow the
+ // conversion to be implicit.
+ template <typename T>
+ IgnoredValue(const T&) {}
+};
+
+// MatcherTuple<T>::type is a tuple type where each field is a Matcher
+// for the corresponding field in tuple type T.
+template <typename Tuple>
+struct MatcherTuple;
+
+
+$range i 0..n
+$for i [[
+$range j 1..i
+$var typename_As = [[$for j, [[typename A$j]]]]
+$var As = [[$for j, [[A$j]]]]
+$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
+template <$typename_As>
+struct MatcherTuple< ::std::tr1::tuple<$As> > {
+ typedef ::std::tr1::tuple<$matcher_As > type;
+};
+
+
+]]
+// Template struct Function<F>, where F must be a function type, contains
+// the following typedefs:
+//
+// Result: the function's return type.
+// ArgumentN: the type of the N-th argument, where N starts with 1.
+// ArgumentTuple: the tuple type consisting of all parameters of F.
+// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
+// parameters of F.
+// MakeResultVoid: the function type obtained by substituting void
+// for the return type of F.
+// MakeResultIgnoredValue:
+// the function type obtained by substituting Something
+// for the return type of F.
+template <typename F>
+struct Function;
+
+template <typename R>
+struct Function<R()> {
+ typedef R Result;
+ typedef ::std::tr1::tuple<> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid();
+ typedef IgnoredValue MakeResultIgnoredValue();
+};
+
+
+$range i 1..n
+$for i [[
+$range j 1..i
+$var typename_As = [[$for j [[, typename A$j]]]]
+$var As = [[$for j, [[A$j]]]]
+$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
+$range k 1..i-1
+$var prev_As = [[$for k, [[A$k]]]]
+template <typename R$typename_As>
+struct Function<R($As)>
+ : Function<R($prev_As)> {
+ typedef A$i Argument$i;
+ typedef ::std::tr1::tuple<$As> ArgumentTuple;
+ typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
+ typedef void MakeResultVoid($As);
+ typedef IgnoredValue MakeResultIgnoredValue($As);
+};
+
+
+]]
+} // namespace internal
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
diff --git a/include/gmock/internal/gmock-internal-utils.h b/include/gmock/internal/gmock-internal-utils.h
new file mode 100644
index 00000000..bdc82882
--- /dev/null
+++ b/include/gmock/internal/gmock-internal-utils.h
@@ -0,0 +1,339 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file defines some utilities useful for implementing Google
+// Mock. They are subject to change without notice, so please DO NOT
+// USE THEM IN USER CODE.
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
+
+#include <stdio.h>
+#include <ostream> // NOLINT
+#include <string>
+
+#include <gmock/internal/gmock-generated-internal-utils.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+// Concatenates two pre-processor symbols; works for concatenating
+// built-in macros like __FILE__ and __LINE__.
+#define GMOCK_CONCAT_TOKEN_IMPL(foo, bar) foo##bar
+#define GMOCK_CONCAT_TOKEN(foo, bar) GMOCK_CONCAT_TOKEN_IMPL(foo, bar)
+
+#ifdef __GNUC__
+#define GMOCK_ATTRIBUTE_UNUSED __attribute__ ((unused))
+#else
+#define GMOCK_ATTRIBUTE_UNUSED
+#endif // __GNUC__
+
+class ProtocolMessage;
+namespace proto2 { class Message; }
+
+namespace testing {
+namespace internal {
+
+// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
+// compiler error iff T1 and T2 are different types.
+template <typename T1, typename T2>
+struct CompileAssertTypesEqual;
+
+template <typename T>
+struct CompileAssertTypesEqual<T, T> {
+};
+
+// Removes the reference from a type if it is a reference type,
+// otherwise leaves it unchanged. This is the same as
+// tr1::remove_reference, which is not widely available yet.
+template <typename T>
+struct RemoveReference { typedef T type; }; // NOLINT
+template <typename T>
+struct RemoveReference<T&> { typedef T type; }; // NOLINT
+
+// A handy wrapper around RemoveReference that works when the argument
+// T depends on template parameters.
+#define GMOCK_REMOVE_REFERENCE(T) \
+ typename ::testing::internal::RemoveReference<T>::type
+
+// Removes const from a type if it is a const type, otherwise leaves
+// it unchanged. This is the same as tr1::remove_const, which is not
+// widely available yet.
+template <typename T>
+struct RemoveConst { typedef T type; }; // NOLINT
+template <typename T>
+struct RemoveConst<const T> { typedef T type; }; // NOLINT
+
+// A handy wrapper around RemoveConst that works when the argument
+// T depends on template parameters.
+#define GMOCK_REMOVE_CONST(T) \
+ typename ::testing::internal::RemoveConst<T>::type
+
+// Adds reference to a type if it is not a reference type,
+// otherwise leaves it unchanged. This is the same as
+// tr1::add_reference, which is not widely available yet.
+template <typename T>
+struct AddReference { typedef T& type; }; // NOLINT
+template <typename T>
+struct AddReference<T&> { typedef T& type; }; // NOLINT
+
+// A handy wrapper around AddReference that works when the argument T
+// depends on template parameters.
+#define GMOCK_ADD_REFERENCE(T) \
+ typename ::testing::internal::AddReference<T>::type
+
+// Adds a reference to const on top of T as necessary. For example,
+// it transforms
+//
+// char ==> const char&
+// const char ==> const char&
+// char& ==> const char&
+// const char& ==> const char&
+//
+// The argument T must depend on some template parameters.
+#define GMOCK_REFERENCE_TO_CONST(T) \
+ GMOCK_ADD_REFERENCE(const GMOCK_REMOVE_REFERENCE(T))
+
+// PointeeOf<Pointer>::type is the type of a value pointed to by a
+// Pointer, which can be either a smart pointer or a raw pointer. The
+// following default implementation is for the case where Pointer is a
+// smart pointer.
+template <typename Pointer>
+struct PointeeOf {
+ // Smart pointer classes define type element_type as the type of
+ // their pointees.
+ typedef typename Pointer::element_type type;
+};
+// This specialization is for the raw pointer case.
+template <typename T>
+struct PointeeOf<T*> { typedef T type; }; // NOLINT
+
+// GetRawPointer(p) returns the raw pointer underlying p when p is a
+// smart pointer, or returns p itself when p is already a raw pointer.
+// The following default implementation is for the smart pointer case.
+template <typename Pointer>
+inline typename Pointer::element_type* GetRawPointer(const Pointer& p) {
+ return p.get();
+}
+// This overloaded version is for the raw pointer case.
+template <typename Element>
+inline Element* GetRawPointer(Element* p) { return p; }
+
+// This comparator allows linked_ptr to be stored in sets.
+template <typename T>
+struct LinkedPtrLessThan {
+ bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
+ const ::testing::internal::linked_ptr<T>& rhs) const {
+ return lhs.get() < rhs.get();
+ }
+};
+
+// ImplicitlyConvertible<From, To>::value is a compile-time bool
+// constant that's true iff type From can be implicitly converted to
+// type To.
+template <typename From, typename To>
+class ImplicitlyConvertible {
+ private:
+ // We need the following helper functions only for their types.
+ // They have no implementations.
+
+ // MakeFrom() is an expression whose type is From. We cannot simply
+ // use From(), as the type From may not have a public default
+ // constructor.
+ static From MakeFrom();
+
+ // These two functions are overloaded. Given an expression
+ // Helper(x), the compiler will pick the first version if x can be
+ // implicitly converted to type To; otherwise it will pick the
+ // second version.
+ //
+ // The first version returns a value of size 1, and the second
+ // version returns a value of size 2. Therefore, by checking the
+ // size of Helper(x), which can be done at compile time, we can tell
+ // which version of Helper() is used, and hence whether x can be
+ // implicitly converted to type To.
+ static char Helper(To);
+ static char (&Helper(...))[2]; // NOLINT
+
+ // We have to put the 'public' section after the 'private' section,
+ // or MSVC refuses to compile the code.
+ public:
+ // MSVC warns about implicitly converting from double to int for
+ // possible loss of data, so we need to temporarily disable the
+ // warning.
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4244) // Temporarily disables warning 4244.
+ static const bool value =
+ sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
+#pragma warning(pop) // Restores the warning state.
+#else
+ static const bool value =
+ sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
+#endif // _MSV_VER
+};
+template <typename From, typename To>
+const bool ImplicitlyConvertible<From, To>::value;
+
+// IsAProtocolMessage<T>::value is a compile-time bool constant that's
+// true iff T is type ProtocolMessage, proto2::Message, or a subclass
+// of those.
+template <typename T>
+struct IsAProtocolMessage {
+ static const bool value =
+ ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
+ ImplicitlyConvertible<const T*, const ::proto2::Message*>::value;
+};
+template <typename T>
+const bool IsAProtocolMessage<T>::value;
+
+// When the compiler sees expression IsContainerTest<C>(0), the first
+// overload of IsContainerTest will be picked if C is an STL-style
+// container class (since C::const_iterator* is a valid type and 0 can
+// be converted to it), while the second overload will be picked
+// otherwise (since C::const_iterator will be an invalid type in this
+// case). Therefore, we can determine whether C is a container class
+// by checking the type of IsContainerTest<C>(0). The value of the
+// expression is insignificant.
+typedef int IsContainer;
+template <class C>
+IsContainer IsContainerTest(typename C::const_iterator*) { return 0; }
+
+typedef char IsNotContainer;
+template <class C>
+IsNotContainer IsContainerTest(...) { return '\0'; }
+
+// This interface knows how to report a Google Mock failure (either
+// non-fatal or fatal).
+class FailureReporterInterface {
+ public:
+ // The type of a failure (either non-fatal or fatal).
+ enum FailureType {
+ NONFATAL, FATAL
+ };
+
+ virtual ~FailureReporterInterface() {}
+
+ // Reports a failure that occurred at the given source file location.
+ virtual void ReportFailure(FailureType type, const char* file, int line,
+ const string& message) = 0;
+};
+
+// Returns the failure reporter used by Google Mock.
+FailureReporterInterface* GetFailureReporter();
+
+// Asserts that condition is true; aborts the process with the given
+// message if condition is false. We cannot use LOG(FATAL) or CHECK()
+// as Google Mock might be used to mock the log sink itself. We
+// inline this function to prevent it from showing up in the stack
+// trace.
+inline void Assert(bool condition, const char* file, int line,
+ const string& msg) {
+ if (!condition) {
+ GetFailureReporter()->ReportFailure(FailureReporterInterface::FATAL,
+ file, line, msg);
+ }
+}
+inline void Assert(bool condition, const char* file, int line) {
+ Assert(condition, file, line, "Assertion failed.");
+}
+
+// Verifies that condition is true; generates a non-fatal failure if
+// condition is false.
+inline void Expect(bool condition, const char* file, int line,
+ const string& msg) {
+ if (!condition) {
+ GetFailureReporter()->ReportFailure(FailureReporterInterface::NONFATAL,
+ file, line, msg);
+ }
+}
+inline void Expect(bool condition, const char* file, int line) {
+ Expect(condition, file, line, "Expectation failed.");
+}
+
+// Severity level of a log.
+enum LogSeverity {
+ INFO = 0,
+ WARNING = 1,
+};
+
+// Valid values for the --gmock_verbose flag.
+
+// All logs (informational and warnings) are printed.
+const char kInfoVerbosity[] = "info";
+// Only warnings are printed.
+const char kWarningVerbosity[] = "warning";
+// No logs are printed.
+const char kErrorVerbosity[] = "error";
+
+// 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
+// stack_frames_to_skip frames. In opt mode, any positive
+// stack_frames_to_skip is treated as 0, since we don't know which
+// function calls will be inlined by the compiler and need to be
+// 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 {};
+
+// Type traits.
+
+// is_reference<T>::value is non-zero iff T is a reference type.
+template <typename T> struct is_reference : public false_type {};
+template <typename T> struct is_reference<T&> : public true_type {};
+
+// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
+template <typename T1, typename T2> struct type_equals : public false_type {};
+template <typename T> struct type_equals<T, T> : public true_type {};
+
+// remove_reference<T>::type removes the reference from type T, if any.
+template <typename T> struct remove_reference { typedef T type; };
+template <typename T> struct remove_reference<T&> { typedef T type; };
+
+// Invalid<T>() returns an invalid value of type T. This is useful
+// when a value of type T is needed for compilation, but the statement
+// will not really be executed (or we don't care if the statement
+// crashes).
+template <typename T>
+inline T Invalid() {
+ return *static_cast<typename remove_reference<T>::type*>(NULL);
+}
+template <>
+inline void Invalid<void>() {}
+
+} // namespace internal
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
diff --git a/include/gmock/internal/gmock-port.h b/include/gmock/internal/gmock-port.h
new file mode 100644
index 00000000..a39f77bc
--- /dev/null
+++ b/include/gmock/internal/gmock-port.h
@@ -0,0 +1,314 @@
+// 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__)
+// GCC 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>
+#else
+// If the compiler is not GCC, we assume the user is using a
+// spec-conforming TR1 implementation.
+#include <tuple>
+#endif // __GNUC__
+
+#ifdef 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.
+#ifdef 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);
+ }
+
+ assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
+ 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
+
+// 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 << " ERROR: Condition " << condition << " failed. ";
+ }
+ ~GMockCheckProvider() {
+ ::std::cerr << ::std::endl;
+ abort();
+ }
+ void FormatFileLocation(const char* file, int line) {
+ if (file == NULL)
+ file = "unknown file";
+ if (line < 0) {
+ ::std::cerr << file << ":";
+ } else {
+#if _MSC_VER
+ ::std::cerr << file << "(" << line << "):";
+#else
+ ::std::cerr << file << ":" << line << ":";
+#endif
+ }
+ }
+ ::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.
+#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_
diff --git a/make/Makefile b/make/Makefile
new file mode 100644
index 00000000..557eb1e1
--- /dev/null
+++ b/make/Makefile
@@ -0,0 +1,109 @@
+# A sample Makefile for building both Google Mock and Google Test and
+# using them in user tests. This file is self-contained, so you don't
+# need to use the Makefile in Google Test's source tree. Please tweak
+# it to suit your environment and project. You may want to move it to
+# your project's root directory.
+#
+# SYNOPSIS:
+#
+# make [all] - makes everything.
+# make TARGET - makes the given target.
+# make clean - removes all files generated by make.
+
+# Please tweak the following variable definitions as needed by your
+# project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use
+# in your own targets but shouldn't modify.
+
+# Points to the root of Google Test, relative to where this file is.
+# Remember to tweak this if you move this file, or if you want to use
+# a copy of Google Test at a different location.
+GTEST_DIR = ../gtest
+
+# Points to the root of Google Mock, relative to where this file is.
+# Remember to tweak this if you move this file.
+GMOCK_DIR = ..
+
+# Where to find user code.
+USER_DIR = ../test
+
+# Flags passed to the preprocessor.
+CPPFLAGS += -I$(GMOCK_DIR) -I$(GMOCK_DIR)/include \
+ -I$(GTEST_DIR) -I$(GTEST_DIR)/include
+
+# Flags passed to the C++ compiler.
+CXXFLAGS += -g
+
+# All tests produced by this Makefile. Remember to add new tests you
+# created to the list.
+TESTS = gmock_link_test gmock_test
+
+# All Google Test headers. Usually you shouldn't change this
+# definition.
+GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
+ $(GTEST_DIR)/include/gtest/internal/*.h
+
+# All Google Mock headers. Note that all Google Test headers are
+# included here too, as they are #included by Google Mock headers.
+# Usually you shouldn't change this definition.
+GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
+ $(GMOCK_DIR)/include/gmock/internal/*.h \
+ $(GTEST_HEADERS)
+
+# House-keeping build targets.
+
+all : $(TESTS)
+
+clean :
+ rm -f $(TESTS) gmock.a gmock_main.a *.o
+
+# Builds gmock.a and gmock_main.a. These libraries contain both
+# Google Mock and Google Test. A test should link with either gmock.a
+# or gmock_main.a, depending on whether it defines its own main()
+# function. It's fine if your test only uses features from Google
+# Test (and not Google Mock).
+
+# Usually you shouldn't tweak such internal variables, indicated by a
+# trailing _.
+GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
+GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
+
+# For simplicity and to avoid depending on implementation details of
+# Google Mock and Google Test, the dependencies specified below are
+# conservative and not optimized. This is fine as Google Mock and
+# Google Test compile fast and for ordinary users their source rarely
+# changes.
+gtest-all.o : $(GTEST_SRCS_)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc
+
+gmock-all.o : $(GMOCK_SRCS_)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock-all.cc
+
+gmock_main.o : $(GMOCK_SRCS_)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock_main.cc
+
+gmock.a : gmock-all.o gtest-all.o
+ $(AR) $(ARFLAGS) $@ $^
+
+gmock_main.a : gmock-all.o gtest-all.o gmock_main.o
+ $(AR) $(ARFLAGS) $@ $^
+
+# Builds a sample test.
+
+gmock-sample.o : $(USER_DIR)/gmock-sample.cc $(USER_DIR)/gmock-sample.h \
+ $(GMOCK_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock-sample.cc
+
+gmock_link_test.o : $(USER_DIR)/gmock_link_test.cc \
+ $(USER_DIR)/gmock-sample.h $(GMOCK_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_link_test.cc
+
+gmock_link_test : gmock-sample.o gmock_link_test.o gmock_main.a
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
+
+# Builds another sample test.
+
+gmock_test.o : $(USER_DIR)/gmock_test.cc $(GMOCK_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_test.cc
+
+gmock_test : gmock_test.o gmock_main.a
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
diff --git a/scripts/generator/COPYING b/scripts/generator/COPYING
new file mode 100644
index 00000000..87ea0636
--- /dev/null
+++ b/scripts/generator/COPYING
@@ -0,0 +1,203 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [2007] Neal Norwitz
+ Portions Copyright [2007] Google Inc.
+
+ 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.
diff --git a/scripts/generator/README b/scripts/generator/README
new file mode 100644
index 00000000..a3ba784b
--- /dev/null
+++ b/scripts/generator/README
@@ -0,0 +1,33 @@
+
+The Google Mock class generator is an application that is part of cppclean.
+For more information about cppclean, see the README.cppclean file or
+visit http://code.google.com/p/cppclean/
+
+cppclean requires Python 2.4 or later. If you don't have Python installed
+on your system, you will also need to install it. You can download Python
+from: http://www.python.org/download/releases/
+
+To use the Google Mock class generator, you need to call it
+on the command line passing the header file and class for which you want
+to generate a Google Mock class.
+
+Make sure to install the scripts somewhere in your path. Then you can
+run the program.
+
+ gmock_gen.py header-file.h ClassName
+
+To change the indentation from the default of 2, set INDENT in
+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.
+
+Known Limitations
+-----------------
+Not all code will be generated properly. For example, when mocking templated
+classes, the template information is lost. You will need to add the template
+information manually.
+
+Not all permutations of using multiple pointers/references will be rendered
+properly. These will also have to be fixed manually.
diff --git a/scripts/generator/README.cppclean b/scripts/generator/README.cppclean
new file mode 100644
index 00000000..65431b61
--- /dev/null
+++ b/scripts/generator/README.cppclean
@@ -0,0 +1,115 @@
+Goal:
+-----
+ CppClean attempts to find problems in C++ source that slow development
+ in large code bases, for example various forms of unused code.
+ Unused code can be unused functions, methods, data members, types, etc
+ to unnecessary #include directives. Unnecessary #includes can cause
+ considerable extra compiles increasing the edit-compile-run cycle.
+
+ The project home page is: http://code.google.com/p/cppclean/
+
+
+Features:
+---------
+ * Find and print C++ language constructs: classes, methods, functions, etc.
+ * Find classes with virtual methods, no virtual destructor, and no bases
+ * Find global/static data that are potential problems when using threads
+ * Unnecessary forward class declarations
+ * Unnecessary function declarations
+ * Undeclared function definitions
+ * (planned) Find unnecessary header files #included
+ - No direct reference to anything in the header
+ - Header is unnecessary if classes were forward declared instead
+ * (planned) Source files that reference headers not directly #included,
+ ie, files that rely on a transitive #include from another header
+ * (planned) Unused members (private, protected, & public) methods and data
+ * (planned) Store AST in a SQL database so relationships can be queried
+
+AST is Abstract Syntax Tree, a representation of parsed source code.
+http://en.wikipedia.org/wiki/Abstract_syntax_tree
+
+
+System Requirements:
+--------------------
+ * Python 2.4 or later (2.3 probably works too)
+ * Works on Windows (untested), Mac OS X, and Unix
+
+
+How to Run:
+-----------
+ For all examples, it is assumed that cppclean resides in a directory called
+ /cppclean.
+
+ To print warnings for classes with virtual methods, no virtual destructor and
+ no base classes:
+
+ /cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
+
+ To print all the functions defined in header file(s):
+
+ /cppclean/run.sh functions.py file1.h file2.h ...
+
+ All the commands take multiple files on the command line. Other programs
+ include: find_warnings, headers, methods, and types. Some other programs
+ are available, but used primarily for debugging.
+
+ run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
+ runs the program in /cppclean/cpp/PROGRAM.py. There is currently
+ no equivalent for Windows. Contributions for a run.bat file
+ would be greatly appreciated.
+
+
+How to Configure:
+-----------------
+ You can add a siteheaders.py file in /cppclean/cpp to configure where
+ to look for other headers (typically -I options passed to a compiler).
+ Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
+ _TRANSITIVE should be set to a boolean value (True or False) indicating
+ whether to transitively process all header files. The default is False.
+
+ GetIncludeDirs is a function that takes a single argument and returns
+ a sequence of directories to include. This can be a generator or
+ return a static list.
+
+ def GetIncludeDirs(filename):
+ return ['/some/path/with/other/headers']
+
+ # Here is a more complicated example.
+ def GetIncludeDirs(filename):
+ yield '/path1'
+ yield os.path.join('/path2', os.path.dirname(filename))
+ yield '/path3'
+
+
+How to Test:
+------------
+ For all examples, it is assumed that cppclean resides in a directory called
+ /cppclean. The tests require
+
+ cd /cppclean
+ make test
+ # To generate expected results after a change:
+ make expected
+
+
+Current Status:
+---------------
+ The parser works pretty well for header files, parsing about 99% of Google's
+ header files. Anything which inspects structure of C++ source files should
+ work reasonably well. Function bodies are not transformed to an AST,
+ but left as tokens. Much work is still needed on finding unused header files
+ and storing an AST in a database.
+
+
+Non-goals:
+----------
+ * Parsing all valid C++ source
+ * Handling invalid C++ source gracefully
+ * Compiling to machine code (or anything beyond an AST)
+
+
+Contact:
+--------
+ If you used cppclean, I would love to hear about your experiences
+ cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
+ hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)
diff --git a/scripts/generator/cpp/__init__.py b/scripts/generator/cpp/__init__.py
new file mode 100755
index 00000000..e69de29b
--- /dev/null
+++ b/scripts/generator/cpp/__init__.py
diff --git a/scripts/generator/cpp/ast.py b/scripts/generator/cpp/ast.py
new file mode 100755
index 00000000..6d1c8d3e
--- /dev/null
+++ b/scripts/generator/cpp/ast.py
@@ -0,0 +1,1713 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Neal Norwitz
+# Portions Copyright 2007 Google Inc.
+#
+# 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.
+
+"""Generate an Abstract Syntax Tree (AST) for C++."""
+
+__author__ = 'nnorwitz@google.com (Neal Norwitz)'
+
+
+# TODO:
+# * Tokens should never be exported, need to convert to Nodes
+# (return types, parameters, etc.)
+# * Handle static class data for templatized classes
+# * Handle casts (both C++ and C-style)
+# * Handle conditions and loops (if/else, switch, for, while/do)
+#
+# TODO much, much later:
+# * Handle #define
+# * exceptions
+
+
+try:
+ # Python 3.x
+ import builtins
+except ImportError:
+ # Python 2.x
+ import __builtin__ as builtins
+
+import sys
+import traceback
+
+from cpp import keywords
+from cpp import tokenize
+from cpp import utils
+
+
+if not hasattr(builtins, 'reversed'):
+ # Support Python 2.3 and earlier.
+ def reversed(seq):
+ for i in range(len(seq)-1, -1, -1):
+ yield seq[i]
+
+if not hasattr(builtins, 'next'):
+ # Support Python 2.5 and earlier.
+ def next(obj):
+ return obj.next()
+
+
+VISIBILITY_PUBLIC, VISIBILITY_PROTECTED, VISIBILITY_PRIVATE = range(3)
+
+FUNCTION_NONE = 0x00
+FUNCTION_CONST = 0x01
+FUNCTION_VIRTUAL = 0x02
+FUNCTION_PURE_VIRTUAL = 0x04
+FUNCTION_CTOR = 0x08
+FUNCTION_DTOR = 0x10
+FUNCTION_ATTRIBUTE = 0x20
+FUNCTION_UNKNOWN_ANNOTATION = 0x40
+FUNCTION_THROW = 0x80
+
+"""
+These are currently unused. Should really handle these properly at some point.
+
+TYPE_MODIFIER_INLINE = 0x010000
+TYPE_MODIFIER_EXTERN = 0x020000
+TYPE_MODIFIER_STATIC = 0x040000
+TYPE_MODIFIER_CONST = 0x080000
+TYPE_MODIFIER_REGISTER = 0x100000
+TYPE_MODIFIER_VOLATILE = 0x200000
+TYPE_MODIFIER_MUTABLE = 0x400000
+
+TYPE_MODIFIER_MAP = {
+ 'inline': TYPE_MODIFIER_INLINE,
+ 'extern': TYPE_MODIFIER_EXTERN,
+ 'static': TYPE_MODIFIER_STATIC,
+ 'const': TYPE_MODIFIER_CONST,
+ 'register': TYPE_MODIFIER_REGISTER,
+ 'volatile': TYPE_MODIFIER_VOLATILE,
+ 'mutable': TYPE_MODIFIER_MUTABLE,
+ }
+"""
+
+_INTERNAL_TOKEN = 'internal'
+_NAMESPACE_POP = 'ns-pop'
+
+
+# TODO(nnorwitz): use this as a singleton for templated_types, etc
+# where we don't want to create a new empty dict each time. It is also const.
+class _NullDict(object):
+ __contains__ = lambda self: False
+ keys = values = items = iterkeys = itervalues = iteritems = lambda self: ()
+
+
+# TODO(nnorwitz): move AST nodes into a separate module.
+class Node(object):
+ """Base AST node."""
+
+ def __init__(self, start, end):
+ self.start = start
+ self.end = end
+
+ def IsDeclaration(self):
+ """Returns bool if this node is a declaration."""
+ return False
+
+ def IsDefinition(self):
+ """Returns bool if this node is a definition."""
+ return False
+
+ def IsExportable(self):
+ """Returns bool if this node exportable from a header file."""
+ return False
+
+ def Requires(self, node):
+ """Does this AST node require the definition of the node passed in?"""
+ return False
+
+ def XXX__str__(self):
+ return self._StringHelper(self.__class__.__name__, '')
+
+ def _StringHelper(self, name, suffix):
+ if not utils.DEBUG:
+ return '%s(%s)' % (name, suffix)
+ return '%s(%d, %d, %s)' % (name, self.start, self.end, suffix)
+
+ def __repr__(self):
+ return str(self)
+
+
+class Define(Node):
+ def __init__(self, start, end, name, definition):
+ Node.__init__(self, start, end)
+ self.name = name
+ self.definition = definition
+
+ def __str__(self):
+ value = '%s %s' % (self.name, self.definition)
+ return self._StringHelper(self.__class__.__name__, value)
+
+
+class Include(Node):
+ def __init__(self, start, end, filename, system):
+ Node.__init__(self, start, end)
+ self.filename = filename
+ self.system = system
+
+ def __str__(self):
+ fmt = '"%s"'
+ if self.system:
+ fmt = '<%s>'
+ return self._StringHelper(self.__class__.__name__, fmt % self.filename)
+
+
+class Goto(Node):
+ def __init__(self, start, end, label):
+ Node.__init__(self, start, end)
+ self.label = label
+
+ def __str__(self):
+ return self._StringHelper(self.__class__.__name__, str(self.label))
+
+
+class Expr(Node):
+ def __init__(self, start, end, expr):
+ Node.__init__(self, start, end)
+ self.expr = expr
+
+ def Requires(self, node):
+ # TODO(nnorwitz): impl.
+ return False
+
+ def __str__(self):
+ return self._StringHelper(self.__class__.__name__, str(self.expr))
+
+
+class Return(Expr):
+ pass
+
+
+class Delete(Expr):
+ pass
+
+
+class Friend(Expr):
+ def __init__(self, start, end, expr, namespace):
+ Expr.__init__(self, start, end, expr)
+ self.namespace = namespace[:]
+
+
+class Using(Node):
+ def __init__(self, start, end, names):
+ Node.__init__(self, start, end)
+ self.names = names
+
+ def __str__(self):
+ return self._StringHelper(self.__class__.__name__, str(self.names))
+
+
+class Parameter(Node):
+ def __init__(self, start, end, name, parameter_type, default):
+ Node.__init__(self, start, end)
+ self.name = name
+ self.type = parameter_type
+ self.default = default
+
+ def Requires(self, node):
+ # TODO(nnorwitz): handle namespaces, etc.
+ return self.type.name == node.name
+
+ def __str__(self):
+ name = str(self.type)
+ suffix = '%s %s' % (name, self.name)
+ if self.default:
+ suffix += ' = ' + ''.join([d.name for d in self.default])
+ return self._StringHelper(self.__class__.__name__, suffix)
+
+
+class _GenericDeclaration(Node):
+ def __init__(self, start, end, name, namespace):
+ Node.__init__(self, start, end)
+ self.name = name
+ self.namespace = namespace[:]
+
+ def FullName(self):
+ prefix = ''
+ if self.namespace and self.namespace[-1]:
+ prefix = '::'.join(self.namespace) + '::'
+ return prefix + self.name
+
+ def _TypeStringHelper(self, suffix):
+ if self.namespace:
+ names = [n or '<anonymous>' for n in self.namespace]
+ suffix += ' in ' + '::'.join(names)
+ return self._StringHelper(self.__class__.__name__, suffix)
+
+
+# TODO(nnorwitz): merge with Parameter in some way?
+class VariableDeclaration(_GenericDeclaration):
+ def __init__(self, start, end, name, var_type, initial_value, namespace):
+ _GenericDeclaration.__init__(self, start, end, name, namespace)
+ self.type = var_type
+ self.initial_value = initial_value
+
+ def Requires(self, node):
+ # TODO(nnorwitz): handle namespaces, etc.
+ return self.type.name == node.name
+
+ def ToString(self):
+ """Return a string that tries to reconstitute the variable decl."""
+ suffix = '%s %s' % (self.type, self.name)
+ if self.initial_value:
+ suffix += ' = ' + self.initial_value
+ return suffix
+
+ def __str__(self):
+ return self._StringHelper(self.__class__.__name__, self.ToString())
+
+
+class Typedef(_GenericDeclaration):
+ def __init__(self, start, end, name, alias, namespace):
+ _GenericDeclaration.__init__(self, start, end, name, namespace)
+ self.alias = alias
+
+ def IsDefinition(self):
+ return True
+
+ def IsExportable(self):
+ return True
+
+ def Requires(self, node):
+ # TODO(nnorwitz): handle namespaces, etc.
+ name = node.name
+ for token in self.alias:
+ if token is not None and name == token.name:
+ return True
+ return False
+
+ def __str__(self):
+ suffix = '%s, %s' % (self.name, self.alias)
+ return self._TypeStringHelper(suffix)
+
+
+class _NestedType(_GenericDeclaration):
+ def __init__(self, start, end, name, fields, namespace):
+ _GenericDeclaration.__init__(self, start, end, name, namespace)
+ self.fields = fields
+
+ def IsDefinition(self):
+ return True
+
+ def IsExportable(self):
+ return True
+
+ def __str__(self):
+ suffix = '%s, {%s}' % (self.name, self.fields)
+ return self._TypeStringHelper(suffix)
+
+
+class Union(_NestedType):
+ pass
+
+
+class Enum(_NestedType):
+ pass
+
+
+class Class(_GenericDeclaration):
+ def __init__(self, start, end, name, bases, templated_types, body, namespace):
+ _GenericDeclaration.__init__(self, start, end, name, namespace)
+ self.bases = bases
+ self.body = body
+ self.templated_types = templated_types
+
+ def IsDeclaration(self):
+ return self.bases is None and self.body is None
+
+ def IsDefinition(self):
+ return not self.IsDeclaration()
+
+ def IsExportable(self):
+ return not self.IsDeclaration()
+
+ def Requires(self, node):
+ # TODO(nnorwitz): handle namespaces, etc.
+ if self.bases:
+ for token_list in self.bases:
+ # TODO(nnorwitz): bases are tokens, do name comparision.
+ for token in token_list:
+ if token.name == node.name:
+ return True
+ # TODO(nnorwitz): search in body too.
+ return False
+
+ def __str__(self):
+ name = self.name
+ if self.templated_types:
+ name += '<%s>' % self.templated_types
+ suffix = '%s, %s, %s' % (name, self.bases, self.body)
+ return self._TypeStringHelper(suffix)
+
+
+class Struct(Class):
+ pass
+
+
+class Function(_GenericDeclaration):
+ def __init__(self, start, end, name, return_type, parameters,
+ modifiers, templated_types, body, namespace):
+ _GenericDeclaration.__init__(self, start, end, name, namespace)
+ converter = TypeConverter(namespace)
+ self.return_type = converter.CreateReturnType(return_type)
+ self.parameters = converter.ToParameters(parameters)
+ self.modifiers = modifiers
+ self.body = body
+ self.templated_types = templated_types
+
+ def IsDeclaration(self):
+ return self.body is None
+
+ def IsDefinition(self):
+ return self.body is not None
+
+ def IsExportable(self):
+ if self.return_type and 'static' in self.return_type.modifiers:
+ return False
+ return None not in self.namespace
+
+ def Requires(self, node):
+ if self.parameters:
+ # TODO(nnorwitz): parameters are tokens, do name comparision.
+ for p in self.parameters:
+ if p.name == node.name:
+ return True
+ # TODO(nnorwitz): search in body too.
+ return False
+
+ def __str__(self):
+ # TODO(nnorwitz): add templated_types.
+ suffix = ('%s %s(%s), 0x%02x, %s' %
+ (self.return_type, self.name, self.parameters,
+ self.modifiers, self.body))
+ return self._TypeStringHelper(suffix)
+
+
+class Method(Function):
+ def __init__(self, start, end, name, in_class, return_type, parameters,
+ modifiers, templated_types, body, namespace):
+ Function.__init__(self, start, end, name, return_type, parameters,
+ modifiers, templated_types, body, namespace)
+ # TODO(nnorwitz): in_class could also be a namespace which can
+ # mess up finding functions properly.
+ self.in_class = in_class
+
+
+class Type(_GenericDeclaration):
+ """Type used for any variable (eg class, primitive, struct, etc)."""
+
+ def __init__(self, start, end, name, templated_types, modifiers,
+ reference, pointer, array):
+ """
+ Args:
+ name: str name of main type
+ templated_types: [Class (Type?)] template type info between <>
+ modifiers: [str] type modifiers (keywords) eg, const, mutable, etc.
+ reference, pointer, array: bools
+ """
+ _GenericDeclaration.__init__(self, start, end, name, [])
+ self.templated_types = templated_types
+ if not name and modifiers:
+ self.name = modifiers.pop()
+ self.modifiers = modifiers
+ self.reference = reference
+ self.pointer = pointer
+ self.array = array
+
+ def __str__(self):
+ prefix = ''
+ if self.modifiers:
+ prefix = ' '.join(self.modifiers) + ' '
+ name = str(self.name)
+ if self.templated_types:
+ name += '<%s>' % self.templated_types
+ suffix = prefix + name
+ if self.reference:
+ suffix += '&'
+ if self.pointer:
+ suffix += '*'
+ if self.array:
+ suffix += '[]'
+ return self._TypeStringHelper(suffix)
+
+ # By definition, Is* are always False. A Type can only exist in
+ # some sort of variable declaration, parameter, or return value.
+ def IsDeclaration(self):
+ return False
+
+ def IsDefinition(self):
+ return False
+
+ def IsExportable(self):
+ return False
+
+
+class TypeConverter(object):
+
+ def __init__(self, namespace_stack):
+ self.namespace_stack = namespace_stack
+
+ def _GetTemplateEnd(self, tokens, start):
+ count = 1
+ end = start
+ while 1:
+ token = tokens[end]
+ end += 1
+ if token.name == '<':
+ count += 1
+ elif token.name == '>':
+ count -= 1
+ if count == 0:
+ break
+ return tokens[start:end-1], end
+
+ def ToType(self, tokens):
+ """Convert [Token,...] to [Class(...), ] useful for base classes.
+ For example, code like class Foo : public Bar<x, y> { ... };
+ the "Bar<x, y>" portion gets converted to an AST.
+
+ Returns:
+ [Class(...), ...]
+ """
+ result = []
+ name_tokens = []
+ reference = pointer = array = False
+
+ def AddType(templated_types):
+ # Partition tokens into name and modifier tokens.
+ names = []
+ modifiers = []
+ for t in name_tokens:
+ if keywords.IsKeyword(t.name):
+ modifiers.append(t.name)
+ else:
+ names.append(t.name)
+ name = ''.join(names)
+ result.append(Type(name_tokens[0].start, name_tokens[-1].end,
+ name, templated_types, modifiers,
+ reference, pointer, array))
+ del name_tokens[:]
+
+ i = 0
+ end = len(tokens)
+ while i < end:
+ token = tokens[i]
+ if token.name == '<':
+ new_tokens, new_end = self._GetTemplateEnd(tokens, i+1)
+ AddType(self.ToType(new_tokens))
+ # If there is a comma after the template, we need to consume
+ # that here otherwise it becomes part of the name.
+ i = new_end
+ reference = pointer = array = False
+ elif token.name == ',':
+ AddType([])
+ reference = pointer = array = False
+ elif token.name == '*':
+ pointer = True
+ elif token.name == '&':
+ reference = True
+ elif token.name == '[':
+ pointer = True
+ elif token.name == ']':
+ pass
+ else:
+ name_tokens.append(token)
+ i += 1
+
+ if name_tokens:
+ # No '<' in the tokens, just a simple name and no template.
+ AddType([])
+ return result
+
+ def DeclarationToParts(self, parts, needs_name_removed):
+ name = None
+ default = []
+ if needs_name_removed:
+ # Handle default (initial) values properly.
+ for i, t in enumerate(parts):
+ if t.name == '=':
+ default = parts[i+1:]
+ name = parts[i-1].name
+ if name == ']' and parts[i-2].name == '[':
+ name = parts[i-3].name
+ i -= 1
+ parts = parts[:i-1]
+ break
+ else:
+ if parts[-1].token_type == tokenize.NAME:
+ name = parts.pop().name
+ else:
+ # TODO(nnorwitz): this is a hack that happens for code like
+ # Register(Foo<T>); where it thinks this is a function call
+ # but it's actually a declaration.
+ name = '???'
+ modifiers = []
+ type_name = []
+ other_tokens = []
+ templated_types = []
+ i = 0
+ end = len(parts)
+ while i < end:
+ p = parts[i]
+ if keywords.IsKeyword(p.name):
+ modifiers.append(p.name)
+ elif p.name == '<':
+ templated_tokens, new_end = self._GetTemplateEnd(parts, i+1)
+ templated_types = self.ToType(templated_tokens)
+ i = new_end - 1
+ # Don't add a spurious :: to data members being initialized.
+ next_index = i + 1
+ if next_index < end and parts[next_index].name == '::':
+ i += 1
+ elif p.name in ('[', ']', '='):
+ # These are handled elsewhere.
+ other_tokens.append(p)
+ elif p.name not in ('*', '&', '>'):
+ # Ensure that names have a space between them.
+ if (type_name and type_name[-1].token_type == tokenize.NAME and
+ p.token_type == tokenize.NAME):
+ type_name.append(tokenize.Token(tokenize.SYNTAX, ' ', 0, 0))
+ type_name.append(p)
+ else:
+ other_tokens.append(p)
+ i += 1
+ type_name = ''.join([t.name for t in type_name])
+ return name, type_name, templated_types, modifiers, default, other_tokens
+
+ def ToParameters(self, tokens):
+ if not tokens:
+ return []
+
+ result = []
+ name = type_name = ''
+ type_modifiers = []
+ pointer = reference = array = False
+ first_token = None
+ default = []
+
+ def AddParameter():
+ if default:
+ del default[0] # Remove flag.
+ end = type_modifiers[-1].end
+ parts = self.DeclarationToParts(type_modifiers, True)
+ (name, type_name, templated_types, modifiers,
+ unused_default, unused_other_tokens) = parts
+ parameter_type = Type(first_token.start, first_token.end,
+ type_name, templated_types, modifiers,
+ reference, pointer, array)
+ p = Parameter(first_token.start, end, name,
+ parameter_type, default)
+ result.append(p)
+
+ template_count = 0
+ for s in tokens:
+ if not first_token:
+ first_token = s
+ if s.name == '<':
+ template_count += 1
+ elif s.name == '>':
+ template_count -= 1
+ if template_count > 0:
+ type_modifiers.append(s)
+ continue
+
+ if s.name == ',':
+ AddParameter()
+ name = type_name = ''
+ type_modifiers = []
+ pointer = reference = array = False
+ first_token = None
+ default = []
+ elif s.name == '*':
+ pointer = True
+ elif s.name == '&':
+ reference = True
+ elif s.name == '[':
+ array = True
+ elif s.name == ']':
+ pass # Just don't add to type_modifiers.
+ elif s.name == '=':
+ # Got a default value. Add any value (None) as a flag.
+ default.append(None)
+ elif default:
+ default.append(s)
+ else:
+ type_modifiers.append(s)
+ AddParameter()
+ return result
+
+ def CreateReturnType(self, return_type_seq):
+ if not return_type_seq:
+ return None
+ start = return_type_seq[0].start
+ end = return_type_seq[-1].end
+ _, name, templated_types, modifiers, default, other_tokens = \
+ self.DeclarationToParts(return_type_seq, False)
+ names = [n.name for n in other_tokens]
+ reference = '&' in names
+ pointer = '*' in names
+ array = '[' in names
+ return Type(start, end, name, templated_types, modifiers,
+ reference, pointer, array)
+
+ def GetTemplateIndices(self, names):
+ # names is a list of strings.
+ start = names.index('<')
+ end = len(names) - 1
+ while end > 0:
+ if names[end] == '>':
+ break
+ end -= 1
+ return start, end+1
+
+class AstBuilder(object):
+ def __init__(self, token_stream, filename, in_class='', visibility=None,
+ namespace_stack=[]):
+ self.tokens = token_stream
+ self.filename = filename
+ # TODO(nnorwitz): use a better data structure (deque) for the queue.
+ # Switching directions of the "queue" improved perf by about 25%.
+ # Using a deque should be even better since we access from both sides.
+ self.token_queue = []
+ self.namespace_stack = namespace_stack[:]
+ self.in_class = in_class
+ if in_class is None:
+ self.in_class_name_only = None
+ else:
+ self.in_class_name_only = in_class.split('::')[-1]
+ self.visibility = visibility
+ self.in_function = False
+ self.current_token = None
+ # Keep the state whether we are currently handling a typedef or not.
+ self._handling_typedef = False
+
+ self.converter = TypeConverter(self.namespace_stack)
+
+ def HandleError(self, msg, token):
+ printable_queue = list(reversed(self.token_queue[-20:]))
+ sys.stderr.write('Got %s in %s @ %s %s\n' %
+ (msg, self.filename, token, printable_queue))
+
+ def Generate(self):
+ while 1:
+ token = self._GetNextToken()
+ if not token:
+ break
+
+ # Get the next token.
+ self.current_token = token
+
+ # Dispatch on the next token type.
+ if token.token_type == _INTERNAL_TOKEN:
+ if token.name == _NAMESPACE_POP:
+ self.namespace_stack.pop()
+ continue
+
+ try:
+ result = self._GenerateOne(token)
+ if result is not None:
+ yield result
+ except:
+ self.HandleError('exception', token)
+ raise
+
+ def _CreateVariable(self, pos_token, name, type_name, type_modifiers,
+ ref_pointer_name_seq, templated_types, value=None):
+ reference = '&' in ref_pointer_name_seq
+ pointer = '*' in ref_pointer_name_seq
+ array = '[' in ref_pointer_name_seq
+ var_type = Type(pos_token.start, pos_token.end, type_name,
+ templated_types, type_modifiers,
+ reference, pointer, array)
+ return VariableDeclaration(pos_token.start, pos_token.end,
+ name, var_type, value, self.namespace_stack)
+
+ def _GenerateOne(self, token):
+ if token.token_type == tokenize.NAME:
+ if (keywords.IsKeyword(token.name) and
+ not keywords.IsBuiltinType(token.name)):
+ method = getattr(self, 'handle_' + token.name)
+ return method()
+ elif token.name == self.in_class_name_only:
+ # The token name is the same as the class, must be a ctor if
+ # there is a paren. Otherwise, it's the return type.
+ # Peek ahead to get the next token to figure out which.
+ next = self._GetNextToken()
+ self._AddBackToken(next)
+ if next.token_type == tokenize.SYNTAX and next.name == '(':
+ return self._GetMethod([token], FUNCTION_CTOR, None, True)
+ # Fall through--handle like any other method.
+
+ # Handle data or function declaration/definition.
+ syntax = tokenize.SYNTAX
+ temp_tokens, last_token = \
+ self._GetVarTokensUpTo(syntax, '(', ';', '{', '[')
+ temp_tokens.insert(0, token)
+ if last_token.name == '(':
+ # If there is an assignment before the paren,
+ # this is an expression, not a method.
+ expr = bool([e for e in temp_tokens if e.name == '='])
+ if expr:
+ new_temp = self._GetTokensUpTo(tokenize.SYNTAX, ';')
+ temp_tokens.append(last_token)
+ temp_tokens.extend(new_temp)
+ last_token = tokenize.Token(tokenize.SYNTAX, ';', 0, 0)
+
+ if last_token.name == '[':
+ # Handle array, this isn't a method, unless it's an operator.
+ # TODO(nnorwitz): keep the size somewhere.
+ # unused_size = self._GetTokensUpTo(tokenize.SYNTAX, ']')
+ temp_tokens.append(last_token)
+ if temp_tokens[-2].name == 'operator':
+ temp_tokens.append(self._GetNextToken())
+ else:
+ temp_tokens2, last_token = \
+ self._GetVarTokensUpTo(tokenize.SYNTAX, ';')
+ temp_tokens.extend(temp_tokens2)
+
+ if last_token.name == ';':
+ # Handle data, this isn't a method.
+ 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:
+ start, end = self.converter.GetTemplateIndices(names)
+ names = names[:start] + names[end:]
+ default = ''.join([t.name for t in default])
+ return self._CreateVariable(t0, name, type_name, modifiers,
+ names, templated_types, default)
+ if last_token.name == '{':
+ self._AddBackTokens(temp_tokens[1:])
+ self._AddBackToken(last_token)
+ method_name = temp_tokens[0].name
+ method = getattr(self, 'handle_' + method_name, None)
+ if not method:
+ # Must be declaring a variable.
+ # TODO(nnorwitz): handle the declaration.
+ return None
+ return method()
+ return self._GetMethod(temp_tokens, 0, None, False)
+ elif token.token_type == tokenize.SYNTAX:
+ if token.name == '~' and self.in_class:
+ # Must be a dtor (probably not in method body).
+ token = self._GetNextToken()
+ # self.in_class can contain A::Name, but the dtor will only
+ # be Name. Make sure to compare against the right value.
+ if (token.token_type == tokenize.NAME and
+ token.name == self.in_class_name_only):
+ return self._GetMethod([token], FUNCTION_DTOR, None, True)
+ # TODO(nnorwitz): handle a lot more syntax.
+ elif token.token_type == tokenize.PREPROCESSOR:
+ # TODO(nnorwitz): handle more preprocessor directives.
+ # token starts with a #, so remove it and strip whitespace.
+ name = token.name[1:].lstrip()
+ if name.startswith('include'):
+ # Remove "include".
+ name = name[7:].strip()
+ assert name
+ # Handle #include \<newline> "header-on-second-line.h".
+ if name.startswith('\\'):
+ name = name[1:].strip()
+ assert name[0] in '<"', token
+ assert name[-1] in '>"', token
+ system = name[0] == '<'
+ filename = name[1:-1]
+ return Include(token.start, token.end, filename, system)
+ if name.startswith('define'):
+ # Remove "define".
+ name = name[6:].strip()
+ assert name
+ value = ''
+ for i, c in enumerate(name):
+ if c.isspace():
+ value = name[i:].lstrip()
+ name = name[:i]
+ break
+ return Define(token.start, token.end, name, value)
+ if name.startswith('if') and name[2:3].isspace():
+ condition = name[3:].strip()
+ if condition.startswith('0') or condition.startswith('(0)'):
+ self._SkipIf0Blocks()
+ return None
+
+ def _GetTokensUpTo(self, expected_token_type, expected_token):
+ return self._GetVarTokensUpTo(expected_token_type, expected_token)[0]
+
+ def _GetVarTokensUpTo(self, expected_token_type, *expected_tokens):
+ last_token = self._GetNextToken()
+ tokens = []
+ while (last_token.token_type != expected_token_type or
+ last_token.name not in expected_tokens):
+ tokens.append(last_token)
+ last_token = self._GetNextToken()
+ return tokens, last_token
+
+ # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary.
+ def _IgnoreUpTo(self, token_type, token):
+ unused_tokens = self._GetTokensUpTo(token_type, token)
+
+ def _SkipIf0Blocks(self):
+ count = 1
+ while 1:
+ token = self._GetNextToken()
+ if token.token_type != tokenize.PREPROCESSOR:
+ continue
+
+ name = token.name[1:].lstrip()
+ if name.startswith('endif'):
+ count -= 1
+ if count == 0:
+ break
+ elif name.startswith('if'):
+ count += 1
+
+ def _GetMatchingChar(self, open_paren, close_paren, GetNextToken=None):
+ if GetNextToken is None:
+ GetNextToken = self._GetNextToken
+ # Assumes the current token is open_paren and we will consume
+ # and return up to the close_paren.
+ count = 1
+ token = GetNextToken()
+ while 1:
+ if token.token_type == tokenize.SYNTAX:
+ if token.name == open_paren:
+ count += 1
+ elif token.name == close_paren:
+ count -= 1
+ if count == 0:
+ break
+ yield token
+ token = GetNextToken()
+ yield token
+
+ def _GetParameters(self):
+ return self._GetMatchingChar('(', ')')
+
+ def GetScope(self):
+ return self._GetMatchingChar('{', '}')
+
+ def _GetNextToken(self):
+ if self.token_queue:
+ return self.token_queue.pop()
+ return next(self.tokens)
+
+ def _AddBackToken(self, token):
+ if token.whence == tokenize.WHENCE_STREAM:
+ token.whence = tokenize.WHENCE_QUEUE
+ self.token_queue.insert(0, token)
+ else:
+ assert token.whence == tokenize.WHENCE_QUEUE, token
+ self.token_queue.append(token)
+
+ def _AddBackTokens(self, tokens):
+ if tokens:
+ if tokens[-1].whence == tokenize.WHENCE_STREAM:
+ for token in tokens:
+ token.whence = tokenize.WHENCE_QUEUE
+ self.token_queue[:0] = reversed(tokens)
+ else:
+ assert tokens[-1].whence == tokenize.WHENCE_QUEUE, tokens
+ self.token_queue.extend(reversed(tokens))
+
+ def GetName(self, seq=None):
+ """Returns ([tokens], next_token_info)."""
+ GetNextToken = self._GetNextToken
+ if seq is not None:
+ it = iter(seq)
+ GetNextToken = lambda: next(it)
+ next_token = GetNextToken()
+ tokens = []
+ last_token_was_name = False
+ while (next_token.token_type == tokenize.NAME or
+ (next_token.token_type == tokenize.SYNTAX and
+ next_token.name in ('::', '<'))):
+ # Two NAMEs in a row means the identifier should terminate.
+ # It's probably some sort of variable declaration.
+ if last_token_was_name and next_token.token_type == tokenize.NAME:
+ break
+ last_token_was_name = next_token.token_type == tokenize.NAME
+ tokens.append(next_token)
+ # Handle templated names.
+ if next_token.name == '<':
+ tokens.extend(self._GetMatchingChar('<', '>', GetNextToken))
+ last_token_was_name = True
+ next_token = GetNextToken()
+ return tokens, next_token
+
+ def GetMethod(self, modifiers, templated_types):
+ return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(')
+ assert len(return_type_and_name) >= 1
+ return self._GetMethod(return_type_and_name, modifiers, templated_types,
+ False)
+
+ def _GetMethod(self, return_type_and_name, modifiers, templated_types,
+ get_paren):
+ template_portion = None
+ if get_paren:
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.SYNTAX, token
+ if token.name == '<':
+ # Handle templatized dtors.
+ template_portion = [token]
+ template_portion.extend(self._GetMatchingChar('<', '>'))
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.SYNTAX, token
+ assert token.name == '(', token
+
+ name = return_type_and_name.pop()
+ # Handle templatized ctors.
+ if name.name == '>':
+ index = 1
+ while return_type_and_name[index].name != '<':
+ index += 1
+ template_portion = return_type_and_name[index:] + [name]
+ del return_type_and_name[index:]
+ name = return_type_and_name.pop()
+ elif name.name == ']':
+ rt = return_type_and_name
+ assert rt[-1].name == '[', return_type_and_name
+ assert rt[-2].name == 'operator', return_type_and_name
+ name_seq = return_type_and_name[-2:]
+ del return_type_and_name[-2:]
+ name = tokenize.Token(tokenize.NAME, 'operator[]',
+ name_seq[0].start, name.end)
+ # Get the open paren so _GetParameters() below works.
+ unused_open_paren = self._GetNextToken()
+
+ # TODO(nnorwitz): store template_portion.
+ return_type = return_type_and_name
+ indices = name
+ if return_type:
+ indices = return_type[0]
+
+ # Force ctor for templatized ctors.
+ if name.name == self.in_class and not modifiers:
+ modifiers |= FUNCTION_CTOR
+ parameters = list(self._GetParameters())
+ del parameters[-1] # Remove trailing ')'.
+
+ # Handling operator() is especially weird.
+ if name.name == 'operator' and not parameters:
+ token = self._GetNextToken()
+ assert token.name == '(', token
+ parameters = list(self._GetParameters())
+ del parameters[-1] # Remove trailing ')'.
+
+ token = self._GetNextToken()
+ while token.token_type == tokenize.NAME:
+ modifier_token = token
+ token = self._GetNextToken()
+ if modifier_token.name == 'const':
+ modifiers |= FUNCTION_CONST
+ elif modifier_token.name == '__attribute__':
+ # TODO(nnorwitz): handle more __attribute__ details.
+ modifiers |= FUNCTION_ATTRIBUTE
+ assert token.name == '(', token
+ # Consume everything between the (parens).
+ unused_tokens = list(self._GetMatchingChar('(', ')'))
+ token = self._GetNextToken()
+ elif modifier_token.name == 'throw':
+ modifiers |= FUNCTION_THROW
+ assert token.name == '(', token
+ # Consume everything between the (parens).
+ unused_tokens = list(self._GetMatchingChar('(', ')'))
+ token = self._GetNextToken()
+ elif modifier_token.name == modifier_token.name.upper():
+ # HACK(nnorwitz): assume that all upper-case names
+ # are some macro we aren't expanding.
+ modifiers |= FUNCTION_UNKNOWN_ANNOTATION
+ else:
+ self.HandleError('unexpected token', modifier_token)
+
+ assert token.token_type == tokenize.SYNTAX, token
+ # Handle ctor initializers.
+ if token.name == ':':
+ # TODO(nnorwitz): anything else to handle for initializer list?
+ while token.name != ';' and token.name != '{':
+ token = self._GetNextToken()
+
+ # Handle pointer to functions that are really data but look
+ # like method declarations.
+ if token.name == '(':
+ if parameters[0].name == '*':
+ # name contains the return type.
+ name = parameters.pop()
+ # parameters contains the name of the data.
+ modifiers = [p.name for p in parameters]
+ # Already at the ( to open the parameter list.
+ function_parameters = list(self._GetMatchingChar('(', ')'))
+ del function_parameters[-1] # Remove trailing ')'.
+ # TODO(nnorwitz): store the function_parameters.
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.SYNTAX, token
+ assert token.name == ';', token
+ return self._CreateVariable(indices, name.name, indices.name,
+ modifiers, '', None)
+ # At this point, we got something like:
+ # return_type (type::*name_)(params);
+ # This is a data member called name_ that is a function pointer.
+ # With this code: void (sq_type::*field_)(string&);
+ # We get: name=void return_type=[] parameters=sq_type ... field_
+ # TODO(nnorwitz): is return_type always empty?
+ # TODO(nnorwitz): this isn't even close to being correct.
+ # Just put in something so we don't crash and can move on.
+ real_name = parameters[-1]
+ modifiers = [p.name for p in self._GetParameters()]
+ del modifiers[-1] # Remove trailing ')'.
+ return self._CreateVariable(indices, real_name.name, indices.name,
+ modifiers, '', None)
+
+ if token.name == '{':
+ body = list(self.GetScope())
+ del body[-1] # Remove trailing '}'.
+ else:
+ body = None
+ if token.name == '=':
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.CONSTANT, token
+ assert token.name == '0', token
+ modifiers |= FUNCTION_PURE_VIRTUAL
+ token = self._GetNextToken()
+
+ if token.name == '[':
+ # TODO(nnorwitz): store tokens and improve parsing.
+ # template <typename T, size_t N> char (&ASH(T (&seq)[N]))[N];
+ tokens = list(self._GetMatchingChar('[', ']'))
+ token = self._GetNextToken()
+
+ assert token.name == ';', (token, return_type_and_name, parameters)
+
+ # Looks like we got a method, not a function.
+ if len(return_type) > 2 and return_type[-1].name == '::':
+ return_type, in_class = \
+ self._GetReturnTypeAndClassName(return_type)
+ return Method(indices.start, indices.end, name.name, in_class,
+ return_type, parameters, modifiers, templated_types,
+ body, self.namespace_stack)
+ return Function(indices.start, indices.end, name.name, return_type,
+ parameters, modifiers, templated_types, body,
+ self.namespace_stack)
+
+ def _GetReturnTypeAndClassName(self, token_seq):
+ # Splitting the return type from the class name in a method
+ # can be tricky. For example, Return::Type::Is::Hard::To::Find().
+ # Where is the return type and where is the class name?
+ # The heuristic used is to pull the last name as the class name.
+ # This includes all the templated type info.
+ # TODO(nnorwitz): if there is only One name like in the
+ # example above, punt and assume the last bit is the class name.
+
+ # Ignore a :: prefix, if exists so we can find the first real name.
+ i = 0
+ if token_seq[0].name == '::':
+ i = 1
+ # Ignore a :: suffix, if exists.
+ end = len(token_seq) - 1
+ if token_seq[end-1].name == '::':
+ end -= 1
+
+ # Make a copy of the sequence so we can append a sentinel
+ # value. This is required for GetName will has to have some
+ # terminating condition beyond the last name.
+ seq_copy = token_seq[i:end]
+ seq_copy.append(tokenize.Token(tokenize.SYNTAX, '', 0, 0))
+ names = []
+ while i < end:
+ # Iterate through the sequence parsing out each name.
+ new_name, next = self.GetName(seq_copy[i:])
+ assert new_name, 'Got empty new_name, next=%s' % next
+ # We got a pointer or ref. Add it to the name.
+ if next and next.token_type == tokenize.SYNTAX:
+ new_name.append(next)
+ names.append(new_name)
+ i += len(new_name)
+
+ # Now that we have the names, it's time to undo what we did.
+
+ # Remove the sentinel value.
+ names[-1].pop()
+ # Flatten the token sequence for the return type.
+ return_type = [e for seq in names[:-1] for e in seq]
+ # The class name is the last name.
+ class_name = names[-1]
+ return return_type, class_name
+
+ def handle_bool(self):
+ pass
+
+ def handle_char(self):
+ pass
+
+ def handle_int(self):
+ pass
+
+ def handle_long(self):
+ pass
+
+ def handle_short(self):
+ pass
+
+ def handle_double(self):
+ pass
+
+ def handle_float(self):
+ pass
+
+ def handle_void(self):
+ pass
+
+ def handle_wchar_t(self):
+ pass
+
+ def handle_unsigned(self):
+ pass
+
+ def handle_signed(self):
+ pass
+
+ def _GetNestedType(self, ctor):
+ name = None
+ name_tokens, token = self.GetName()
+ if name_tokens:
+ name = ''.join([t.name for t in name_tokens])
+
+ # Handle forward declarations.
+ if token.token_type == tokenize.SYNTAX and token.name == ';':
+ return ctor(token.start, token.end, name, None,
+ self.namespace_stack)
+
+ if token.token_type == tokenize.NAME and self._handling_typedef:
+ self._AddBackToken(token)
+ return ctor(token.start, token.end, name, None,
+ self.namespace_stack)
+
+ # Must be the type declaration.
+ fields = list(self._GetMatchingChar('{', '}'))
+ del fields[-1] # Remove trailing '}'.
+ if token.token_type == tokenize.SYNTAX and token.name == '{':
+ next = self._GetNextToken()
+ new_type = ctor(token.start, token.end, name, fields,
+ self.namespace_stack)
+ # A name means this is an anonymous type and the name
+ # is the variable declaration.
+ if next.token_type != tokenize.NAME:
+ return new_type
+ name = new_type
+ token = next
+
+ # Must be variable declaration using the type prefixed with keyword.
+ assert token.token_type == tokenize.NAME, token
+ return self._CreateVariable(token, token.name, name, [], '', None)
+
+ def handle_struct(self):
+ # Special case the handling typedef/aliasing of structs here.
+ # It would be a pain to handle in the class code.
+ name_tokens, var_token = self.GetName()
+ if name_tokens:
+ next_token = self._GetNextToken()
+ is_syntax = (var_token.token_type == tokenize.SYNTAX and
+ var_token.name[0] in '*&')
+ is_variable = (var_token.token_type == tokenize.NAME and
+ next_token.name == ';')
+ variable = var_token
+ if is_syntax and not is_variable:
+ variable = next_token
+ temp = self._GetNextToken()
+ if temp.token_type == tokenize.SYNTAX and temp.name == '(':
+ # Handle methods declared to return a struct.
+ t0 = name_tokens[0]
+ struct = tokenize.Token(tokenize.NAME, 'struct',
+ t0.start-7, t0.start-2)
+ type_and_name = [struct]
+ type_and_name.extend(name_tokens)
+ type_and_name.extend((var_token, next_token))
+ return self._GetMethod(type_and_name, 0, None, False)
+ assert temp.name == ';', (temp, name_tokens, var_token)
+ if is_syntax or (is_variable and not self._handling_typedef):
+ modifiers = ['struct']
+ type_name = ''.join([t.name for t in name_tokens])
+ position = name_tokens[0]
+ return self._CreateVariable(position, variable.name, type_name,
+ modifiers, var_token.name, None)
+ name_tokens.extend((var_token, next_token))
+ self._AddBackTokens(name_tokens)
+ else:
+ self._AddBackToken(var_token)
+ return self._GetClass(Struct, VISIBILITY_PUBLIC, None)
+
+ def handle_union(self):
+ return self._GetNestedType(Union)
+
+ def handle_enum(self):
+ return self._GetNestedType(Enum)
+
+ def handle_auto(self):
+ # TODO(nnorwitz): warn about using auto? Probably not since it
+ # will be reclaimed and useful for C++0x.
+ pass
+
+ def handle_register(self):
+ pass
+
+ def handle_const(self):
+ pass
+
+ def handle_inline(self):
+ pass
+
+ def handle_extern(self):
+ pass
+
+ def handle_static(self):
+ pass
+
+ def handle_virtual(self):
+ # What follows must be a method.
+ token = token2 = self._GetNextToken()
+ if token.name == 'inline':
+ # HACK(nnorwitz): handle inline dtors by ignoring 'inline'.
+ token2 = self._GetNextToken()
+ if token2.token_type == tokenize.SYNTAX and token2.name == '~':
+ return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None)
+ assert token.token_type == tokenize.NAME or token.name == '::', token
+ return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(')
+ return_type_and_name.insert(0, token)
+ if token2 is not token:
+ return_type_and_name.insert(1, token2)
+ return self._GetMethod(return_type_and_name, FUNCTION_VIRTUAL,
+ None, False)
+
+ def handle_volatile(self):
+ pass
+
+ def handle_mutable(self):
+ pass
+
+ def handle_public(self):
+ assert self.in_class
+ self.visibility = VISIBILITY_PUBLIC
+
+ def handle_protected(self):
+ assert self.in_class
+ self.visibility = VISIBILITY_PROTECTED
+
+ def handle_private(self):
+ assert self.in_class
+ self.visibility = VISIBILITY_PRIVATE
+
+ def handle_friend(self):
+ tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
+ assert tokens
+ t0 = tokens[0]
+ return Friend(t0.start, t0.end, tokens, self.namespace_stack)
+
+ def handle_static_cast(self):
+ pass
+
+ def handle_const_cast(self):
+ pass
+
+ def handle_dynamic_cast(self):
+ pass
+
+ def handle_reinterpret_cast(self):
+ pass
+
+ def handle_new(self):
+ pass
+
+ def handle_delete(self):
+ tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
+ assert tokens
+ return Delete(tokens[0].start, tokens[0].end, tokens)
+
+ def handle_typedef(self):
+ token = self._GetNextToken()
+ if (token.token_type == tokenize.NAME and
+ keywords.IsKeyword(token.name)):
+ # Token must be struct/enum/union/class.
+ method = getattr(self, 'handle_' + token.name)
+ self._handling_typedef = True
+ tokens = [method()]
+ self._handling_typedef = False
+ else:
+ tokens = [token]
+
+ # Get the remainder of the typedef up to the semi-colon.
+ tokens.extend(self._GetTokensUpTo(tokenize.SYNTAX, ';'))
+
+ # TODO(nnorwitz): clean all this up.
+ assert tokens
+ name = tokens.pop()
+ indices = name
+ if tokens:
+ indices = tokens[0]
+ if not indices:
+ indices = token
+ if name.name == ')':
+ # HACK(nnorwitz): Handle pointers to functions "properly".
+ if (len(tokens) >= 4 and
+ tokens[1].name == '(' and tokens[2].name == '*'):
+ tokens.append(name)
+ name = tokens[3]
+ elif name.name == ']':
+ # HACK(nnorwitz): Handle arrays properly.
+ if len(tokens) >= 2:
+ tokens.append(name)
+ name = tokens[1]
+ new_type = tokens
+ if tokens and isinstance(tokens[0], tokenize.Token):
+ new_type = self.converter.ToType(tokens)[0]
+ return Typedef(indices.start, indices.end, name.name,
+ new_type, self.namespace_stack)
+
+ def handle_typeid(self):
+ pass # Not needed yet.
+
+ def handle_typename(self):
+ pass # Not needed yet.
+
+ def _GetTemplatedTypes(self):
+ result = {}
+ tokens = list(self._GetMatchingChar('<', '>'))
+ len_tokens = len(tokens) - 1 # Ignore trailing '>'.
+ i = 0
+ while i < len_tokens:
+ key = tokens[i].name
+ i += 1
+ if keywords.IsKeyword(key) or key == ',':
+ continue
+ type_name = default = None
+ if i < len_tokens:
+ i += 1
+ if tokens[i-1].name == '=':
+ assert i < len_tokens, '%s %s' % (i, tokens)
+ default, unused_next_token = self.GetName(tokens[i:])
+ i += len(default)
+ else:
+ if tokens[i-1].name != ',':
+ # We got something like: Type variable.
+ # Re-adjust the key (variable) and type_name (Type).
+ key = tokens[i-1].name
+ type_name = tokens[i-2]
+
+ result[key] = (type_name, default)
+ return result
+
+ def handle_template(self):
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.SYNTAX, token
+ assert token.name == '<', token
+ templated_types = self._GetTemplatedTypes()
+ # TODO(nnorwitz): for now, just ignore the template params.
+ token = self._GetNextToken()
+ if token.token_type == tokenize.NAME:
+ if token.name == 'class':
+ return self._GetClass(Class, VISIBILITY_PRIVATE, templated_types)
+ elif token.name == 'struct':
+ return self._GetClass(Struct, VISIBILITY_PUBLIC, templated_types)
+ elif token.name == 'friend':
+ return self.handle_friend()
+ self._AddBackToken(token)
+ tokens, last = self._GetVarTokensUpTo(tokenize.SYNTAX, '(', ';')
+ tokens.append(last)
+ self._AddBackTokens(tokens)
+ if last.name == '(':
+ return self.GetMethod(FUNCTION_NONE, templated_types)
+ # Must be a variable definition.
+ return None
+
+ def handle_true(self):
+ pass # Nothing to do.
+
+ def handle_false(self):
+ pass # Nothing to do.
+
+ def handle_asm(self):
+ pass # Not needed yet.
+
+ def handle_class(self):
+ return self._GetClass(Class, VISIBILITY_PRIVATE, None)
+
+ def _GetBases(self):
+ # Get base classes.
+ bases = []
+ while 1:
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.NAME, token
+ # TODO(nnorwitz): store kind of inheritance...maybe.
+ if token.name not in ('public', 'protected', 'private'):
+ # If inheritance type is not specified, it is private.
+ # Just put the token back so we can form a name.
+ # TODO(nnorwitz): it would be good to warn about this.
+ self._AddBackToken(token)
+ else:
+ # Check for virtual inheritance.
+ token = self._GetNextToken()
+ if token.name != 'virtual':
+ self._AddBackToken(token)
+ else:
+ # TODO(nnorwitz): store that we got virtual for this base.
+ pass
+ base, next_token = self.GetName()
+ bases_ast = self.converter.ToType(base)
+ assert len(bases_ast) == 1, bases_ast
+ bases.append(bases_ast[0])
+ assert next_token.token_type == tokenize.SYNTAX, next_token
+ if next_token.name == '{':
+ token = next_token
+ break
+ # Support multiple inheritance.
+ assert next_token.name == ',', next_token
+ return bases, token
+
+ def _GetClass(self, class_type, visibility, templated_types):
+ class_name = None
+ class_token = self._GetNextToken()
+ if class_token.token_type != tokenize.NAME:
+ assert class_token.token_type == tokenize.SYNTAX, class_token
+ token = class_token
+ else:
+ self._AddBackToken(class_token)
+ name_tokens, token = self.GetName()
+ class_name = ''.join([t.name for t in name_tokens])
+ bases = None
+ if token.token_type == tokenize.SYNTAX:
+ if token.name == ';':
+ # Forward declaration.
+ return class_type(class_token.start, class_token.end,
+ class_name, None, templated_types, None,
+ self.namespace_stack)
+ if token.name in '*&':
+ # Inline forward declaration. Could be method or data.
+ name_token = self._GetNextToken()
+ next_token = self._GetNextToken()
+ if next_token.name == ';':
+ # Handle data
+ modifiers = ['class']
+ return self._CreateVariable(class_token, name_token.name,
+ class_name,
+ modifiers, token.name, None)
+ else:
+ # Assume this is a method.
+ tokens = (class_token, token, name_token, next_token)
+ self._AddBackTokens(tokens)
+ return self.GetMethod(FUNCTION_NONE, None)
+ if token.name == ':':
+ bases, token = self._GetBases()
+
+ body = None
+ if token.token_type == tokenize.SYNTAX and token.name == '{':
+ assert token.token_type == tokenize.SYNTAX, token
+ assert token.name == '{', token
+
+ ast = AstBuilder(self.GetScope(), self.filename, class_name,
+ visibility, self.namespace_stack)
+ body = list(ast.Generate())
+
+ if not self._handling_typedef:
+ token = self._GetNextToken()
+ if token.token_type != tokenize.NAME:
+ assert token.token_type == tokenize.SYNTAX, token
+ assert token.name == ';', token
+ else:
+ new_class = class_type(class_token.start, class_token.end,
+ class_name, bases, None,
+ body, self.namespace_stack)
+
+ modifiers = []
+ return self._CreateVariable(class_token,
+ token.name, new_class,
+ modifiers, token.name, None)
+ else:
+ if not self._handling_typedef:
+ self.HandleError('non-typedef token', token)
+ self._AddBackToken(token)
+
+ return class_type(class_token.start, class_token.end, class_name,
+ bases, None, body, self.namespace_stack)
+
+ def handle_namespace(self):
+ token = self._GetNextToken()
+ # Support anonymous namespaces.
+ name = None
+ if token.token_type == tokenize.NAME:
+ name = token.name
+ token = self._GetNextToken()
+ self.namespace_stack.append(name)
+ assert token.token_type == tokenize.SYNTAX, token
+ if token.name == '=':
+ # TODO(nnorwitz): handle aliasing namespaces.
+ name, next_token = self.GetName()
+ assert next_token.name == ';', next_token
+ else:
+ assert token.name == '{', token
+ tokens = list(self.GetScope())
+ del tokens[-1] # Remove trailing '}'.
+ # 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):
+ tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
+ assert tokens
+ return Using(tokens[0].start, tokens[0].end, tokens)
+
+ def handle_explicit(self):
+ assert self.in_class
+ # Nothing much to do.
+ # TODO(nnorwitz): maybe verify the method name == class name.
+ # This must be a ctor.
+ return self.GetMethod(FUNCTION_CTOR, None)
+
+ def handle_this(self):
+ pass # Nothing to do.
+
+ def handle_operator(self):
+ # Pull off the next token(s?) and make that part of the method name.
+ pass
+
+ def handle_sizeof(self):
+ pass
+
+ def handle_case(self):
+ pass
+
+ def handle_switch(self):
+ pass
+
+ def handle_default(self):
+ token = self._GetNextToken()
+ assert token.token_type == tokenize.SYNTAX
+ assert token.name == ':'
+
+ def handle_if(self):
+ pass
+
+ def handle_else(self):
+ pass
+
+ def handle_return(self):
+ tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
+ if not tokens:
+ return Return(self.current_token.start, self.current_token.end, None)
+ return Return(tokens[0].start, tokens[0].end, tokens)
+
+ def handle_goto(self):
+ tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
+ assert len(tokens) == 1, str(tokens)
+ return Goto(tokens[0].start, tokens[0].end, tokens[0].name)
+
+ def handle_try(self):
+ pass # Not needed yet.
+
+ def handle_catch(self):
+ pass # Not needed yet.
+
+ def handle_throw(self):
+ pass # Not needed yet.
+
+ def handle_while(self):
+ pass
+
+ def handle_do(self):
+ pass
+
+ def handle_for(self):
+ pass
+
+ def handle_break(self):
+ self._IgnoreUpTo(tokenize.SYNTAX, ';')
+
+ def handle_continue(self):
+ self._IgnoreUpTo(tokenize.SYNTAX, ';')
+
+
+def BuilderFromSource(source, filename):
+ """Utility method that returns an AstBuilder from source code.
+
+ Args:
+ source: 'C++ source code'
+ filename: 'file1'
+
+ Returns:
+ AstBuilder
+ """
+ return AstBuilder(tokenize.GetTokens(source), filename)
+
+
+def PrintIndentifiers(filename, should_print):
+ """Prints all identifiers for a C++ source file.
+
+ Args:
+ filename: 'file1'
+ should_print: predicate with signature: bool Function(token)
+ """
+ source = utils.ReadFile(filename, False)
+ if source is None:
+ sys.stderr.write('Unable to find: %s\n' % filename)
+ return
+
+ #print('Processing %s' % actual_filename)
+ builder = BuilderFromSource(source, filename)
+ try:
+ for node in builder.Generate():
+ if should_print(node):
+ print(node.name)
+ except KeyboardInterrupt:
+ return
+ except:
+ pass
+
+
+def PrintAllIndentifiers(filenames, should_print):
+ """Prints all identifiers for each C++ source file in filenames.
+
+ Args:
+ filenames: ['file1', 'file2', ...]
+ should_print: predicate with signature: bool Function(token)
+ """
+ for path in filenames:
+ PrintIndentifiers(path, should_print)
+
+
+def main(argv):
+ for filename in argv[1:]:
+ source = utils.ReadFile(filename)
+ if source is None:
+ continue
+
+ print('Processing %s' % filename)
+ builder = BuilderFromSource(source, filename)
+ try:
+ entire_ast = filter(None, builder.Generate())
+ except KeyboardInterrupt:
+ return
+ except:
+ # Already printed a warning, print the traceback and continue.
+ traceback.print_exc()
+ else:
+ if utils.DEBUG:
+ for ast in entire_ast:
+ print(ast)
+
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py
new file mode 100755
index 00000000..f2b3521f
--- /dev/null
+++ b/scripts/generator/cpp/gmock_class.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Google Inc.
+#
+# 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.
+
+"""Generate a Google Mock class from a production class.
+
+This program will read in a C++ source file and output the Google Mock class
+for the specified class.
+
+Usage:
+ gmock_class.py header-file.h ClassName
+
+Output is sent to stdout.
+"""
+
+__author__ = 'nnorwitz@google.com (Neal Norwitz)'
+
+
+import os
+import re
+import sys
+
+from cpp import ast
+from cpp import utils
+
+# How many spaces to indent. Can me set with INDENT environment variable.
+_INDENT = 2
+
+
+def _GenerateMethods(output_lines, source, class_node):
+ function_type = ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL
+ ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR
+
+ for node in class_node.body:
+ # We only care about virtual functions.
+ if (isinstance(node, ast.Function) and
+ node.modifiers & function_type and
+ not node.modifiers & ctor_or_dtor):
+ # Pick out all the elements we need from the original function.
+ const = ''
+ if node.modifiers & ast.FUNCTION_CONST:
+ const = 'CONST_'
+ return_type = 'void'
+ if node.return_type:
+ return_type = node.return_type.name
+ if node.return_type.pointer:
+ return_type += '*'
+ if node.return_type.reference:
+ return_type += '&'
+ prefix = 'MOCK_%sMETHOD%d' % (const, len(node.parameters))
+ args = ''
+ if node.parameters:
+ # Get the full text of the parameters from the start
+ # of the first parameter to the end of the last parameter.
+ start = node.parameters[0].start
+ end = node.parameters[-1].end
+ args = re.sub(' +', ' ', source[start:end].replace('\n', ''))
+
+ # Create the prototype.
+ indent = ' ' * _INDENT
+ line = ('%s%s(%s,\n%s%s(%s));' %
+ (indent, prefix, node.name, indent*3, return_type, args))
+ output_lines.append(line)
+
+
+def _GenerateMock(filename, source, ast_list, class_name):
+ lines = []
+ for node in ast_list:
+ if isinstance(node, ast.Class) and node.body and node.name == class_name:
+ class_node = node
+ # Add namespace before the class.
+ if class_node.namespace:
+ lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
+ lines.append('')
+
+ # Add the class prolog.
+ lines.append('class Mock%s : public %s {' % (class_name, class_name)) # }
+ lines.append('%spublic:' % (' ' * (_INDENT // 2)))
+
+ # Add all the methods.
+ _GenerateMethods(lines, source, class_node)
+
+ # Close the class.
+ if lines:
+ # If there are no virtual methods, no need for a public label.
+ if len(lines) == 2:
+ del lines[-1]
+
+ # Only close the class if there really is a class.
+ lines.append('};')
+ lines.append('') # Add an extra newline.
+
+ # Close the namespace.
+ if class_node.namespace:
+ for i in range(len(class_node.namespace)-1, -1, -1):
+ lines.append('} // namespace %s' % class_node.namespace[i])
+ lines.append('') # Add an extra newline.
+
+ if lines:
+ sys.stdout.write('\n'.join(lines))
+ else:
+ sys.stderr.write('Class %s not found\n' % class_name)
+
+
+def main(argv=sys.argv):
+ if len(argv) != 3:
+ sys.stdout.write(__doc__)
+ return 1
+
+ global _INDENT
+ try:
+ _INDENT = int(os.environ['INDENT'])
+ except KeyError:
+ pass
+ except:
+ sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT'))
+
+ filename, class_name = argv[1:]
+ source = utils.ReadFile(filename)
+ if source is None:
+ return 1
+
+ builder = ast.BuilderFromSource(source, filename)
+ try:
+ entire_ast = filter(None, builder.Generate())
+ except KeyboardInterrupt:
+ return
+ except:
+ # An error message was already printed since we couldn't parse.
+ pass
+ else:
+ _GenerateMock(filename, source, entire_ast, class_name)
+
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/scripts/generator/cpp/keywords.py b/scripts/generator/cpp/keywords.py
new file mode 100755
index 00000000..73f0202c
--- /dev/null
+++ b/scripts/generator/cpp/keywords.py
@@ -0,0 +1,58 @@
+#
+# Copyright 2007 Neal Norwitz
+# Portions Copyright 2007 Google Inc.
+#
+# 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.
+
+"""C++ keywords and helper utilities for determining keywords."""
+
+__author__ = 'nnorwitz@google.com (Neal Norwitz)'
+
+
+try:
+ # Python 3.x
+ import builtins
+except ImportError:
+ # Python 2.x
+ import __builtin__ as builtins
+
+
+if not hasattr(builtins, 'set'):
+ # Nominal support for Python 2.3.
+ from sets import Set as set
+
+
+TYPES = set('bool char int long short double float void wchar_t unsigned signed'.split())
+TYPE_MODIFIERS = set('auto register const inline extern static virtual volatile mutable'.split())
+ACCESS = set('public protected private friend'.split())
+
+CASTS = set('static_cast const_cast dynamic_cast reinterpret_cast'.split())
+
+OTHERS = set('true false asm class namespace using explicit this operator sizeof'.split())
+OTHER_TYPES = set('new delete typedef struct union enum typeid typename template'.split())
+
+CONTROL = set('case switch default if else return goto'.split())
+EXCEPTION = set('try catch throw'.split())
+LOOP = set('while do for break continue'.split())
+
+ALL = TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | CONTROL | EXCEPTION | LOOP
+
+
+def IsKeyword(token):
+ return token in ALL
+
+def IsBuiltinType(token):
+ if token in ('virtual', 'inline'):
+ # These only apply to methods, they can't be types by themselves.
+ return False
+ return token in TYPES or token in TYPE_MODIFIERS
diff --git a/scripts/generator/cpp/tokenize.py b/scripts/generator/cpp/tokenize.py
new file mode 100755
index 00000000..28c33452
--- /dev/null
+++ b/scripts/generator/cpp/tokenize.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Neal Norwitz
+# Portions Copyright 2007 Google Inc.
+#
+# 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.
+
+"""Tokenize C++ source code."""
+
+__author__ = 'nnorwitz@google.com (Neal Norwitz)'
+
+
+try:
+ # Python 3.x
+ import builtins
+except ImportError:
+ # Python 2.x
+ import __builtin__ as builtins
+
+
+import sys
+
+from cpp import utils
+
+
+if not hasattr(builtins, 'set'):
+ # Nominal support for Python 2.3.
+ from sets import Set as set
+
+
+# Add $ as a valid identifier char since so much code uses it.
+_letters = 'abcdefghijklmnopqrstuvwxyz'
+VALID_IDENTIFIER_CHARS = set(_letters + _letters.upper() + '_0123456789$')
+HEX_DIGITS = set('0123456789abcdefABCDEF')
+INT_OR_FLOAT_DIGITS = set('01234567890eE-+')
+
+
+# C++0x string preffixes.
+_STR_PREFIXES = set(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR'))
+
+
+# Token types.
+UNKNOWN = 'UNKNOWN'
+SYNTAX = 'SYNTAX'
+CONSTANT = 'CONSTANT'
+NAME = 'NAME'
+PREPROCESSOR = 'PREPROCESSOR'
+
+# Where the token originated from. This can be used for backtracking.
+# It is always set to WHENCE_STREAM in this code.
+WHENCE_STREAM, WHENCE_QUEUE = range(2)
+
+
+class Token(object):
+ """Data container to represent a C++ token.
+
+ Tokens can be identifiers, syntax char(s), constants, or
+ pre-processor directives.
+
+ start contains the index of the first char of the token in the source
+ end contains the index of the last char of the token in the source
+ """
+
+ def __init__(self, token_type, name, start, end):
+ self.token_type = token_type
+ self.name = name
+ self.start = start
+ self.end = end
+ self.whence = WHENCE_STREAM
+
+ def __str__(self):
+ if not utils.DEBUG:
+ return 'Token(%r)' % self.name
+ return 'Token(%r, %s, %s)' % (self.name, self.start, self.end)
+
+ __repr__ = __str__
+
+
+def _GetString(source, start, i):
+ i = source.find('"', i+1)
+ while source[i-1] == '\\':
+ # Count the trailing backslashes.
+ backslash_count = 1
+ j = i - 2
+ while source[j] == '\\':
+ backslash_count += 1
+ j -= 1
+ # When trailing backslashes are even, they escape each other.
+ if (backslash_count % 2) == 0:
+ break
+ i = source.find('"', i+1)
+ return i + 1
+
+
+def _GetChar(source, start, i):
+ # NOTE(nnorwitz): may not be quite correct, should be good enough.
+ i = source.find("'", i+1)
+ while source[i-1] == '\\':
+ # Need to special case '\\'.
+ if (i - 2) > start and source[i-2] == '\\':
+ break
+ i = source.find("'", i+1)
+ # Try to handle unterminated single quotes (in a #if 0 block).
+ if i < 0:
+ i = start
+ return i + 1
+
+
+def GetTokens(source):
+ """Returns a sequence of Tokens.
+
+ Args:
+ source: string of C++ source code.
+
+ Yields:
+ Token that represents the next token in the source.
+ """
+ # Cache various valid character sets for speed.
+ valid_identifier_chars = VALID_IDENTIFIER_CHARS
+ hex_digits = HEX_DIGITS
+ int_or_float_digits = INT_OR_FLOAT_DIGITS
+ int_or_float_digits2 = int_or_float_digits | set('.')
+
+ # Only ignore errors while in a #if 0 block.
+ ignore_errors = False
+ count_ifs = 0
+
+ i = 0
+ end = len(source)
+ while i < end:
+ # Skip whitespace.
+ while i < end and source[i].isspace():
+ i += 1
+ if i >= end:
+ return
+
+ token_type = UNKNOWN
+ start = i
+ c = source[i]
+ if c.isalpha() or c == '_': # Find a string token.
+ token_type = NAME
+ while source[i] in valid_identifier_chars:
+ i += 1
+ # String and character constants can look like a name if
+ # they are something like L"".
+ if (source[i] == "'" and (i - start) == 1 and
+ source[start:i] in 'uUL'):
+ # u, U, and L are valid C++0x character preffixes.
+ token_type = CONSTANT
+ i = _GetChar(source, start, i)
+ elif source[i] == "'" and source[start:i] in _STR_PREFIXES:
+ token_type = CONSTANT
+ i = _GetString(source, start, i)
+ elif c == '/' and source[i+1] == '/': # Find // comments.
+ i = source.find('\n', i)
+ if i == -1: # Handle EOF.
+ i = end
+ continue
+ elif c == '/' and source[i+1] == '*': # Find /* comments. */
+ i = source.find('*/', i) + 2
+ continue
+ elif c in ':+-<>&|*=': # : or :: (plus other chars).
+ token_type = SYNTAX
+ i += 1
+ new_ch = source[i]
+ if new_ch == c:
+ i += 1
+ elif c == '-' and new_ch == '>':
+ i += 1
+ elif new_ch == '=':
+ i += 1
+ elif c in '()[]{}~!?^%;/.,': # Handle single char tokens.
+ token_type = SYNTAX
+ i += 1
+ if c == '.' and source[i].isdigit():
+ token_type = CONSTANT
+ i += 1
+ while source[i] in int_or_float_digits:
+ i += 1
+ # Handle float suffixes.
+ for suffix in ('l', 'f'):
+ if suffix == source[i:i+1].lower():
+ i += 1
+ break
+ elif c.isdigit(): # Find integer.
+ token_type = CONSTANT
+ if c == '0' and source[i+1] in 'xX':
+ # Handle hex digits.
+ i += 2
+ while source[i] in hex_digits:
+ i += 1
+ else:
+ while source[i] in int_or_float_digits2:
+ i += 1
+ # Handle integer (and float) suffixes.
+ for suffix in ('ull', 'll', 'ul', 'l', 'f', 'u'):
+ size = len(suffix)
+ if suffix == source[i:i+size].lower():
+ i += size
+ break
+ elif c == '"': # Find string.
+ token_type = CONSTANT
+ i = _GetString(source, start, i)
+ elif c == "'": # Find char.
+ token_type = CONSTANT
+ i = _GetChar(source, start, i)
+ elif c == '#': # Find pre-processor command.
+ token_type = PREPROCESSOR
+ got_if = source[i:i+3] == '#if' and source[i+3:i+4].isspace()
+ if got_if:
+ count_ifs += 1
+ elif source[i:i+6] == '#endif':
+ count_ifs -= 1
+ if count_ifs == 0:
+ ignore_errors = False
+
+ # TODO(nnorwitz): handle preprocessor statements (\ continuations).
+ while 1:
+ i1 = source.find('\n', i)
+ i2 = source.find('//', i)
+ i3 = source.find('/*', i)
+ i4 = source.find('"', i)
+ # NOTE(nnorwitz): doesn't handle comments in #define macros.
+ # Get the first important symbol (newline, comment, EOF/end).
+ i = min([x for x in (i1, i2, i3, i4, end) if x != -1])
+
+ # Handle #include "dir//foo.h" properly.
+ if source[i] == '"':
+ i = source.find('"', i+1) + 1
+ assert i > 0
+ continue
+ # Keep going if end of the line and the line ends with \.
+ if not (i == i1 and source[i-1] == '\\'):
+ if got_if:
+ condition = source[start+4:i].lstrip()
+ if (condition.startswith('0') or
+ condition.startswith('(0)')):
+ ignore_errors = True
+ break
+ i += 1
+ elif c == '\\': # Handle \ in code.
+ # This is different from the pre-processor \ handling.
+ i += 1
+ continue
+ elif ignore_errors:
+ # The tokenizer seems to be in pretty good shape. This
+ # raise is conditionally disabled so that bogus code
+ # in an #if 0 block can be handled. Since we will ignore
+ # it anyways, this is probably fine. So disable the
+ # exception and return the bogus char.
+ i += 1
+ else:
+ sys.stderr.write('Got invalid token in %s @ %d token:%s: %r\n' %
+ ('?', i, c, source[i-10:i+10]))
+ raise RuntimeError('unexpected token')
+
+ if i <= 0:
+ print('Invalid index, exiting now.')
+ return
+ yield Token(token_type, source[start:i], start, i)
+
+
+if __name__ == '__main__':
+ def main(argv):
+ """Driver mostly for testing purposes."""
+ for filename in argv[1:]:
+ source = utils.ReadFile(filename)
+ if source is None:
+ continue
+
+ for token in GetTokens(source):
+ print('%-12s: %s' % (token.token_type, token.name))
+ # print('\r%6.2f%%' % (100.0 * index / token.end),)
+ sys.stdout.write('\n')
+
+
+ main(sys.argv)
diff --git a/scripts/generator/cpp/utils.py b/scripts/generator/cpp/utils.py
new file mode 100755
index 00000000..eab36eec
--- /dev/null
+++ b/scripts/generator/cpp/utils.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Neal Norwitz
+# Portions Copyright 2007 Google Inc.
+#
+# 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.
+
+"""Generic utilities for C++ parsing."""
+
+__author__ = 'nnorwitz@google.com (Neal Norwitz)'
+
+
+import sys
+
+
+# Set to True to see the start/end token indices.
+DEBUG = True
+
+
+def ReadFile(filename, print_error=True):
+ """Returns the contents of a file."""
+ try:
+ fp = open(filename)
+ try:
+ return fp.read()
+ finally:
+ fp.close()
+ except IOError:
+ if print_error:
+ print('Error reading %s: %s' % (filename, sys.exc_info()[1]))
+ return None
diff --git a/scripts/generator/gmock_gen.py b/scripts/generator/gmock_gen.py
new file mode 100755
index 00000000..5a3f6583
--- /dev/null
+++ b/scripts/generator/gmock_gen.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python2.4
+#
+# 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.
+# 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.
+
+"""Driver for starting up Google Mock class generator."""
+
+__author__ = 'nnorwitz@google.com (Neal Norwitz)'
+
+import os
+import sys
+
+if __name__ == '__main__':
+ # Add the directory of this script to the path so we can import gmock_class.
+ sys.path.append(os.path.dirname(__file__))
+
+ from cpp import gmock_class
+ # Fix the docstring in case they require the usage.
+ gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__)
+ gmock_class.main()
diff --git a/scripts/gmock_doctor.py b/scripts/gmock_doctor.py
new file mode 100755
index 00000000..ce8ec498
--- /dev/null
+++ b/scripts/gmock_doctor.py
@@ -0,0 +1,376 @@
+#!/usr/bin/python2.4
+#
+# 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.
+
+"""Converts gcc errors in code using Google Mock to plain English."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import re
+import sys
+
+_VERSION = '0.1.0.80421'
+
+_COMMON_GMOCK_SYMBOLS = [
+ # Matchers
+ '_',
+ 'A',
+ 'AddressSatisfies',
+ 'AllOf',
+ 'An',
+ 'AnyOf',
+ 'ContainsRegex',
+ 'DoubleEq',
+ 'EndsWith',
+ 'Eq',
+ 'Field',
+ 'FloatEq',
+ 'Ge',
+ 'Gt',
+ 'HasSubstr',
+ 'Le',
+ 'Lt',
+ 'MatcherCast',
+ 'MatchesRegex',
+ 'Ne',
+ 'Not',
+ 'NotNull',
+ 'Pointee',
+ 'Property',
+ 'Ref',
+ 'StartsWith',
+ 'StrCaseEq',
+ 'StrCaseNe',
+ 'StrEq',
+ 'StrNe',
+ 'Truly',
+ 'TypedEq',
+
+ # Actions
+ 'ByRef',
+ 'DoAll',
+ 'DoDefault',
+ 'IgnoreResult',
+ 'Invoke',
+ 'InvokeArgument',
+ 'InvokeWithoutArgs',
+ 'Return',
+ 'ReturnNull',
+ 'ReturnRef',
+ 'SetArgumentPointee',
+ 'SetArrayArgument',
+ 'WithArgs',
+
+ # Cardinalities
+ 'AnyNumber',
+ 'AtLeast',
+ 'AtMost',
+ 'Between',
+ 'Exactly',
+
+ # Sequences
+ 'InSequence',
+ 'Sequence',
+
+ # Misc
+ 'DefaultValue',
+ 'Mock',
+ ]
+
+
+def _FindAllMatches(regex, s):
+ """Generates all matches of regex in string s."""
+
+ r = re.compile(regex)
+ return r.finditer(s)
+
+
+def _GenericDiagnoser(short_name, long_name, regex, diagnosis, msg):
+ """Diagnoses the given disease by pattern matching.
+
+ Args:
+ short_name: Short name of the disease.
+ long_name: Long name of the disease.
+ regex: Regex for matching the symptoms.
+ diagnosis: Pattern for formatting the diagnosis.
+ msg: Gcc's error messages.
+ Yields:
+ Tuples of the form
+ (short name of disease, long name of disease, diagnosis).
+ """
+
+ for m in _FindAllMatches(regex, msg):
+ yield (short_name, long_name, diagnosis % m.groupdict())
+
+
+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'
+ r'.*gmock-actions\.h.*error: creating array with negative size')
+ diagnosis = """%(file)s:%(line)s:
+You are using an Return() action in a function that returns a reference.
+Please use ReturnRef() instead."""
+ return _GenericDiagnoser('NRR', 'Need to Return Reference',
+ regex, diagnosis, msg)
+
+
+def _NeedToReturnSomethingDiagnoser(msg):
+ """Diagnoses the NRS disease, given the error messages by gcc."""
+
+ regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
+ r'.*gmock-actions\.h.*error: void value not ignored')
+ diagnosis = """%(file)s:%(line)s:
+You are using an action that returns void, but it needs to return
+*something*. Please tell it *what* to return."""
+ return _GenericDiagnoser('NRS', 'Need to Return Something',
+ regex, diagnosis, msg)
+
+
+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'
+ r'.*gmock-actions\.h.*error: return-statement with a value, '
+ r'in function returning \'void\'')
+ diagnosis = """%(file)s:%(line)s:
+You are using an action that returns *something*, but it needs to return
+void. Please use a void-returning action instead.
+
+All actions but the last in DoAll(...) must return void. Perhaps you need
+to re-arrange the order of actions in a DoAll(), if you are using one?"""
+ return _GenericDiagnoser('NRN', 'Need to Return Nothing',
+ regex, diagnosis, msg)
+
+
+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'
+ r'.*gmock-printers\.h.*error: invalid application of '
+ r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
+ diagnosis = """%(file)s:%(line)s:
+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
+by pointer."""
+ return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type',
+ regex, diagnosis, msg)
+
+
+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 '
+ r'call to \'Truly\(<unresolved overloaded function type>\)')
+ diagnosis = """%(file)s:%(line)s:
+The argument you gave to Truly() is an overloaded function. Please tell
+gcc which overloaded version you want to use.
+
+For example, if you want to use the version whose signature is
+ bool Foo(int n);
+you should write
+ Truly(static_cast<bool (*)(int n)>(Foo))"""
+ return _GenericDiagnoser('OFM', 'Overloaded Function Matcher',
+ regex, diagnosis, msg)
+
+
+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\('
+ r'<unresolved overloaded function type>')
+ diagnosis = """%(file)s:%(line)s:
+You are passing an overloaded function to Invoke(). Please tell gcc
+which overloaded version you want to use.
+
+For example, if you want to use the version whose signature is
+ bool MyFunction(int n, double x);
+you should write something like
+ Invoke(static_cast<bool (*)(int n, double x)>(MyFunction))"""
+ return _GenericDiagnoser('OFA', 'Overloaded Function Action',
+ regex, diagnosis, msg)
+
+
+def _OverloadedMethodActionDiagnoser1(msg):
+ """Diagnoses the OMA disease, given the error messages by gcc."""
+
+ regex = (r'(?P<file>.*):(?P<line>\d+): error: '
+ r'.*no matching function for call to \'Invoke\(.*, '
+ r'unresolved overloaded function type>')
+ diagnosis = """%(file)s:%(line)s:
+The second argument you gave to Invoke() is an overloaded method. Please
+tell gcc which overloaded version you want to use.
+
+For example, if you want to use the version whose signature is
+ class Foo {
+ ...
+ bool Bar(int n, double x);
+ };
+you should write something like
+ Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
+ return _GenericDiagnoser('OMA', 'Overloaded Method Action',
+ regex, diagnosis, msg)
+
+
+def _MockObjectPointerDiagnoser(msg):
+ """Diagnoses the MOP disease, given the error messages by gcc."""
+
+ regex = (r'(?P<file>.*):(?P<line>\d+): 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:
+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.
+
+For example, given the mock class:
+
+ class %(class_name)s : public ... {
+ ...
+ MOCK_METHOD0(%(method)s, ...);
+ };
+
+and the following mock instance:
+
+ %(class_name)s* mock_ptr = ...
+
+you should use the EXPECT_CALL like this:
+
+ EXPECT_CALL(*mock_ptr, %(method)s(...));"""
+ return _GenericDiagnoser('MOP', 'Mock Object Pointer',
+ regex, diagnosis, msg)
+
+
+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 '
+ r'call to \'Invoke\(.+, <unresolved overloaded function type>\)')
+ diagnosis = """%(file)s:%(line)s:
+The second argument you gave to Invoke() is an overloaded method. Please
+tell gcc which overloaded version you want to use.
+
+For example, if you want to use the version whose signature is
+ class Foo {
+ ...
+ bool Bar(int n, double x);
+ };
+you should write something like
+ Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
+ return _GenericDiagnoser('OMA', 'Overloaded Method Action',
+ regex, diagnosis, msg)
+
+
+def _NeedToUseSymbolDiagnoser(msg):
+ """Diagnoses the NUS disease, given the error messages by gcc."""
+
+ regex = (r'(?P<file>.*):(?P<line>\d+): error: \'(?P<symbol>.+)\' '
+ r'(was not declared in this scope|has not been declared)')
+ diagnosis = """%(file)s:%(line)s:
+'%(symbol)s' is defined by Google Mock in the testing namespace.
+Did you forget to write
+ using testing::%(symbol)s;
+?"""
+ for m in _FindAllMatches(regex, msg):
+ symbol = m.groupdict()['symbol']
+ if symbol in _COMMON_GMOCK_SYMBOLS:
+ yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict())
+
+
+_DIAGNOSERS = [
+ _IncompleteByReferenceArgumentDiagnoser,
+ _MockObjectPointerDiagnoser,
+ _NeedToReturnNothingDiagnoser,
+ _NeedToReturnReferenceDiagnoser,
+ _NeedToReturnSomethingDiagnoser,
+ _NeedToUseSymbolDiagnoser,
+ _OverloadedFunctionActionDiagnoser,
+ _OverloadedFunctionMatcherDiagnoser,
+ _OverloadedMethodActionDiagnoser1,
+ _OverloadedMethodActionDiagnoser2,
+ ]
+
+
+def Diagnose(msg):
+ """Generates all possible diagnoses given the gcc error message."""
+
+ for diagnoser in _DIAGNOSERS:
+ for diagnosis in diagnoser(msg):
+ yield '[%s - %s]\n%s' % diagnosis
+
+
+def main():
+ print ('Google Mock Doctor v%s - '
+ 'diagnoses problems in code using Google Mock.' % _VERSION)
+
+ if sys.stdin.isatty():
+ print ('Please copy and paste the compiler errors here. Press c-D when '
+ 'you are done:')
+ else:
+ print 'Waiting for compiler errors on stdin . . .'
+
+ msg = sys.stdin.read().strip()
+ diagnoses = list(Diagnose(msg))
+ count = len(diagnoses)
+ if not count:
+ print '\nGcc complained:'
+ print '8<------------------------------------------------------------'
+ print msg
+ print '------------------------------------------------------------>8'
+ print """
+Uh-oh, I'm not smart enough to figure out what the problem is. :-(
+However...
+If you send your source code and gcc's error messages to
+googlemock@googlegroups.com, you can be helped and I can get smarter --
+win-win for us!"""
+ else:
+ print '------------------------------------------------------------'
+ print 'Your code appears to have the following',
+ if count > 1:
+ print '%s diseases:' % (count,)
+ else:
+ print 'disease:'
+ i = 0
+ for d in diagnoses:
+ i += 1
+ if count > 1:
+ print '\n#%s:' % (i,)
+ print d
+ print """
+How did I do? If you think I'm wrong or unhelpful, please send your
+source code and gcc's error messages to googlemock@googlegroups.com. Then
+you can be helped and I can get smarter -- I promise I won't be upset!"""
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/gmock-all.cc b/src/gmock-all.cc
new file mode 100644
index 00000000..a14c397d
--- /dev/null
+++ b/src/gmock-all.cc
@@ -0,0 +1,43 @@
+// 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: wan@google.com (Zhanyong Wan)
+//
+// Google C++ Mocking Framework (Google Mock)
+//
+// This file #includes all Google Mock implementation .cc files. The
+// purpose is to allow a user to build Google Mock by compiling this
+// file alone.
+
+#include "src/gmock-cardinalities.cc"
+#include "src/gmock-internal-utils.cc"
+#include "src/gmock-matchers.cc"
+#include "src/gmock-printers.cc"
+#include "src/gmock-spec-builders.cc"
+#include "src/gmock.cc"
diff --git a/src/gmock-cardinalities.cc b/src/gmock-cardinalities.cc
new file mode 100644
index 00000000..07eed469
--- /dev/null
+++ b/src/gmock-cardinalities.cc
@@ -0,0 +1,155 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements cardinalities.
+
+#include <gmock/gmock-cardinalities.h>
+
+#include <limits.h>
+#include <ostream> // NOLINT
+#include <sstream>
+#include <string>
+#include <gmock/internal/gmock-internal-utils.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+
+namespace {
+
+// Implements the Between(m, n) cardinality.
+class BetweenCardinalityImpl : public CardinalityInterface {
+ public:
+ BetweenCardinalityImpl(int min, int max)
+ : min_(min >= 0 ? min : 0),
+ max_(max >= min_ ? max : min_) {
+ std::stringstream ss;
+ if (min < 0) {
+ ss << "The invocation lower bound must be >= 0, "
+ << "but is actually " << min << ".";
+ internal::Expect(false, __FILE__, __LINE__, ss.str());
+ } else if (max < 0) {
+ ss << "The invocation upper bound must be >= 0, "
+ << "but is actually " << max << ".";
+ internal::Expect(false, __FILE__, __LINE__, ss.str());
+ } else if (min > max) {
+ ss << "The invocation upper bound (" << max
+ << ") must be >= the invocation lower bound (" << min
+ << ").";
+ internal::Expect(false, __FILE__, __LINE__, ss.str());
+ }
+ }
+
+ // Conservative estimate on the lower/upper bound of the number of
+ // calls allowed.
+ virtual int ConservativeLowerBound() const { return min_; }
+ virtual int ConservativeUpperBound() const { return max_; }
+
+ virtual bool IsSatisfiedByCallCount(int call_count) const {
+ return min_ <= call_count && call_count <= max_ ;
+ }
+
+ virtual bool IsSaturatedByCallCount(int call_count) const {
+ return call_count >= max_;
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const;
+ private:
+ const int min_;
+ const int max_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
+};
+
+// Formats "n times" in a human-friendly way.
+inline internal::string FormatTimes(int n) {
+ if (n == 1) {
+ return "once";
+ } else if (n == 2) {
+ return "twice";
+ } else {
+ std::stringstream ss;
+ ss << n << " times";
+ return ss.str();
+ }
+}
+
+// Describes the Between(m, n) cardinality in human-friendly text.
+void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
+ if (min_ == 0) {
+ if (max_ == 0) {
+ *os << "never called";
+ } else if (max_ == INT_MAX) {
+ *os << "called any number of times";
+ } else {
+ *os << "called at most " << FormatTimes(max_);
+ }
+ } else if (min_ == max_) {
+ *os << "called " << FormatTimes(min_);
+ } else if (max_ == INT_MAX) {
+ *os << "called at least " << FormatTimes(min_);
+ } else {
+ // 0 < min_ < max_ < INT_MAX
+ *os << "called between " << min_ << " and " << max_ << " times";
+ }
+}
+
+} // Unnamed namespace
+
+// Describes the given call count to an ostream.
+void Cardinality::DescribeActualCallCountTo(int actual_call_count,
+ ::std::ostream* os) {
+ if (actual_call_count > 0) {
+ *os << "called " << FormatTimes(actual_call_count);
+ } else {
+ *os << "never called";
+ }
+}
+
+// Creates a cardinality that allows at least n calls.
+Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
+
+// Creates a cardinality that allows at most n calls.
+Cardinality AtMost(int n) { return Between(0, n); }
+
+// Creates a cardinality that allows any number of calls.
+Cardinality AnyNumber() { return AtLeast(0); }
+
+// Creates a cardinality that allows between min and max calls.
+Cardinality Between(int min, int max) {
+ return Cardinality(new BetweenCardinalityImpl(min, max));
+}
+
+// Creates a cardinality that allows exactly n calls.
+Cardinality Exactly(int n) { return Between(n, n); }
+
+} // namespace testing
diff --git a/src/gmock-internal-utils.cc b/src/gmock-internal-utils.cc
new file mode 100644
index 00000000..58bc64e4
--- /dev/null
+++ b/src/gmock-internal-utils.cc
@@ -0,0 +1,135 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file defines some utilities useful for implementing Google
+// Mock. They are subject to change without notice, so please DO NOT
+// USE THEM IN USER CODE.
+
+#include <gmock/internal/gmock-internal-utils.h>
+
+#include <ostream> // NOLINT
+#include <string>
+#include <gmock/gmock.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+namespace internal {
+
+// This class reports Google Mock failures as Google Test failures. A
+// user can define another class in a similar fashion if he intends to
+// use Google Mock with a testing framework other than Google Test.
+class GoogleTestFailureReporter : public FailureReporterInterface {
+ public:
+ virtual void ReportFailure(FailureType type, const char* file, int line,
+ const string& message) {
+ AssertHelper(type == FATAL ? TPRT_FATAL_FAILURE : TPRT_NONFATAL_FAILURE,
+ file, line, message.c_str()) = Message();
+ if (type == FATAL) {
+ abort();
+ }
+ }
+};
+
+// Returns the global failure reporter. Will create a
+// GoogleTestFailureReporter and return it the first time called.
+FailureReporterInterface* GetFailureReporter() {
+ // Points to the global failure reporter used by Google Mock. gcc
+ // guarantees that the following use of failure_reporter is
+ // thread-safe. We may need to add additional synchronization to
+ // protect failure_reporter if we port Google Mock to other
+ // compilers.
+ static FailureReporterInterface* const failure_reporter =
+ new GoogleTestFailureReporter();
+ return failure_reporter;
+}
+
+// Protects global resources (stdout in particular) used by Log().
+static Mutex g_log_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
+
+// 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
+// stack_frames_to_skip frames. In opt mode, any positive
+// stack_frames_to_skip is treated as 0, since we don't know which
+// function calls will be inlined by the compiler and need to be
+// 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.
+ 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;
+ if (severity == WARNING) {
+ // Prints a GMOCK WARNING marker to make the warnings easily searchable.
+ 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";
+ }
+ cout << message;
+ if (stack_frames_to_skip >= 0) {
+#ifdef NDEBUG
+ // In opt mode, we have to be conservative and skip no stack frame.
+ const int actual_to_skip = 0;
+#else
+ // In dbg mode, we can do what the caller tell us to do (plus one
+ // for skipping this function's stack frame).
+ const int actual_to_skip = stack_frames_to_skip + 1;
+#endif // NDEBUG
+
+ // Appends a new-line to message if it doesn't end with one.
+ if (!message.empty() && *message.rbegin() != '\n') {
+ cout << "\n";
+ }
+ cout << "Stack trace:\n"
+ << ::testing::internal::GetCurrentOsStackTraceExceptTop(
+ ::testing::UnitTest::GetInstance(), actual_to_skip);
+ }
+ cout << ::std::flush;
+}
+
+} // namespace internal
+} // namespace testing
diff --git a/src/gmock-matchers.cc b/src/gmock-matchers.cc
new file mode 100644
index 00000000..99fd3a2d
--- /dev/null
+++ b/src/gmock-matchers.cc
@@ -0,0 +1,61 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements the Matcher<const string&> and
+// Matcher<string>.
+
+#include <gmock/gmock-matchers.h>
+
+namespace testing {
+
+// Constructs a matcher that matches a const string& whose value is
+// equal to s.
+Matcher<const internal::string&>::Matcher(const internal::string& s) {
+ *this = Eq(s);
+}
+
+// Constructs a matcher that matches a const string& whose value is
+// equal to s.
+Matcher<const internal::string&>::Matcher(const char* s) {
+ *this = Eq(internal::string(s));
+}
+
+// Constructs a matcher that matches a string whose value is equal to s.
+Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
+
+// Constructs a matcher that matches a string whose value is equal to s.
+Matcher<internal::string>::Matcher(const char* s) {
+ *this = Eq(internal::string(s));
+}
+
+} // namespace testing
diff --git a/src/gmock-printers.cc b/src/gmock-printers.cc
new file mode 100644
index 00000000..611d8659
--- /dev/null
+++ b/src/gmock-printers.cc
@@ -0,0 +1,309 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements a universal value printer that can print a
+// value of any type T:
+//
+// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
+//
+// It uses the << operator when possible, and prints the bytes in the
+// object otherwise. A user can override its behavior for a class
+// type Foo by defining either operator<<(::std::ostream&, const Foo&)
+// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
+// defines Foo.
+
+#include <gmock/gmock-printers.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <ostream> // NOLINT
+#include <string>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+namespace {
+
+using ::std::ostream;
+
+#ifdef GTEST_OS_WINDOWS
+#define snprintf _snprintf_s
+#endif
+
+// Prints a segment of bytes in the given object.
+void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
+ size_t count, ostream* os) {
+ char text[5] = "";
+ for (size_t i = 0; i != count; i++) {
+ const size_t j = start + i;
+ if (i != 0) {
+ // Organizes the bytes into groups of 2 for easy parsing by
+ // human.
+ if ((j % 2) == 0) {
+ *os << " ";
+ }
+ }
+ snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
+ *os << text;
+ }
+}
+
+// Prints the bytes in the given value to the given ostream.
+void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
+ ostream* os) {
+ // Tells the user how big the object is.
+ *os << count << "-byte object <";
+
+ const size_t kThreshold = 132;
+ const size_t kChunkSize = 64;
+ // If the object size is bigger than kThreshold, we'll have to omit
+ // some details by printing only the first and the last kChunkSize
+ // bytes.
+ // TODO(wan): let the user control the threshold using a flag.
+ if (count < kThreshold) {
+ PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
+ } else {
+ PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
+ *os << " ... ";
+ // Rounds up to 2-byte boundary.
+ const size_t resume_pos = (count - kChunkSize + 1)/2*2;
+ PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
+ }
+ *os << ">";
+}
+
+} // namespace
+
+namespace internal2 {
+
+// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
+// given object. The delegation simplifies the implementation, which
+// uses the << operator and thus is easier done outside of the
+// ::testing::internal namespace, which contains a << operator that
+// sometimes conflicts with the one in STL.
+void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
+ ostream* os) {
+ PrintBytesInObjectToImpl(obj_bytes, count, os);
+}
+
+} // namespace internal2
+
+namespace internal {
+
+// Prints a wide char as a char literal without the quotes, escaping it
+// when necessary.
+static void PrintAsWideCharLiteralTo(wchar_t c, ostream* os) {
+ switch (c) {
+ case L'\0':
+ *os << "\\0";
+ break;
+ case L'\'':
+ *os << "\\'";
+ break;
+ case L'\?':
+ *os << "\\?";
+ break;
+ case L'\\':
+ *os << "\\\\";
+ break;
+ case L'\a':
+ *os << "\\a";
+ break;
+ case L'\b':
+ *os << "\\b";
+ break;
+ case L'\f':
+ *os << "\\f";
+ break;
+ case L'\n':
+ *os << "\\n";
+ break;
+ case L'\r':
+ *os << "\\r";
+ break;
+ case L'\t':
+ *os << "\\t";
+ break;
+ case L'\v':
+ *os << "\\v";
+ break;
+ default:
+ // isprint() takes an int and requires it to be either EOF or in
+ // the range [0, 255]. We check that c is in this range before calling it.
+ if ((c & 0xFF) == c && isprint(c)) {
+ *os << static_cast<char>(c);
+ } else {
+ // Buffer size enough for the maximum number of digits and \0.
+ char text[2 * sizeof(unsigned long) + 1] = "";
+ snprintf(text, sizeof(text), "%lX", static_cast<unsigned long>(c));
+ *os << "\\x" << text;
+ }
+ }
+}
+
+// Prints a char as if it's part of a string literal, escaping it when
+// necessary.
+static void PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
+ switch (c) {
+ case L'\'':
+ *os << "'";
+ break;
+ case L'"':
+ *os << "\\\"";
+ break;
+ default:
+ PrintAsWideCharLiteralTo(c, os);
+ }
+}
+
+// Prints a char as a char literal without the quotes, escaping it
+// when necessary.
+static void PrintAsCharLiteralTo(char c, ostream* os) {
+ PrintAsWideCharLiteralTo(static_cast<unsigned char>(c), os);
+}
+
+// Prints a char as if it's part of a string literal, escaping it when
+// necessary.
+static void PrintAsStringLiteralTo(char c, ostream* os) {
+ PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
+}
+
+// Prints a char and its code. The '\0' char is printed as "'\\0'",
+// other unprintable characters are also properly escaped using the
+// standard C++ escape sequence.
+void PrintCharTo(char c, int char_code, ostream* os) {
+ *os << "'";
+ PrintAsCharLiteralTo(c, os);
+ *os << "'";
+ if (c != '\0')
+ *os << " (" << char_code << ")";
+}
+
+// Prints a wchar_t as a symbol if it is printable or as its internal
+// code otherwise and also as its decimal code (except for L'\0').
+// The L'\0' char is printed as "L'\\0'". The decimal code is printed
+// as signed integer when wchar_t is implemented by the compiler
+// as a signed type and is printed as an unsigned integer when wchar_t
+// is implemented as an unsigned type.
+void PrintTo(wchar_t wc, ostream* os) {
+ *os << "L'";
+ PrintAsWideCharLiteralTo(wc, os);
+ *os << "'";
+ if (wc != L'\0') {
+ // Type Int64 is used because it provides more storage than wchar_t thus
+ // when the compiler converts signed or unsigned implementation of wchar_t
+ // to Int64 it fills higher bits with either zeros or the sign bit
+ // passing it to operator <<() as either signed or unsigned integer.
+ *os << " (" << static_cast<Int64>(wc) << ")";
+ }
+}
+
+// Prints the given array of characters to the ostream.
+// The array starts at *begin, the length is len, it may include '\0' characters
+// and may not be null-terminated.
+static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
+ *os << "\"";
+ for (size_t index = 0; index < len; ++index) {
+ PrintAsStringLiteralTo(begin[index], os);
+ }
+ *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.
+static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
+ ostream* os) {
+ *os << "L\"";
+ for (size_t index = 0; index < len; ++index) {
+ PrintAsWideStringLiteralTo(begin[index], os);
+ }
+ *os << "\"";
+}
+
+// Prints the given C string to the ostream.
+void PrintTo(const char* s, ostream* os) {
+ if (s == NULL) {
+ *os << "NULL";
+ } else {
+ *os << implicit_cast<const void*>(s) << " pointing to ";
+ PrintCharsAsStringTo(s, strlen(s), os);
+ }
+}
+
+// MSVC compiler can be configured to define whar_t as a typedef
+// of unsigned short. Defining an overload for const wchar_t* in that case
+// would cause pointers to unsigned shorts be printed as wide strings,
+// possibly accessing more memory than intended and causing invalid
+// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
+// wchar_t is implemented as a native type.
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+// Prints the given wide C string to the ostream.
+void PrintTo(const wchar_t* s, ostream* os) {
+ if (s == NULL) {
+ *os << "NULL";
+ } else {
+ *os << implicit_cast<const void*>(s) << " pointing to ";
+ PrintWideCharsAsStringTo(s, wcslen(s), os);
+ }
+}
+#endif // wchar_t is native
+
+// Prints a ::string object.
+#if GTEST_HAS_GLOBAL_STRING
+void PrintStringTo(const ::string& s, ostream* os) {
+ PrintCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_STD_STRING
+void PrintStringTo(const ::std::string& s, ostream* os) {
+ PrintCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif // GTEST_HAS_STD_STRING
+
+// Prints a ::wstring object.
+#if GTEST_HAS_GLOBAL_WSTRING
+void PrintWideStringTo(const ::wstring& s, ostream* os) {
+ PrintWideCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+#if GTEST_HAS_STD_WSTRING
+void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
+ PrintWideCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif // GTEST_HAS_STD_WSTRING
+
+} // namespace internal
+
+} // namespace testing
diff --git a/src/gmock-spec-builders.cc b/src/gmock-spec-builders.cc
new file mode 100644
index 00000000..353bb2df
--- /dev/null
+++ b/src/gmock-spec-builders.cc
@@ -0,0 +1,337 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements the spec builder syntax (ON_CALL and
+// EXPECT_CALL).
+
+#include <gmock/gmock-spec-builders.h>
+
+#include <set>
+#include <gtest/gtest.h>
+
+namespace testing {
+namespace internal {
+
+// Protects the mock object registry (in class Mock), all function
+// mockers, and all expectations.
+Mutex g_gmock_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
+
+// Constructs an ExpectationBase object.
+ExpectationBase::ExpectationBase(const char* file, int line)
+ : file_(file),
+ line_(line),
+ cardinality_specified_(false),
+ cardinality_(Exactly(1)),
+ call_count_(0),
+ retired_(false) {
+}
+
+// Destructs an ExpectationBase object.
+ExpectationBase::~ExpectationBase() {}
+
+// Explicitly specifies the cardinality of this expectation. Used by
+// the subclasses to implement the .Times() clause.
+void ExpectationBase::SpecifyCardinality(const Cardinality& cardinality) {
+ cardinality_specified_ = true;
+ cardinality_ = cardinality;
+}
+
+// Retires all pre-requisites of this expectation.
+void ExpectationBase::RetireAllPreRequisites() {
+ if (is_retired()) {
+ // We can take this short-cut as we never retire an expectation
+ // until we have retired all its pre-requisites.
+ return;
+ }
+
+ for (ExpectationBaseSet::const_iterator it =
+ immediate_prerequisites_.begin();
+ it != immediate_prerequisites_.end();
+ ++it) {
+ ExpectationBase* const prerequisite = (*it).get();
+ if (!prerequisite->is_retired()) {
+ prerequisite->RetireAllPreRequisites();
+ prerequisite->Retire();
+ }
+ }
+}
+
+// Returns true iff all pre-requisites of this expectation have been
+// satisfied.
+// L >= g_gmock_mutex
+bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
+ g_gmock_mutex.AssertHeld();
+ for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
+ it != immediate_prerequisites_.end(); ++it) {
+ if (!(*it)->IsSatisfied() ||
+ !(*it)->AllPrerequisitesAreSatisfied())
+ return false;
+ }
+ return true;
+}
+
+// Adds unsatisfied pre-requisites of this expectation to 'result'.
+// L >= g_gmock_mutex
+void ExpectationBase::FindUnsatisfiedPrerequisites(
+ ExpectationBaseSet* result) const {
+ g_gmock_mutex.AssertHeld();
+ for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
+ it != immediate_prerequisites_.end(); ++it) {
+ if ((*it)->IsSatisfied()) {
+ // If *it is satisfied and has a call count of 0, some of its
+ // pre-requisites may not be satisfied yet.
+ if ((*it)->call_count_ == 0) {
+ (*it)->FindUnsatisfiedPrerequisites(result);
+ }
+ } else {
+ // Now that we know *it is unsatisfied, we are not so interested
+ // in whether its pre-requisites are satisfied. Therefore we
+ // don't recursively call FindUnsatisfiedPrerequisites() here.
+ result->insert(*it);
+ }
+ }
+}
+
+// Points to the implicit sequence introduced by a living InSequence
+// object (if any) in the current thread or NULL.
+ThreadLocal<Sequence*> g_gmock_implicit_sequence;
+
+// Reports an uninteresting call (whose description is in msg) in the
+// manner specified by 'reaction'.
+void ReportUninterestingCall(CallReaction reaction, const string& msg) {
+ switch (reaction) {
+ case ALLOW:
+ Log(INFO, msg, 4);
+ break;
+ case WARN:
+ Log(WARNING, msg, 4);
+ break;
+ default: // FAIL
+ Expect(false, NULL, -1, msg);
+ }
+}
+
+} // namespace internal
+
+// Class Mock.
+
+namespace {
+
+typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
+typedef std::map<const void*, FunctionMockers> MockObjectRegistry;
+
+// Maps a mock object to the set of mock methods it owns. Protected
+// by g_gmock_mutex.
+MockObjectRegistry g_mock_object_registry;
+
+// Maps a mock object to the reaction Google Mock should have when an
+// uninteresting method is called. Protected by g_gmock_mutex.
+std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
+
+// Sets the reaction Google Mock should have when an uninteresting
+// method of the given mock object is called.
+// L < g_gmock_mutex
+void SetReactionOnUninterestingCalls(const void* mock_obj,
+ internal::CallReaction reaction) {
+ internal::MutexLock l(&internal::g_gmock_mutex);
+ g_uninteresting_call_reaction[mock_obj] = reaction;
+}
+
+} // namespace
+
+// Tells Google Mock to allow uninteresting calls on the given mock
+// object.
+// L < g_gmock_mutex
+void Mock::AllowUninterestingCalls(const void* mock_obj) {
+ SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
+}
+
+// Tells Google Mock to warn the user about uninteresting calls on the
+// given mock object.
+// L < g_gmock_mutex
+void Mock::WarnUninterestingCalls(const void* mock_obj) {
+ SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
+}
+
+// Tells Google Mock to fail uninteresting calls on the given mock
+// object.
+// L < g_gmock_mutex
+void Mock::FailUninterestingCalls(const void* mock_obj) {
+ SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
+}
+
+// Tells Google Mock the given mock object is being destroyed and its
+// entry in the call-reaction table should be removed.
+// L < g_gmock_mutex
+void Mock::UnregisterCallReaction(const void* mock_obj) {
+ internal::MutexLock l(&internal::g_gmock_mutex);
+ g_uninteresting_call_reaction.erase(mock_obj);
+}
+
+// Returns the reaction Google Mock will have on uninteresting calls
+// made on the given mock object.
+// L < g_gmock_mutex
+internal::CallReaction Mock::GetReactionOnUninterestingCalls(
+ const void* mock_obj) {
+ internal::MutexLock l(&internal::g_gmock_mutex);
+ return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
+ internal::WARN : g_uninteresting_call_reaction[mock_obj];
+}
+
+// Verifies and clears all expectations on the given mock object. If
+// the expectations aren't satisfied, generates one or more Google
+// Test non-fatal failures and returns false.
+// L < g_gmock_mutex
+bool Mock::VerifyAndClearExpectations(void* mock_obj) {
+ internal::MutexLock l(&internal::g_gmock_mutex);
+ return VerifyAndClearExpectationsLocked(mock_obj);
+}
+
+// Verifies all expectations on the given mock object and clears its
+// default actions and expectations. Returns true iff the
+// verification was successful.
+// L < g_gmock_mutex
+bool Mock::VerifyAndClear(void* mock_obj) {
+ internal::MutexLock l(&internal::g_gmock_mutex);
+ ClearDefaultActionsLocked(mock_obj);
+ return VerifyAndClearExpectationsLocked(mock_obj);
+}
+
+// Verifies and clears all expectations on the given mock object. If
+// the expectations aren't satisfied, generates one or more Google
+// Test non-fatal failures and returns false.
+// L >= g_gmock_mutex
+bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
+ internal::g_gmock_mutex.AssertHeld();
+ if (g_mock_object_registry.count(mock_obj) == 0) {
+ // No EXPECT_CALL() was set on the given mock object.
+ return true;
+ }
+
+ // Verifies and clears the expectations on each mock method in the
+ // given mock object.
+ bool expectations_met = true;
+ FunctionMockers& mockers = g_mock_object_registry[mock_obj];
+ for (FunctionMockers::const_iterator it = mockers.begin();
+ it != mockers.end(); ++it) {
+ if (!(*it)->VerifyAndClearExpectationsLocked()) {
+ expectations_met = false;
+ }
+ }
+
+ // We don't clear the content of mockers, as they may still be
+ // needed by ClearDefaultActionsLocked().
+ return expectations_met;
+}
+
+// Registers a mock object and a mock method it owns.
+// L < g_gmock_mutex
+void Mock::Register(const void* mock_obj,
+ internal::UntypedFunctionMockerBase* mocker) {
+ internal::MutexLock l(&internal::g_gmock_mutex);
+ g_mock_object_registry[mock_obj].insert(mocker);
+}
+
+// Unregisters a mock method; removes the owning mock object from the
+// registry when the last mock method associated with it has been
+// unregistered. This is called only in the destructor of
+// FunctionMockerBase.
+// L >= g_gmock_mutex
+void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
+ internal::g_gmock_mutex.AssertHeld();
+ for (MockObjectRegistry::iterator it = g_mock_object_registry.begin();
+ it != g_mock_object_registry.end(); ++it) {
+ FunctionMockers& mockers = it->second;
+ if (mockers.erase(mocker) > 0) {
+ // mocker was in mockers and has been just removed.
+ if (mockers.empty()) {
+ g_mock_object_registry.erase(it);
+ }
+ return;
+ }
+ }
+}
+
+// Clears all ON_CALL()s set on the given mock object.
+// L >= g_gmock_mutex
+void Mock::ClearDefaultActionsLocked(void* mock_obj) {
+ internal::g_gmock_mutex.AssertHeld();
+
+ if (g_mock_object_registry.count(mock_obj) == 0) {
+ // No ON_CALL() was set on the given mock object.
+ return;
+ }
+
+ // Clears the default actions for each mock method in the given mock
+ // object.
+ FunctionMockers& mockers = g_mock_object_registry[mock_obj];
+ for (FunctionMockers::const_iterator it = mockers.begin();
+ it != mockers.end(); ++it) {
+ (*it)->ClearDefaultActionsLocked();
+ }
+
+ // We don't clear the content of mockers, as they may still be
+ // needed by VerifyAndClearExpectationsLocked().
+}
+
+// Adds an expectation to a sequence.
+void Sequence::AddExpectation(
+ const internal::linked_ptr<internal::ExpectationBase>& expectation) const {
+ if (*last_expectation_ != expectation) {
+ if (*last_expectation_ != NULL) {
+ expectation->immediate_prerequisites_.insert(*last_expectation_);
+ }
+ *last_expectation_ = expectation;
+ }
+}
+
+// Creates the implicit sequence if there isn't one.
+InSequence::InSequence() {
+ if (internal::g_gmock_implicit_sequence.get() == NULL) {
+ internal::g_gmock_implicit_sequence.set(new Sequence);
+ sequence_created_ = true;
+ } else {
+ sequence_created_ = false;
+ }
+}
+
+// Deletes the implicit sequence if it was created by the constructor
+// of this object.
+InSequence::~InSequence() {
+ if (sequence_created_) {
+ delete internal::g_gmock_implicit_sequence.get();
+ internal::g_gmock_implicit_sequence.set(NULL);
+ }
+}
+
+} // namespace testing
diff --git a/src/gmock.cc b/src/gmock.cc
new file mode 100644
index 00000000..b2f3d59d
--- /dev/null
+++ b/src/gmock.cc
@@ -0,0 +1,155 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+#include <gmock/gmock.h>
+#include <gmock/internal/gmock-port.h>
+
+namespace testing {
+
+GMOCK_DEFINE_string(verbose, internal::kWarningVerbosity,
+ "Controls how verbose Google Mock's output is."
+ " Valid values:\n"
+ " info - prints all messages.\n"
+ " warning - prints warnings and errors.\n"
+ " error - prints errors only.");
+
+namespace internal {
+
+// Parses a string as a command line flag. The string should have the
+// format "--gmock_flag=value". When def_optional is true, the
+// "=value" part can be omitted.
+//
+// Returns the value of the flag, or NULL if the parsing failed.
+static const char* ParseGoogleMockFlagValue(const char* str,
+ const char* flag,
+ bool def_optional) {
+ // str and flag must not be NULL.
+ if (str == NULL || flag == NULL) return NULL;
+
+ // The flag must start with "--gmock_".
+ const String flag_str = String::Format("--gmock_%s", flag);
+ const size_t flag_len = flag_str.GetLength();
+ if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+
+ // Skips the flag name.
+ const char* flag_end = str + flag_len;
+
+ // When def_optional is true, it's OK to not have a "=value" part.
+ if (def_optional && (flag_end[0] == '\0')) {
+ return flag_end;
+ }
+
+ // If def_optional is true and there are more characters after the
+ // flag name, or if def_optional is false, there must be a '=' after
+ // the flag name.
+ if (flag_end[0] != '=') return NULL;
+
+ // Returns the string after "=".
+ return flag_end + 1;
+}
+
+// Parses a string for a Google Mock string flag, in the form of
+// "--gmock_flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true. On failure, returns false without changing *value.
+static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
+ String* value) {
+ // Gets the value of the flag as a string.
+ const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
+
+ // Aborts if the parsing failed.
+ if (value_str == NULL) return false;
+
+ // Sets *value to the value of the flag.
+ *value = value_str;
+ return true;
+}
+
+// The internal implementation of InitGoogleMock().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void InitGoogleMockImpl(int* argc, CharType** argv) {
+ // Makes sure Google Test is initialized. InitGoogleTest() is
+ // idempotent, so it's fine if the user has already called it.
+ InitGoogleTest(argc, argv);
+ if (*argc <= 0) return;
+
+ for (int i = 1; i != *argc; i++) {
+ const String arg_string = StreamableToString(argv[i]);
+ const char* const arg = arg_string.c_str();
+
+ // Do we see a Google Mock flag?
+ if (ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
+ // Yes. Shift the remainder of the argv list left by one. Note
+ // that argv has (*argc + 1) elements, the last one always being
+ // NULL. The following loop moves the trailing NULL element as
+ // well.
+ for (int j = i; j != *argc; j++) {
+ argv[j] = argv[j + 1];
+ }
+
+ // Decrements the argument count.
+ (*argc)--;
+
+ // We also need to decrement the iterator as we just removed
+ // an element.
+ i--;
+ }
+ }
+}
+
+} // namespace internal
+
+// Initializes Google Mock. This must be called before running the
+// tests. In particular, it parses a command line for the flags that
+// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
+// removed from argv, and *argc is decremented.
+//
+// No value is returned. Instead, the Google Mock flag variables are
+// updated.
+//
+// Since Google Test is needed for Google Mock to work, this function
+// also initializes Google Test and parses its flags, if that hasn't
+// been done.
+void InitGoogleMock(int* argc, char** argv) {
+ internal::InitGoogleMockImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleMock(int* argc, wchar_t** argv) {
+ internal::InitGoogleMockImpl(argc, argv);
+}
+
+} // namespace testing
diff --git a/src/gmock_main.cc b/src/gmock_main.cc
new file mode 100644
index 00000000..a97e9532
--- /dev/null
+++ b/src/gmock_main.cc
@@ -0,0 +1,43 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+#include <iostream>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+ std::cout << "Running main() from gmock_main.cc\n";
+ // Since Google Mock depends on Google Test, InitGoogleMock() is
+ // also responsible for initializing Google Test. Therefore there's
+ // no need for calling testing::InitGoogleTest() separately.
+ testing::InitGoogleMock(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc
new file mode 100644
index 00000000..1000e306
--- /dev/null
+++ b/test/gmock-actions_test.cc
@@ -0,0 +1,902 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the built-in actions.
+
+#include <gmock/gmock-actions.h>
+#include <algorithm>
+#include <iterator>
+#include <string>
+#include <gmock/gmock.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace {
+
+using ::std::tr1::get;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+using ::std::tr1::tuple_element;
+using testing::internal::BuiltInDefaultValue;
+using testing::internal::Int64;
+using testing::internal::UInt64;
+// This list should be kept sorted.
+using testing::_;
+using testing::Action;
+using testing::ActionInterface;
+using testing::Assign;
+using testing::DefaultValue;
+using testing::DoDefault;
+using testing::IgnoreResult;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::MakePolymorphicAction;
+using testing::Ne;
+using testing::PolymorphicAction;
+using testing::Return;
+using testing::ReturnNull;
+using testing::ReturnRef;
+using testing::SetArgumentPointee;
+using testing::SetArrayArgument;
+using testing::SetErrnoAndReturn;
+
+#if GMOCK_HAS_PROTOBUF_
+using testing::internal::TestMessage;
+#endif // GMOCK_HAS_PROTOBUF_
+
+// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
+TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
+ EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == NULL);
+ EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == NULL);
+ EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == NULL);
+}
+
+// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a
+// built-in numeric type.
+TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
+ EXPECT_EQ(0, BuiltInDefaultValue<unsigned char>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
+#ifndef GTEST_OS_WINDOWS
+ EXPECT_EQ(0, BuiltInDefaultValue<unsigned wchar_t>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get());
+#endif // GTEST_OS_WINDOWS
+ EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT
+ EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT
+ EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT
+ EXPECT_EQ(0, BuiltInDefaultValue<unsigned int>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<int>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT
+ EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT
+ EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT
+ EXPECT_EQ(0, BuiltInDefaultValue<UInt64>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<float>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<double>::Get());
+}
+
+// Tests that BuiltInDefaultValue<bool>::Get() returns false.
+TEST(BuiltInDefaultValueTest, IsFalseForBool) {
+ EXPECT_FALSE(BuiltInDefaultValue<bool>::Get());
+}
+
+// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a
+// string type.
+TEST(BuiltInDefaultValueTest, IsEmptyStringForString) {
+#if GTEST_HAS_GLOBAL_STRING
+ EXPECT_EQ("", BuiltInDefaultValue< ::string>::Get());
+#endif // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_STD_STRING
+ EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get());
+#endif // GTEST_HAS_STD_STRING
+}
+
+// Tests that BuiltInDefaultValue<const T>::Get() returns the same
+// value as BuiltInDefaultValue<T>::Get() does.
+TEST(BuiltInDefaultValueTest, WorksForConstTypes) {
+ EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get());
+ EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get());
+ EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == NULL);
+ EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get());
+}
+
+// Tests that BuiltInDefaultValue<T>::Get() aborts the program with
+// the correct error message when T is a user-defined type.
+struct UserType {
+ UserType() : value(0) {}
+
+ int value;
+};
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Tests that BuiltInDefaultValue<T&>::Get() aborts the program.
+TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) {
+ EXPECT_DEATH({ // NOLINT
+ BuiltInDefaultValue<int&>::Get();
+ }, "");
+ EXPECT_DEATH({ // NOLINT
+ BuiltInDefaultValue<const char&>::Get();
+ }, "");
+}
+
+TEST(BuiltInDefaultValueDeathTest, IsUndefinedForUserTypes) {
+ EXPECT_DEATH({ // NOLINT
+ BuiltInDefaultValue<UserType>::Get();
+ }, "");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+// Tests that DefaultValue<T>::IsSet() is false initially.
+TEST(DefaultValueTest, IsInitiallyUnset) {
+ EXPECT_FALSE(DefaultValue<int>::IsSet());
+ EXPECT_FALSE(DefaultValue<const UserType>::IsSet());
+}
+
+// Tests that DefaultValue<T> can be set and then unset.
+TEST(DefaultValueTest, CanBeSetAndUnset) {
+ DefaultValue<int>::Set(1);
+ DefaultValue<const UserType>::Set(UserType());
+
+ EXPECT_EQ(1, DefaultValue<int>::Get());
+ EXPECT_EQ(0, DefaultValue<const UserType>::Get().value);
+
+ DefaultValue<int>::Clear();
+ DefaultValue<const UserType>::Clear();
+
+ EXPECT_FALSE(DefaultValue<int>::IsSet());
+ EXPECT_FALSE(DefaultValue<const UserType>::IsSet());
+}
+
+// Tests that DefaultValue<T>::Get() returns the
+// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is
+// false.
+TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
+ EXPECT_FALSE(DefaultValue<int>::IsSet());
+ EXPECT_FALSE(DefaultValue<UserType>::IsSet());
+
+ EXPECT_EQ(0, DefaultValue<int>::Get());
+
+#ifdef GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH({ // NOLINT
+ DefaultValue<UserType>::Get();
+ }, "");
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+// Tests that DefaultValue<void>::Get() returns void.
+TEST(DefaultValueTest, GetWorksForVoid) {
+ return DefaultValue<void>::Get();
+}
+
+// Tests using DefaultValue with a reference type.
+
+// Tests that DefaultValue<T&>::IsSet() is false initially.
+TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) {
+ EXPECT_FALSE(DefaultValue<int&>::IsSet());
+ EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
+}
+
+// Tests that DefaultValue<T&> can be set and then unset.
+TEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) {
+ int n = 1;
+ DefaultValue<const int&>::Set(n);
+ UserType u;
+ DefaultValue<UserType&>::Set(u);
+
+ EXPECT_EQ(&n, &(DefaultValue<const int&>::Get()));
+ EXPECT_EQ(&u, &(DefaultValue<UserType&>::Get()));
+
+ DefaultValue<const int&>::Clear();
+ DefaultValue<UserType&>::Clear();
+
+ EXPECT_FALSE(DefaultValue<const int&>::IsSet());
+ EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
+}
+
+// Tests that DefaultValue<T&>::Get() returns the
+// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is
+// false.
+TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
+ EXPECT_FALSE(DefaultValue<int&>::IsSet());
+ EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
+
+#ifdef GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH({ // NOLINT
+ DefaultValue<int&>::Get();
+ }, "");
+ EXPECT_DEATH({ // NOLINT
+ DefaultValue<UserType>::Get();
+ }, "");
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+// Tests that ActionInterface can be implemented by defining the
+// Perform method.
+
+typedef int MyFunction(bool, int);
+
+class MyActionImpl : public ActionInterface<MyFunction> {
+ public:
+ virtual int Perform(const tuple<bool, int>& args) {
+ return get<0>(args) ? get<1>(args) : 0;
+ }
+};
+
+TEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) {
+ MyActionImpl my_action_impl;
+
+ EXPECT_FALSE(my_action_impl.IsDoDefault());
+}
+
+TEST(ActionInterfaceTest, MakeAction) {
+ Action<MyFunction> action = MakeAction(new MyActionImpl);
+
+ // When exercising the Perform() method of Action<F>, we must pass
+ // it a tuple whose size and type are compatible with F's argument
+ // types. For example, if F is int(), then Perform() takes a
+ // 0-tuple; if F is void(bool, int), then Perform() takes a
+ // tuple<bool, int>, and so on.
+ EXPECT_EQ(5, action.Perform(make_tuple(true, 5)));
+}
+
+// Tests that Action<F> can be contructed from a pointer to
+// ActionInterface<F>.
+TEST(ActionTest, CanBeConstructedFromActionInterface) {
+ Action<MyFunction> action(new MyActionImpl);
+}
+
+// Tests that Action<F> delegates actual work to ActionInterface<F>.
+TEST(ActionTest, DelegatesWorkToActionInterface) {
+ const Action<MyFunction> action(new MyActionImpl);
+
+ EXPECT_EQ(5, action.Perform(make_tuple(true, 5)));
+ EXPECT_EQ(0, action.Perform(make_tuple(false, 1)));
+}
+
+// Tests that Action<F> can be copied.
+TEST(ActionTest, IsCopyable) {
+ Action<MyFunction> a1(new MyActionImpl);
+ Action<MyFunction> a2(a1); // Tests the copy constructor.
+
+ // a1 should continue to work after being copied from.
+ EXPECT_EQ(5, a1.Perform(make_tuple(true, 5)));
+ EXPECT_EQ(0, a1.Perform(make_tuple(false, 1)));
+
+ // a2 should work like the action it was copied from.
+ EXPECT_EQ(5, a2.Perform(make_tuple(true, 5)));
+ EXPECT_EQ(0, a2.Perform(make_tuple(false, 1)));
+
+ a2 = a1; // Tests the assignment operator.
+
+ // a1 should continue to work after being copied from.
+ EXPECT_EQ(5, a1.Perform(make_tuple(true, 5)));
+ EXPECT_EQ(0, a1.Perform(make_tuple(false, 1)));
+
+ // a2 should work like the action it was copied from.
+ EXPECT_EQ(5, a2.Perform(make_tuple(true, 5)));
+ EXPECT_EQ(0, a2.Perform(make_tuple(false, 1)));
+}
+
+// Tests that an Action<From> object can be converted to a
+// compatible Action<To> object.
+
+class IsNotZero : public ActionInterface<bool(int)> { // NOLINT
+ public:
+ virtual bool Perform(const tuple<int>& arg) {
+ return get<0>(arg) != 0;
+ }
+};
+
+TEST(ActionTest, CanBeConvertedToOtherActionType) {
+ const Action<bool(int)> a1(new IsNotZero); // NOLINT
+ const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT
+ EXPECT_EQ(1, a2.Perform(make_tuple('a')));
+ EXPECT_EQ(0, a2.Perform(make_tuple('\0')));
+}
+
+// The following two classes are for testing MakePolymorphicAction().
+
+// Implements a polymorphic action that returns the second of the
+// arguments it receives.
+class ReturnSecondArgumentAction {
+ public:
+ // We want to verify that MakePolymorphicAction() can work with a
+ // polymorphic action whose Perform() method template is either
+ // const or not. This lets us verify the non-const case.
+ template <typename Result, typename ArgumentTuple>
+ Result Perform(const ArgumentTuple& args) { return get<1>(args); }
+};
+
+// Implements a polymorphic action that can be used in a nullary
+// function to return 0.
+class ReturnZeroFromNullaryFunctionAction {
+ public:
+ // For testing that MakePolymorphicAction() works when the
+ // implementation class' Perform() method template takes only one
+ // template parameter.
+ //
+ // We want to verify that MakePolymorphicAction() can work with a
+ // polymorphic action whose Perform() method template is either
+ // const or not. This lets us verify the const case.
+ template <typename Result>
+ Result Perform(const tuple<>&) const { return 0; }
+};
+
+// These functions verify that MakePolymorphicAction() returns a
+// PolymorphicAction<T> where T is the argument's type.
+
+PolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() {
+ return MakePolymorphicAction(ReturnSecondArgumentAction());
+}
+
+PolymorphicAction<ReturnZeroFromNullaryFunctionAction>
+ReturnZeroFromNullaryFunction() {
+ return MakePolymorphicAction(ReturnZeroFromNullaryFunctionAction());
+}
+
+// Tests that MakePolymorphicAction() turns a polymorphic action
+// implementation class into a polymorphic action.
+TEST(MakePolymorphicActionTest, ConstructsActionFromImpl) {
+ Action<int(bool, int, double)> a1 = ReturnSecondArgument(); // NOLINT
+ EXPECT_EQ(5, a1.Perform(make_tuple(false, 5, 2.0)));
+}
+
+// Tests that MakePolymorphicAction() works when the implementation
+// class' Perform() method template has only one template parameter.
+TEST(MakePolymorphicActionTest, WorksWhenPerformHasOneTemplateParameter) {
+ Action<int()> a1 = ReturnZeroFromNullaryFunction();
+ EXPECT_EQ(0, a1.Perform(make_tuple()));
+
+ Action<void*()> a2 = ReturnZeroFromNullaryFunction();
+ EXPECT_TRUE(a2.Perform(make_tuple()) == NULL);
+}
+
+// Tests that Return() works as an action for void-returning
+// functions.
+TEST(ReturnTest, WorksForVoid) {
+ const Action<void(int)> ret = Return(); // NOLINT
+ return ret.Perform(make_tuple(1));
+}
+
+// Tests that Return(v) returns v.
+TEST(ReturnTest, ReturnsGivenValue) {
+ Action<int()> ret = Return(1); // NOLINT
+ EXPECT_EQ(1, ret.Perform(make_tuple()));
+
+ ret = Return(-5);
+ EXPECT_EQ(-5, ret.Perform(make_tuple()));
+}
+
+// Tests that Return("string literal") works.
+TEST(ReturnTest, AcceptsStringLiteral) {
+ Action<const char*()> a1 = Return("Hello");
+ EXPECT_STREQ("Hello", a1.Perform(make_tuple()));
+
+ Action<std::string()> a2 = Return("world");
+ EXPECT_EQ("world", a2.Perform(make_tuple()));
+}
+
+// Tests that Return(v) is covaraint.
+
+struct Base {
+ bool operator==(const Base&) { return true; }
+};
+
+struct Derived : public Base {
+ bool operator==(const Derived&) { return true; }
+};
+
+TEST(ReturnTest, IsCovariant) {
+ Base base;
+ Derived derived;
+ Action<Base*()> ret = Return(&base);
+ EXPECT_EQ(&base, ret.Perform(make_tuple()));
+
+ ret = Return(&derived);
+ EXPECT_EQ(&derived, ret.Perform(make_tuple()));
+}
+
+// Tests that ReturnNull() returns NULL in a pointer-returning function.
+TEST(ReturnNullTest, WorksInPointerReturningFunction) {
+ const Action<int*()> a1 = ReturnNull();
+ EXPECT_TRUE(a1.Perform(make_tuple()) == NULL);
+
+ const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT
+ EXPECT_TRUE(a2.Perform(make_tuple(true)) == NULL);
+}
+
+// Tests that ReturnRef(v) works for reference types.
+TEST(ReturnRefTest, WorksForReference) {
+ const int n = 0;
+ const Action<const int&(bool)> ret = ReturnRef(n); // NOLINT
+
+ EXPECT_EQ(&n, &ret.Perform(make_tuple(true)));
+}
+
+// Tests that ReturnRef(v) is covariant.
+TEST(ReturnRefTest, IsCovariant) {
+ Base base;
+ Derived derived;
+ Action<Base&()> a = ReturnRef(base);
+ EXPECT_EQ(&base, &a.Perform(make_tuple()));
+
+ a = ReturnRef(derived);
+ EXPECT_EQ(&derived, &a.Perform(make_tuple()));
+}
+
+// Tests that DoDefault() does the default action for the mock method.
+
+class MyClass {};
+
+class MockClass {
+ public:
+ MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
+ MOCK_METHOD0(Foo, MyClass());
+};
+
+// Tests that DoDefault() returns the built-in default value for the
+// return type by default.
+TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) {
+ MockClass mock;
+ EXPECT_CALL(mock, IntFunc(_))
+ .WillOnce(DoDefault());
+ EXPECT_EQ(0, mock.IntFunc(true));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Tests that DoDefault() aborts the process when there is no built-in
+// default value for the return type.
+TEST(DoDefaultDeathTest, DiesForUnknowType) {
+ MockClass mock;
+ EXPECT_CALL(mock, Foo())
+ .WillRepeatedly(DoDefault());
+ EXPECT_DEATH({ // NOLINT
+ mock.Foo();
+ }, "");
+}
+
+// Tests that using DoDefault() inside a composite action leads to a
+// run-time error.
+
+void VoidFunc(bool flag) {}
+
+TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
+ MockClass mock;
+ EXPECT_CALL(mock, IntFunc(_))
+ .WillRepeatedly(DoAll(Invoke(VoidFunc),
+ DoDefault()));
+
+ // Ideally we should verify the error message as well. Sadly,
+ // EXPECT_DEATH() can only capture stderr, while Google Mock's
+ // errors are printed on stdout. Therefore we have to settle for
+ // not verifying the message.
+ EXPECT_DEATH({ // NOLINT
+ mock.IntFunc(true);
+ }, "");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+// Tests that DoDefault() returns the default value set by
+// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
+TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
+ DefaultValue<int>::Set(1);
+ MockClass mock;
+ EXPECT_CALL(mock, IntFunc(_))
+ .WillOnce(DoDefault());
+ EXPECT_EQ(1, mock.IntFunc(false));
+ DefaultValue<int>::Clear();
+}
+
+// Tests that DoDefault() does the action specified by ON_CALL().
+TEST(DoDefaultTest, DoesWhatOnCallSpecifies) {
+ MockClass mock;
+ ON_CALL(mock, IntFunc(_))
+ .WillByDefault(Return(2));
+ EXPECT_CALL(mock, IntFunc(_))
+ .WillOnce(DoDefault());
+ EXPECT_EQ(2, mock.IntFunc(false));
+}
+
+// Tests that using DoDefault() in ON_CALL() leads to a run-time failure.
+TEST(DoDefaultTest, CannotBeUsedInOnCall) {
+ MockClass mock;
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ ON_CALL(mock, IntFunc(_))
+ .WillByDefault(DoDefault());
+ }, "DoDefault() cannot be used in ON_CALL()");
+}
+
+// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
+// the N-th (0-based) argument to v.
+TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
+ typedef void MyFunction(bool, int*, char*);
+ Action<MyFunction> a = SetArgumentPointee<1>(2);
+
+ int n = 0;
+ char ch = '\0';
+ a.Perform(make_tuple(true, &n, &ch));
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('\0', ch);
+
+ a = SetArgumentPointee<2>('a');
+ n = 0;
+ ch = '\0';
+ a.Perform(make_tuple(true, &n, &ch));
+ EXPECT_EQ(0, n);
+ EXPECT_EQ('a', ch);
+}
+
+#if GMOCK_HAS_PROTOBUF_
+
+// Tests that SetArgumentPointee<N>(proto_buffer) sets the variable
+// pointed to by the N-th (0-based) argument to proto_buffer.
+TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
+ typedef void MyFunction(bool, TestMessage*);
+ TestMessage* const msg = new TestMessage;
+ msg->set_member("yes");
+ TestMessage orig_msg;
+ orig_msg.CopyFrom(*msg);
+
+ Action<MyFunction> a = SetArgumentPointee<1>(*msg);
+ // SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
+ // s.t. the action works even when the original proto_buffer has
+ // died. We ensure this behavior by deleting msg before using the
+ // action.
+ delete msg;
+
+ TestMessage dest;
+ EXPECT_FALSE(orig_msg.Equals(dest));
+ a.Perform(make_tuple(true, &dest));
+ EXPECT_TRUE(orig_msg.Equals(dest));
+}
+
+// Tests that SetArgumentPointee<N>(proto2_buffer) sets the variable
+// pointed to by the N-th (0-based) argument to proto2_buffer.
+TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
+ using testing::internal::FooMessage;
+ typedef void MyFunction(bool, FooMessage*);
+ FooMessage* const msg = new FooMessage;
+ msg->set_int_field(2);
+ msg->set_string_field("hi");
+ FooMessage orig_msg;
+ orig_msg.CopyFrom(*msg);
+
+ Action<MyFunction> a = SetArgumentPointee<1>(*msg);
+ // SetArgumentPointee<N>(proto2_buffer) makes a copy of
+ // proto2_buffer s.t. the action works even when the original
+ // proto2_buffer has died. We ensure this behavior by deleting msg
+ // before using the action.
+ delete msg;
+
+ FooMessage dest;
+ dest.set_int_field(0);
+ a.Perform(make_tuple(true, &dest));
+ EXPECT_EQ(2, dest.int_field());
+ EXPECT_EQ("hi", dest.string_field());
+}
+
+#endif // GMOCK_HAS_PROTOBUF_
+
+// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
+// pointed to by the N-th (0-based) argument to values in range [first, last).
+TEST(SetArrayArgumentTest, SetsTheNthArray) {
+ typedef void MyFunction(bool, int*, char*);
+ int numbers[] = { 1, 2, 3 };
+ Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
+
+ int n[4] = {};
+ int* pn = n;
+ char ch[4] = {};
+ char* pch = ch;
+ a.Perform(make_tuple(true, pn, pch));
+ EXPECT_EQ(1, n[0]);
+ EXPECT_EQ(2, n[1]);
+ EXPECT_EQ(3, n[2]);
+ EXPECT_EQ(0, n[3]);
+ EXPECT_EQ('\0', ch[0]);
+ EXPECT_EQ('\0', ch[1]);
+ EXPECT_EQ('\0', ch[2]);
+ EXPECT_EQ('\0', ch[3]);
+
+ // Tests first and last are iterators.
+ std::string letters = "abc";
+ a = SetArrayArgument<2>(letters.begin(), letters.end());
+ std::fill_n(n, 4, 0);
+ std::fill_n(ch, 4, '\0');
+ a.Perform(make_tuple(true, pn, pch));
+ EXPECT_EQ(0, n[0]);
+ EXPECT_EQ(0, n[1]);
+ EXPECT_EQ(0, n[2]);
+ EXPECT_EQ(0, n[3]);
+ EXPECT_EQ('a', ch[0]);
+ EXPECT_EQ('b', ch[1]);
+ EXPECT_EQ('c', ch[2]);
+ EXPECT_EQ('\0', ch[3]);
+}
+
+// Tests SetArrayArgument<N>(first, last) where first == last.
+TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
+ typedef void MyFunction(bool, int*);
+ int numbers[] = { 1, 2, 3 };
+ Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
+
+ int n[4] = {};
+ int* pn = n;
+ a.Perform(make_tuple(true, pn));
+ EXPECT_EQ(0, n[0]);
+ EXPECT_EQ(0, n[1]);
+ EXPECT_EQ(0, n[2]);
+ EXPECT_EQ(0, n[3]);
+}
+
+// Tests SetArrayArgument<N>(first, last) where *first is convertible
+// (but not equal) to the argument type.
+TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
+ typedef void MyFunction(bool, char*);
+ int codes[] = { 97, 98, 99 };
+ Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
+
+ char ch[4] = {};
+ char* pch = ch;
+ a.Perform(make_tuple(true, pch));
+ EXPECT_EQ('a', ch[0]);
+ EXPECT_EQ('b', ch[1]);
+ EXPECT_EQ('c', ch[2]);
+ EXPECT_EQ('\0', ch[3]);
+}
+
+// Test SetArrayArgument<N>(first, last) with iterator as argument.
+TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
+ typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
+ std::string letters = "abc";
+ Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
+
+ std::string s;
+ a.Perform(make_tuple(true, back_inserter(s)));
+ EXPECT_EQ(letters, s);
+}
+
+// Sample functions and functors for testing Invoke() and etc.
+int Nullary() { return 1; }
+
+class NullaryFunctor {
+ public:
+ int operator()() { return 2; }
+};
+
+bool g_done = false;
+void VoidNullary() { g_done = true; }
+
+class VoidNullaryFunctor {
+ public:
+ void operator()() { g_done = true; }
+};
+
+bool Unary(int x) { return x < 0; }
+
+const char* Plus1(const char* s) { return s + 1; }
+
+void VoidUnary(int n) { g_done = true; }
+
+bool ByConstRef(const std::string& s) { return s == "Hi"; }
+
+const double g_double = 0;
+bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
+
+std::string ByNonConstRef(std::string& s) { return s += "+"; } // NOLINT
+
+struct UnaryFunctor {
+ int operator()(bool x) { return x ? 1 : -1; }
+};
+
+const char* Binary(const char* input, short n) { return input + n; } // NOLINT
+
+void VoidBinary(int, char) { g_done = true; }
+
+int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
+
+void VoidTernary(int, char, bool) { g_done = true; }
+
+int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
+
+void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
+
+int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
+
+struct SumOf5Functor {
+ int operator()(int a, int b, int c, int d, int e) {
+ return a + b + c + d + e;
+ }
+};
+
+int SumOf6(int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+}
+
+struct SumOf6Functor {
+ int operator()(int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+ }
+};
+
+class Foo {
+ public:
+ Foo() : value_(123) {}
+
+ int Nullary() const { return value_; }
+ short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
+ std::string Binary(const std::string& str, char c) const { return str + c; }
+ int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
+ int SumOf4(int a, int b, int c, int d) const {
+ return a + b + c + d + value_;
+ }
+ int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
+ int SumOf6(int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+ }
+ private:
+ int value_;
+};
+
+// Tests InvokeWithoutArgs(function).
+TEST(InvokeWithoutArgsTest, Function) {
+ // As an action that takes one argument.
+ Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT
+ EXPECT_EQ(1, a.Perform(make_tuple(2)));
+
+ // As an action that takes two arguments.
+ Action<short(int, double)> a2 = InvokeWithoutArgs(Nullary); // NOLINT
+ EXPECT_EQ(1, a2.Perform(make_tuple(2, 3.5)));
+
+ // As an action that returns void.
+ Action<void(int)> a3 = InvokeWithoutArgs(VoidNullary); // NOLINT
+ g_done = false;
+ a3.Perform(make_tuple(1));
+ EXPECT_TRUE(g_done);
+}
+
+// Tests InvokeWithoutArgs(functor).
+TEST(InvokeWithoutArgsTest, Functor) {
+ // As an action that takes no argument.
+ Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT
+ EXPECT_EQ(2, a.Perform(make_tuple()));
+
+ // As an action that takes three arguments.
+ Action<short(int, double, char)> a2 = // NOLINT
+ InvokeWithoutArgs(NullaryFunctor());
+ EXPECT_EQ(2, a2.Perform(make_tuple(3, 3.5, 'a')));
+
+ // As an action that returns void.
+ Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor());
+ g_done = false;
+ a3.Perform(make_tuple());
+ EXPECT_TRUE(g_done);
+}
+
+// Tests InvokeWithoutArgs(obj_ptr, method).
+TEST(InvokeWithoutArgsTest, Method) {
+ Foo foo;
+ Action<int(bool, char)> a = // NOLINT
+ InvokeWithoutArgs(&foo, &Foo::Nullary);
+ EXPECT_EQ(123, a.Perform(make_tuple(true, 'a')));
+}
+
+// Tests using IgnoreResult() on a polymorphic action.
+TEST(IgnoreResultTest, PolymorphicAction) {
+ Action<void(int)> a = IgnoreResult(Return(5)); // NOLINT
+ a.Perform(make_tuple(1));
+}
+
+// Tests using IgnoreResult() on a monomorphic action.
+
+int ReturnOne() {
+ g_done = true;
+ return 1;
+}
+
+TEST(IgnoreResultTest, MonomorphicAction) {
+ g_done = false;
+ Action<void()> a = IgnoreResult(Invoke(ReturnOne));
+ a.Perform(make_tuple());
+ EXPECT_TRUE(g_done);
+}
+
+// Tests using IgnoreResult() on an action that returns a class type.
+
+MyClass ReturnMyClass(double x) {
+ g_done = true;
+ return MyClass();
+}
+
+TEST(IgnoreResultTest, ActionReturningClass) {
+ g_done = false;
+ Action<void(int)> a = IgnoreResult(Invoke(ReturnMyClass)); // NOLINT
+ a.Perform(make_tuple(2));
+ EXPECT_TRUE(g_done);
+}
+
+TEST(AssignTest, Int) {
+ int x = 0;
+ Action<void(int)> a = Assign(&x, 5);
+ a.Perform(make_tuple(0));
+ EXPECT_EQ(5, x);
+}
+
+TEST(AssignTest, String) {
+ ::std::string x;
+ Action<void(void)> a = Assign(&x, "Hello, world");
+ a.Perform(make_tuple());
+ EXPECT_EQ("Hello, world", x);
+}
+
+TEST(AssignTest, CompatibleTypes) {
+ double x = 0;
+ Action<void(int)> a = Assign(&x, 5);
+ a.Perform(make_tuple(0));
+ EXPECT_DOUBLE_EQ(5, x);
+}
+
+class SetErrnoAndReturnTest : public testing::Test {
+ protected:
+ virtual void SetUp() { errno = 0; }
+ virtual void TearDown() { errno = 0; }
+};
+
+TEST_F(SetErrnoAndReturnTest, Int) {
+ Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5);
+ EXPECT_EQ(-5, a.Perform(make_tuple()));
+ EXPECT_EQ(ENOTTY, errno);
+}
+
+TEST_F(SetErrnoAndReturnTest, Ptr) {
+ int x;
+ Action<int*(void)> a = SetErrnoAndReturn(ENOTTY, &x);
+ EXPECT_EQ(&x, a.Perform(make_tuple()));
+ EXPECT_EQ(ENOTTY, errno);
+}
+
+TEST_F(SetErrnoAndReturnTest, CompatibleTypes) {
+ Action<double()> a = SetErrnoAndReturn(EINVAL, 5);
+ EXPECT_DOUBLE_EQ(5.0, a.Perform(make_tuple()));
+ EXPECT_EQ(EINVAL, errno);
+}
+
+} // Unnamed namespace
diff --git a/test/gmock-cardinalities_test.cc b/test/gmock-cardinalities_test.cc
new file mode 100644
index 00000000..f3f1e106
--- /dev/null
+++ b/test/gmock-cardinalities_test.cc
@@ -0,0 +1,422 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the built-in cardinalities.
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace {
+
+using std::stringstream;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::AtMost;
+using testing::Between;
+using testing::Cardinality;
+using testing::CardinalityInterface;
+using testing::Exactly;
+using testing::IsSubstring;
+using testing::MakeCardinality;
+
+class MockFoo {
+ public:
+ MOCK_METHOD0(Bar, int()); // NOLINT
+};
+
+// Tests that Cardinality objects can be default constructed.
+TEST(CardinalityTest, IsDefaultConstructable) {
+ Cardinality c;
+}
+
+// Tests that Cardinality objects are copyable.
+TEST(CardinalityTest, IsCopyable) {
+ // Tests the copy constructor.
+ Cardinality c = Exactly(1);
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(1));
+
+ // Tests the assignment operator.
+ c = Exactly(2);
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(2));
+}
+
+TEST(CardinalityTest, IsOverSaturatedByCallCountWorks) {
+ const Cardinality c = AtMost(5);
+ EXPECT_FALSE(c.IsOverSaturatedByCallCount(4));
+ EXPECT_FALSE(c.IsOverSaturatedByCallCount(5));
+ EXPECT_TRUE(c.IsOverSaturatedByCallCount(6));
+}
+
+// Tests that Cardinality::DescribeActualCallCountTo() creates the
+// correct description.
+TEST(CardinalityTest, CanDescribeActualCallCount) {
+ stringstream ss0;
+ Cardinality::DescribeActualCallCountTo(0, &ss0);
+ EXPECT_EQ("never called", ss0.str());
+
+ stringstream ss1;
+ Cardinality::DescribeActualCallCountTo(1, &ss1);
+ EXPECT_EQ("called once", ss1.str());
+
+ stringstream ss2;
+ Cardinality::DescribeActualCallCountTo(2, &ss2);
+ EXPECT_EQ("called twice", ss2.str());
+
+ stringstream ss3;
+ Cardinality::DescribeActualCallCountTo(3, &ss3);
+ EXPECT_EQ("called 3 times", ss3.str());
+}
+
+// Tests AnyNumber()
+TEST(AnyNumber, Works) {
+ const Cardinality c = AnyNumber();
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(1));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(9));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(9));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times",
+ ss.str());
+}
+
+TEST(AnyNumberTest, HasCorrectBounds) {
+ const Cardinality c = AnyNumber();
+ EXPECT_EQ(0, c.ConservativeLowerBound());
+ EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
+}
+
+// Tests AtLeast(n).
+
+TEST(AtLeastTest, OnNegativeNumber) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ AtLeast(-1);
+ }, "The invocation lower bound must be >= 0");
+}
+
+TEST(AtLeastTest, OnZero) {
+ const Cardinality c = AtLeast(0);
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(1));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "any number of times",
+ ss.str());
+}
+
+TEST(AtLeastTest, OnPositiveNumber) {
+ const Cardinality c = AtLeast(2);
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(1));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(2));
+
+ stringstream ss1;
+ AtLeast(1).DescribeTo(&ss1);
+ EXPECT_PRED_FORMAT2(IsSubstring, "at least once",
+ ss1.str());
+
+ stringstream ss2;
+ c.DescribeTo(&ss2);
+ EXPECT_PRED_FORMAT2(IsSubstring, "at least twice",
+ ss2.str());
+
+ stringstream ss3;
+ AtLeast(3).DescribeTo(&ss3);
+ EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times",
+ ss3.str());
+}
+
+TEST(AtLeastTest, HasCorrectBounds) {
+ const Cardinality c = AtLeast(2);
+ EXPECT_EQ(2, c.ConservativeLowerBound());
+ EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
+}
+
+// Tests AtMost(n).
+
+TEST(AtMostTest, OnNegativeNumber) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ AtMost(-1);
+ }, "The invocation upper bound must be >= 0");
+}
+
+TEST(AtMostTest, OnZero) {
+ const Cardinality c = AtMost(0);
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(1));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "never called",
+ ss.str());
+}
+
+TEST(AtMostTest, OnPositiveNumber) {
+ const Cardinality c = AtMost(2);
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(1));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(2));
+
+ stringstream ss1;
+ AtMost(1).DescribeTo(&ss1);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called at most once",
+ ss1.str());
+
+ stringstream ss2;
+ c.DescribeTo(&ss2);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
+ ss2.str());
+
+ stringstream ss3;
+ AtMost(3).DescribeTo(&ss3);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times",
+ ss3.str());
+}
+
+TEST(AtMostTest, HasCorrectBounds) {
+ const Cardinality c = AtMost(2);
+ EXPECT_EQ(0, c.ConservativeLowerBound());
+ EXPECT_EQ(2, c.ConservativeUpperBound());
+}
+
+// Tests Between(m, n).
+
+TEST(BetweenTest, OnNegativeStart) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ Between(-1, 2);
+ }, "The invocation lower bound must be >= 0, but is actually -1");
+}
+
+TEST(BetweenTest, OnNegativeEnd) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ Between(1, -2);
+ }, "The invocation upper bound must be >= 0, but is actually -2");
+}
+
+TEST(BetweenTest, OnStartBiggerThanEnd) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ Between(2, 1);
+ }, "The invocation upper bound (1) must be >= "
+ "the invocation lower bound (2)");
+}
+
+TEST(BetweenTest, OnZeroStartAndZeroEnd) {
+ const Cardinality c = Between(0, 0);
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(1));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "never called",
+ ss.str());
+}
+
+TEST(BetweenTest, OnZeroStartAndNonZeroEnd) {
+ const Cardinality c = Between(0, 2);
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(2));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(4));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
+ ss.str());
+}
+
+TEST(BetweenTest, OnSameStartAndEnd) {
+ const Cardinality c = Between(3, 3);
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(2));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(3));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(4));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
+ ss.str());
+}
+
+TEST(BetweenTest, OnDifferentStartAndEnd) {
+ const Cardinality c = Between(3, 5);
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(2));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(3));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(5));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(5));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(6));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(6));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times",
+ ss.str());
+}
+
+TEST(BetweenTest, HasCorrectBounds) {
+ const Cardinality c = Between(3, 5);
+ EXPECT_EQ(3, c.ConservativeLowerBound());
+ EXPECT_EQ(5, c.ConservativeUpperBound());
+}
+
+// Tests Exactly(n).
+
+TEST(ExactlyTest, OnNegativeNumber) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ Exactly(-1);
+ }, "The invocation lower bound must be >= 0");
+}
+
+TEST(ExactlyTest, OnZero) {
+ const Cardinality c = Exactly(0);
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(1));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_PRED_FORMAT2(IsSubstring, "never called",
+ ss.str());
+}
+
+TEST(ExactlyTest, OnPositiveNumber) {
+ const Cardinality c = Exactly(2);
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
+ EXPECT_FALSE(c.IsSaturatedByCallCount(0));
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
+ EXPECT_TRUE(c.IsSaturatedByCallCount(2));
+
+ stringstream ss1;
+ Exactly(1).DescribeTo(&ss1);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called once",
+ ss1.str());
+
+ stringstream ss2;
+ c.DescribeTo(&ss2);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called twice",
+ ss2.str());
+
+ stringstream ss3;
+ Exactly(3).DescribeTo(&ss3);
+ EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
+ ss3.str());
+}
+
+TEST(ExactlyTest, HasCorrectBounds) {
+ const Cardinality c = Exactly(3);
+ EXPECT_EQ(3, c.ConservativeLowerBound());
+ EXPECT_EQ(3, c.ConservativeUpperBound());
+}
+
+// Tests that a user can make his own cardinality by implementing
+// CardinalityInterface and calling MakeCardinality().
+
+class EvenCardinality : public CardinalityInterface {
+ public:
+ // Returns true iff call_count calls will satisfy this cardinality.
+ virtual bool IsSatisfiedByCallCount(int call_count) const {
+ return (call_count % 2 == 0);
+ }
+
+ // Returns true iff call_count calls will saturate this cardinality.
+ virtual bool IsSaturatedByCallCount(int call_count) const { return false; }
+
+ // Describes self to an ostream.
+ virtual void DescribeTo(::std::ostream* ss) const {
+ *ss << "called even number of times";
+ }
+};
+
+TEST(MakeCardinalityTest, ConstructsCardinalityFromInterface) {
+ const Cardinality c = MakeCardinality(new EvenCardinality);
+
+ EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
+ EXPECT_FALSE(c.IsSatisfiedByCallCount(3));
+
+ EXPECT_FALSE(c.IsSaturatedByCallCount(10000));
+
+ stringstream ss;
+ c.DescribeTo(&ss);
+ EXPECT_EQ("called even number of times", ss.str());
+}
+
+} // Unnamed namespace
diff --git a/test/gmock-generated-actions_test.cc b/test/gmock-generated-actions_test.cc
new file mode 100644
index 00000000..4f2e877a
--- /dev/null
+++ b/test/gmock-generated-actions_test.cc
@@ -0,0 +1,946 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the built-in actions generated by a script.
+
+#include <gmock/gmock-generated-actions.h>
+
+#include <functional>
+#include <string>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+namespace gmock_generated_actions_test {
+
+using ::std::plus;
+using ::std::string;
+using ::std::tr1::get;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+using ::std::tr1::tuple_element;
+using testing::_;
+using testing::Action;
+using testing::ActionInterface;
+using testing::ByRef;
+using testing::DoAll;
+using testing::Invoke;
+using testing::InvokeArgument;
+using testing::Return;
+using testing::SetArgumentPointee;
+using testing::Unused;
+using testing::WithArg;
+using testing::WithArgs;
+using testing::WithoutArgs;
+
+// Sample functions and functors for testing Invoke() and etc.
+int Nullary() { return 1; }
+
+class NullaryFunctor {
+ public:
+ int operator()() { return 2; }
+};
+
+bool g_done = false;
+void VoidNullary() { g_done = true; }
+
+class VoidNullaryFunctor {
+ public:
+ void operator()() { g_done = true; }
+};
+
+bool Unary(int x) { return x < 0; }
+
+const char* Plus1(const char* s) { return s + 1; }
+
+void VoidUnary(int n) { g_done = true; }
+
+bool ByConstRef(const string& s) { return s == "Hi"; }
+
+const double g_double = 0;
+bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
+
+string ByNonConstRef(string& s) { return s += "+"; } // NOLINT
+
+struct UnaryFunctor {
+ int operator()(bool x) { return x ? 1 : -1; }
+};
+
+const char* Binary(const char* input, short n) { return input + n; } // NOLINT
+
+void VoidBinary(int, char) { g_done = true; }
+
+int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
+
+void VoidTernary(int, char, bool) { g_done = true; }
+
+int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
+
+int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
+
+void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
+
+string Concat4(const char* s1, const char* s2, const char* s3,
+ const char* s4) {
+ return string(s1) + s2 + s3 + s4;
+}
+
+int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
+
+struct SumOf5Functor {
+ int operator()(int a, int b, int c, int d, int e) {
+ return a + b + c + d + e;
+ }
+};
+
+string Concat5(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5) {
+ return string(s1) + s2 + s3 + s4 + s5;
+}
+
+int SumOf6(int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+}
+
+struct SumOf6Functor {
+ int operator()(int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+ }
+};
+
+string Concat6(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6;
+}
+
+string Concat7(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
+}
+
+string Concat8(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7, const char* s8) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
+}
+
+string Concat9(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7, const char* s8, const char* s9) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
+}
+
+string Concat10(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7, const char* s8, const char* s9,
+ const char* s10) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
+}
+
+class Foo {
+ public:
+ Foo() : value_(123) {}
+
+ int Nullary() const { return value_; }
+
+ short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
+
+ string Binary(const string& str, char c) const { return str + c; }
+
+ int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
+
+ int SumOf4(int a, int b, int c, int d) const {
+ return a + b + c + d + value_;
+ }
+
+ int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
+
+ int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
+
+ int SumOf6(int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+ }
+
+ string Concat7(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
+ }
+
+ string Concat8(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7, const char* s8) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
+ }
+
+ string Concat9(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7, const char* s8, const char* s9) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
+ }
+
+ string Concat10(const char* s1, const char* s2, const char* s3,
+ const char* s4, const char* s5, const char* s6,
+ const char* s7, const char* s8, const char* s9,
+ const char* s10) {
+ return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
+ }
+ private:
+ int value_;
+};
+
+// Tests using Invoke() with a nullary function.
+TEST(InvokeTest, Nullary) {
+ Action<int()> a = Invoke(Nullary); // NOLINT
+ EXPECT_EQ(1, a.Perform(make_tuple()));
+}
+
+// Tests using Invoke() with a unary function.
+TEST(InvokeTest, Unary) {
+ Action<bool(int)> a = Invoke(Unary); // NOLINT
+ EXPECT_FALSE(a.Perform(make_tuple(1)));
+ EXPECT_TRUE(a.Perform(make_tuple(-1)));
+}
+
+// Tests using Invoke() with a binary function.
+TEST(InvokeTest, Binary) {
+ Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
+ const char* p = "Hello";
+ EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
+}
+
+// Tests using Invoke() with a ternary function.
+TEST(InvokeTest, Ternary) {
+ Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
+ EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
+}
+
+// Tests using Invoke() with a 4-argument function.
+TEST(InvokeTest, FunctionThatTakes4Arguments) {
+ Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
+ EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
+}
+
+// Tests using Invoke() with a 5-argument function.
+TEST(InvokeTest, FunctionThatTakes5Arguments) {
+ Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
+ EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
+}
+
+// Tests using Invoke() with a 6-argument function.
+TEST(InvokeTest, FunctionThatTakes6Arguments) {
+ Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
+ EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
+}
+
+// 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")));
+}
+
+// Tests using Invoke() with a 8-argument function.
+TEST(InvokeTest, FunctionThatTakes8Arguments) {
+ Action<string(const char*, const char*, const char*, const char*,
+ 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")));
+}
+
+// Tests using Invoke() with a 9-argument function.
+TEST(InvokeTest, FunctionThatTakes9Arguments) {
+ Action<string(const char*, const char*, const char*, const char*,
+ 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")));
+}
+
+// Tests using Invoke() with a 10-argument function.
+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")));
+}
+
+// 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")));
+
+ Action<int(int, int, bool, int*)> a2 =
+ Invoke(SumOfFirst2);
+ EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
+}
+
+// Tests using Invoke() with methods with parameters declared as Unused.
+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)));
+
+ Action<int(char, double, int, int)> a2 =
+ Invoke(&foo, &Foo::SumOfLast2);
+ EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
+}
+
+// Tests using Invoke() with a functor.
+TEST(InvokeTest, Functor) {
+ Action<int(short, char)> a = Invoke(plus<short>()); // NOLINT
+ EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
+}
+
+// Tests using Invoke(f) as an action of a compatible type.
+TEST(InvokeTest, FunctionWithCompatibleType) {
+ Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
+ EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
+}
+
+// Tests using Invoke() with an object pointer and a method pointer.
+
+// Tests using Invoke() with a nullary method.
+TEST(InvokeMethodTest, Nullary) {
+ Foo foo;
+ Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT
+ EXPECT_EQ(123, a.Perform(make_tuple()));
+}
+
+// Tests using Invoke() with a unary method.
+TEST(InvokeMethodTest, Unary) {
+ Foo foo;
+ Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT
+ EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
+}
+
+// Tests using Invoke() with a binary method.
+TEST(InvokeMethodTest, Binary) {
+ Foo foo;
+ Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
+ string s("Hell");
+ EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
+}
+
+// Tests using Invoke() with a ternary method.
+TEST(InvokeMethodTest, Ternary) {
+ Foo foo;
+ Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT
+ EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
+}
+
+// Tests using Invoke() with a 4-argument method.
+TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
+ Foo foo;
+ Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT
+ EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
+}
+
+// Tests using Invoke() with a 5-argument method.
+TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
+ Foo foo;
+ Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5); // NOLINT
+ EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
+}
+
+// Tests using Invoke() with a 6-argument method.
+TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
+ Foo foo;
+ Action<int(int, int, int, int, int, int)> a = // NOLINT
+ Invoke(&foo, &Foo::SumOf6);
+ EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
+}
+
+// Tests using Invoke() with a 7-argument method.
+TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
+ Foo foo;
+ Action<string(const char*, const char*, const char*, const char*,
+ 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")));
+}
+
+// Tests using Invoke() with a 8-argument method.
+TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
+ Foo foo;
+ Action<string(const char*, const char*, const char*, const char*,
+ 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")));
+}
+
+// Tests using Invoke() with a 9-argument method.
+TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
+ Foo foo;
+ Action<string(const char*, const char*, const char*, const char*,
+ 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")));
+}
+
+// Tests using Invoke() with a 10-argument method.
+TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
+ Foo foo;
+ 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")));
+}
+
+// Tests using Invoke(f) as an action of a compatible type.
+TEST(InvokeMethodTest, MethodWithCompatibleType) {
+ Foo foo;
+ Action<long(int, short, char, bool)> a = // NOLINT
+ Invoke(&foo, &Foo::SumOf4);
+ EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
+}
+
+// Tests ByRef().
+
+// Tests that ReferenceWrapper<T> is copyable.
+TEST(ByRefTest, IsCopyable) {
+ const string s1 = "Hi";
+ const string s2 = "Hello";
+
+ ::testing::internal::ReferenceWrapper<const string> ref_wrapper = ByRef(s1);
+ const string& r1 = ref_wrapper;
+ EXPECT_EQ(&s1, &r1);
+
+ // Assigns a new value to ref_wrapper.
+ ref_wrapper = ByRef(s2);
+ const string& r2 = ref_wrapper;
+ EXPECT_EQ(&s2, &r2);
+
+ ::testing::internal::ReferenceWrapper<const string> ref_wrapper1 = ByRef(s1);
+ // Copies ref_wrapper1 to ref_wrapper.
+ ref_wrapper = ref_wrapper1;
+ const string& r3 = ref_wrapper;
+ EXPECT_EQ(&s1, &r3);
+}
+
+// Tests using ByRef() on a const value.
+TEST(ByRefTest, ConstValue) {
+ const int n = 0;
+ // int& ref = ByRef(n); // This shouldn't compile - we have a
+ // negative compilation test to catch it.
+ const int& const_ref = ByRef(n);
+ EXPECT_EQ(&n, &const_ref);
+}
+
+// Tests using ByRef() on a non-const value.
+TEST(ByRefTest, NonConstValue) {
+ int n = 0;
+
+ // ByRef(n) can be used as either an int&,
+ int& ref = ByRef(n);
+ EXPECT_EQ(&n, &ref);
+
+ // or a const int&.
+ const int& const_ref = ByRef(n);
+ EXPECT_EQ(&n, &const_ref);
+}
+
+struct Base {
+ bool operator==(const Base&) { return true; }
+};
+
+struct Derived : public Base {
+ bool operator==(const Derived&) { return true; }
+};
+
+// Tests explicitly specifying the type when using ByRef().
+TEST(ByRefTest, ExplicitType) {
+ int n = 0;
+ const int& r1 = ByRef<const int>(n);
+ EXPECT_EQ(&n, &r1);
+
+ // ByRef<char>(n); // This shouldn't compile - we have a negative
+ // compilation test to catch it.
+
+
+ Derived d;
+ Derived& r2 = ByRef<Derived>(d);
+ EXPECT_EQ(&d, &r2);
+
+ const Derived& r3 = ByRef<const Derived>(d);
+ EXPECT_EQ(&d, &r3);
+
+ Base& r4 = ByRef<Base>(d);
+ EXPECT_EQ(&d, &r4);
+
+ const Base& r5 = ByRef<const Base>(d);
+ EXPECT_EQ(&d, &r5);
+
+ // The following shouldn't compile - we have a negative compilation
+ // test for it.
+ //
+ // Base b;
+ // ByRef<Derived>(b);
+}
+
+// Tests InvokeArgument<N>(...).
+
+// Tests using InvokeArgument with a nullary function.
+TEST(InvokeArgumentTest, Function0) {
+ Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT
+ EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary)));
+}
+
+// Tests using InvokeArgument with a unary function.
+TEST(InvokeArgumentTest, Functor1) {
+ Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
+ EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor())));
+}
+
+// Tests using InvokeArgument with a 5-ary function.
+TEST(InvokeArgumentTest, Function5) {
+ Action<int(int(*)(int, int, int, int, int))> a = // NOLINT
+ InvokeArgument<0>(10000, 2000, 300, 40, 5);
+ EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5)));
+}
+
+// Tests using InvokeArgument with a 5-ary functor.
+TEST(InvokeArgumentTest, Functor5) {
+ Action<int(SumOf5Functor)> a = // NOLINT
+ InvokeArgument<0>(10000, 2000, 300, 40, 5);
+ EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor())));
+}
+
+// Tests using InvokeArgument with a 6-ary function.
+TEST(InvokeArgumentTest, Function6) {
+ Action<int(int(*)(int, int, int, int, int, int))> a = // NOLINT
+ InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
+ EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6)));
+}
+
+// Tests using InvokeArgument with a 6-ary functor.
+TEST(InvokeArgumentTest, Functor6) {
+ Action<int(SumOf6Functor)> a = // NOLINT
+ InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
+ EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor())));
+}
+
+// Tests using InvokeArgument with a 7-ary function.
+TEST(InvokeArgumentTest, Function7) {
+ Action<string(string(*)(const char*, const char*, const char*,
+ const char*, const char*, const char*,
+ const char*))> a =
+ InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
+ EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7)));
+}
+
+// Tests using InvokeArgument with a 8-ary function.
+TEST(InvokeArgumentTest, Function8) {
+ Action<string(string(*)(const char*, const char*, const char*,
+ const char*, const char*, const char*,
+ const char*, const char*))> a =
+ InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
+ EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8)));
+}
+
+// Tests using InvokeArgument with a 9-ary function.
+TEST(InvokeArgumentTest, Function9) {
+ Action<string(string(*)(const char*, const char*, const char*,
+ const char*, const char*, const char*,
+ const char*, const char*, const char*))> a =
+ InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
+ EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9)));
+}
+
+// Tests using InvokeArgument with a 10-ary function.
+TEST(InvokeArgumentTest, Function10) {
+ Action<string(string(*)(const char*, const char*, const char*,
+ const char*, const char*, const char*,
+ const char*, const char*, const char*,
+ const char*))> a =
+ InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
+ EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
+}
+
+// Tests using InvokeArgument with a function that takes a pointer argument.
+TEST(InvokeArgumentTest, ByPointerFunction) {
+ Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
+ InvokeArgument<0>(static_cast<const char*>("Hi"), 1);
+ EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
+}
+
+// Tests using InvokeArgument with a function that takes a const char*
+// by passing it a C-string literal.
+TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
+ Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
+ InvokeArgument<0>("Hi", 1);
+ EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
+}
+
+// Tests using InvokeArgument with a function that takes a const reference.
+TEST(InvokeArgumentTest, ByConstReferenceFunction) {
+ Action<bool(bool(*function)(const string& s))> a = // NOLINT
+ InvokeArgument<0>(string("Hi"));
+ // When action 'a' is constructed, it makes a copy of the temporary
+ // string object passed to it, so it's OK to use 'a' later, when the
+ // temporary object has already died.
+ EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef)));
+}
+
+// Tests using InvokeArgument with ByRef() and a function that takes a
+// const reference.
+TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
+ Action<bool(bool(*)(const double& x))> a = // NOLINT
+ InvokeArgument<0>(ByRef(g_double));
+ // The above line calls ByRef() on a const value.
+ EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
+
+ double x = 0;
+ a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.
+ EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
+}
+
+// Tests using WithoutArgs with an action that takes no argument.
+TEST(WithoutArgsTest, NoArg) {
+ Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
+ EXPECT_EQ(1, a.Perform(make_tuple(2)));
+}
+
+// Tests using WithArgs and WithArg with an action that takes 1 argument.
+TEST(WithArgsTest, OneArg) {
+ Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
+ EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
+ EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
+
+ // Also tests the synonym WithArg.
+ Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
+ EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
+ EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
+
+}
+
+// Tests using WithArgs with an action that takes 2 arguments.
+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)));
+}
+
+// Tests using WithArgs with an action that takes 3 arguments.
+TEST(WithArgsTest, ThreeArgs) {
+ Action<int(int, double, char, short)> a = // NOLINT
+ WithArgs<0, 2, 3>(Invoke(Ternary));
+ EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, 20, 3)));
+}
+
+// Tests using WithArgs with an action that takes 4 arguments.
+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")));
+}
+
+// Tests using WithArgs with an action that takes 5 arguments.
+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")));
+}
+
+// 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")));
+}
+
+// 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")));
+}
+
+// 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")));
+}
+
+// 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")));
+}
+
+// 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")));
+}
+
+// Tests using WithArgs with an action that is not Invoke().
+class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT
+ public:
+ virtual int Perform(const tuple<int, int>& args) {
+ return get<0>(args) - get<1>(args);
+ }
+};
+
+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)));
+}
+
+// Tests using WithArgs to pass all original arguments in the original order.
+TEST(WithArgsTest, Identity) {
+ Action<int(int x, char y, short z)> a = // NOLINT
+ WithArgs<0, 1, 2>(Invoke(Ternary));
+ EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 3)));
+}
+
+// Tests using WithArgs with repeated arguments.
+TEST(WithArgsTest, RepeatedArguments) {
+ Action<int(bool, int m, int n)> a = // NOLINT
+ WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
+ EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
+}
+
+// Tests using WithArgs with reversed argument order.
+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)));
+}
+
+// Tests using WithArgs with compatible, but not identical, argument types.
+TEST(WithArgsTest, ArgsOfCompatibleTypes) {
+ Action<long(short x, int y, double z, char c)> a = // NOLINT
+ WithArgs<0, 1, 3>(Invoke(Ternary));
+ EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 5.6, 3)));
+}
+
+// Tests using WithArgs with an action that returns void.
+TEST(WithArgsTest, VoidAction) {
+ Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
+ g_done = false;
+ a.Perform(make_tuple(1.5, 'a', 3));
+ EXPECT_TRUE(g_done);
+}
+
+// Tests DoAll(a1, a2).
+TEST(DoAllTest, TwoActions) {
+ int n = 0;
+ Action<int(int*)> a = DoAll(SetArgumentPointee<0>(1), // NOLINT
+ Return(2));
+ EXPECT_EQ(2, a.Perform(make_tuple(&n)));
+ EXPECT_EQ(1, n);
+}
+
+// Tests DoAll(a1, a2, a3).
+TEST(DoAllTest, ThreeActions) {
+ int m = 0, n = 0;
+ Action<int(int*, int*)> a = DoAll(SetArgumentPointee<0>(1), // NOLINT
+ SetArgumentPointee<1>(2),
+ Return(3));
+ EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+}
+
+// Tests DoAll(a1, a2, a3, a4).
+TEST(DoAllTest, FourActions) {
+ int m = 0, n = 0;
+ char ch = '\0';
+ Action<int(int*, int*, char*)> a = // NOLINT
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ Return(3));
+ EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', ch);
+}
+
+// Tests DoAll(a1, a2, a3, a4, a5).
+TEST(DoAllTest, FiveActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0';
+ Action<int(int*, int*, char*, char*)> action = // NOLINT
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ SetArgumentPointee<3>('b'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+}
+
+// Tests DoAll(a1, a2, ..., a6).
+TEST(DoAllTest, SixActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0';
+ Action<int(int*, int*, char*, char*, char*)> action = // NOLINT
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ SetArgumentPointee<3>('b'),
+ SetArgumentPointee<4>('c'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+}
+
+// Tests DoAll(a1, a2, ..., a7).
+TEST(DoAllTest, SevenActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ SetArgumentPointee<3>('b'),
+ SetArgumentPointee<4>('c'),
+ SetArgumentPointee<5>('d'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+}
+
+// Tests DoAll(a1, a2, ..., a8).
+TEST(DoAllTest, EightActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
+ char*)> action =
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ SetArgumentPointee<3>('b'),
+ SetArgumentPointee<4>('c'),
+ SetArgumentPointee<5>('d'),
+ SetArgumentPointee<6>('e'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+ EXPECT_EQ('e', e);
+}
+
+// Tests DoAll(a1, a2, ..., a9).
+TEST(DoAllTest, NineActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
+ char*, char*)> action =
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ SetArgumentPointee<3>('b'),
+ SetArgumentPointee<4>('c'),
+ SetArgumentPointee<5>('d'),
+ SetArgumentPointee<6>('e'),
+ SetArgumentPointee<7>('f'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+ EXPECT_EQ('e', e);
+ EXPECT_EQ('f', f);
+}
+
+// Tests DoAll(a1, a2, ..., a10).
+TEST(DoAllTest, TenActions) {
+ int m = 0, n = 0;
+ char a = '\0', b = '\0', c = '\0', d = '\0';
+ char e = '\0', f = '\0', g = '\0';
+ Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
+ char*, char*, char*)> action =
+ DoAll(SetArgumentPointee<0>(1),
+ SetArgumentPointee<1>(2),
+ SetArgumentPointee<2>('a'),
+ SetArgumentPointee<3>('b'),
+ SetArgumentPointee<4>('c'),
+ SetArgumentPointee<5>('d'),
+ SetArgumentPointee<6>('e'),
+ SetArgumentPointee<7>('f'),
+ SetArgumentPointee<8>('g'),
+ Return(3));
+ EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
+ EXPECT_EQ(1, m);
+ EXPECT_EQ(2, n);
+ EXPECT_EQ('a', a);
+ EXPECT_EQ('b', b);
+ EXPECT_EQ('c', c);
+ EXPECT_EQ('d', d);
+ EXPECT_EQ('e', e);
+ EXPECT_EQ('f', f);
+ EXPECT_EQ('g', g);
+}
+
+} // namespace gmock_generated_actions_test
+} // namespace testing
diff --git a/test/gmock-generated-function-mockers_test.cc b/test/gmock-generated-function-mockers_test.cc
new file mode 100644
index 00000000..d8e678b2
--- /dev/null
+++ b/test/gmock-generated-function-mockers_test.cc
@@ -0,0 +1,426 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the function mocker classes.
+
+#include <gmock/gmock-generated-function-mockers.h>
+
+#include <map>
+#include <string>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#ifdef GTEST_OS_WINDOWS
+// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
+// we are getting compiler errors if we use basetyps.h, hence including
+// objbase.h for definition of STDMETHOD.
+#include <objbase.h>
+#endif // GTEST_OS_WINDOWS
+
+// There is a bug in MSVC (fixed in VS 2008) that prevents creating a
+// mock for a function with const arguments, so we don't test such
+// cases for MSVC versions older than 2008.
+#if !defined(GTEST_OS_WINDOWS) || (_MSC_VER >= 1500)
+#define GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+#endif // !defined(GTEST_OS_WINDOWS) || (_MSC_VER >= 1500)
+
+namespace testing {
+namespace gmock_generated_function_mockers_test {
+
+using testing::internal::string;
+using testing::_;
+using testing::A;
+using testing::An;
+using testing::AnyNumber;
+using testing::Const;
+using testing::DoDefault;
+using testing::Eq;
+using testing::Lt;
+using testing::Ref;
+using testing::Return;
+using testing::ReturnRef;
+using testing::TypedEq;
+
+class FooInterface {
+ public:
+ virtual ~FooInterface() {}
+
+ virtual void VoidReturning(int x) = 0;
+
+ virtual int Nullary() = 0;
+ virtual bool Unary(int x) = 0;
+ virtual long Binary(short x, int y) = 0; // NOLINT
+ virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
+ float g, double h, unsigned i, char* j, const string& k)
+ = 0;
+
+ virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
+ virtual string TakesConstReference(const int& n) = 0;
+#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+ virtual bool TakesConst(const int x) = 0;
+#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+
+ virtual int OverloadedOnArgumentNumber() = 0;
+ virtual int OverloadedOnArgumentNumber(int n) = 0;
+
+ virtual int OverloadedOnArgumentType(int n) = 0;
+ virtual char OverloadedOnArgumentType(char c) = 0;
+
+ virtual int OverloadedOnConstness() = 0;
+ virtual char OverloadedOnConstness() const = 0;
+
+ virtual int TypeWithHole(int (*func)()) = 0;
+ virtual int TypeWithComma(const std::map<int, string>& a_map) = 0;
+
+#ifdef GTEST_OS_WINDOWS
+ STDMETHOD_(int, CTNullary)() = 0;
+ STDMETHOD_(bool, CTUnary)(int x) = 0;
+ STDMETHOD_(int, CTDecimal)(bool b, char c, short d, int e, long f, // NOLINT
+ float g, double h, unsigned i, char* j, const string& k) = 0;
+ STDMETHOD_(char, CTConst)(int x) const = 0;
+#endif // GTEST_OS_WINDOWS
+};
+
+class MockFoo : public FooInterface {
+ public:
+ // Makes sure that a mock function parameter can be named.
+ MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
+
+ MOCK_METHOD0(Nullary, int()); // NOLINT
+
+ // Makes sure that a mock function parameter can be unnamed.
+ MOCK_METHOD1(Unary, bool(int)); // NOLINT
+ MOCK_METHOD2(Binary, long(short, int)); // NOLINT
+ MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
+ double, unsigned, char*, const string& str));
+
+ MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
+ MOCK_METHOD1(TakesConstReference, string(const int&));
+#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+ MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
+#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+ MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
+ MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
+
+ MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
+ MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
+
+ MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
+ MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
+
+ MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
+ MOCK_METHOD1(TypeWithComma, int(const std::map<int, string>&)); // NOLINT
+#ifdef GTEST_OS_WINDOWS
+ MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
+ MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int));
+ MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, int(bool b, char c,
+ short d, int e, long f, float g, double h, unsigned i, char* j,
+ const string& k));
+ MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int));
+#endif // GTEST_OS_WINDOWS
+};
+
+class FunctionMockerTest : public testing::Test {
+ protected:
+ FunctionMockerTest() : foo_(&mock_foo_) {}
+
+ FooInterface* const foo_;
+ MockFoo mock_foo_;
+};
+
+// Tests mocking a void-returning function.
+TEST_F(FunctionMockerTest, MocksVoidFunction) {
+ EXPECT_CALL(mock_foo_, VoidReturning(Lt(100)));
+ foo_->VoidReturning(0);
+}
+
+// Tests mocking a nullary function.
+TEST_F(FunctionMockerTest, MocksNullaryFunction) {
+ EXPECT_CALL(mock_foo_, Nullary())
+ .WillOnce(DoDefault())
+ .WillOnce(Return(1));
+
+ EXPECT_EQ(0, foo_->Nullary());
+ EXPECT_EQ(1, foo_->Nullary());
+}
+
+// Tests mocking a unary function.
+TEST_F(FunctionMockerTest, MocksUnaryFunction) {
+ EXPECT_CALL(mock_foo_, Unary(Eq(2)))
+ .Times(2)
+ .WillOnce(Return(true));
+
+ EXPECT_TRUE(foo_->Unary(2));
+ EXPECT_FALSE(foo_->Unary(2));
+}
+
+// Tests mocking a binary function.
+TEST_F(FunctionMockerTest, MocksBinaryFunction) {
+ EXPECT_CALL(mock_foo_, Binary(2, _))
+ .WillOnce(Return(3));
+
+ EXPECT_EQ(3, foo_->Binary(2, 1));
+}
+
+// Tests mocking a decimal function.
+TEST_F(FunctionMockerTest, MocksDecimalFunction) {
+ EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(),
+ Lt(100), 5U, NULL, "hi"))
+ .WillOnce(Return(5));
+
+ EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
+}
+
+// Tests mocking a function that takes a non-const reference.
+TEST_F(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
+ int a = 0;
+ EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a)))
+ .WillOnce(Return(true));
+
+ EXPECT_TRUE(foo_->TakesNonConstReference(a));
+}
+
+// Tests mocking a function that takes a const reference.
+TEST_F(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
+ int a = 0;
+ EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a)))
+ .WillOnce(Return("Hello"));
+
+ EXPECT_EQ("Hello", foo_->TakesConstReference(a));
+}
+
+#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+// Tests mocking a function that takes a const variable.
+TEST_F(FunctionMockerTest, MocksFunctionWithConstArgument) {
+ EXPECT_CALL(mock_foo_, TakesConst(Lt(10)))
+ .WillOnce(DoDefault());
+
+ EXPECT_FALSE(foo_->TakesConst(5));
+}
+#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
+
+// Tests mocking functions overloaded on the number of arguments.
+TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
+ EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber())
+ .WillOnce(Return(1));
+ EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_))
+ .WillOnce(Return(2));
+
+ EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1));
+ EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber());
+}
+
+// Tests mocking functions overloaded on the types of argument.
+TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
+ EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>()))
+ .WillOnce(Return(1));
+ EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
+ .WillOnce(Return('b'));
+
+ EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0));
+ EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a'));
+}
+
+// Tests mocking functions overloaded on the const-ness of this object.
+TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
+ EXPECT_CALL(mock_foo_, OverloadedOnConstness());
+ EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness())
+ .WillOnce(Return('a'));
+
+ EXPECT_EQ(0, foo_->OverloadedOnConstness());
+ EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness());
+}
+
+#ifdef GTEST_OS_WINDOWS
+// Tests mocking a nullary function with calltype.
+TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
+ EXPECT_CALL(mock_foo_, CTNullary())
+ .WillOnce(Return(-1))
+ .WillOnce(Return(0));
+
+ EXPECT_EQ(-1, foo_->CTNullary());
+ EXPECT_EQ(0, foo_->CTNullary());
+}
+
+// Tests mocking a unary function with calltype.
+TEST_F(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
+ EXPECT_CALL(mock_foo_, CTUnary(Eq(2)))
+ .Times(2)
+ .WillOnce(Return(true))
+ .WillOnce(Return(false));
+
+ EXPECT_TRUE(foo_->CTUnary(2));
+ EXPECT_FALSE(foo_->CTUnary(2));
+}
+
+// Tests mocking a decimal function with calltype.
+TEST_F(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
+ EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
+ Lt(100), 5U, NULL, "hi"))
+ .WillOnce(Return(10));
+
+ EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
+}
+
+// Tests mocking functions overloaded on the const-ness of this object.
+TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
+ EXPECT_CALL(Const(mock_foo_), CTConst(_))
+ .WillOnce(Return('a'));
+
+ EXPECT_EQ('a', Const(*foo_).CTConst(0));
+}
+
+#endif // GTEST_OS_WINDOWS
+
+class MockB {
+ public:
+ MOCK_METHOD0(DoB, void());
+};
+
+// Tests that functions with no EXPECT_CALL() ruls can be called any
+// number of times.
+TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
+ {
+ MockB b;
+ }
+
+ {
+ MockB b;
+ b.DoB();
+ }
+
+ {
+ MockB b;
+ b.DoB();
+ b.DoB();
+ }
+}
+
+// Tests mocking template interfaces.
+
+template <typename T>
+class StackInterface {
+ public:
+ virtual ~StackInterface() {}
+
+ // Template parameter appears in function parameter.
+ virtual void Push(const T& value) = 0;
+ virtual void Pop() = 0;
+ virtual int GetSize() const = 0;
+ // Template parameter appears in function return type.
+ virtual const T& GetTop() const = 0;
+};
+
+template <typename T>
+class MockStack : public StackInterface<T> {
+ public:
+ MOCK_METHOD1_T(Push, void(const T& elem));
+ MOCK_METHOD0_T(Pop, void());
+ MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
+ MOCK_CONST_METHOD0_T(GetTop, const T&());
+};
+
+// Tests that template mock works.
+TEST(TemplateMockTest, Works) {
+ MockStack<int> mock;
+
+ EXPECT_CALL(mock, GetSize())
+ .WillOnce(Return(0))
+ .WillOnce(Return(1))
+ .WillOnce(Return(0));
+ EXPECT_CALL(mock, Push(_));
+ int n = 5;
+ EXPECT_CALL(mock, GetTop())
+ .WillOnce(ReturnRef(n));
+ EXPECT_CALL(mock, Pop())
+ .Times(AnyNumber());
+
+ EXPECT_EQ(0, mock.GetSize());
+ mock.Push(5);
+ EXPECT_EQ(1, mock.GetSize());
+ EXPECT_EQ(5, mock.GetTop());
+ mock.Pop();
+ EXPECT_EQ(0, mock.GetSize());
+}
+
+#ifdef GTEST_OS_WINDOWS
+// Tests mocking template interfaces with calltype.
+
+template <typename T>
+class StackInterfaceWithCallType {
+ public:
+ virtual ~StackInterfaceWithCallType() {}
+
+ // Template parameter appears in function parameter.
+ STDMETHOD_(void, Push)(const T& value) = 0;
+ STDMETHOD_(void, Pop)() = 0;
+ STDMETHOD_(int, GetSize)() const = 0;
+ // Template parameter appears in function return type.
+ STDMETHOD_(const T&, GetTop)() const = 0;
+};
+
+template <typename T>
+class MockStackWithCallType : public StackInterfaceWithCallType<T> {
+ public:
+ MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
+ MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
+ MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
+ MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
+};
+
+// Tests that template mock with calltype works.
+TEST(TemplateMockTestWithCallType, Works) {
+ MockStackWithCallType<int> mock;
+
+ EXPECT_CALL(mock, GetSize())
+ .WillOnce(Return(0))
+ .WillOnce(Return(1))
+ .WillOnce(Return(0));
+ EXPECT_CALL(mock, Push(_));
+ int n = 5;
+ EXPECT_CALL(mock, GetTop())
+ .WillOnce(ReturnRef(n));
+ EXPECT_CALL(mock, Pop())
+ .Times(AnyNumber());
+
+ EXPECT_EQ(0, mock.GetSize());
+ mock.Push(5);
+ EXPECT_EQ(1, mock.GetSize());
+ EXPECT_EQ(5, mock.GetTop());
+ mock.Pop();
+ EXPECT_EQ(0, mock.GetSize());
+}
+#endif // GTEST_OS_WINDOWS
+
+} // namespace gmock_generated_function_mockers_test
+} // namespace testing
diff --git a/test/gmock-generated-internal-utils_test.cc b/test/gmock-generated-internal-utils_test.cc
new file mode 100644
index 00000000..13b4c5cf
--- /dev/null
+++ b/test/gmock-generated-internal-utils_test.cc
@@ -0,0 +1,127 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the internal utilities.
+
+#include <gmock/internal/gmock-generated-internal-utils.h>
+#include <gmock/internal/gmock-internal-utils.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+using ::std::tr1::tuple;
+using ::testing::Matcher;
+using ::testing::internal::CompileAssertTypesEqual;
+using ::testing::internal::MatcherTuple;
+using ::testing::internal::Function;
+using ::testing::internal::IgnoredValue;
+
+// Tests the MatcherTuple template struct.
+
+TEST(MatcherTupleTest, ForSize0) {
+ CompileAssertTypesEqual<tuple<>, MatcherTuple<tuple<> >::type>();
+}
+
+TEST(MatcherTupleTest, ForSize1) {
+ CompileAssertTypesEqual<tuple<Matcher<int> >,
+ MatcherTuple<tuple<int> >::type>();
+}
+
+TEST(MatcherTupleTest, ForSize2) {
+ CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char> >,
+ MatcherTuple<tuple<int, char> >::type>();
+}
+
+TEST(MatcherTupleTest, ForSize5) {
+ CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char>, Matcher<bool>,
+ Matcher<double>, Matcher<char*> >,
+ MatcherTuple<tuple<int, char, bool, double, char*>
+ >::type>();
+}
+
+// Tests the Function template struct.
+
+TEST(FunctionTest, Nullary) {
+ typedef Function<int()> F; // NOLINT
+ CompileAssertTypesEqual<int, F::Result>();
+ CompileAssertTypesEqual<tuple<>, F::ArgumentTuple>();
+ CompileAssertTypesEqual<tuple<>, F::ArgumentMatcherTuple>();
+ CompileAssertTypesEqual<void(), F::MakeResultVoid>();
+ CompileAssertTypesEqual<IgnoredValue(), F::MakeResultIgnoredValue>();
+}
+
+TEST(FunctionTest, Unary) {
+ typedef Function<int(bool)> F; // NOLINT
+ CompileAssertTypesEqual<int, F::Result>();
+ CompileAssertTypesEqual<bool, F::Argument1>();
+ CompileAssertTypesEqual<tuple<bool>, F::ArgumentTuple>();
+ CompileAssertTypesEqual<tuple<Matcher<bool> >, F::ArgumentMatcherTuple>();
+ CompileAssertTypesEqual<void(bool), F::MakeResultVoid>(); // NOLINT
+ CompileAssertTypesEqual<IgnoredValue(bool), // NOLINT
+ F::MakeResultIgnoredValue>();
+}
+
+TEST(FunctionTest, Binary) {
+ typedef Function<int(bool, const long&)> F; // NOLINT
+ CompileAssertTypesEqual<int, F::Result>();
+ CompileAssertTypesEqual<bool, F::Argument1>();
+ CompileAssertTypesEqual<const long&, F::Argument2>(); // NOLINT
+ CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>(); // NOLINT
+ CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT
+ F::ArgumentMatcherTuple>();
+ CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>(); // NOLINT
+ CompileAssertTypesEqual<IgnoredValue(bool, const long&), // NOLINT
+ F::MakeResultIgnoredValue>();
+}
+
+TEST(FunctionTest, LongArgumentList) {
+ typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT
+ CompileAssertTypesEqual<char, F::Result>();
+ CompileAssertTypesEqual<bool, F::Argument1>();
+ CompileAssertTypesEqual<int, F::Argument2>();
+ CompileAssertTypesEqual<char*, F::Argument3>();
+ CompileAssertTypesEqual<int&, F::Argument4>();
+ CompileAssertTypesEqual<const long&, F::Argument5>(); // NOLINT
+ CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>, // NOLINT
+ F::ArgumentTuple>();
+ CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<int>, Matcher<char*>,
+ Matcher<int&>, Matcher<const long&> >, // NOLINT
+ F::ArgumentMatcherTuple>();
+ CompileAssertTypesEqual<void(bool, int, char*, int&, const long&), // NOLINT
+ F::MakeResultVoid>();
+ CompileAssertTypesEqual<
+ IgnoredValue(bool, int, char*, int&, const long&), // NOLINT
+ F::MakeResultIgnoredValue>();
+}
+
+} // Unnamed namespace
diff --git a/test/gmock-generated-matchers_test.cc b/test/gmock-generated-matchers_test.cc
new file mode 100644
index 00000000..89b26caa
--- /dev/null
+++ b/test/gmock-generated-matchers_test.cc
@@ -0,0 +1,373 @@
+// 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.
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the built-in matchers generated by a script.
+
+#include <gmock/gmock-generated-matchers.h>
+
+#include <list>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+using std::list;
+using std::stringstream;
+using std::vector;
+using testing::_;
+using testing::ElementsAre;
+using testing::ElementsAreArray;
+using testing::Eq;
+using testing::Ge;
+using testing::Gt;
+using testing::MakeMatcher;
+using testing::Matcher;
+using testing::MatcherInterface;
+using testing::Ne;
+using testing::Not;
+using testing::Pointee;
+using testing::Ref;
+using testing::StrEq;
+using testing::internal::string;
+
+// Returns the description of the given matcher.
+template <typename T>
+string Describe(const Matcher<T>& m) {
+ stringstream ss;
+ m.DescribeTo(&ss);
+ return ss.str();
+}
+
+// Returns the description of the negation of the given matcher.
+template <typename T>
+string DescribeNegation(const Matcher<T>& m) {
+ stringstream ss;
+ m.DescribeNegationTo(&ss);
+ return ss.str();
+}
+
+// Returns the reason why x matches, or doesn't match, m.
+template <typename MatcherType, typename Value>
+string Explain(const MatcherType& m, const Value& x) {
+ stringstream ss;
+ m.ExplainMatchResultTo(x, &ss);
+ return ss.str();
+}
+
+// For testing ExplainMatchResultTo().
+class GreaterThanMatcher : public MatcherInterface<int> {
+ public:
+ explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
+
+ virtual bool Matches(int lhs) const { return lhs > rhs_; }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "is greater than " << rhs_;
+ }
+
+ virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const {
+ const int diff = lhs - rhs_;
+ if (diff > 0) {
+ *os << "is " << diff << " more than " << rhs_;
+ } else if (diff == 0) {
+ *os << "is the same as " << rhs_;
+ } else {
+ *os << "is " << -diff << " less than " << rhs_;
+ }
+ }
+ private:
+ const int rhs_;
+};
+
+Matcher<int> GreaterThan(int n) {
+ return MakeMatcher(new GreaterThanMatcher(n));
+}
+
+// Tests for ElementsAre().
+
+// Evaluates to the number of elements in 'array'.
+#define GMOCK_ARRAY_SIZE_(array) (sizeof(array)/sizeof(array[0]))
+
+TEST(ElementsAreTest, CanDescribeExpectingNoElement) {
+ Matcher<const vector<int>&> m = ElementsAre();
+ EXPECT_EQ("is empty", Describe(m));
+}
+
+TEST(ElementsAreTest, CanDescribeExpectingOneElement) {
+ Matcher<vector<int> > m = ElementsAre(Gt(5));
+ EXPECT_EQ("has 1 element that is greater than 5", Describe(m));
+}
+
+TEST(ElementsAreTest, CanDescribeExpectingManyElements) {
+ Matcher<list<string> > m = ElementsAre(StrEq("one"), "two");
+ EXPECT_EQ("has 2 elements where\n"
+ "element 0 is equal to \"one\",\n"
+ "element 1 is equal to \"two\"", Describe(m));
+}
+
+TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) {
+ Matcher<vector<int> > m = ElementsAre();
+ EXPECT_EQ("is not empty", DescribeNegation(m));
+}
+
+TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) {
+ Matcher<const list<int>& > m = ElementsAre(Gt(5));
+ EXPECT_EQ("does not have 1 element, or\n"
+ "element 0 is not greater than 5", DescribeNegation(m));
+}
+
+TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) {
+ Matcher<const list<string>& > m = ElementsAre("one", "two");
+ EXPECT_EQ("does not have 2 elements, or\n"
+ "element 0 is not equal to \"one\", or\n"
+ "element 1 is not equal to \"two\"", DescribeNegation(m));
+}
+
+TEST(ElementsAreTest, DoesNotExplainTrivialMatch) {
+ Matcher<const list<int>& > m = ElementsAre(1, Ne(2));
+
+ list<int> test_list;
+ test_list.push_back(1);
+ test_list.push_back(3);
+ EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything.
+}
+
+TEST(ElementsAreTest, ExplainsNonTrivialMatch) {
+ Matcher<const vector<int>& > m =
+ ElementsAre(GreaterThan(1), 0, GreaterThan(2));
+
+ const int a[] = { 10, 0, 100 };
+ vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
+ EXPECT_EQ("element 0 is 9 more than 1,\n"
+ "element 2 is 98 more than 2", Explain(m, test_vector));
+}
+
+TEST(ElementsAreTest, CanExplainMismatchWrongSize) {
+ Matcher<const list<int>& > m = ElementsAre(1, 3);
+
+ list<int> test_list;
+ // No need to explain when the container is empty.
+ EXPECT_EQ("", Explain(m, test_list));
+
+ test_list.push_back(1);
+ EXPECT_EQ("has 1 element", Explain(m, test_list));
+}
+
+TEST(ElementsAreTest, CanExplainMismatchRightSize) {
+ Matcher<const vector<int>& > m = ElementsAre(1, GreaterThan(5));
+
+ vector<int> v;
+ v.push_back(2);
+ v.push_back(1);
+ EXPECT_EQ("element 0 doesn't match", Explain(m, v));
+
+ v[0] = 1;
+ EXPECT_EQ("element 1 doesn't match (is 4 less than 5)", Explain(m, v));
+}
+
+TEST(ElementsAreTest, MatchesOneElementVector) {
+ vector<string> test_vector;
+ test_vector.push_back("test string");
+
+ EXPECT_THAT(test_vector, ElementsAre(StrEq("test string")));
+}
+
+TEST(ElementsAreTest, MatchesOneElementList) {
+ list<string> test_list;
+ test_list.push_back("test string");
+
+ EXPECT_THAT(test_list, ElementsAre("test string"));
+}
+
+TEST(ElementsAreTest, MatchesThreeElementVector) {
+ vector<string> test_vector;
+ test_vector.push_back("one");
+ test_vector.push_back("two");
+ test_vector.push_back("three");
+
+ EXPECT_THAT(test_vector, ElementsAre("one", StrEq("two"), _));
+}
+
+TEST(ElementsAreTest, MatchesOneElementEqMatcher) {
+ vector<int> test_vector;
+ test_vector.push_back(4);
+
+ EXPECT_THAT(test_vector, ElementsAre(Eq(4)));
+}
+
+TEST(ElementsAreTest, MatchesOneElementAnyMatcher) {
+ vector<int> test_vector;
+ test_vector.push_back(4);
+
+ EXPECT_THAT(test_vector, ElementsAre(_));
+}
+
+TEST(ElementsAreTest, MatchesOneElementValue) {
+ vector<int> test_vector;
+ test_vector.push_back(4);
+
+ EXPECT_THAT(test_vector, ElementsAre(4));
+}
+
+TEST(ElementsAreTest, MatchesThreeElementsMixedMatchers) {
+ vector<int> test_vector;
+ test_vector.push_back(1);
+ test_vector.push_back(2);
+ test_vector.push_back(3);
+
+ EXPECT_THAT(test_vector, ElementsAre(1, Eq(2), _));
+}
+
+TEST(ElementsAreTest, MatchesTenElementVector) {
+ const int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
+
+ EXPECT_THAT(test_vector,
+ // The element list can contain values and/or matchers
+ // of different types.
+ ElementsAre(0, Ge(0), _, 3, 4, Ne(2), Eq(6), 7, 8, _));
+}
+
+TEST(ElementsAreTest, DoesNotMatchWrongSize) {
+ vector<string> test_vector;
+ test_vector.push_back("test string");
+ test_vector.push_back("test string");
+
+ Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
+ EXPECT_FALSE(m.Matches(test_vector));
+}
+
+TEST(ElementsAreTest, DoesNotMatchWrongValue) {
+ vector<string> test_vector;
+ test_vector.push_back("other string");
+
+ Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
+ EXPECT_FALSE(m.Matches(test_vector));
+}
+
+TEST(ElementsAreTest, DoesNotMatchWrongOrder) {
+ vector<string> test_vector;
+ test_vector.push_back("one");
+ test_vector.push_back("three");
+ test_vector.push_back("two");
+
+ Matcher<vector<string> > m = ElementsAre(
+ StrEq("one"), StrEq("two"), StrEq("three"));
+ EXPECT_FALSE(m.Matches(test_vector));
+}
+
+TEST(ElementsAreTest, WorksForNestedContainer) {
+ const char* strings[] = {
+ "Hi",
+ "world"
+ };
+
+ vector<list<char> > nested;
+ for (int i = 0; i < GMOCK_ARRAY_SIZE_(strings); i++) {
+ nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i])));
+ }
+
+ EXPECT_THAT(nested, ElementsAre(ElementsAre('H', Ne('e')),
+ ElementsAre('w', 'o', _, _, 'd')));
+ EXPECT_THAT(nested, Not(ElementsAre(ElementsAre('H', 'e'),
+ ElementsAre('w', 'o', _, _, 'd'))));
+}
+
+TEST(ElementsAreTest, WorksWithByRefElementMatchers) {
+ int a[] = { 0, 1, 2 };
+ vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
+
+ EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2])));
+ EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2]))));
+}
+
+TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
+ int a[] = { 0, 1, 2 };
+ vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
+
+ EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _)));
+ EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
+}
+
+// Tests for ElementsAreArray(). Since ElementsAreArray() shares most
+// of the implementation with ElementsAre(), we don't test it as
+// thoroughly here.
+
+TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) {
+ const int a[] = { 1, 2, 3 };
+
+ vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
+ EXPECT_THAT(test_vector, ElementsAreArray(a));
+
+ test_vector[2] = 0;
+ EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
+}
+
+TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) {
+ const char* a[] = { "one", "two", "three" };
+
+ vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
+ EXPECT_THAT(test_vector, ElementsAreArray(a, GMOCK_ARRAY_SIZE_(a)));
+
+ const char** p = a;
+ test_vector[0] = "1";
+ EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GMOCK_ARRAY_SIZE_(a))));
+}
+
+TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) {
+ const char* a[] = { "one", "two", "three" };
+
+ vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
+ EXPECT_THAT(test_vector, ElementsAreArray(a));
+
+ test_vector[0] = "1";
+ EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
+}
+
+TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
+ const Matcher<string> kMatcherArray[] =
+ { StrEq("one"), StrEq("two"), StrEq("three") };
+
+ vector<string> test_vector;
+ test_vector.push_back("one");
+ test_vector.push_back("two");
+ test_vector.push_back("three");
+ EXPECT_THAT(test_vector, ElementsAreArray(kMatcherArray));
+
+ test_vector.push_back("three");
+ EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
+}
+
+} // namespace
diff --git a/test/gmock-internal-utils_test.cc b/test/gmock-internal-utils_test.cc
new file mode 100644
index 00000000..2a43caa9
--- /dev/null
+++ b/test/gmock-internal-utils_test.cc
@@ -0,0 +1,521 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the internal utilities.
+
+#include <gmock/internal/gmock-internal-utils.h>
+#include <map>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <gmock/gmock.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+namespace internal {
+
+namespace {
+
+using ::std::tr1::tuple;
+
+// Tests that CompileAssertTypesEqual compiles when the type arguments are
+// equal.
+TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) {
+ CompileAssertTypesEqual<void, void>();
+ CompileAssertTypesEqual<int*, int*>();
+}
+
+// Tests that RemoveReference does not affect non-reference types.
+TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) {
+ CompileAssertTypesEqual<int, RemoveReference<int>::type>();
+ CompileAssertTypesEqual<const char, RemoveReference<const char>::type>();
+}
+
+// Tests that RemoveReference removes reference from reference types.
+TEST(RemoveReferenceTest, RemovesReference) {
+ CompileAssertTypesEqual<int, RemoveReference<int&>::type>();
+ CompileAssertTypesEqual<const char, RemoveReference<const char&>::type>();
+}
+
+// Tests GMOCK_REMOVE_REFERENCE.
+
+template <typename T1, typename T2>
+void TestGMockRemoveReference() {
+ CompileAssertTypesEqual<T1, GMOCK_REMOVE_REFERENCE(T2)>();
+}
+
+TEST(RemoveReferenceTest, MacroVersion) {
+ TestGMockRemoveReference<int, int>();
+ TestGMockRemoveReference<const char, const char&>();
+}
+
+
+// Tests that RemoveConst does not affect non-const types.
+TEST(RemoveConstTest, DoesNotAffectNonConstType) {
+ CompileAssertTypesEqual<int, RemoveConst<int>::type>();
+ CompileAssertTypesEqual<char&, RemoveConst<char&>::type>();
+}
+
+// Tests that RemoveConst removes const from const types.
+TEST(RemoveConstTest, RemovesConst) {
+ CompileAssertTypesEqual<int, RemoveConst<const int>::type>();
+}
+
+// Tests GMOCK_REMOVE_CONST.
+
+template <typename T1, typename T2>
+void TestGMockRemoveConst() {
+ CompileAssertTypesEqual<T1, GMOCK_REMOVE_CONST(T2)>();
+}
+
+TEST(RemoveConstTest, MacroVersion) {
+ TestGMockRemoveConst<int, int>();
+ TestGMockRemoveConst<double&, double&>();
+ TestGMockRemoveConst<char, const char>();
+}
+
+// Tests that AddReference does not affect reference types.
+TEST(AddReferenceTest, DoesNotAffectReferenceType) {
+ CompileAssertTypesEqual<int&, AddReference<int&>::type>();
+ CompileAssertTypesEqual<const char&, AddReference<const char&>::type>();
+}
+
+// Tests that AddReference adds reference to non-reference types.
+TEST(AddReferenceTest, AddsReference) {
+ CompileAssertTypesEqual<int&, AddReference<int>::type>();
+ CompileAssertTypesEqual<const char&, AddReference<const char>::type>();
+}
+
+// Tests GMOCK_ADD_REFERENCE.
+
+template <typename T1, typename T2>
+void TestGMockAddReference() {
+ CompileAssertTypesEqual<T1, GMOCK_ADD_REFERENCE(T2)>();
+}
+
+TEST(AddReferenceTest, MacroVersion) {
+ TestGMockAddReference<int&, int>();
+ TestGMockAddReference<const char&, const char&>();
+}
+
+// Tests GMOCK_REFERENCE_TO_CONST.
+
+template <typename T1, typename T2>
+void TestGMockReferenceToConst() {
+ CompileAssertTypesEqual<T1, GMOCK_REFERENCE_TO_CONST(T2)>();
+}
+
+TEST(GMockReferenceToConstTest, Works) {
+ TestGMockReferenceToConst<const char&, char>();
+ TestGMockReferenceToConst<const int&, const int>();
+ TestGMockReferenceToConst<const double&, double>();
+ TestGMockReferenceToConst<const string&, const string&>();
+}
+
+TEST(PointeeOfTest, WorksForSmartPointers) {
+ CompileAssertTypesEqual<const char,
+ PointeeOf<internal::linked_ptr<const char> >::type>();
+}
+
+TEST(PointeeOfTest, WorksForRawPointers) {
+ CompileAssertTypesEqual<int, PointeeOf<int*>::type>();
+ CompileAssertTypesEqual<const char, PointeeOf<const char*>::type>();
+ CompileAssertTypesEqual<void, PointeeOf<void*>::type>();
+}
+
+TEST(GetRawPointerTest, WorksForSmartPointers) {
+ const char* const raw_p4 = new const char('a'); // NOLINT
+ const internal::linked_ptr<const char> p4(raw_p4);
+ EXPECT_EQ(raw_p4, GetRawPointer(p4));
+}
+
+TEST(GetRawPointerTest, WorksForRawPointers) {
+ int* p = NULL;
+ EXPECT_EQ(NULL, GetRawPointer(p));
+ int n = 1;
+ EXPECT_EQ(&n, GetRawPointer(&n));
+}
+
+class Base {};
+class Derived : public Base {};
+
+// Tests that ImplicitlyConvertible<T1, T2>::value is a compile-time constant.
+TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) {
+ GMOCK_COMPILE_ASSERT((ImplicitlyConvertible<int, int>::value), const_true);
+ GMOCK_COMPILE_ASSERT((!ImplicitlyConvertible<void*, int*>::value), const_false);
+}
+
+// Tests that ImplicitlyConvertible<T1, T2>::value is true when T1 can
+// be implicitly converted to T2.
+TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) {
+ EXPECT_TRUE((ImplicitlyConvertible<int, double>::value));
+ EXPECT_TRUE((ImplicitlyConvertible<double, int>::value));
+ EXPECT_TRUE((ImplicitlyConvertible<int*, void*>::value));
+ EXPECT_TRUE((ImplicitlyConvertible<int*, const int*>::value));
+ EXPECT_TRUE((ImplicitlyConvertible<Derived&, const Base&>::value));
+ EXPECT_TRUE((ImplicitlyConvertible<const Base, Base>::value));
+}
+
+// Tests that ImplicitlyConvertible<T1, T2>::value is false when T1
+// cannot be implicitly converted to T2.
+TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) {
+ EXPECT_FALSE((ImplicitlyConvertible<double, int*>::value));
+ EXPECT_FALSE((ImplicitlyConvertible<void*, int*>::value));
+ EXPECT_FALSE((ImplicitlyConvertible<const int*, int*>::value));
+ EXPECT_FALSE((ImplicitlyConvertible<Base&, Derived&>::value));
+}
+
+// Tests that IsAProtocolMessage<T>::value is a compile-time constant.
+TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) {
+ GMOCK_COMPILE_ASSERT(IsAProtocolMessage<ProtocolMessage>::value, const_true);
+ GMOCK_COMPILE_ASSERT(!IsAProtocolMessage<int>::value, const_false);
+}
+
+// Tests that IsAProtocolMessage<T>::value is true when T is
+// ProtocolMessage or a sub-class of it.
+TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) {
+ EXPECT_TRUE(IsAProtocolMessage<ProtocolMessage>::value);
+#if GMOCK_HAS_PROTOBUF_
+ EXPECT_TRUE(IsAProtocolMessage<const TestMessage>::value);
+#endif // GMOCK_HAS_PROTOBUF_
+}
+
+// Tests that IsAProtocolMessage<T>::value is false when T is neither
+// ProtocolMessage nor a sub-class of it.
+TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) {
+ EXPECT_FALSE(IsAProtocolMessage<int>::value);
+ EXPECT_FALSE(IsAProtocolMessage<const Base>::value);
+}
+
+// Tests IsContainerTest.
+
+class NonContainer {};
+
+TEST(IsContainerTestTest, WorksForNonContainer) {
+ EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<int>(0)));
+ EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<char[5]>(0)));
+ EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<NonContainer>(0)));
+}
+
+TEST(IsContainerTestTest, WorksForContainer) {
+ EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest<std::vector<bool> >(0)));
+ EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest<std::map<int, double> >(0)));
+}
+
+// Tests the TupleMatches() template function.
+
+TEST(TupleMatchesTest, WorksForSize0) {
+ tuple<> matchers;
+ tuple<> values;
+
+ EXPECT_TRUE(TupleMatches(matchers, values));
+}
+
+TEST(TupleMatchesTest, WorksForSize1) {
+ tuple<Matcher<int> > matchers(Eq(1));
+ tuple<int> values1(1),
+ values2(2);
+
+ EXPECT_TRUE(TupleMatches(matchers, values1));
+ EXPECT_FALSE(TupleMatches(matchers, values2));
+}
+
+TEST(TupleMatchesTest, WorksForSize2) {
+ tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a'));
+ tuple<int, char> values1(1, 'a'),
+ values2(1, 'b'),
+ values3(2, 'a'),
+ values4(2, 'b');
+
+ EXPECT_TRUE(TupleMatches(matchers, values1));
+ EXPECT_FALSE(TupleMatches(matchers, values2));
+ EXPECT_FALSE(TupleMatches(matchers, values3));
+ EXPECT_FALSE(TupleMatches(matchers, values4));
+}
+
+TEST(TupleMatchesTest, WorksForSize5) {
+ tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<long>, // NOLINT
+ Matcher<string> >
+ matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi"));
+ tuple<int, char, bool, long, string> // NOLINT
+ values1(1, 'a', true, 2L, "hi"),
+ values2(1, 'a', true, 2L, "hello"),
+ values3(2, 'a', true, 2L, "hi");
+
+ EXPECT_TRUE(TupleMatches(matchers, values1));
+ EXPECT_FALSE(TupleMatches(matchers, values2));
+ EXPECT_FALSE(TupleMatches(matchers, values3));
+}
+
+// Tests that Assert(true, ...) succeeds.
+TEST(AssertTest, SucceedsOnTrue) {
+ Assert(true, __FILE__, __LINE__, "This should succeed.");
+ Assert(true, __FILE__, __LINE__); // This should succeed too.
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Tests that Assert(false, ...) generates a fatal failure.
+TEST(AssertTest, FailsFatallyOnFalse) {
+ EXPECT_DEATH({ // NOLINT
+ Assert(false, __FILE__, __LINE__, "This should fail.");
+ }, "");
+
+ EXPECT_DEATH({ // NOLINT
+ Assert(false, __FILE__, __LINE__);
+ }, "");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+// Tests that Expect(true, ...) succeeds.
+TEST(ExpectTest, SucceedsOnTrue) {
+ Expect(true, __FILE__, __LINE__, "This should succeed.");
+ Expect(true, __FILE__, __LINE__); // This should succeed too.
+}
+
+// Tests that Expect(false, ...) generates a non-fatal failure.
+TEST(ExpectTest, FailsNonfatallyOnFalse) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ Expect(false, __FILE__, __LINE__, "This should fail.");
+ }, "This should fail");
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ Expect(false, __FILE__, __LINE__);
+ }, "Expectation failed");
+}
+
+// TODO(wan@google.com): find a way to re-enable these tests.
+#if 0
+
+// Tests the Log() function.
+
+// Verifies that Log() behaves correctly for the given verbosity level
+// and log severity.
+void TestLogWithSeverity(const string& verbosity, LogSeverity severity,
+ bool should_print) {
+ const string old_flag = GMOCK_FLAG(verbose);
+ GMOCK_FLAG(verbose) = verbosity;
+ CaptureTestStdout();
+ Log(severity, "Test log.\n", 0);
+ if (should_print) {
+ EXPECT_PRED2(RE::FullMatch,
+ GetCapturedTestStdout(),
+ severity == WARNING ?
+ "\nGMOCK WARNING:\nTest log\\.\nStack trace:\n[\\s\\S]*" :
+ "\nTest log\\.\nStack trace:\n[\\s\\S]*");
+ } else {
+ EXPECT_EQ("", GetCapturedTestStdout());
+ }
+ GMOCK_FLAG(verbose) = old_flag;
+}
+
+// Tests that when the stack_frames_to_skip parameter is negative,
+// Log() doesn't include the stack trace in the output.
+TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
+ GMOCK_FLAG(verbose) = kInfoVerbosity;
+ CaptureTestStdout();
+ Log(INFO, "Test log.\n", -1);
+ EXPECT_EQ("\nTest log.\n", GetCapturedTestStdout());
+}
+
+// Tests that in opt mode, a positive stack_frames_to_skip argument is
+// treated as 0.
+TEST(LogTest, NoSkippingStackFrameInOptMode) {
+ CaptureTestStdout();
+ Log(WARNING, "Test log.\n", 100);
+ const string log = GetCapturedTestStdout();
+#ifdef NDEBUG
+ // In opt mode, no stack frame should be skipped.
+ EXPECT_THAT(log, ContainsRegex("\nGMOCK WARNING:\n"
+ "Test log\\.\n"
+ "Stack trace:\n"
+ ".+"));
+#else
+ // In dbg mode, the stack frames should be skipped.
+ EXPECT_EQ("\nGMOCK WARNING:\n"
+ "Test log.\n"
+ "Stack trace:\n", log);
+#endif // NDEBUG
+}
+
+// Tests that all logs are printed when the value of the
+// --gmock_verbose flag is "info".
+TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) {
+ TestLogWithSeverity(kInfoVerbosity, INFO, true);
+ TestLogWithSeverity(kInfoVerbosity, WARNING, true);
+}
+
+// Tests that only warnings are printed when the value of the
+// --gmock_verbose flag is "warning".
+TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) {
+ TestLogWithSeverity(kWarningVerbosity, INFO, false);
+ TestLogWithSeverity(kWarningVerbosity, WARNING, true);
+}
+
+// Tests that no logs are printed when the value of the
+// --gmock_verbose flag is "error".
+TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) {
+ TestLogWithSeverity(kErrorVerbosity, INFO, false);
+ TestLogWithSeverity(kErrorVerbosity, WARNING, false);
+}
+
+// Tests that only warnings are printed when the value of the
+// --gmock_verbose flag is invalid.
+TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
+ TestLogWithSeverity("invalid", INFO, false);
+ TestLogWithSeverity("invalid", WARNING, true);
+}
+
+#endif // 0
+
+TEST(TypeTraitsTest, true_type) {
+ EXPECT_TRUE(true_type::value);
+}
+
+TEST(TypeTraitsTest, false_type) {
+ EXPECT_FALSE(false_type::value);
+}
+
+TEST(TypeTraitsTest, is_reference) {
+ EXPECT_FALSE(is_reference<int>::value);
+ EXPECT_FALSE(is_reference<char*>::value);
+ EXPECT_TRUE(is_reference<const int&>::value);
+}
+
+TEST(TypeTraitsTest, is_pointer) {
+ EXPECT_FALSE(is_pointer<int>::value);
+ EXPECT_FALSE(is_pointer<char&>::value);
+ EXPECT_TRUE(is_pointer<const int*>::value);
+}
+
+TEST(TypeTraitsTest, type_equals) {
+ EXPECT_FALSE((type_equals<int, const int>::value));
+ EXPECT_FALSE((type_equals<int, int&>::value));
+ EXPECT_FALSE((type_equals<int, double>::value));
+ EXPECT_TRUE((type_equals<char, char>::value));
+}
+
+TEST(TypeTraitsTest, remove_reference) {
+ EXPECT_TRUE((type_equals<char, remove_reference<char&>::type>::value));
+ EXPECT_TRUE((type_equals<const int,
+ remove_reference<const int&>::type>::value));
+ EXPECT_TRUE((type_equals<int, remove_reference<int>::type>::value));
+ EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value));
+}
+
+// TODO(wan@google.com): find a way to re-enable these tests.
+#if 0
+
+// Verifies that Log() behaves correctly for the given verbosity level
+// and log severity.
+string GrabOutput(void(*logger)(), const char* verbosity) {
+ const string saved_flag = GMOCK_FLAG(verbose);
+ GMOCK_FLAG(verbose) = verbosity;
+ CaptureTestStdout();
+ logger();
+ GMOCK_FLAG(verbose) = saved_flag;
+ return GetCapturedTestStdout();
+}
+
+class DummyMock {
+ public:
+ MOCK_METHOD0(TestMethod, void());
+ MOCK_METHOD1(TestMethodArg, void(int dummy));
+};
+
+void ExpectCallLogger() {
+ DummyMock mock;
+ EXPECT_CALL(mock, TestMethod());
+ mock.TestMethod();
+};
+
+// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info".
+TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) {
+ EXPECT_THAT(GrabOutput(ExpectCallLogger, kInfoVerbosity),
+ HasSubstr("EXPECT_CALL(mock, TestMethod())"));
+}
+
+// Verifies that EXPECT_CALL doesn't log
+// if the --gmock_verbose flag is set to "warning".
+TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) {
+ EXPECT_EQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity));
+}
+
+// Verifies that EXPECT_CALL doesn't log
+// if the --gmock_verbose flag is set to "error".
+TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
+ EXPECT_EQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity));
+}
+
+void OnCallLogger() {
+ DummyMock mock;
+ ON_CALL(mock, TestMethod());
+};
+
+// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
+TEST(OnCallTest, LogsWhenVerbosityIsInfo) {
+ EXPECT_THAT(GrabOutput(OnCallLogger, kInfoVerbosity),
+ HasSubstr("ON_CALL(mock, TestMethod())"));
+}
+
+// Verifies that ON_CALL doesn't log
+// if the --gmock_verbose flag is set to "warning".
+TEST(OnCallTest, DoesNotLogWhenVerbosityIsWarning) {
+ EXPECT_EQ("", GrabOutput(OnCallLogger, kWarningVerbosity));
+}
+
+// Verifies that ON_CALL doesn't log if
+// the --gmock_verbose flag is set to "error".
+TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
+ EXPECT_EQ("", GrabOutput(OnCallLogger, kErrorVerbosity));
+}
+
+void OnCallAnyArgumentLogger() {
+ DummyMock mock;
+ ON_CALL(mock, TestMethodArg(_));
+}
+
+// Verifies that ON_CALL prints provided _ argument.
+TEST(OnCallTest, LogsAnythingArgument) {
+ EXPECT_THAT(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity),
+ HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
+}
+
+#endif // 0
+
+} // namespace
+} // namespace internal
+} // namespace testing
diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc
new file mode 100644
index 00000000..29b038e4
--- /dev/null
+++ b/test/gmock-matchers_test.cc
@@ -0,0 +1,2629 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests some commonly used argument matchers.
+
+#include <gmock/gmock-matchers.h>
+
+#include <string.h>
+#include <functional>
+#include <string>
+#include <sstream>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+namespace gmock_matchers_test {
+
+using std::stringstream;
+using testing::A;
+using testing::AllOf;
+using testing::An;
+using testing::AnyOf;
+using testing::ByRef;
+using testing::DoubleEq;
+using testing::EndsWith;
+using testing::Eq;
+using testing::Field;
+using testing::FloatEq;
+using testing::Ge;
+using testing::Gt;
+using testing::HasSubstr;
+using testing::Le;
+using testing::Lt;
+using testing::MakeMatcher;
+using testing::MakePolymorphicMatcher;
+using testing::Matcher;
+using testing::MatcherCast;
+using testing::MatcherInterface;
+using testing::Matches;
+using testing::NanSensitiveDoubleEq;
+using testing::NanSensitiveFloatEq;
+using testing::Ne;
+using testing::Not;
+using testing::NotNull;
+using testing::Pointee;
+using testing::PolymorphicMatcher;
+using testing::Property;
+using testing::Ref;
+using testing::ResultOf;
+using testing::StartsWith;
+using testing::StrCaseEq;
+using testing::StrCaseNe;
+using testing::StrEq;
+using testing::StrNe;
+using testing::Truly;
+using testing::TypedEq;
+using testing::_;
+using testing::internal::FloatingEqMatcher;
+using testing::internal::String;
+using testing::internal::string;
+
+#ifdef GMOCK_HAS_REGEX
+using testing::ContainsRegex;
+using testing::MatchesRegex;
+using testing::internal::RE;
+#endif // GMOCK_HAS_REGEX
+
+// Returns the description of the given matcher.
+template <typename T>
+string Describe(const Matcher<T>& m) {
+ stringstream ss;
+ m.DescribeTo(&ss);
+ return ss.str();
+}
+
+// Returns the description of the negation of the given matcher.
+template <typename T>
+string DescribeNegation(const Matcher<T>& m) {
+ stringstream ss;
+ m.DescribeNegationTo(&ss);
+ return ss.str();
+}
+
+// Returns the reason why x matches, or doesn't match, m.
+template <typename MatcherType, typename Value>
+string Explain(const MatcherType& m, const Value& x) {
+ stringstream ss;
+ m.ExplainMatchResultTo(x, &ss);
+ return ss.str();
+}
+
+// Makes sure that the MatcherInterface<T> interface doesn't
+// change.
+class EvenMatcherImpl : public MatcherInterface<int> {
+ public:
+ virtual bool Matches(int x) const { return x % 2 == 0; }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "is an even number";
+ }
+
+ // We deliberately don't define DescribeNegationTo() and
+ // ExplainMatchResultTo() here, to make sure the definition of these
+ // two methods is optional.
+};
+
+TEST(MatcherInterfaceTest, CanBeImplemented) {
+ EvenMatcherImpl m;
+}
+
+// Tests default-constructing a matcher.
+TEST(MatcherTest, CanBeDefaultConstructed) {
+ Matcher<double> m;
+}
+
+// Tests that Matcher<T> can be constructed from a MatcherInterface<T>*.
+TEST(MatcherTest, CanBeConstructedFromMatcherInterface) {
+ const MatcherInterface<int>* impl = new EvenMatcherImpl;
+ Matcher<int> m(impl);
+ EXPECT_TRUE(m.Matches(4));
+ EXPECT_FALSE(m.Matches(5));
+}
+
+// Tests that value can be used in place of Eq(value).
+TEST(MatcherTest, CanBeImplicitlyConstructedFromValue) {
+ Matcher<int> m1 = 5;
+ EXPECT_TRUE(m1.Matches(5));
+ EXPECT_FALSE(m1.Matches(6));
+}
+
+// Tests that NULL can be used in place of Eq(NULL).
+TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) {
+ Matcher<int*> m1 = NULL;
+ EXPECT_TRUE(m1.Matches(NULL));
+ int n = 0;
+ EXPECT_FALSE(m1.Matches(&n));
+}
+
+// Tests that matchers are copyable.
+TEST(MatcherTest, IsCopyable) {
+ // Tests the copy constructor.
+ Matcher<bool> m1 = Eq(false);
+ EXPECT_TRUE(m1.Matches(false));
+ EXPECT_FALSE(m1.Matches(true));
+
+ // Tests the assignment operator.
+ m1 = Eq(true);
+ EXPECT_TRUE(m1.Matches(true));
+ EXPECT_FALSE(m1.Matches(false));
+}
+
+// Tests that Matcher<T>::DescribeTo() calls
+// MatcherInterface<T>::DescribeTo().
+TEST(MatcherTest, CanDescribeItself) {
+ EXPECT_EQ("is an even number",
+ Describe(Matcher<int>(new EvenMatcherImpl)));
+}
+
+// Tests that a C-string literal can be implicitly converted to a
+// Matcher<string> or Matcher<const string&>.
+TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) {
+ Matcher<string> m1 = "hi";
+ EXPECT_TRUE(m1.Matches("hi"));
+ EXPECT_FALSE(m1.Matches("hello"));
+
+ Matcher<const string&> m2 = "hi";
+ EXPECT_TRUE(m2.Matches("hi"));
+ EXPECT_FALSE(m2.Matches("hello"));
+}
+
+// Tests that a string object can be implicitly converted to a
+// Matcher<string> or Matcher<const string&>.
+TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) {
+ Matcher<string> m1 = string("hi");
+ EXPECT_TRUE(m1.Matches("hi"));
+ EXPECT_FALSE(m1.Matches("hello"));
+
+ Matcher<const string&> m2 = string("hi");
+ EXPECT_TRUE(m2.Matches("hi"));
+ EXPECT_FALSE(m2.Matches("hello"));
+}
+
+// Tests that MakeMatcher() constructs a Matcher<T> from a
+// MatcherInterface* without requiring the user to explicitly
+// write the type.
+TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) {
+ const MatcherInterface<int>* dummy_impl = NULL;
+ Matcher<int> m = MakeMatcher(dummy_impl);
+}
+
+// Tests that MakePolymorphicMatcher() constructs a polymorphic
+// matcher from its implementation.
+const int bar = 1;
+class ReferencesBarOrIsZeroImpl {
+ public:
+ template <typename T>
+ bool Matches(const T& x) const {
+ const void* p = &x;
+ return p == &bar || x == 0;
+ }
+
+ void DescribeTo(::std::ostream* os) const { *os << "bar or zero"; }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't reference bar and is not zero";
+ }
+};
+
+// This function verifies that MakePolymorphicMatcher() returns a
+// PolymorphicMatcher<T> where T is the argument's type.
+PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() {
+ return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl());
+}
+
+TEST(MakePolymorphicMatcherTest, ConstructsMatcherFromImpl) {
+ // Using a polymorphic matcher to match a reference type.
+ Matcher<const int&> m1 = ReferencesBarOrIsZero();
+ EXPECT_TRUE(m1.Matches(0));
+ // Verifies that the identity of a by-reference argument is preserved.
+ EXPECT_TRUE(m1.Matches(bar));
+ EXPECT_FALSE(m1.Matches(1));
+ EXPECT_EQ("bar or zero", Describe(m1));
+
+ // Using a polymorphic matcher to match a value type.
+ Matcher<double> m2 = ReferencesBarOrIsZero();
+ EXPECT_TRUE(m2.Matches(0.0));
+ EXPECT_FALSE(m2.Matches(0.1));
+ EXPECT_EQ("bar or zero", Describe(m2));
+}
+
+// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher.
+TEST(MatcherCastTest, FromPolymorphicMatcher) {
+ Matcher<int> m = MatcherCast<int>(Eq(5));
+ EXPECT_TRUE(m.Matches(5));
+ EXPECT_FALSE(m.Matches(6));
+}
+
+// For testing casting matchers between compatible types.
+class IntValue {
+ public:
+ // An int can be statically (although not implicitly) cast to a
+ // IntValue.
+ explicit IntValue(int value) : value_(value) {}
+
+ int value() const { return value_; }
+ private:
+ int value_;
+};
+
+// For testing casting matchers between compatible types.
+bool IsPositiveIntValue(const IntValue& foo) {
+ return foo.value() > 0;
+}
+
+// Tests that MatcherCast<T>(m) works when m is a Matcher<U> where T
+// can be statically converted to U.
+TEST(MatcherCastTest, FromCompatibleType) {
+ Matcher<double> m1 = Eq(2.0);
+ Matcher<int> m2 = MatcherCast<int>(m1);
+ EXPECT_TRUE(m2.Matches(2));
+ EXPECT_FALSE(m2.Matches(3));
+
+ Matcher<IntValue> m3 = Truly(IsPositiveIntValue);
+ Matcher<int> m4 = MatcherCast<int>(m3);
+ // In the following, the arguments 1 and 0 are statically converted
+ // to IntValue objects, and then tested by the IsPositiveIntValue()
+ // predicate.
+ EXPECT_TRUE(m4.Matches(1));
+ EXPECT_FALSE(m4.Matches(0));
+}
+
+// Tests that MatcherCast<T>(m) works when m is a Matcher<const T&>.
+TEST(MatcherCastTest, FromConstReferenceToNonReference) {
+ Matcher<const int&> m1 = Eq(0);
+ Matcher<int> m2 = MatcherCast<int>(m1);
+ EXPECT_TRUE(m2.Matches(0));
+ EXPECT_FALSE(m2.Matches(1));
+}
+
+// Tests that MatcherCast<T>(m) works when m is a Matcher<T&>.
+TEST(MatcherCastTest, FromReferenceToNonReference) {
+ Matcher<int&> m1 = Eq(0);
+ Matcher<int> m2 = MatcherCast<int>(m1);
+ EXPECT_TRUE(m2.Matches(0));
+ EXPECT_FALSE(m2.Matches(1));
+}
+
+// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>.
+TEST(MatcherCastTest, FromNonReferenceToConstReference) {
+ Matcher<int> m1 = Eq(0);
+ Matcher<const int&> m2 = MatcherCast<const int&>(m1);
+ EXPECT_TRUE(m2.Matches(0));
+ EXPECT_FALSE(m2.Matches(1));
+}
+
+// Tests that MatcherCast<T&>(m) works when m is a Matcher<T>.
+TEST(MatcherCastTest, FromNonReferenceToReference) {
+ Matcher<int> m1 = Eq(0);
+ Matcher<int&> m2 = MatcherCast<int&>(m1);
+ int n = 0;
+ EXPECT_TRUE(m2.Matches(n));
+ n = 1;
+ EXPECT_FALSE(m2.Matches(n));
+}
+
+// Tests that MatcherCast<T>(m) works when m is a Matcher<T>.
+TEST(MatcherCastTest, FromSameType) {
+ Matcher<int> m1 = Eq(0);
+ Matcher<int> m2 = MatcherCast<int>(m1);
+ EXPECT_TRUE(m2.Matches(0));
+ EXPECT_FALSE(m2.Matches(1));
+}
+
+// Tests that A<T>() matches any value of type T.
+TEST(ATest, MatchesAnyValue) {
+ // Tests a matcher for a value type.
+ Matcher<double> m1 = A<double>();
+ EXPECT_TRUE(m1.Matches(91.43));
+ EXPECT_TRUE(m1.Matches(-15.32));
+
+ // Tests a matcher for a reference type.
+ int a = 2;
+ int b = -6;
+ Matcher<int&> m2 = A<int&>();
+ EXPECT_TRUE(m2.Matches(a));
+ EXPECT_TRUE(m2.Matches(b));
+}
+
+// Tests that A<T>() describes itself properly.
+TEST(ATest, CanDescribeSelf) {
+ EXPECT_EQ("is anything", Describe(A<bool>()));
+}
+
+// Tests that An<T>() matches any value of type T.
+TEST(AnTest, MatchesAnyValue) {
+ // Tests a matcher for a value type.
+ Matcher<int> m1 = An<int>();
+ EXPECT_TRUE(m1.Matches(9143));
+ EXPECT_TRUE(m1.Matches(-1532));
+
+ // Tests a matcher for a reference type.
+ int a = 2;
+ int b = -6;
+ Matcher<int&> m2 = An<int&>();
+ EXPECT_TRUE(m2.Matches(a));
+ EXPECT_TRUE(m2.Matches(b));
+}
+
+// Tests that An<T>() describes itself properly.
+TEST(AnTest, CanDescribeSelf) {
+ EXPECT_EQ("is anything", Describe(An<int>()));
+}
+
+// Tests that _ can be used as a matcher for any type and matches any
+// value of that type.
+TEST(UnderscoreTest, MatchesAnyValue) {
+ // Uses _ as a matcher for a value type.
+ Matcher<int> m1 = _;
+ EXPECT_TRUE(m1.Matches(123));
+ EXPECT_TRUE(m1.Matches(-242));
+
+ // Uses _ as a matcher for a reference type.
+ bool a = false;
+ const bool b = true;
+ Matcher<const bool&> m2 = _;
+ EXPECT_TRUE(m2.Matches(a));
+ EXPECT_TRUE(m2.Matches(b));
+}
+
+// Tests that _ describes itself properly.
+TEST(UnderscoreTest, CanDescribeSelf) {
+ Matcher<int> m = _;
+ EXPECT_EQ("is anything", Describe(m));
+}
+
+// Tests that Eq(x) matches any value equal to x.
+TEST(EqTest, MatchesEqualValue) {
+ // 2 C-strings with same content but different addresses.
+ const char a1[] = "hi";
+ const char a2[] = "hi";
+
+ Matcher<const char*> m1 = Eq(a1);
+ EXPECT_TRUE(m1.Matches(a1));
+ EXPECT_FALSE(m1.Matches(a2));
+}
+
+// Tests that Eq(v) describes itself properly.
+
+class Unprintable {
+ public:
+ Unprintable() : c_('a') {}
+
+ bool operator==(const Unprintable& rhs) { return true; }
+ private:
+ char c_;
+};
+
+TEST(EqTest, CanDescribeSelf) {
+ Matcher<Unprintable> m = Eq(Unprintable());
+ EXPECT_EQ("is equal to 1-byte object <61>", Describe(m));
+}
+
+// Tests that Eq(v) can be used to match any type that supports
+// comparing with type T, where T is v's type.
+TEST(EqTest, IsPolymorphic) {
+ Matcher<int> m1 = Eq(1);
+ EXPECT_TRUE(m1.Matches(1));
+ EXPECT_FALSE(m1.Matches(2));
+
+ Matcher<char> m2 = Eq(1);
+ EXPECT_TRUE(m2.Matches('\1'));
+ EXPECT_FALSE(m2.Matches('a'));
+}
+
+// Tests that TypedEq<T>(v) matches values of type T that's equal to v.
+TEST(TypedEqTest, ChecksEqualityForGivenType) {
+ Matcher<char> m1 = TypedEq<char>('a');
+ EXPECT_TRUE(m1.Matches('a'));
+ EXPECT_FALSE(m1.Matches('b'));
+
+ Matcher<int> m2 = TypedEq<int>(6);
+ EXPECT_TRUE(m2.Matches(6));
+ EXPECT_FALSE(m2.Matches(7));
+}
+
+// Tests that TypedEq(v) describes itself properly.
+TEST(TypedEqTest, CanDescribeSelf) {
+ EXPECT_EQ("is equal to 2", Describe(TypedEq<int>(2)));
+}
+
+// Tests that TypedEq<T>(v) has type Matcher<T>.
+
+// Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T
+// is a "bare" type (i.e. not in the form of const U or U&). If v's
+// type is not T, the compiler will generate a message about
+// "undefined referece".
+template <typename T>
+struct Type {
+ static bool IsTypeOf(const T& v) { return true; }
+
+ template <typename T2>
+ static void IsTypeOf(T2 v);
+};
+
+TEST(TypedEqTest, HasSpecifiedType) {
+ // Verfies that the type of TypedEq<T>(v) is Matcher<T>.
+ Type<Matcher<int> >::IsTypeOf(TypedEq<int>(5));
+ Type<Matcher<double> >::IsTypeOf(TypedEq<double>(5));
+}
+
+// Tests that Ge(v) matches anything >= v.
+TEST(GeTest, ImplementsGreaterThanOrEqual) {
+ Matcher<int> m1 = Ge(0);
+ EXPECT_TRUE(m1.Matches(1));
+ EXPECT_TRUE(m1.Matches(0));
+ EXPECT_FALSE(m1.Matches(-1));
+}
+
+// Tests that Ge(v) describes itself properly.
+TEST(GeTest, CanDescribeSelf) {
+ Matcher<int> m = Ge(5);
+ EXPECT_EQ("is greater than or equal to 5", Describe(m));
+}
+
+// Tests that Gt(v) matches anything > v.
+TEST(GtTest, ImplementsGreaterThan) {
+ Matcher<double> m1 = Gt(0);
+ EXPECT_TRUE(m1.Matches(1.0));
+ EXPECT_FALSE(m1.Matches(0.0));
+ EXPECT_FALSE(m1.Matches(-1.0));
+}
+
+// Tests that Gt(v) describes itself properly.
+TEST(GtTest, CanDescribeSelf) {
+ Matcher<int> m = Gt(5);
+ EXPECT_EQ("is greater than 5", Describe(m));
+}
+
+// Tests that Le(v) matches anything <= v.
+TEST(LeTest, ImplementsLessThanOrEqual) {
+ Matcher<char> m1 = Le('b');
+ EXPECT_TRUE(m1.Matches('a'));
+ EXPECT_TRUE(m1.Matches('b'));
+ EXPECT_FALSE(m1.Matches('c'));
+}
+
+// Tests that Le(v) describes itself properly.
+TEST(LeTest, CanDescribeSelf) {
+ Matcher<int> m = Le(5);
+ EXPECT_EQ("is less than or equal to 5", Describe(m));
+}
+
+// Tests that Lt(v) matches anything < v.
+TEST(LtTest, ImplementsLessThan) {
+ Matcher<const string&> m1 = Lt("Hello");
+ EXPECT_TRUE(m1.Matches("Abc"));
+ EXPECT_FALSE(m1.Matches("Hello"));
+ EXPECT_FALSE(m1.Matches("Hello, world!"));
+}
+
+// Tests that Lt(v) describes itself properly.
+TEST(LtTest, CanDescribeSelf) {
+ Matcher<int> m = Lt(5);
+ EXPECT_EQ("is less than 5", Describe(m));
+}
+
+// Tests that Ne(v) matches anything != v.
+TEST(NeTest, ImplementsNotEqual) {
+ Matcher<int> m1 = Ne(0);
+ EXPECT_TRUE(m1.Matches(1));
+ EXPECT_TRUE(m1.Matches(-1));
+ EXPECT_FALSE(m1.Matches(0));
+}
+
+// Tests that Ne(v) describes itself properly.
+TEST(NeTest, CanDescribeSelf) {
+ Matcher<int> m = Ne(5);
+ EXPECT_EQ("is not equal to 5", Describe(m));
+}
+
+// Tests that NotNull() matches any non-NULL pointer of any type.
+TEST(NotNullTest, MatchesNonNullPointer) {
+ Matcher<int*> m1 = NotNull();
+ int* p1 = NULL;
+ int n = 0;
+ EXPECT_FALSE(m1.Matches(p1));
+ EXPECT_TRUE(m1.Matches(&n));
+
+ Matcher<const char*> m2 = NotNull();
+ const char* p2 = NULL;
+ EXPECT_FALSE(m2.Matches(p2));
+ EXPECT_TRUE(m2.Matches("hi"));
+}
+
+// Tests that NotNull() describes itself properly.
+TEST(NotNullTest, CanDescribeSelf) {
+ Matcher<int*> m = NotNull();
+ EXPECT_EQ("is not NULL", Describe(m));
+}
+
+// Tests that Ref(variable) matches an argument that references
+// 'variable'.
+TEST(RefTest, MatchesSameVariable) {
+ int a = 0;
+ int b = 0;
+ Matcher<int&> m = Ref(a);
+ EXPECT_TRUE(m.Matches(a));
+ EXPECT_FALSE(m.Matches(b));
+}
+
+// Tests that Ref(variable) describes itself properly.
+TEST(RefTest, CanDescribeSelf) {
+ int n = 5;
+ Matcher<int&> m = Ref(n);
+ stringstream ss;
+ ss << "references the variable @" << &n << " 5";
+ EXPECT_EQ(string(ss.str()), Describe(m));
+}
+
+// Test that Ref(non_const_varialbe) can be used as a matcher for a
+// const reference.
+TEST(RefTest, CanBeUsedAsMatcherForConstReference) {
+ int a = 0;
+ int b = 0;
+ Matcher<const int&> m = Ref(a);
+ EXPECT_TRUE(m.Matches(a));
+ EXPECT_FALSE(m.Matches(b));
+}
+
+// Tests that Ref(variable) is covariant, i.e. Ref(derived) can be
+// used wherever Ref(base) can be used (Ref(derived) is a sub-type
+// of Ref(base), but not vice versa.
+
+class Base {};
+class Derived : public Base {};
+
+TEST(RefTest, IsCovariant) {
+ Base base, base2;
+ Derived derived;
+ Matcher<const Base&> m1 = Ref(base);
+ EXPECT_TRUE(m1.Matches(base));
+ EXPECT_FALSE(m1.Matches(base2));
+ EXPECT_FALSE(m1.Matches(derived));
+
+ m1 = Ref(derived);
+ EXPECT_TRUE(m1.Matches(derived));
+ EXPECT_FALSE(m1.Matches(base));
+ EXPECT_FALSE(m1.Matches(base2));
+}
+
+// Tests string comparison matchers.
+
+TEST(StrEqTest, MatchesEqualString) {
+ Matcher<const char*> m = StrEq(string("Hello"));
+ EXPECT_TRUE(m.Matches("Hello"));
+ EXPECT_FALSE(m.Matches("hello"));
+ EXPECT_FALSE(m.Matches(NULL));
+
+ Matcher<const string&> m2 = StrEq("Hello");
+ EXPECT_TRUE(m2.Matches("Hello"));
+ EXPECT_FALSE(m2.Matches("Hi"));
+}
+
+TEST(StrEqTest, CanDescribeSelf) {
+ Matcher<string> m = StrEq("Hi-\'\"\?\\\a\b\f\n\r\t\v\xD3");
+ EXPECT_EQ("is equal to \"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\\xD3\"",
+ Describe(m));
+
+ string str("01204500800");
+ str[3] = '\0';
+ Matcher<string> m2 = StrEq(str);
+ EXPECT_EQ("is equal to \"012\\04500800\"", Describe(m2));
+ str[0] = str[6] = str[7] = str[9] = str[10] = '\0';
+ Matcher<string> m3 = StrEq(str);
+ EXPECT_EQ("is equal to \"\\012\\045\\0\\08\\0\\0\"", Describe(m3));
+}
+
+TEST(StrNeTest, MatchesUnequalString) {
+ Matcher<const char*> m = StrNe("Hello");
+ EXPECT_TRUE(m.Matches(""));
+ EXPECT_TRUE(m.Matches(NULL));
+ EXPECT_FALSE(m.Matches("Hello"));
+
+ Matcher<string> m2 = StrNe(string("Hello"));
+ EXPECT_TRUE(m2.Matches("hello"));
+ EXPECT_FALSE(m2.Matches("Hello"));
+}
+
+TEST(StrNeTest, CanDescribeSelf) {
+ Matcher<const char*> m = StrNe("Hi");
+ EXPECT_EQ("is not equal to \"Hi\"", Describe(m));
+}
+
+TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) {
+ Matcher<const char*> m = StrCaseEq(string("Hello"));
+ EXPECT_TRUE(m.Matches("Hello"));
+ EXPECT_TRUE(m.Matches("hello"));
+ EXPECT_FALSE(m.Matches("Hi"));
+ EXPECT_FALSE(m.Matches(NULL));
+
+ Matcher<const string&> m2 = StrCaseEq("Hello");
+ EXPECT_TRUE(m2.Matches("hello"));
+ EXPECT_FALSE(m2.Matches("Hi"));
+}
+
+TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) {
+ string str1("oabocdooeoo");
+ string str2("OABOCDOOEOO");
+ Matcher<const string&> m0 = StrCaseEq(str1);
+ EXPECT_FALSE(m0.Matches(str2 + string(1, '\0')));
+
+ str1[3] = str2[3] = '\0';
+ Matcher<const string&> m1 = StrCaseEq(str1);
+ EXPECT_TRUE(m1.Matches(str2));
+
+ str1[0] = str1[6] = str1[7] = str1[10] = '\0';
+ str2[0] = str2[6] = str2[7] = str2[10] = '\0';
+ Matcher<const string&> m2 = StrCaseEq(str1);
+ str1[9] = str2[9] = '\0';
+ EXPECT_FALSE(m2.Matches(str2));
+
+ Matcher<const string&> m3 = StrCaseEq(str1);
+ EXPECT_TRUE(m3.Matches(str2));
+
+ EXPECT_FALSE(m3.Matches(str2 + "x"));
+ str2.append(1, '\0');
+ EXPECT_FALSE(m3.Matches(str2));
+ EXPECT_FALSE(m3.Matches(string(str2, 0, 9)));
+}
+
+TEST(StrCaseEqTest, CanDescribeSelf) {
+ Matcher<string> m = StrCaseEq("Hi");
+ EXPECT_EQ("is equal to (ignoring case) \"Hi\"", Describe(m));
+}
+
+TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) {
+ Matcher<const char*> m = StrCaseNe("Hello");
+ EXPECT_TRUE(m.Matches("Hi"));
+ EXPECT_TRUE(m.Matches(NULL));
+ EXPECT_FALSE(m.Matches("Hello"));
+ EXPECT_FALSE(m.Matches("hello"));
+
+ Matcher<string> m2 = StrCaseNe(string("Hello"));
+ EXPECT_TRUE(m2.Matches(""));
+ EXPECT_FALSE(m2.Matches("Hello"));
+}
+
+TEST(StrCaseNeTest, CanDescribeSelf) {
+ Matcher<const char*> m = StrCaseNe("Hi");
+ EXPECT_EQ("is not equal to (ignoring case) \"Hi\"", Describe(m));
+}
+
+// Tests that HasSubstr() works for matching string-typed values.
+TEST(HasSubstrTest, WorksForStringClasses) {
+ const Matcher<string> m1 = HasSubstr("foo");
+ EXPECT_TRUE(m1.Matches(string("I love food.")));
+ EXPECT_FALSE(m1.Matches(string("tofo")));
+
+ const Matcher<const std::string&> m2 = HasSubstr("foo");
+ EXPECT_TRUE(m2.Matches(std::string("I love food.")));
+ EXPECT_FALSE(m2.Matches(std::string("tofo")));
+}
+
+// Tests that HasSubstr() works for matching C-string-typed values.
+TEST(HasSubstrTest, WorksForCStrings) {
+ const Matcher<char*> m1 = HasSubstr("foo");
+ EXPECT_TRUE(m1.Matches(const_cast<char*>("I love food.")));
+ EXPECT_FALSE(m1.Matches(const_cast<char*>("tofo")));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const char*> m2 = HasSubstr("foo");
+ EXPECT_TRUE(m2.Matches("I love food."));
+ EXPECT_FALSE(m2.Matches("tofo"));
+ EXPECT_FALSE(m2.Matches(NULL));
+}
+
+// Tests that HasSubstr(s) describes itself properly.
+TEST(HasSubstrTest, CanDescribeSelf) {
+ Matcher<string> m = HasSubstr("foo\n\"");
+ EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m));
+}
+
+// Tests StartsWith(s).
+
+TEST(StartsWithTest, MatchesStringWithGivenPrefix) {
+ const Matcher<const char*> m1 = StartsWith(string(""));
+ EXPECT_TRUE(m1.Matches("Hi"));
+ EXPECT_TRUE(m1.Matches(""));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const string&> m2 = StartsWith("Hi");
+ EXPECT_TRUE(m2.Matches("Hi"));
+ EXPECT_TRUE(m2.Matches("Hi Hi!"));
+ EXPECT_TRUE(m2.Matches("High"));
+ EXPECT_FALSE(m2.Matches("H"));
+ EXPECT_FALSE(m2.Matches(" Hi"));
+}
+
+TEST(StartsWithTest, CanDescribeSelf) {
+ Matcher<const std::string> m = StartsWith("Hi");
+ EXPECT_EQ("starts with \"Hi\"", Describe(m));
+}
+
+// Tests EndsWith(s).
+
+TEST(EndsWithTest, MatchesStringWithGivenSuffix) {
+ const Matcher<const char*> m1 = EndsWith("");
+ EXPECT_TRUE(m1.Matches("Hi"));
+ EXPECT_TRUE(m1.Matches(""));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const string&> m2 = EndsWith(string("Hi"));
+ EXPECT_TRUE(m2.Matches("Hi"));
+ EXPECT_TRUE(m2.Matches("Wow Hi Hi"));
+ EXPECT_TRUE(m2.Matches("Super Hi"));
+ EXPECT_FALSE(m2.Matches("i"));
+ EXPECT_FALSE(m2.Matches("Hi "));
+}
+
+TEST(EndsWithTest, CanDescribeSelf) {
+ Matcher<const std::string> m = EndsWith("Hi");
+ EXPECT_EQ("ends with \"Hi\"", Describe(m));
+}
+
+#ifdef GMOCK_HAS_REGEX
+
+// Tests MatchesRegex().
+
+TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
+ const Matcher<const char*> m1 = MatchesRegex("a.*z");
+ EXPECT_TRUE(m1.Matches("az"));
+ EXPECT_TRUE(m1.Matches("abcz"));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const string&> m2 = MatchesRegex(new RE("a.*z"));
+ EXPECT_TRUE(m2.Matches("azbz"));
+ EXPECT_FALSE(m2.Matches("az1"));
+ EXPECT_FALSE(m2.Matches("1az"));
+}
+
+TEST(MatchesRegexTest, CanDescribeSelf) {
+ Matcher<const std::string> m1 = MatchesRegex(string("Hi.*"));
+ EXPECT_EQ("matches regular expression \"Hi.*\"", Describe(m1));
+
+ Matcher<const char*> m2 = MatchesRegex(new RE("[a-z].*"));
+ EXPECT_EQ("matches regular expression \"[a-z].*\"", Describe(m2));
+}
+
+// Tests ContainsRegex().
+
+TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) {
+ const Matcher<const char*> m1 = ContainsRegex(string("a.*z"));
+ EXPECT_TRUE(m1.Matches("az"));
+ EXPECT_TRUE(m1.Matches("0abcz1"));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const string&> m2 = ContainsRegex(new RE("a.*z"));
+ EXPECT_TRUE(m2.Matches("azbz"));
+ EXPECT_TRUE(m2.Matches("az1"));
+ EXPECT_FALSE(m2.Matches("1a"));
+}
+
+TEST(ContainsRegexTest, CanDescribeSelf) {
+ Matcher<const std::string> m1 = ContainsRegex("Hi.*");
+ EXPECT_EQ("contains regular expression \"Hi.*\"", Describe(m1));
+
+ Matcher<const char*> m2 = ContainsRegex(new RE("[a-z].*"));
+ EXPECT_EQ("contains regular expression \"[a-z].*\"", Describe(m2));
+}
+#endif // GMOCK_HAS_REGEX
+
+// Tests for wide strings.
+#if GTEST_HAS_STD_WSTRING
+TEST(StdWideStrEqTest, MatchesEqual) {
+ Matcher<const wchar_t*> m = StrEq(::std::wstring(L"Hello"));
+ EXPECT_TRUE(m.Matches(L"Hello"));
+ EXPECT_FALSE(m.Matches(L"hello"));
+ EXPECT_FALSE(m.Matches(NULL));
+
+ Matcher<const ::std::wstring&> m2 = StrEq(L"Hello");
+ EXPECT_TRUE(m2.Matches(L"Hello"));
+ EXPECT_FALSE(m2.Matches(L"Hi"));
+
+ Matcher<const ::std::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D");
+ EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D"));
+ EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E"));
+
+ ::std::wstring str(L"01204500800");
+ str[3] = L'\0';
+ Matcher<const ::std::wstring&> m4 = StrEq(str);
+ EXPECT_TRUE(m4.Matches(str));
+ str[0] = str[6] = str[7] = str[9] = str[10] = L'\0';
+ Matcher<const ::std::wstring&> m5 = StrEq(str);
+ EXPECT_TRUE(m5.Matches(str));
+}
+
+TEST(StdWideStrEqTest, CanDescribeSelf) {
+ Matcher< ::std::wstring> m = StrEq(L"Hi-\'\"\?\\\a\b\f\n\r\t\v");
+ EXPECT_EQ("is equal to L\"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"",
+ Describe(m));
+
+ Matcher< ::std::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D");
+ EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"",
+ Describe(m2));
+
+ ::std::wstring str(L"01204500800");
+ str[3] = L'\0';
+ Matcher<const ::std::wstring&> m4 = StrEq(str);
+ EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4));
+ str[0] = str[6] = str[7] = str[9] = str[10] = L'\0';
+ Matcher<const ::std::wstring&> m5 = StrEq(str);
+ EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5));
+}
+
+TEST(StdWideStrNeTest, MatchesUnequalString) {
+ Matcher<const wchar_t*> m = StrNe(L"Hello");
+ EXPECT_TRUE(m.Matches(L""));
+ EXPECT_TRUE(m.Matches(NULL));
+ EXPECT_FALSE(m.Matches(L"Hello"));
+
+ Matcher< ::std::wstring> m2 = StrNe(::std::wstring(L"Hello"));
+ EXPECT_TRUE(m2.Matches(L"hello"));
+ EXPECT_FALSE(m2.Matches(L"Hello"));
+}
+
+TEST(StdWideStrNeTest, CanDescribeSelf) {
+ Matcher<const wchar_t*> m = StrNe(L"Hi");
+ EXPECT_EQ("is not equal to L\"Hi\"", Describe(m));
+}
+
+TEST(StdWideStrCaseEqTest, MatchesEqualStringIgnoringCase) {
+ Matcher<const wchar_t*> m = StrCaseEq(::std::wstring(L"Hello"));
+ EXPECT_TRUE(m.Matches(L"Hello"));
+ EXPECT_TRUE(m.Matches(L"hello"));
+ EXPECT_FALSE(m.Matches(L"Hi"));
+ EXPECT_FALSE(m.Matches(NULL));
+
+ Matcher<const ::std::wstring&> m2 = StrCaseEq(L"Hello");
+ EXPECT_TRUE(m2.Matches(L"hello"));
+ EXPECT_FALSE(m2.Matches(L"Hi"));
+}
+
+TEST(StdWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) {
+ ::std::wstring str1(L"oabocdooeoo");
+ ::std::wstring str2(L"OABOCDOOEOO");
+ Matcher<const ::std::wstring&> m0 = StrCaseEq(str1);
+ EXPECT_FALSE(m0.Matches(str2 + ::std::wstring(1, L'\0')));
+
+ str1[3] = str2[3] = L'\0';
+ Matcher<const ::std::wstring&> m1 = StrCaseEq(str1);
+ EXPECT_TRUE(m1.Matches(str2));
+
+ str1[0] = str1[6] = str1[7] = str1[10] = L'\0';
+ str2[0] = str2[6] = str2[7] = str2[10] = L'\0';
+ Matcher<const ::std::wstring&> m2 = StrCaseEq(str1);
+ str1[9] = str2[9] = L'\0';
+ EXPECT_FALSE(m2.Matches(str2));
+
+ Matcher<const ::std::wstring&> m3 = StrCaseEq(str1);
+ EXPECT_TRUE(m3.Matches(str2));
+
+ EXPECT_FALSE(m3.Matches(str2 + L"x"));
+ str2.append(1, L'\0');
+ EXPECT_FALSE(m3.Matches(str2));
+ EXPECT_FALSE(m3.Matches(::std::wstring(str2, 0, 9)));
+}
+
+TEST(StdWideStrCaseEqTest, CanDescribeSelf) {
+ Matcher< ::std::wstring> m = StrCaseEq(L"Hi");
+ EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m));
+}
+
+TEST(StdWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) {
+ Matcher<const wchar_t*> m = StrCaseNe(L"Hello");
+ EXPECT_TRUE(m.Matches(L"Hi"));
+ EXPECT_TRUE(m.Matches(NULL));
+ EXPECT_FALSE(m.Matches(L"Hello"));
+ EXPECT_FALSE(m.Matches(L"hello"));
+
+ Matcher< ::std::wstring> m2 = StrCaseNe(::std::wstring(L"Hello"));
+ EXPECT_TRUE(m2.Matches(L""));
+ EXPECT_FALSE(m2.Matches(L"Hello"));
+}
+
+TEST(StdWideStrCaseNeTest, CanDescribeSelf) {
+ Matcher<const wchar_t*> m = StrCaseNe(L"Hi");
+ EXPECT_EQ("is not equal to (ignoring case) L\"Hi\"", Describe(m));
+}
+
+// Tests that HasSubstr() works for matching wstring-typed values.
+TEST(StdWideHasSubstrTest, WorksForStringClasses) {
+ const Matcher< ::std::wstring> m1 = HasSubstr(L"foo");
+ EXPECT_TRUE(m1.Matches(::std::wstring(L"I love food.")));
+ EXPECT_FALSE(m1.Matches(::std::wstring(L"tofo")));
+
+ const Matcher<const ::std::wstring&> m2 = HasSubstr(L"foo");
+ EXPECT_TRUE(m2.Matches(::std::wstring(L"I love food.")));
+ EXPECT_FALSE(m2.Matches(::std::wstring(L"tofo")));
+}
+
+// Tests that HasSubstr() works for matching C-wide-string-typed values.
+TEST(StdWideHasSubstrTest, WorksForCStrings) {
+ const Matcher<wchar_t*> m1 = HasSubstr(L"foo");
+ EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food.")));
+ EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo")));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const wchar_t*> m2 = HasSubstr(L"foo");
+ EXPECT_TRUE(m2.Matches(L"I love food."));
+ EXPECT_FALSE(m2.Matches(L"tofo"));
+ EXPECT_FALSE(m2.Matches(NULL));
+}
+
+// Tests that HasSubstr(s) describes itself properly.
+TEST(StdWideHasSubstrTest, CanDescribeSelf) {
+ Matcher< ::std::wstring> m = HasSubstr(L"foo\n\"");
+ EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m));
+}
+
+// Tests StartsWith(s).
+
+TEST(StdWideStartsWithTest, MatchesStringWithGivenPrefix) {
+ const Matcher<const wchar_t*> m1 = StartsWith(::std::wstring(L""));
+ EXPECT_TRUE(m1.Matches(L"Hi"));
+ EXPECT_TRUE(m1.Matches(L""));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const ::std::wstring&> m2 = StartsWith(L"Hi");
+ EXPECT_TRUE(m2.Matches(L"Hi"));
+ EXPECT_TRUE(m2.Matches(L"Hi Hi!"));
+ EXPECT_TRUE(m2.Matches(L"High"));
+ EXPECT_FALSE(m2.Matches(L"H"));
+ EXPECT_FALSE(m2.Matches(L" Hi"));
+}
+
+TEST(StdWideStartsWithTest, CanDescribeSelf) {
+ Matcher<const ::std::wstring> m = StartsWith(L"Hi");
+ EXPECT_EQ("starts with L\"Hi\"", Describe(m));
+}
+
+// Tests EndsWith(s).
+
+TEST(StdWideEndsWithTest, MatchesStringWithGivenSuffix) {
+ const Matcher<const wchar_t*> m1 = EndsWith(L"");
+ EXPECT_TRUE(m1.Matches(L"Hi"));
+ EXPECT_TRUE(m1.Matches(L""));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const ::std::wstring&> m2 = EndsWith(::std::wstring(L"Hi"));
+ EXPECT_TRUE(m2.Matches(L"Hi"));
+ EXPECT_TRUE(m2.Matches(L"Wow Hi Hi"));
+ EXPECT_TRUE(m2.Matches(L"Super Hi"));
+ EXPECT_FALSE(m2.Matches(L"i"));
+ EXPECT_FALSE(m2.Matches(L"Hi "));
+}
+
+TEST(StdWideEndsWithTest, CanDescribeSelf) {
+ Matcher<const ::std::wstring> m = EndsWith(L"Hi");
+ EXPECT_EQ("ends with L\"Hi\"", Describe(m));
+}
+
+#endif // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+TEST(GlobalWideStrEqTest, MatchesEqual) {
+ Matcher<const wchar_t*> m = StrEq(::wstring(L"Hello"));
+ EXPECT_TRUE(m.Matches(L"Hello"));
+ EXPECT_FALSE(m.Matches(L"hello"));
+ EXPECT_FALSE(m.Matches(NULL));
+
+ Matcher<const ::wstring&> m2 = StrEq(L"Hello");
+ EXPECT_TRUE(m2.Matches(L"Hello"));
+ EXPECT_FALSE(m2.Matches(L"Hi"));
+
+ Matcher<const ::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D");
+ EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D"));
+ EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E"));
+
+ ::wstring str(L"01204500800");
+ str[3] = L'\0';
+ Matcher<const ::wstring&> m4 = StrEq(str);
+ EXPECT_TRUE(m4.Matches(str));
+ str[0] = str[6] = str[7] = str[9] = str[10] = L'\0';
+ Matcher<const ::wstring&> m5 = StrEq(str);
+ EXPECT_TRUE(m5.Matches(str));
+}
+
+TEST(GlobalWideStrEqTest, CanDescribeSelf) {
+ Matcher< ::wstring> m = StrEq(L"Hi-\'\"\?\\\a\b\f\n\r\t\v");
+ EXPECT_EQ("is equal to L\"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"",
+ Describe(m));
+
+ Matcher< ::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D");
+ EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"",
+ Describe(m2));
+
+ ::wstring str(L"01204500800");
+ str[3] = L'\0';
+ Matcher<const ::wstring&> m4 = StrEq(str);
+ EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4));
+ str[0] = str[6] = str[7] = str[9] = str[10] = L'\0';
+ Matcher<const ::wstring&> m5 = StrEq(str);
+ EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5));
+}
+
+TEST(GlobalWideStrNeTest, MatchesUnequalString) {
+ Matcher<const wchar_t*> m = StrNe(L"Hello");
+ EXPECT_TRUE(m.Matches(L""));
+ EXPECT_TRUE(m.Matches(NULL));
+ EXPECT_FALSE(m.Matches(L"Hello"));
+
+ Matcher< ::wstring> m2 = StrNe(::wstring(L"Hello"));
+ EXPECT_TRUE(m2.Matches(L"hello"));
+ EXPECT_FALSE(m2.Matches(L"Hello"));
+}
+
+TEST(GlobalWideStrNeTest, CanDescribeSelf) {
+ Matcher<const wchar_t*> m = StrNe(L"Hi");
+ EXPECT_EQ("is not equal to L\"Hi\"", Describe(m));
+}
+
+TEST(GlobalWideStrCaseEqTest, MatchesEqualStringIgnoringCase) {
+ Matcher<const wchar_t*> m = StrCaseEq(::wstring(L"Hello"));
+ EXPECT_TRUE(m.Matches(L"Hello"));
+ EXPECT_TRUE(m.Matches(L"hello"));
+ EXPECT_FALSE(m.Matches(L"Hi"));
+ EXPECT_FALSE(m.Matches(NULL));
+
+ Matcher<const ::wstring&> m2 = StrCaseEq(L"Hello");
+ EXPECT_TRUE(m2.Matches(L"hello"));
+ EXPECT_FALSE(m2.Matches(L"Hi"));
+}
+
+TEST(GlobalWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) {
+ ::wstring str1(L"oabocdooeoo");
+ ::wstring str2(L"OABOCDOOEOO");
+ Matcher<const ::wstring&> m0 = StrCaseEq(str1);
+ EXPECT_FALSE(m0.Matches(str2 + ::wstring(1, L'\0')));
+
+ str1[3] = str2[3] = L'\0';
+ Matcher<const ::wstring&> m1 = StrCaseEq(str1);
+ EXPECT_TRUE(m1.Matches(str2));
+
+ str1[0] = str1[6] = str1[7] = str1[10] = L'\0';
+ str2[0] = str2[6] = str2[7] = str2[10] = L'\0';
+ Matcher<const ::wstring&> m2 = StrCaseEq(str1);
+ str1[9] = str2[9] = L'\0';
+ EXPECT_FALSE(m2.Matches(str2));
+
+ Matcher<const ::wstring&> m3 = StrCaseEq(str1);
+ EXPECT_TRUE(m3.Matches(str2));
+
+ EXPECT_FALSE(m3.Matches(str2 + L"x"));
+ str2.append(1, L'\0');
+ EXPECT_FALSE(m3.Matches(str2));
+ EXPECT_FALSE(m3.Matches(::wstring(str2, 0, 9)));
+}
+
+TEST(GlobalWideStrCaseEqTest, CanDescribeSelf) {
+ Matcher< ::wstring> m = StrCaseEq(L"Hi");
+ EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m));
+}
+
+TEST(GlobalWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) {
+ Matcher<const wchar_t*> m = StrCaseNe(L"Hello");
+ EXPECT_TRUE(m.Matches(L"Hi"));
+ EXPECT_TRUE(m.Matches(NULL));
+ EXPECT_FALSE(m.Matches(L"Hello"));
+ EXPECT_FALSE(m.Matches(L"hello"));
+
+ Matcher< ::wstring> m2 = StrCaseNe(::wstring(L"Hello"));
+ EXPECT_TRUE(m2.Matches(L""));
+ EXPECT_FALSE(m2.Matches(L"Hello"));
+}
+
+TEST(GlobalWideStrCaseNeTest, CanDescribeSelf) {
+ Matcher<const wchar_t*> m = StrCaseNe(L"Hi");
+ EXPECT_EQ("is not equal to (ignoring case) L\"Hi\"", Describe(m));
+}
+
+// Tests that HasSubstr() works for matching wstring-typed values.
+TEST(GlobalWideHasSubstrTest, WorksForStringClasses) {
+ const Matcher< ::wstring> m1 = HasSubstr(L"foo");
+ EXPECT_TRUE(m1.Matches(::wstring(L"I love food.")));
+ EXPECT_FALSE(m1.Matches(::wstring(L"tofo")));
+
+ const Matcher<const ::wstring&> m2 = HasSubstr(L"foo");
+ EXPECT_TRUE(m2.Matches(::wstring(L"I love food.")));
+ EXPECT_FALSE(m2.Matches(::wstring(L"tofo")));
+}
+
+// Tests that HasSubstr() works for matching C-wide-string-typed values.
+TEST(GlobalWideHasSubstrTest, WorksForCStrings) {
+ const Matcher<wchar_t*> m1 = HasSubstr(L"foo");
+ EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food.")));
+ EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo")));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const wchar_t*> m2 = HasSubstr(L"foo");
+ EXPECT_TRUE(m2.Matches(L"I love food."));
+ EXPECT_FALSE(m2.Matches(L"tofo"));
+ EXPECT_FALSE(m2.Matches(NULL));
+}
+
+// Tests that HasSubstr(s) describes itself properly.
+TEST(GlobalWideHasSubstrTest, CanDescribeSelf) {
+ Matcher< ::wstring> m = HasSubstr(L"foo\n\"");
+ EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m));
+}
+
+// Tests StartsWith(s).
+
+TEST(GlobalWideStartsWithTest, MatchesStringWithGivenPrefix) {
+ const Matcher<const wchar_t*> m1 = StartsWith(::wstring(L""));
+ EXPECT_TRUE(m1.Matches(L"Hi"));
+ EXPECT_TRUE(m1.Matches(L""));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const ::wstring&> m2 = StartsWith(L"Hi");
+ EXPECT_TRUE(m2.Matches(L"Hi"));
+ EXPECT_TRUE(m2.Matches(L"Hi Hi!"));
+ EXPECT_TRUE(m2.Matches(L"High"));
+ EXPECT_FALSE(m2.Matches(L"H"));
+ EXPECT_FALSE(m2.Matches(L" Hi"));
+}
+
+TEST(GlobalWideStartsWithTest, CanDescribeSelf) {
+ Matcher<const ::wstring> m = StartsWith(L"Hi");
+ EXPECT_EQ("starts with L\"Hi\"", Describe(m));
+}
+
+// Tests EndsWith(s).
+
+TEST(GlobalWideEndsWithTest, MatchesStringWithGivenSuffix) {
+ const Matcher<const wchar_t*> m1 = EndsWith(L"");
+ EXPECT_TRUE(m1.Matches(L"Hi"));
+ EXPECT_TRUE(m1.Matches(L""));
+ EXPECT_FALSE(m1.Matches(NULL));
+
+ const Matcher<const ::wstring&> m2 = EndsWith(::wstring(L"Hi"));
+ EXPECT_TRUE(m2.Matches(L"Hi"));
+ EXPECT_TRUE(m2.Matches(L"Wow Hi Hi"));
+ EXPECT_TRUE(m2.Matches(L"Super Hi"));
+ EXPECT_FALSE(m2.Matches(L"i"));
+ EXPECT_FALSE(m2.Matches(L"Hi "));
+}
+
+TEST(GlobalWideEndsWithTest, CanDescribeSelf) {
+ Matcher<const ::wstring> m = EndsWith(L"Hi");
+ EXPECT_EQ("ends with L\"Hi\"", Describe(m));
+}
+
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+
+typedef ::std::tr1::tuple<long, int> Tuple2; // NOLINT
+
+// Tests that Eq() matches a 2-tuple where the first field == the
+// second field.
+TEST(Eq2Test, MatchesEqualArguments) {
+ Matcher<const Tuple2&> m = Eq();
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 5)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 6)));
+}
+
+// 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));
+}
+
+// Tests that Ge() matches a 2-tuple where the first field >= the
+// second field.
+TEST(Ge2Test, MatchesGreaterThanOrEqualArguments) {
+ Matcher<const Tuple2&> m = Ge();
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 4)));
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 5)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 6)));
+}
+
+// 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));
+}
+
+// Tests that Gt() matches a 2-tuple where the first field > the
+// second field.
+TEST(Gt2Test, MatchesGreaterThanArguments) {
+ Matcher<const Tuple2&> m = Gt();
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 4)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 5)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 6)));
+}
+
+// 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));
+}
+
+// Tests that Le() matches a 2-tuple where the first field <= the
+// second field.
+TEST(Le2Test, MatchesLessThanOrEqualArguments) {
+ Matcher<const Tuple2&> m = Le();
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 6)));
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 5)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 4)));
+}
+
+// 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));
+}
+
+// Tests that Lt() matches a 2-tuple where the first field < the
+// second field.
+TEST(Lt2Test, MatchesLessThanArguments) {
+ Matcher<const Tuple2&> m = Lt();
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 6)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 5)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 4)));
+}
+
+// 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));
+}
+
+// Tests that Ne() matches a 2-tuple where the first field != the
+// second field.
+TEST(Ne2Test, MatchesUnequalArguments) {
+ Matcher<const Tuple2&> m = Ne();
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 6)));
+ EXPECT_TRUE(m.Matches(Tuple2(5L, 4)));
+ EXPECT_FALSE(m.Matches(Tuple2(5L, 5)));
+}
+
+// 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));
+}
+
+// Tests that Not(m) matches any value that doesn't match m.
+TEST(NotTest, NegatesMatcher) {
+ Matcher<int> m;
+ m = Not(Eq(2));
+ EXPECT_TRUE(m.Matches(3));
+ EXPECT_FALSE(m.Matches(2));
+}
+
+// Tests that Not(m) describes itself properly.
+TEST(NotTest, CanDescribeSelf) {
+ Matcher<int> m = Not(Eq(5));
+ EXPECT_EQ("is not equal to 5", Describe(m));
+}
+
+// Tests that AllOf(m1, ..., mn) matches any value that matches all of
+// the given matchers.
+TEST(AllOfTest, MatchesWhenAllMatch) {
+ Matcher<int> m;
+ m = AllOf(Le(2), Ge(1));
+ EXPECT_TRUE(m.Matches(1));
+ EXPECT_TRUE(m.Matches(2));
+ EXPECT_FALSE(m.Matches(0));
+ EXPECT_FALSE(m.Matches(3));
+
+ m = AllOf(Gt(0), Ne(1), Ne(2));
+ EXPECT_TRUE(m.Matches(3));
+ EXPECT_FALSE(m.Matches(2));
+ EXPECT_FALSE(m.Matches(1));
+ EXPECT_FALSE(m.Matches(0));
+
+ m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
+ EXPECT_TRUE(m.Matches(4));
+ EXPECT_FALSE(m.Matches(3));
+ EXPECT_FALSE(m.Matches(2));
+ EXPECT_FALSE(m.Matches(1));
+ EXPECT_FALSE(m.Matches(0));
+
+ m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
+ EXPECT_TRUE(m.Matches(0));
+ EXPECT_TRUE(m.Matches(1));
+ EXPECT_FALSE(m.Matches(3));
+}
+
+// Tests that AllOf(m1, ..., mn) describes itself properly.
+TEST(AllOfTest, CanDescribeSelf) {
+ Matcher<int> m;
+ m = AllOf(Le(2), Ge(1));
+ EXPECT_EQ("(is less than or equal to 2) and "
+ "(is greater than or equal to 1)",
+ Describe(m));
+
+ m = AllOf(Gt(0), Ne(1), Ne(2));
+ EXPECT_EQ("(is greater than 0) and "
+ "((is not equal to 1) and "
+ "(is not equal to 2))",
+ Describe(m));
+
+
+ m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
+ EXPECT_EQ("(is greater than 0) and "
+ "((is not equal to 1) and "
+ "((is not equal to 2) and "
+ "(is not equal to 3)))",
+ Describe(m));
+
+
+ m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
+ EXPECT_EQ("(is greater than or equal to 0) and "
+ "((is less than 10) and "
+ "((is not equal to 3) and "
+ "((is not equal to 5) and "
+ "(is not equal to 7))))", Describe(m));
+}
+
+// Tests that AnyOf(m1, ..., mn) matches any value that matches at
+// least one of the given matchers.
+TEST(AnyOfTest, MatchesWhenAnyMatches) {
+ Matcher<int> m;
+ m = AnyOf(Le(1), Ge(3));
+ EXPECT_TRUE(m.Matches(1));
+ EXPECT_TRUE(m.Matches(4));
+ EXPECT_FALSE(m.Matches(2));
+
+ m = AnyOf(Lt(0), Eq(1), Eq(2));
+ EXPECT_TRUE(m.Matches(-1));
+ EXPECT_TRUE(m.Matches(1));
+ EXPECT_TRUE(m.Matches(2));
+ EXPECT_FALSE(m.Matches(0));
+
+ m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
+ EXPECT_TRUE(m.Matches(-1));
+ EXPECT_TRUE(m.Matches(1));
+ EXPECT_TRUE(m.Matches(2));
+ EXPECT_TRUE(m.Matches(3));
+ EXPECT_FALSE(m.Matches(0));
+
+ m = AnyOf(Le(0), Gt(10), 3, 5, 7);
+ EXPECT_TRUE(m.Matches(0));
+ EXPECT_TRUE(m.Matches(11));
+ EXPECT_TRUE(m.Matches(3));
+ EXPECT_FALSE(m.Matches(2));
+}
+
+// Tests that AnyOf(m1, ..., mn) describes itself properly.
+TEST(AnyOfTest, CanDescribeSelf) {
+ Matcher<int> m;
+ m = AnyOf(Le(1), Ge(3));
+ EXPECT_EQ("(is less than or equal to 1) or "
+ "(is greater than or equal to 3)",
+ Describe(m));
+
+ m = AnyOf(Lt(0), Eq(1), Eq(2));
+ EXPECT_EQ("(is less than 0) or "
+ "((is equal to 1) or (is equal to 2))",
+ Describe(m));
+
+ m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
+ EXPECT_EQ("(is less than 0) or "
+ "((is equal to 1) or "
+ "((is equal to 2) or "
+ "(is equal to 3)))",
+ Describe(m));
+
+ m = AnyOf(Le(0), Gt(10), 3, 5, 7);
+ EXPECT_EQ("(is less than or equal to 0) or "
+ "((is greater than 10) or "
+ "((is equal to 3) or "
+ "((is equal to 5) or "
+ "(is equal to 7))))",
+ Describe(m));
+}
+
+// The following predicate function and predicate functor are for
+// testing the Truly(predicate) matcher.
+
+// Returns non-zero if the input is positive. Note that the return
+// type of this function is not bool. It's OK as Truly() accepts any
+// unary function or functor whose return type can be implicitly
+// converted to bool.
+int IsPositive(double x) {
+ return x > 0 ? 1 : 0;
+}
+
+// This functor returns true if the input is greater than the given
+// number.
+class IsGreaterThan {
+ public:
+ explicit IsGreaterThan(int threshold) : threshold_(threshold) {}
+
+ bool operator()(int n) const { return n > threshold_; }
+ private:
+ const int threshold_;
+};
+
+// For testing Truly().
+const int foo = 0;
+
+// This predicate returns true iff the argument references foo and has
+// a zero value.
+bool ReferencesFooAndIsZero(const int& n) {
+ return (&n == &foo) && (n == 0);
+}
+
+// Tests that Truly(predicate) matches what satisfies the given
+// predicate.
+TEST(TrulyTest, MatchesWhatSatisfiesThePredicate) {
+ Matcher<double> m = Truly(IsPositive);
+ EXPECT_TRUE(m.Matches(2.0));
+ EXPECT_FALSE(m.Matches(-1.5));
+}
+
+// Tests that Truly(predicate_functor) works too.
+TEST(TrulyTest, CanBeUsedWithFunctor) {
+ Matcher<int> m = Truly(IsGreaterThan(5));
+ EXPECT_TRUE(m.Matches(6));
+ EXPECT_FALSE(m.Matches(4));
+}
+
+// Tests that Truly(predicate) can describe itself properly.
+TEST(TrulyTest, CanDescribeSelf) {
+ Matcher<double> m = Truly(IsPositive);
+ EXPECT_EQ("satisfies the given predicate",
+ Describe(m));
+}
+
+// Tests that Truly(predicate) works when the matcher takes its
+// argument by reference.
+TEST(TrulyTest, WorksForByRefArguments) {
+ Matcher<const int&> m = Truly(ReferencesFooAndIsZero);
+ EXPECT_TRUE(m.Matches(foo));
+ int n = 0;
+ EXPECT_FALSE(m.Matches(n));
+}
+
+// Tests that Matches(m) is a predicate satisfied by whatever that
+// matches matcher m.
+TEST(MatchesTest, IsSatisfiedByWhatMatchesTheMatcher) {
+ EXPECT_TRUE(Matches(Ge(0))(1));
+ EXPECT_FALSE(Matches(Eq('a'))('b'));
+}
+
+// Tests that Matches(m) works when the matcher takes its argument by
+// reference.
+TEST(MatchesTest, WorksOnByRefArguments) {
+ int m = 0, n = 0;
+ EXPECT_TRUE(Matches(AllOf(Ref(n), Eq(0)))(n));
+ EXPECT_FALSE(Matches(Ref(m))(n));
+}
+
+// Tests that a Matcher on non-reference type can be used in
+// Matches().
+TEST(MatchesTest, WorksWithMatcherOnNonRefType) {
+ Matcher<int> eq5 = Eq(5);
+ EXPECT_TRUE(Matches(eq5)(5));
+ EXPECT_FALSE(Matches(eq5)(2));
+}
+
+// Tests that ASSERT_THAT() and EXPECT_THAT() work when the value
+// matches the matcher.
+TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) {
+ ASSERT_THAT(5, Ge(2)) << "This should succeed.";
+ ASSERT_THAT("Foo", EndsWith("oo"));
+ EXPECT_THAT(2, AllOf(Le(7), Ge(0))) << "This should succeed too.";
+ EXPECT_THAT("Hello", StartsWith("Hell"));
+}
+
+// Tests that ASSERT_THAT() and EXPECT_THAT() work when the value
+// doesn't match the matcher.
+TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) {
+ // 'n' must be static as it is used in an EXPECT_FATAL_FAILURE(),
+ // which cannot reference auto variables.
+ static int n;
+ n = 5;
+ EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Gt(10)) << "This should fail.",
+ "Value of: n\n"
+ "Expected: is greater than 10\n"
+ " Actual: 5\n"
+ "This should fail.");
+ n = 0;
+ EXPECT_NONFATAL_FAILURE(EXPECT_THAT(n, AllOf(Le(7), Ge(5))),
+ "Value of: n\n"
+ "Expected: (is less than or equal to 7) and "
+ "(is greater than or equal to 5)\n"
+ " Actual: 0");
+}
+
+// Tests that ASSERT_THAT() and EXPECT_THAT() work when the argument
+// has a reference type.
+TEST(MatcherAssertionTest, WorksForByRefArguments) {
+ // We use a static variable here as EXPECT_FATAL_FAILURE() cannot
+ // reference auto variables.
+ static int n;
+ n = 0;
+ EXPECT_THAT(n, AllOf(Le(7), Ref(n)));
+ EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))),
+ "Value of: n\n"
+ "Expected: does not reference the variable @");
+ // Tests the "Actual" part.
+ EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))),
+ "Actual: 0 (is located @");
+}
+
+// Tests that ASSERT_THAT() and EXPECT_THAT() work when the matcher is
+// monomorphic.
+TEST(MatcherAssertionTest, WorksForMonomorphicMatcher) {
+ Matcher<const char*> starts_with_he = StartsWith("he");
+ ASSERT_THAT("hello", starts_with_he);
+
+ Matcher<const string&> ends_with_ok = EndsWith("ok");
+ ASSERT_THAT("book", ends_with_ok);
+
+ Matcher<int> is_greater_than_5 = Gt(5);
+ EXPECT_NONFATAL_FAILURE(EXPECT_THAT(5, is_greater_than_5),
+ "Value of: 5\n"
+ "Expected: is greater than 5\n"
+ " Actual: 5");
+}
+
+// Tests floating-point matchers.
+template <typename RawType>
+class FloatingPointTest : public testing::Test {
+ protected:
+ typedef typename testing::internal::FloatingPoint<RawType> Floating;
+ typedef typename Floating::Bits Bits;
+
+ virtual void SetUp() {
+ const size_t max_ulps = Floating::kMaxUlps;
+
+ // The bits that represent 0.0.
+ const Bits zero_bits = Floating(0).bits();
+
+ // Makes some numbers close to 0.0.
+ close_to_positive_zero_ = Floating::ReinterpretBits(zero_bits + max_ulps/2);
+ close_to_negative_zero_ = -Floating::ReinterpretBits(
+ zero_bits + max_ulps - max_ulps/2);
+ further_from_negative_zero_ = -Floating::ReinterpretBits(
+ zero_bits + max_ulps + 1 - max_ulps/2);
+
+ // The bits that represent 1.0.
+ const Bits one_bits = Floating(1).bits();
+
+ // Makes some numbers close to 1.0.
+ close_to_one_ = Floating::ReinterpretBits(one_bits + max_ulps);
+ further_from_one_ = Floating::ReinterpretBits(one_bits + max_ulps + 1);
+
+ // +infinity.
+ infinity_ = Floating::Infinity();
+
+ // The bits that represent +infinity.
+ const Bits infinity_bits = Floating(infinity_).bits();
+
+ // Makes some numbers close to infinity.
+ close_to_infinity_ = Floating::ReinterpretBits(infinity_bits - max_ulps);
+ further_from_infinity_ = Floating::ReinterpretBits(
+ infinity_bits - max_ulps - 1);
+
+ // Makes some NAN's.
+ nan1_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 1);
+ nan2_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 200);
+ }
+
+ void TestSize() {
+ EXPECT_EQ(sizeof(RawType), sizeof(Bits));
+ }
+
+ // A battery of tests for FloatingEqMatcher::Matches.
+ // matcher_maker is a pointer to a function which creates a FloatingEqMatcher.
+ void TestMatches(
+ testing::internal::FloatingEqMatcher<RawType> (*matcher_maker)(RawType)) {
+ Matcher<RawType> m1 = matcher_maker(0.0);
+ EXPECT_TRUE(m1.Matches(-0.0));
+ EXPECT_TRUE(m1.Matches(close_to_positive_zero_));
+ EXPECT_TRUE(m1.Matches(close_to_negative_zero_));
+ EXPECT_FALSE(m1.Matches(1.0));
+
+ Matcher<RawType> m2 = matcher_maker(close_to_positive_zero_);
+ EXPECT_FALSE(m2.Matches(further_from_negative_zero_));
+
+ Matcher<RawType> m3 = matcher_maker(1.0);
+ EXPECT_TRUE(m3.Matches(close_to_one_));
+ EXPECT_FALSE(m3.Matches(further_from_one_));
+
+ // Test commutativity: matcher_maker(0.0).Matches(1.0) was tested above.
+ EXPECT_FALSE(m3.Matches(0.0));
+
+ Matcher<RawType> m4 = matcher_maker(-infinity_);
+ EXPECT_TRUE(m4.Matches(-close_to_infinity_));
+
+ Matcher<RawType> m5 = matcher_maker(infinity_);
+ EXPECT_TRUE(m5.Matches(close_to_infinity_));
+
+ // This is interesting as the representations of infinity_ and nan1_
+ // are only 1 DLP apart.
+ EXPECT_FALSE(m5.Matches(nan1_));
+
+ // matcher_maker can produce a Matcher<const RawType&>, which is needed in
+ // some cases.
+ Matcher<const RawType&> m6 = matcher_maker(0.0);
+ EXPECT_TRUE(m6.Matches(-0.0));
+ EXPECT_TRUE(m6.Matches(close_to_positive_zero_));
+ EXPECT_FALSE(m6.Matches(1.0));
+
+ // matcher_maker can produce a Matcher<RawType&>, which is needed in some
+ // cases.
+ Matcher<RawType&> m7 = matcher_maker(0.0);
+ RawType x = 0.0;
+ EXPECT_TRUE(m7.Matches(x));
+ x = 0.01f;
+ EXPECT_FALSE(m7.Matches(x));
+ }
+
+ // Pre-calculated numbers to be used by the tests.
+
+ static RawType close_to_positive_zero_;
+ static RawType close_to_negative_zero_;
+ static RawType further_from_negative_zero_;
+
+ static RawType close_to_one_;
+ static RawType further_from_one_;
+
+ static RawType infinity_;
+ static RawType close_to_infinity_;
+ static RawType further_from_infinity_;
+
+ static RawType nan1_;
+ static RawType nan2_;
+};
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::close_to_positive_zero_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::close_to_negative_zero_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::further_from_negative_zero_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::close_to_one_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::further_from_one_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::infinity_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::close_to_infinity_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::further_from_infinity_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::nan1_;
+
+template <typename RawType>
+RawType FloatingPointTest<RawType>::nan2_;
+
+// Instantiate FloatingPointTest for testing floats.
+typedef FloatingPointTest<float> FloatTest;
+
+TEST_F(FloatTest, FloatEqApproximatelyMatchesFloats) {
+ TestMatches(&FloatEq);
+}
+
+TEST_F(FloatTest, NanSensitiveFloatEqApproximatelyMatchesFloats) {
+ TestMatches(&NanSensitiveFloatEq);
+}
+
+TEST_F(FloatTest, FloatEqCannotMatchNaN) {
+ // FloatEq never matches NaN.
+ Matcher<float> m = FloatEq(nan1_);
+ EXPECT_FALSE(m.Matches(nan1_));
+ EXPECT_FALSE(m.Matches(nan2_));
+ EXPECT_FALSE(m.Matches(1.0));
+}
+
+TEST_F(FloatTest, NanSensitiveFloatEqCanMatchNaN) {
+ // NanSensitiveFloatEq will match NaN.
+ Matcher<float> m = NanSensitiveFloatEq(nan1_);
+ EXPECT_TRUE(m.Matches(nan1_));
+ EXPECT_TRUE(m.Matches(nan2_));
+ EXPECT_FALSE(m.Matches(1.0));
+}
+
+TEST_F(FloatTest, FloatEqCanDescribeSelf) {
+ Matcher<float> m1 = FloatEq(2.0f);
+ EXPECT_EQ("is approximately 2", Describe(m1));
+ EXPECT_EQ("is not approximately 2", DescribeNegation(m1));
+
+ Matcher<float> m2 = FloatEq(0.5f);
+ EXPECT_EQ("is approximately 0.5", Describe(m2));
+ EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2));
+
+ Matcher<float> m3 = FloatEq(nan1_);
+ EXPECT_EQ("never matches", Describe(m3));
+ EXPECT_EQ("is anything", DescribeNegation(m3));
+}
+
+TEST_F(FloatTest, NanSensitiveFloatEqCanDescribeSelf) {
+ Matcher<float> m1 = NanSensitiveFloatEq(2.0f);
+ EXPECT_EQ("is approximately 2", Describe(m1));
+ EXPECT_EQ("is not approximately 2", DescribeNegation(m1));
+
+ Matcher<float> m2 = NanSensitiveFloatEq(0.5f);
+ EXPECT_EQ("is approximately 0.5", Describe(m2));
+ EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2));
+
+ Matcher<float> m3 = NanSensitiveFloatEq(nan1_);
+ EXPECT_EQ("is NaN", Describe(m3));
+ EXPECT_EQ("is not NaN", DescribeNegation(m3));
+}
+
+// Instantiate FloatingPointTest for testing doubles.
+typedef FloatingPointTest<double> DoubleTest;
+
+TEST_F(DoubleTest, DoubleEqApproximatelyMatchesDoubles) {
+ TestMatches(&DoubleEq);
+}
+
+TEST_F(DoubleTest, NanSensitiveDoubleEqApproximatelyMatchesDoubles) {
+ TestMatches(&NanSensitiveDoubleEq);
+}
+
+TEST_F(DoubleTest, DoubleEqCannotMatchNaN) {
+ // DoubleEq never matches NaN.
+ Matcher<double> m = DoubleEq(nan1_);
+ EXPECT_FALSE(m.Matches(nan1_));
+ EXPECT_FALSE(m.Matches(nan2_));
+ EXPECT_FALSE(m.Matches(1.0));
+}
+
+TEST_F(DoubleTest, NanSensitiveDoubleEqCanMatchNaN) {
+ // NanSensitiveDoubleEq will match NaN.
+ Matcher<double> m = NanSensitiveDoubleEq(nan1_);
+ EXPECT_TRUE(m.Matches(nan1_));
+ EXPECT_TRUE(m.Matches(nan2_));
+ EXPECT_FALSE(m.Matches(1.0));
+}
+
+TEST_F(DoubleTest, DoubleEqCanDescribeSelf) {
+ Matcher<double> m1 = DoubleEq(2.0);
+ EXPECT_EQ("is approximately 2", Describe(m1));
+ EXPECT_EQ("is not approximately 2", DescribeNegation(m1));
+
+ Matcher<double> m2 = DoubleEq(0.5);
+ EXPECT_EQ("is approximately 0.5", Describe(m2));
+ EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2));
+
+ Matcher<double> m3 = DoubleEq(nan1_);
+ EXPECT_EQ("never matches", Describe(m3));
+ EXPECT_EQ("is anything", DescribeNegation(m3));
+}
+
+TEST_F(DoubleTest, NanSensitiveDoubleEqCanDescribeSelf) {
+ Matcher<double> m1 = NanSensitiveDoubleEq(2.0);
+ EXPECT_EQ("is approximately 2", Describe(m1));
+ EXPECT_EQ("is not approximately 2", DescribeNegation(m1));
+
+ Matcher<double> m2 = NanSensitiveDoubleEq(0.5);
+ EXPECT_EQ("is approximately 0.5", Describe(m2));
+ EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2));
+
+ Matcher<double> m3 = NanSensitiveDoubleEq(nan1_);
+ EXPECT_EQ("is NaN", Describe(m3));
+ EXPECT_EQ("is not NaN", DescribeNegation(m3));
+}
+
+TEST(PointeeTest, RawPointer) {
+ const Matcher<int*> m = Pointee(Ge(0));
+
+ int n = 1;
+ EXPECT_TRUE(m.Matches(&n));
+ n = -1;
+ EXPECT_FALSE(m.Matches(&n));
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+TEST(PointeeTest, RawPointerToConst) {
+ const Matcher<const double*> m = Pointee(Ge(0));
+
+ double x = 1;
+ EXPECT_TRUE(m.Matches(&x));
+ x = -1;
+ EXPECT_FALSE(m.Matches(&x));
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+TEST(PointeeTest, ReferenceToConstRawPointer) {
+ const Matcher<int* const &> m = Pointee(Ge(0));
+
+ int n = 1;
+ EXPECT_TRUE(m.Matches(&n));
+ n = -1;
+ EXPECT_FALSE(m.Matches(&n));
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+TEST(PointeeTest, ReferenceToNonConstRawPointer) {
+ const Matcher<double* &> m = Pointee(Ge(0));
+
+ double x = 1.0;
+ double* p = &x;
+ EXPECT_TRUE(m.Matches(p));
+ x = -1;
+ EXPECT_FALSE(m.Matches(p));
+ p = NULL;
+ EXPECT_FALSE(m.Matches(p));
+}
+
+TEST(PointeeTest, NeverMatchesNull) {
+ const Matcher<const char*> m = Pointee(_);
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+// Tests that we can write Pointee(value) instead of Pointee(Eq(value)).
+TEST(PointeeTest, MatchesAgainstAValue) {
+ const Matcher<int*> m = Pointee(5);
+
+ int n = 5;
+ EXPECT_TRUE(m.Matches(&n));
+ n = -1;
+ EXPECT_FALSE(m.Matches(&n));
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+TEST(PointeeTest, CanDescribeSelf) {
+ const Matcher<int*> m = Pointee(Gt(3));
+ EXPECT_EQ("points to a value that is greater than 3", Describe(m));
+ EXPECT_EQ("does not point to a value that is greater than 3",
+ DescribeNegation(m));
+}
+
+// For testing ExplainMatchResultTo().
+class GreaterThanMatcher : public MatcherInterface<int> {
+ public:
+ explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
+
+ virtual bool Matches(int lhs) const { return lhs > rhs_; }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "is greater than " << rhs_;
+ }
+
+ virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const {
+ const int diff = lhs - rhs_;
+ if (diff > 0) {
+ *os << "is " << diff << " more than " << rhs_;
+ } else if (diff == 0) {
+ *os << "is the same as " << rhs_;
+ } else {
+ *os << "is " << -diff << " less than " << rhs_;
+ }
+ }
+ private:
+ const int rhs_;
+};
+
+Matcher<int> GreaterThan(int n) {
+ return MakeMatcher(new GreaterThanMatcher(n));
+}
+
+TEST(PointeeTest, CanExplainMatchResult) {
+ const Matcher<const string*> m = Pointee(StartsWith("Hi"));
+
+ EXPECT_EQ("", Explain(m, static_cast<const string*>(NULL)));
+
+ const Matcher<int*> m2 = Pointee(GreaterThan(1));
+ int n = 3;
+ EXPECT_EQ("points to a value that is 2 more than 1", Explain(m2, &n));
+}
+
+// An uncopyable class.
+class Uncopyable {
+ public:
+ explicit Uncopyable(int value) : value_(value) {}
+
+ int value() const { return value_; }
+ private:
+ const int value_;
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Uncopyable);
+};
+
+// Returns true iff x.value() is positive.
+bool ValueIsPositive(const Uncopyable& x) { return x.value() > 0; }
+
+// A user-defined struct for testing Field().
+struct AStruct {
+ AStruct() : x(0), y(1.0), z(5), p(NULL) {}
+ AStruct(const AStruct& rhs)
+ : x(rhs.x), y(rhs.y), z(rhs.z.value()), p(rhs.p) {}
+
+ int x; // A non-const field.
+ const double y; // A const field.
+ Uncopyable z; // An uncopyable field.
+ const char* p; // A pointer field.
+};
+
+// A derived struct for testing Field().
+struct DerivedStruct : public AStruct {
+ char ch;
+};
+
+// Tests that Field(&Foo::field, ...) works when field is non-const.
+TEST(FieldTest, WorksForNonConstField) {
+ Matcher<AStruct> m = Field(&AStruct::x, Ge(0));
+
+ AStruct a;
+ EXPECT_TRUE(m.Matches(a));
+ a.x = -1;
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Field(&Foo::field, ...) works when field is const.
+TEST(FieldTest, WorksForConstField) {
+ AStruct a;
+
+ Matcher<AStruct> m = Field(&AStruct::y, Ge(0.0));
+ EXPECT_TRUE(m.Matches(a));
+ m = Field(&AStruct::y, Le(0.0));
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Field(&Foo::field, ...) works when field is not copyable.
+TEST(FieldTest, WorksForUncopyableField) {
+ AStruct a;
+
+ Matcher<AStruct> m = Field(&AStruct::z, Truly(ValueIsPositive));
+ EXPECT_TRUE(m.Matches(a));
+ m = Field(&AStruct::z, Not(Truly(ValueIsPositive)));
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Field(&Foo::field, ...) works when field is a pointer.
+TEST(FieldTest, WorksForPointerField) {
+ // Matching against NULL.
+ Matcher<AStruct> m = Field(&AStruct::p, static_cast<const char*>(NULL));
+ AStruct a;
+ EXPECT_TRUE(m.Matches(a));
+ a.p = "hi";
+ EXPECT_FALSE(m.Matches(a));
+
+ // Matching a pointer that is not NULL.
+ m = Field(&AStruct::p, StartsWith("hi"));
+ a.p = "hill";
+ EXPECT_TRUE(m.Matches(a));
+ a.p = "hole";
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Field() works when the object is passed by reference.
+TEST(FieldTest, WorksForByRefArgument) {
+ Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0));
+
+ AStruct a;
+ EXPECT_TRUE(m.Matches(a));
+ a.x = -1;
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Field(&Foo::field, ...) works when the argument's type
+// is a sub-type of Foo.
+TEST(FieldTest, WorksForArgumentOfSubType) {
+ // Note that the matcher expects DerivedStruct but we say AStruct
+ // inside Field().
+ Matcher<const DerivedStruct&> m = Field(&AStruct::x, Ge(0));
+
+ DerivedStruct d;
+ EXPECT_TRUE(m.Matches(d));
+ d.x = -1;
+ EXPECT_FALSE(m.Matches(d));
+}
+
+// Tests that Field(&Foo::field, m) works when field's type and m's
+// argument type are compatible but not the same.
+TEST(FieldTest, WorksForCompatibleMatcherType) {
+ // The field is an int, but the inner matcher expects a signed char.
+ Matcher<const AStruct&> m = Field(&AStruct::x,
+ Matcher<signed char>(Ge(0)));
+
+ AStruct a;
+ EXPECT_TRUE(m.Matches(a));
+ a.x = -1;
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Field() can describe itself.
+TEST(FieldTest, CanDescribeSelf) {
+ Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0));
+
+ EXPECT_EQ("the given field is greater than or equal to 0", Describe(m));
+ EXPECT_EQ("the given field is not greater than or equal to 0",
+ DescribeNegation(m));
+}
+
+// Tests that Field() can explain the match result.
+TEST(FieldTest, CanExplainMatchResult) {
+ Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0));
+
+ AStruct a;
+ a.x = 1;
+ EXPECT_EQ("", Explain(m, a));
+
+ m = Field(&AStruct::x, GreaterThan(0));
+ EXPECT_EQ("the given field is 1 more than 0", Explain(m, a));
+}
+
+// Tests that Field() works when the argument is a pointer to const.
+TEST(FieldForPointerTest, WorksForPointerToConst) {
+ Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0));
+
+ AStruct a;
+ EXPECT_TRUE(m.Matches(&a));
+ a.x = -1;
+ EXPECT_FALSE(m.Matches(&a));
+}
+
+// Tests that Field() works when the argument is a pointer to non-const.
+TEST(FieldForPointerTest, WorksForPointerToNonConst) {
+ Matcher<AStruct*> m = Field(&AStruct::x, Ge(0));
+
+ AStruct a;
+ EXPECT_TRUE(m.Matches(&a));
+ a.x = -1;
+ EXPECT_FALSE(m.Matches(&a));
+}
+
+// Tests that Field() does not match the NULL pointer.
+TEST(FieldForPointerTest, DoesNotMatchNull) {
+ Matcher<const AStruct*> m = Field(&AStruct::x, _);
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+// Tests that Field(&Foo::field, ...) works when the argument's type
+// is a sub-type of const Foo*.
+TEST(FieldForPointerTest, WorksForArgumentOfSubType) {
+ // Note that the matcher expects DerivedStruct but we say AStruct
+ // inside Field().
+ Matcher<DerivedStruct*> m = Field(&AStruct::x, Ge(0));
+
+ DerivedStruct d;
+ EXPECT_TRUE(m.Matches(&d));
+ d.x = -1;
+ EXPECT_FALSE(m.Matches(&d));
+}
+
+// Tests that Field() can describe itself when used to match a pointer.
+TEST(FieldForPointerTest, CanDescribeSelf) {
+ Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0));
+
+ EXPECT_EQ("the given field is greater than or equal to 0", Describe(m));
+ EXPECT_EQ("the given field is not greater than or equal to 0",
+ DescribeNegation(m));
+}
+
+// Tests that Field() can explain the result of matching a pointer.
+TEST(FieldForPointerTest, CanExplainMatchResult) {
+ Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0));
+
+ AStruct a;
+ a.x = 1;
+ EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL)));
+ EXPECT_EQ("", Explain(m, &a));
+
+ m = Field(&AStruct::x, GreaterThan(0));
+ EXPECT_EQ("the given field is 1 more than 0", Explain(m, &a));
+}
+
+// A user-defined class for testing Property().
+class AClass {
+ public:
+ AClass() : n_(0) {}
+
+ // A getter that returns a non-reference.
+ int n() const { return n_; }
+
+ void set_n(int new_n) { n_ = new_n; }
+
+ // A getter that returns a reference to const.
+ const string& s() const { return s_; }
+
+ void set_s(const string& new_s) { s_ = new_s; }
+
+ // A getter that returns a reference to non-const.
+ double& x() const { return x_; }
+ private:
+ int n_;
+ string s_;
+
+ static double x_;
+};
+
+double AClass::x_ = 0.0;
+
+// A derived class for testing Property().
+class DerivedClass : public AClass {
+ private:
+ int k_;
+};
+
+// Tests that Property(&Foo::property, ...) works when property()
+// returns a non-reference.
+TEST(PropertyTest, WorksForNonReferenceProperty) {
+ Matcher<const AClass&> m = Property(&AClass::n, Ge(0));
+
+ AClass a;
+ a.set_n(1);
+ EXPECT_TRUE(m.Matches(a));
+
+ a.set_n(-1);
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Property(&Foo::property, ...) works when property()
+// returns a reference to const.
+TEST(PropertyTest, WorksForReferenceToConstProperty) {
+ Matcher<const AClass&> m = Property(&AClass::s, StartsWith("hi"));
+
+ AClass a;
+ a.set_s("hill");
+ EXPECT_TRUE(m.Matches(a));
+
+ a.set_s("hole");
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Property(&Foo::property, ...) works when property()
+// returns a reference to non-const.
+TEST(PropertyTest, WorksForReferenceToNonConstProperty) {
+ double x = 0.0;
+ AClass a;
+
+ Matcher<const AClass&> m = Property(&AClass::x, Ref(x));
+ EXPECT_FALSE(m.Matches(a));
+
+ m = Property(&AClass::x, Not(Ref(x)));
+ EXPECT_TRUE(m.Matches(a));
+}
+
+// Tests that Property(&Foo::property, ...) works when the argument is
+// passed by value.
+TEST(PropertyTest, WorksForByValueArgument) {
+ Matcher<AClass> m = Property(&AClass::s, StartsWith("hi"));
+
+ AClass a;
+ a.set_s("hill");
+ EXPECT_TRUE(m.Matches(a));
+
+ a.set_s("hole");
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Property(&Foo::property, ...) works when the argument's
+// type is a sub-type of Foo.
+TEST(PropertyTest, WorksForArgumentOfSubType) {
+ // The matcher expects a DerivedClass, but inside the Property() we
+ // say AClass.
+ Matcher<const DerivedClass&> m = Property(&AClass::n, Ge(0));
+
+ DerivedClass d;
+ d.set_n(1);
+ EXPECT_TRUE(m.Matches(d));
+
+ d.set_n(-1);
+ EXPECT_FALSE(m.Matches(d));
+}
+
+// Tests that Property(&Foo::property, m) works when property()'s type
+// and m's argument type are compatible but different.
+TEST(PropertyTest, WorksForCompatibleMatcherType) {
+ // n() returns an int but the inner matcher expects a signed char.
+ Matcher<const AClass&> m = Property(&AClass::n,
+ Matcher<signed char>(Ge(0)));
+
+ AClass a;
+ EXPECT_TRUE(m.Matches(a));
+ a.set_n(-1);
+ EXPECT_FALSE(m.Matches(a));
+}
+
+// Tests that Property() can describe itself.
+TEST(PropertyTest, CanDescribeSelf) {
+ Matcher<const AClass&> m = Property(&AClass::n, Ge(0));
+
+ EXPECT_EQ("the given property is greater than or equal to 0", Describe(m));
+ EXPECT_EQ("the given property is not greater than or equal to 0",
+ DescribeNegation(m));
+}
+
+// Tests that Property() can explain the match result.
+TEST(PropertyTest, CanExplainMatchResult) {
+ Matcher<const AClass&> m = Property(&AClass::n, Ge(0));
+
+ AClass a;
+ a.set_n(1);
+ EXPECT_EQ("", Explain(m, a));
+
+ m = Property(&AClass::n, GreaterThan(0));
+ EXPECT_EQ("the given property is 1 more than 0", Explain(m, a));
+}
+
+// Tests that Property() works when the argument is a pointer to const.
+TEST(PropertyForPointerTest, WorksForPointerToConst) {
+ Matcher<const AClass*> m = Property(&AClass::n, Ge(0));
+
+ AClass a;
+ a.set_n(1);
+ EXPECT_TRUE(m.Matches(&a));
+
+ a.set_n(-1);
+ EXPECT_FALSE(m.Matches(&a));
+}
+
+// Tests that Property() works when the argument is a pointer to non-const.
+TEST(PropertyForPointerTest, WorksForPointerToNonConst) {
+ Matcher<AClass*> m = Property(&AClass::s, StartsWith("hi"));
+
+ AClass a;
+ a.set_s("hill");
+ EXPECT_TRUE(m.Matches(&a));
+
+ a.set_s("hole");
+ EXPECT_FALSE(m.Matches(&a));
+}
+
+// Tests that Property() does not match the NULL pointer.
+TEST(PropertyForPointerTest, WorksForReferenceToNonConstProperty) {
+ Matcher<const AClass*> m = Property(&AClass::x, _);
+ EXPECT_FALSE(m.Matches(NULL));
+}
+
+// Tests that Property(&Foo::property, ...) works when the argument's
+// type is a sub-type of const Foo*.
+TEST(PropertyForPointerTest, WorksForArgumentOfSubType) {
+ // The matcher expects a DerivedClass, but inside the Property() we
+ // say AClass.
+ Matcher<const DerivedClass*> m = Property(&AClass::n, Ge(0));
+
+ DerivedClass d;
+ d.set_n(1);
+ EXPECT_TRUE(m.Matches(&d));
+
+ d.set_n(-1);
+ EXPECT_FALSE(m.Matches(&d));
+}
+
+// Tests that Property() can describe itself when used to match a pointer.
+TEST(PropertyForPointerTest, CanDescribeSelf) {
+ Matcher<const AClass*> m = Property(&AClass::n, Ge(0));
+
+ EXPECT_EQ("the given property is greater than or equal to 0", Describe(m));
+ EXPECT_EQ("the given property is not greater than or equal to 0",
+ DescribeNegation(m));
+}
+
+// Tests that Property() can explain the result of matching a pointer.
+TEST(PropertyForPointerTest, CanExplainMatchResult) {
+ Matcher<const AClass*> m = Property(&AClass::n, Ge(0));
+
+ AClass a;
+ a.set_n(1);
+ EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL)));
+ EXPECT_EQ("", Explain(m, &a));
+
+ m = Property(&AClass::n, GreaterThan(0));
+ EXPECT_EQ("the given property is 1 more than 0", Explain(m, &a));
+}
+
+// Tests ResultOf.
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f is a
+// function pointer.
+string IntToStringFunction(int input) { return input == 1 ? "foo" : "bar"; }
+
+TEST(ResultOfTest, WorksForFunctionPointers) {
+ Matcher<int> matcher = ResultOf(&IntToStringFunction, Eq(string("foo")));
+
+ EXPECT_TRUE(matcher.Matches(1));
+ EXPECT_FALSE(matcher.Matches(2));
+}
+
+// Tests that ResultOf() can describe itself.
+TEST(ResultOfTest, CanDescribeItself) {
+ Matcher<int> matcher = ResultOf(&IntToStringFunction, StrEq("foo"));
+
+ EXPECT_EQ("result of the given callable is equal to \"foo\"",
+ Describe(matcher));
+ EXPECT_EQ("result of the given callable is not equal to \"foo\"",
+ DescribeNegation(matcher));
+}
+
+// Tests that ResultOf() can explain the match result.
+int IntFunction(int input) { return input == 42 ? 80 : 90; }
+
+TEST(ResultOfTest, CanExplainMatchResult) {
+ Matcher<int> matcher = ResultOf(&IntFunction, Ge(85));
+ EXPECT_EQ("", Explain(matcher, 36));
+
+ matcher = ResultOf(&IntFunction, GreaterThan(85));
+ EXPECT_EQ("result of the given callable is 5 more than 85",
+ Explain(matcher, 36));
+}
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f(x)
+// returns a non-reference.
+TEST(ResultOfTest, WorksForNonReferenceResults) {
+ Matcher<int> matcher = ResultOf(&IntFunction, Eq(80));
+
+ EXPECT_TRUE(matcher.Matches(42));
+ EXPECT_FALSE(matcher.Matches(36));
+}
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f(x)
+// returns a reference to non-const.
+double& DoubleFunction(double& input) { return input; }
+
+Uncopyable& RefUncopyableFunction(Uncopyable& obj) {
+ return obj;
+}
+
+TEST(ResultOfTest, WorksForReferenceToNonConstResults) {
+ double x = 3.14;
+ double x2 = x;
+ Matcher<double&> matcher = ResultOf(&DoubleFunction, Ref(x));
+
+ EXPECT_TRUE(matcher.Matches(x));
+ EXPECT_FALSE(matcher.Matches(x2));
+
+ // Test that ResultOf works with uncopyable objects
+ Uncopyable obj(0);
+ Uncopyable obj2(0);
+ Matcher<Uncopyable&> matcher2 =
+ ResultOf(&RefUncopyableFunction, Ref(obj));
+
+ EXPECT_TRUE(matcher2.Matches(obj));
+ EXPECT_FALSE(matcher2.Matches(obj2));
+}
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f(x)
+// returns a reference to const.
+const string& StringFunction(const string& input) { return input; }
+
+TEST(ResultOfTest, WorksForReferenceToConstResults) {
+ string s = "foo";
+ string s2 = s;
+ Matcher<const string&> matcher = ResultOf(&StringFunction, Ref(s));
+
+ EXPECT_TRUE(matcher.Matches(s));
+ EXPECT_FALSE(matcher.Matches(s2));
+}
+
+// Tests that ResultOf(f, m) works when f(x) and m's
+// argument types are compatible but different.
+TEST(ResultOfTest, WorksForCompatibleMatcherTypes) {
+ // IntFunction() returns int but the inner matcher expects a signed char.
+ Matcher<int> matcher = ResultOf(IntFunction, Matcher<signed char>(Ge(85)));
+
+ EXPECT_TRUE(matcher.Matches(36));
+ EXPECT_FALSE(matcher.Matches(42));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+// Tests that the program aborts when ResultOf is passed
+// a NULL function pointer.
+TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) {
+ EXPECT_DEATH(
+ ResultOf(static_cast<string(*)(int)>(NULL), Eq(string("foo"))),
+ "NULL function pointer is passed into ResultOf\\(\\)\\.");
+}
+#endif // GTEST_HAS_DEATH_TEST
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f is a
+// function reference.
+TEST(ResultOfTest, WorksForFunctionReferences) {
+ Matcher<int> matcher = ResultOf(IntToStringFunction, StrEq("foo"));
+ EXPECT_TRUE(matcher.Matches(1));
+ EXPECT_FALSE(matcher.Matches(2));
+}
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f is a
+// function object.
+struct Functor : public ::std::unary_function<int, string> {
+ result_type operator()(argument_type input) const {
+ return IntToStringFunction(input);
+ }
+};
+
+TEST(ResultOfTest, WorksForFunctors) {
+ Matcher<int> matcher = ResultOf(Functor(), Eq(string("foo")));
+
+ EXPECT_TRUE(matcher.Matches(1));
+ EXPECT_FALSE(matcher.Matches(2));
+}
+
+// Tests that ResultOf(f, ...) compiles and works as expected when f is a
+// functor with more then one operator() defined. ResultOf() must work
+// for each defined operator().
+struct PolymorphicFunctor {
+ typedef int result_type;
+ int operator()(int n) { return n; }
+ int operator()(const char* s) { return static_cast<int>(strlen(s)); }
+};
+
+TEST(ResultOfTest, WorksForPolymorphicFunctors) {
+ Matcher<int> matcher_int = ResultOf(PolymorphicFunctor(), Ge(5));
+
+ EXPECT_TRUE(matcher_int.Matches(10));
+ EXPECT_FALSE(matcher_int.Matches(2));
+
+ Matcher<const char*> matcher_string = ResultOf(PolymorphicFunctor(), Ge(5));
+
+ EXPECT_TRUE(matcher_string.Matches("long string"));
+ EXPECT_FALSE(matcher_string.Matches("shrt"));
+}
+
+const int* ReferencingFunction(const int& n) { return &n; }
+
+struct ReferencingFunctor {
+ typedef const int* result_type;
+ result_type operator()(const int& n) { return &n; }
+};
+
+TEST(ResultOfTest, WorksForReferencingCallables) {
+ const int n = 1;
+ const int n2 = 1;
+ Matcher<const int&> matcher2 = ResultOf(ReferencingFunction, Eq(&n));
+ EXPECT_TRUE(matcher2.Matches(n));
+ EXPECT_FALSE(matcher2.Matches(n2));
+
+ Matcher<const int&> matcher3 = ResultOf(ReferencingFunctor(), Eq(&n));
+ EXPECT_TRUE(matcher3.Matches(n));
+ EXPECT_FALSE(matcher3.Matches(n2));
+}
+
+
+class DivisibleByImpl {
+ public:
+ explicit DivisibleByImpl(int divider) : divider_(divider) {}
+
+ template <typename T>
+ bool Matches(const T& n) const {
+ return (n % divider_) == 0;
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << "is divisible by " << divider_;
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "is not divisible by " << divider_;
+ }
+
+ int divider() const { return divider_; }
+ private:
+ const int divider_;
+};
+
+// For testing using ExplainMatchResultTo() with polymorphic matchers.
+template <typename T>
+void ExplainMatchResultTo(const DivisibleByImpl& impl, const T& n,
+ ::std::ostream* os) {
+ *os << "is " << (n % impl.divider()) << " modulo "
+ << impl.divider();
+}
+
+PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) {
+ return MakePolymorphicMatcher(DivisibleByImpl(n));
+}
+
+// Tests that when AllOf() fails, only the first failing matcher is
+// asked to explain why.
+TEST(ExplainMatchResultTest, AllOf_False_False) {
+ const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
+ EXPECT_EQ("is 1 modulo 4", Explain(m, 5));
+}
+
+// Tests that when AllOf() fails, only the first failing matcher is
+// asked to explain why.
+TEST(ExplainMatchResultTest, AllOf_False_True) {
+ const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
+ EXPECT_EQ("is 2 modulo 4", Explain(m, 6));
+}
+
+// Tests that when AllOf() fails, only the first failing matcher is
+// asked to explain why.
+TEST(ExplainMatchResultTest, AllOf_True_False) {
+ const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3));
+ EXPECT_EQ("is 2 modulo 3", Explain(m, 5));
+}
+
+// Tests that when AllOf() succeeds, all matchers are asked to explain
+// why.
+TEST(ExplainMatchResultTest, AllOf_True_True) {
+ const Matcher<int> m = AllOf(DivisibleBy(2), DivisibleBy(3));
+ EXPECT_EQ("is 0 modulo 2; is 0 modulo 3", Explain(m, 6));
+}
+
+TEST(ExplainMatchResultTest, AllOf_True_True_2) {
+ const Matcher<int> m = AllOf(Ge(2), Le(3));
+ EXPECT_EQ("", Explain(m, 2));
+}
+
+TEST(ExplainmatcherResultTest, MonomorphicMatcher) {
+ const Matcher<int> m = GreaterThan(5);
+ EXPECT_EQ("is 1 more than 5", Explain(m, 6));
+}
+
+// The following two tests verify that values without a public copy
+// ctor can be used as arguments to matchers like Eq(), Ge(), and etc
+// with the help of ByRef().
+
+class NotCopyable {
+ public:
+ explicit NotCopyable(int value) : value_(value) {}
+
+ int value() const { return value_; }
+
+ bool operator==(const NotCopyable& rhs) const {
+ return value() == rhs.value();
+ }
+
+ bool operator>=(const NotCopyable& rhs) const {
+ return value() >= rhs.value();
+ }
+ private:
+ int value_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(NotCopyable);
+};
+
+TEST(ByRefTest, AllowsNotCopyableConstValueInMatchers) {
+ const NotCopyable const_value1(1);
+ const Matcher<const NotCopyable&> m = Eq(ByRef(const_value1));
+
+ const NotCopyable n1(1), n2(2);
+ EXPECT_TRUE(m.Matches(n1));
+ EXPECT_FALSE(m.Matches(n2));
+}
+
+TEST(ByRefTest, AllowsNotCopyableValueInMatchers) {
+ NotCopyable value2(2);
+ const Matcher<NotCopyable&> m = Ge(ByRef(value2));
+
+ NotCopyable n1(1), n2(2);
+ EXPECT_FALSE(m.Matches(n1));
+ EXPECT_TRUE(m.Matches(n2));
+}
+
+} // namespace gmock_matchers_test
+} // namespace testing
diff --git a/test/gmock-nice-strict_test.cc b/test/gmock-nice-strict_test.cc
new file mode 100644
index 00000000..955961c5
--- /dev/null
+++ b/test/gmock-nice-strict_test.cc
@@ -0,0 +1,228 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+#include <gmock/gmock-generated-nice-strict.h>
+
+#include <string>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+namespace gmock_nice_strict_test {
+
+using testing::internal::string;
+using testing::GMOCK_FLAG(verbose);
+using testing::HasSubstr;
+using testing::NiceMock;
+using testing::StrictMock;
+
+// Defines some mock classes needed by the tests.
+
+class Foo {
+ public:
+ virtual ~Foo() {}
+
+ virtual void DoThis() = 0;
+ virtual int DoThat(bool flag) = 0;
+};
+
+class MockFoo : public Foo {
+ public:
+ void Delete() { delete this; }
+
+ MOCK_METHOD0(DoThis, void());
+ MOCK_METHOD1(DoThat, int(bool flag));
+};
+
+class MockBar {
+ public:
+ explicit MockBar(const string& s) : str_(s) {}
+
+ MockBar(char a1, char a2, string a3, string a4, int a5, int a6,
+ const string& a7, const string& a8, bool a9, bool a10) {
+ str_ = string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) +
+ static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + (a10 ? 'T' : 'F');
+ }
+
+ virtual ~MockBar() {}
+
+ const string& str() const { return str_; }
+
+ MOCK_METHOD0(This, int());
+ MOCK_METHOD2(That, string(int, bool));
+
+ private:
+ string str_;
+};
+
+// TODO(wan@google.com): find a way to re-enable these tests.
+#if 0
+
+// Tests that a nice mock generates no warning for uninteresting calls.
+TEST(NiceMockTest, NoWarningForUninterestingCall) {
+ NiceMock<MockFoo> nice_foo;
+
+ CaptureTestStdout();
+ nice_foo.DoThis();
+ nice_foo.DoThat(true);
+ EXPECT_EQ("", GetCapturedTestStdout());
+}
+
+// Tests that a nice mock generates no warning for uninteresting calls
+// that delete the mock object.
+TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
+ NiceMock<MockFoo>* const nice_foo = new NiceMock<MockFoo>;
+
+ ON_CALL(*nice_foo, DoThis())
+ .WillByDefault(Invoke(nice_foo, &MockFoo::Delete));
+
+ CaptureTestStdout();
+ nice_foo->DoThis();
+ EXPECT_EQ("", GetCapturedTestStdout());
+}
+
+// Tests that a nice mock generates informational logs for
+// uninteresting calls.
+TEST(NiceMockTest, InfoForUninterestingCall) {
+ NiceMock<MockFoo> nice_foo;
+
+ GMOCK_FLAG(verbose) = "info";
+ CaptureTestStdout();
+ nice_foo.DoThis();
+ EXPECT_THAT(GetCapturedTestStdout(),
+ HasSubstr("Uninteresting mock function call"));
+
+ CaptureTestStdout();
+ nice_foo.DoThat(true);
+ EXPECT_THAT(GetCapturedTestStdout(),
+ HasSubstr("Uninteresting mock function call"));
+}
+
+#endif // 0
+
+// Tests that a nice mock allows expected calls.
+TEST(NiceMockTest, AllowsExpectedCall) {
+ NiceMock<MockFoo> nice_foo;
+
+ EXPECT_CALL(nice_foo, DoThis());
+ nice_foo.DoThis();
+}
+
+// Tests that an unexpected call on a nice mock fails.
+TEST(NiceMockTest, UnexpectedCallFails) {
+ NiceMock<MockFoo> nice_foo;
+
+ EXPECT_CALL(nice_foo, DoThis()).Times(0);
+ EXPECT_NONFATAL_FAILURE(nice_foo.DoThis(), "called more times than expected");
+}
+
+// Tests that NiceMock works with a mock class that has a non-default
+// constructor.
+TEST(NiceMockTest, NonDefaultConstructor) {
+ NiceMock<MockBar> nice_bar("hi");
+ EXPECT_EQ("hi", nice_bar.str());
+
+ nice_bar.This();
+ nice_bar.That(5, true);
+}
+
+// Tests that NiceMock works with a mock class that has a 10-ary
+// non-default constructor.
+TEST(NiceMockTest, NonDefaultConstructor10) {
+ NiceMock<MockBar> nice_bar('a', 'b', "c", "d", 'e', 'f',
+ "g", "h", true, false);
+ EXPECT_EQ("abcdefghTF", nice_bar.str());
+
+ nice_bar.This();
+ nice_bar.That(5, true);
+}
+
+// Tests that a strict mock allows expected calls.
+TEST(StrictMockTest, AllowsExpectedCall) {
+ StrictMock<MockFoo> strict_foo;
+
+ EXPECT_CALL(strict_foo, DoThis());
+ strict_foo.DoThis();
+}
+
+// Tests that an unexpected call on a strict mock fails.
+TEST(StrictMockTest, UnexpectedCallFails) {
+ StrictMock<MockFoo> strict_foo;
+
+ EXPECT_CALL(strict_foo, DoThis()).Times(0);
+ EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
+ "called more times than expected");
+}
+
+// Tests that an uninteresting call on a strict mock fails.
+TEST(StrictMockTest, UninterestingCallFails) {
+ StrictMock<MockFoo> strict_foo;
+
+ EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
+ "Uninteresting mock function call");
+}
+
+// Tests that an uninteresting call on a strict mock fails, even if
+// the call deletes the mock object.
+TEST(StrictMockTest, UninterestingCallFailsAfterDeath) {
+ StrictMock<MockFoo>* const strict_foo = new StrictMock<MockFoo>;
+
+ ON_CALL(*strict_foo, DoThis())
+ .WillByDefault(Invoke(strict_foo, &MockFoo::Delete));
+
+ EXPECT_NONFATAL_FAILURE(strict_foo->DoThis(),
+ "Uninteresting mock function call");
+}
+
+// Tests that StrictMock works with a mock class that has a
+// non-default constructor.
+TEST(StrictMockTest, NonDefaultConstructor) {
+ StrictMock<MockBar> strict_bar("hi");
+ EXPECT_EQ("hi", strict_bar.str());
+
+ EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
+ "Uninteresting mock function call");
+}
+
+// Tests that StrictMock works with a mock class that has a 10-ary
+// non-default constructor.
+TEST(StrictMockTest, NonDefaultConstructor10) {
+ StrictMock<MockBar> strict_bar('a', 'b', "c", "d", 'e', 'f',
+ "g", "h", true, false);
+ EXPECT_EQ("abcdefghTF", strict_bar.str());
+
+ EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
+ "Uninteresting mock function call");
+}
+
+} // namespace gmock_nice_strict_test
+} // namespace testing
diff --git a/test/gmock-port_test.cc b/test/gmock-port_test.cc
new file mode 100644
index 00000000..f35bc115
--- /dev/null
+++ b/test/gmock-port_test.cc
@@ -0,0 +1,95 @@
+// 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: vladl@google.com (Vlad Losev)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the internal cross-platform support utilities.
+
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+TEST(GmockCheckSyntaxTest, BehavesLikeASingleStatement) {
+ if (false)
+ GMOCK_CHECK_(false) << "This should never be executed; "
+ "It's a compilation test only.";
+
+ if (true)
+ GMOCK_CHECK_(true);
+ else
+ ;
+
+ if (false)
+ ;
+ else
+ GMOCK_CHECK_(true) << "";
+}
+
+TEST(GmockCheckSyntaxTest, WorksWithSwitch) {
+ switch (0) {
+ case 1:
+ break;
+ default:
+ GMOCK_CHECK_(true);
+ }
+
+ switch(0)
+ case 0:
+ GMOCK_CHECK_(true) << "Check failed in switch case";
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(GmockCheckDeathTest, DiesWithCorrectOutputOnFailure) {
+ const bool a_false_condition = false;
+ EXPECT_DEATH(GMOCK_CHECK_(a_false_condition) << "Extra info",
+ // MSVC and gcc use different formats to print source
+ // file locations. Google Mock's failure messages use
+ // the same format as used by the compiler, in order
+ // for the IDE to recognize them. Therefore we look
+ // for different patterns here depending on the
+ // compiler.
+#ifdef _MSC_VER
+ "gmock-port_test\\.cc\\([0-9]+\\):"
+#else
+ "gmock-port_test\\.cc:[0-9]+"
+#endif // _MSC_VER
+ ".*a_false_condition.*Extra info");
+}
+
+TEST(GmockCheckDeathTest, LivesSilentlyOnSuccess) {
+ EXPECT_EXIT({
+ GMOCK_CHECK_(true) << "Extra info";
+ ::std::cerr << "Success\n";
+ exit(0); },
+ ::testing::ExitedWithCode(0), "Success");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
diff --git a/test/gmock-printers_test.cc b/test/gmock-printers_test.cc
new file mode 100644
index 00000000..7457af2b
--- /dev/null
+++ b/test/gmock-printers_test.cc
@@ -0,0 +1,903 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the universal value printer.
+
+#include <gmock/gmock-printers.h>
+
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <algorithm>
+#include <deque>
+#include <list>
+#include <map>
+#include <set>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+#include <gmock/gmock-matchers.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+
+// hash_map and hash_set are available on Windows.
+#ifdef GTEST_OS_WINDOWS
+#define GMOCK_HAS_HASH_MAP_ // Indicates that hash_map is available.
+#include <hash_map> // NOLINT
+#define GMOCK_HAS_HASH_SET_ // Indicates that hash_set is available.
+#include <hash_set> // NOLINT
+#endif // GTEST_OS_WINDOWS
+
+// Some user-defined types for testing the universal value printer.
+
+// A user-defined unprintable class template in the global namespace.
+template <typename T>
+class UnprintableTemplateInGlobal {
+ public:
+ UnprintableTemplateInGlobal() : value_() {}
+ private:
+ T value_;
+};
+
+// A user-defined streamable type in the global namespace.
+class StreamableInGlobal {
+ public:
+ virtual ~StreamableInGlobal() {}
+};
+
+inline void operator<<(::std::ostream& os, const StreamableInGlobal& x) {
+ os << "StreamableInGlobal";
+}
+
+namespace foo {
+
+// A user-defined unprintable type in a user namespace.
+class UnprintableInFoo {
+ public:
+ UnprintableInFoo() : x_(0x12EF), y_(0xAB34), z_(0) {}
+ private:
+ testing::internal::Int32 x_;
+ testing::internal::Int32 y_;
+ double z_;
+};
+
+// A user-defined printable type in a user-chosen namespace.
+struct PrintableViaPrintTo {
+ PrintableViaPrintTo() : value() {}
+ int value;
+};
+
+void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) {
+ *os << "PrintableViaPrintTo: " << x.value;
+}
+
+// A user-defined printable class template in a user-chosen namespace.
+template <typename T>
+class PrintableViaPrintToTemplate {
+ public:
+ explicit PrintableViaPrintToTemplate(const T& value) : value_(value) {}
+
+ const T& value() const { return value_; }
+ private:
+ T value_;
+};
+
+template <typename T>
+void PrintTo(const PrintableViaPrintToTemplate<T>& x, ::std::ostream* os) {
+ *os << "PrintableViaPrintToTemplate: " << x.value();
+}
+
+// A user-defined streamable class template in a user namespace.
+template <typename T>
+class StreamableTemplateInFoo {
+ public:
+ StreamableTemplateInFoo() : value_() {}
+
+ const T& value() const { return value_; }
+ private:
+ T value_;
+};
+
+template <typename T>
+inline ::std::ostream& operator<<(::std::ostream& os,
+ const StreamableTemplateInFoo<T>& x) {
+ return os << "StreamableTemplateInFoo: " << x.value();
+}
+
+} // namespace foo
+
+namespace testing {
+namespace gmock_printers_test {
+
+using ::std::deque;
+using ::std::list;
+using ::std::make_pair;
+using ::std::map;
+using ::std::multimap;
+using ::std::multiset;
+using ::std::pair;
+using ::std::set;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+using ::std::vector;
+using ::testing::StartsWith;
+using ::testing::internal::UniversalPrinter;
+using ::testing::internal::string;
+
+#ifdef GTEST_OS_WINDOWS
+// MSVC defines the following classes in the ::stdext namespace while
+// gcc defines them in the :: namespace. Note that they are not part
+// of the C++ standard.
+
+using ::stdext::hash_map;
+using ::stdext::hash_set;
+using ::stdext::hash_multimap;
+using ::stdext::hash_multiset;
+
+#endif // GTEST_OS_WINDOWS
+
+// Prints a value to a string using the universal value printer. This
+// is a helper for testing UniversalPrinter<T>::Print() for various types.
+template <typename T>
+string Print(const T& value) {
+ ::std::stringstream ss;
+ UniversalPrinter<T>::Print(value, &ss);
+ return ss.str();
+}
+
+// Prints a value passed by reference to a string, using the universal
+// value printer. This is a helper for testing
+// UniversalPrinter<T&>::Print() for various types.
+template <typename T>
+string PrintByRef(const T& value) {
+ ::std::stringstream ss;
+ UniversalPrinter<T&>::Print(value, &ss);
+ return ss.str();
+}
+
+// Tests printing various char types.
+
+// char.
+TEST(PrintCharTest, PlainChar) {
+ EXPECT_EQ("'\\0'", Print('\0'));
+ EXPECT_EQ("'\\'' (39)", Print('\''));
+ EXPECT_EQ("'\"' (34)", Print('"'));
+ EXPECT_EQ("'\\?' (63)", Print('\?'));
+ EXPECT_EQ("'\\\\' (92)", Print('\\'));
+ EXPECT_EQ("'\\a' (7)", Print('\a'));
+ EXPECT_EQ("'\\b' (8)", Print('\b'));
+ EXPECT_EQ("'\\f' (12)", Print('\f'));
+ EXPECT_EQ("'\\n' (10)", Print('\n'));
+ EXPECT_EQ("'\\r' (13)", Print('\r'));
+ EXPECT_EQ("'\\t' (9)", Print('\t'));
+ EXPECT_EQ("'\\v' (11)", Print('\v'));
+ EXPECT_EQ("'\\x7F' (127)", Print('\x7F'));
+ EXPECT_EQ("'\\xFF' (255)", Print('\xFF'));
+ EXPECT_EQ("' ' (32)", Print(' '));
+ EXPECT_EQ("'a' (97)", Print('a'));
+}
+
+// signed char.
+TEST(PrintCharTest, SignedChar) {
+ EXPECT_EQ("'\\0'", Print(static_cast<signed char>('\0')));
+ EXPECT_EQ("'\\xCE' (-50)",
+ Print(static_cast<signed char>(-50)));
+}
+
+// unsigned char.
+TEST(PrintCharTest, UnsignedChar) {
+ EXPECT_EQ("'\\0'", Print(static_cast<unsigned char>('\0')));
+ EXPECT_EQ("'b' (98)",
+ Print(static_cast<unsigned char>('b')));
+}
+
+// Tests printing other simple, built-in types.
+
+// bool.
+TEST(PrintBuiltInTypeTest, Bool) {
+ EXPECT_EQ("false", Print(false));
+ EXPECT_EQ("true", Print(true));
+}
+
+// wchar_t.
+TEST(PrintBuiltInTypeTest, Wchar_t) {
+ EXPECT_EQ("L'\\0'", Print(L'\0'));
+ EXPECT_EQ("L'\\'' (39)", Print(L'\''));
+ EXPECT_EQ("L'\"' (34)", Print(L'"'));
+ EXPECT_EQ("L'\\?' (63)", Print(L'\?'));
+ EXPECT_EQ("L'\\\\' (92)", Print(L'\\'));
+ EXPECT_EQ("L'\\a' (7)", Print(L'\a'));
+ EXPECT_EQ("L'\\b' (8)", Print(L'\b'));
+ EXPECT_EQ("L'\\f' (12)", Print(L'\f'));
+ EXPECT_EQ("L'\\n' (10)", Print(L'\n'));
+ EXPECT_EQ("L'\\r' (13)", Print(L'\r'));
+ EXPECT_EQ("L'\\t' (9)", Print(L'\t'));
+ EXPECT_EQ("L'\\v' (11)", Print(L'\v'));
+ EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F'));
+ EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF'));
+ EXPECT_EQ("L' ' (32)", Print(L' '));
+ EXPECT_EQ("L'a' (97)", Print(L'a'));
+ EXPECT_EQ("L'\\x576' (1398)", Print(L'\x576'));
+ EXPECT_EQ("L'\\xC74D' (51021)", Print(L'\xC74D'));
+}
+
+// Test that Int64 provides more storage than wchar_t.
+TEST(PrintTypeSizeTest, Wchar_t) {
+ EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64));
+}
+
+// Various integer types.
+TEST(PrintBuiltInTypeTest, Integer) {
+ EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8
+ EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8
+ EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16
+ EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16
+ EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32
+ EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32
+ EXPECT_EQ("18446744073709551615",
+ Print(static_cast<testing::internal::UInt64>(-1))); // uint64
+ EXPECT_EQ("-9223372036854775808",
+ Print(static_cast<testing::internal::Int64>(1) << 63)); // int64
+}
+
+// Size types.
+TEST(PrintBuiltInTypeTest, Size_t) {
+ EXPECT_EQ("1", Print(sizeof('a'))); // size_t.
+#ifndef GTEST_OS_WINDOWS
+ // Windows has no ssize_t type.
+ EXPECT_EQ("-2", Print(static_cast<ssize_t>(-2))); // ssize_t.
+#endif // GTEST_OS_WINDOWS
+}
+
+// Floating-points.
+TEST(PrintBuiltInTypeTest, FloatingPoints) {
+ EXPECT_EQ("1.5", Print(1.5f)); // float
+ EXPECT_EQ("-2.5", Print(-2.5)); // double
+}
+
+// Since ::std::stringstream::operator<<(const void *) formats the pointer
+// output differently with different compilers, we have to create the expected
+// output first and use it as our expectation.
+static string PrintPointer(const void *p) {
+ ::std::stringstream expected_result_stream;
+ expected_result_stream << p;
+ return expected_result_stream.str();
+}
+
+// Tests printing C strings.
+
+// const char*.
+TEST(PrintCStringTest, Const) {
+ const char* p = "World";
+ EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p));
+}
+
+// char*.
+TEST(PrintCStringTest, NonConst) {
+ char p[] = "Hi";
+ EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"",
+ Print(static_cast<char*>(p)));
+}
+
+// NULL C string.
+TEST(PrintCStringTest, Null) {
+ const char* p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// Tests that C strings are escaped properly.
+TEST(PrintCStringTest, EscapesProperly) {
+ const char* p = "'\"\?\\\a\b\f\n\r\t\v\x7F\xFF a";
+ EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"\\?\\\\\\a\\b\\f"
+ "\\n\\r\\t\\v\\x7F\\xFF a\"",
+ Print(p));
+}
+
+
+
+// MSVC compiler can be configured to define whar_t as a typedef
+// of unsigned short. Defining an overload for const wchar_t* in that case
+// would cause pointers to unsigned shorts be printed as wide strings,
+// possibly accessing more memory than intended and causing invalid
+// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
+// wchar_t is implemented as a native type.
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+
+// const wchar_t*.
+TEST(PrintWideCStringTest, Const) {
+ const wchar_t* p = L"World";
+ EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p));
+}
+
+// wchar_t*.
+TEST(PrintWideCStringTest, NonConst) {
+ wchar_t p[] = L"Hi";
+ EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"",
+ Print(static_cast<wchar_t*>(p)));
+}
+
+// NULL wide C string.
+TEST(PrintWideCStringTest, Null) {
+ const wchar_t* p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// Tests that wide C strings are escaped properly.
+TEST(PrintWideCStringTest, EscapesProperly) {
+ const wchar_t* p = L"'\"\?\\\a\b\f\n\r\t\v\xD3\x576\x8D3\xC74D a";
+ EXPECT_EQ(PrintPointer(p) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f"
+ "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"",
+ Print(p));
+}
+#endif // native wchar_t
+
+// Tests printing pointers to other char types.
+
+// signed char*.
+TEST(PrintCharPointerTest, SignedChar) {
+ signed char* p = reinterpret_cast<signed char*>(0x1234);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// const signed char*.
+TEST(PrintCharPointerTest, ConstSignedChar) {
+ signed char* p = reinterpret_cast<signed char*>(0x1234);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// unsigned char*.
+TEST(PrintCharPointerTest, UnsignedChar) {
+ unsigned char* p = reinterpret_cast<unsigned char*>(0x1234);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// const unsigned char*.
+TEST(PrintCharPointerTest, ConstUnsignedChar) {
+ const unsigned char* p = reinterpret_cast<const unsigned char*>(0x1234);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// Tests printing pointers to simple, built-in types.
+
+// bool*.
+TEST(PrintPointerToBuiltInTypeTest, Bool) {
+ bool* p = reinterpret_cast<bool*>(0xABCD);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// void*.
+TEST(PrintPointerToBuiltInTypeTest, Void) {
+ void* p = reinterpret_cast<void*>(0xABCD);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// const void*.
+TEST(PrintPointerToBuiltInTypeTest, ConstVoid) {
+ const void* p = reinterpret_cast<const void*>(0xABCD);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// Tests printing pointers to pointers.
+TEST(PrintPointerToPointerTest, IntPointerPointer) {
+ int** p = reinterpret_cast<int**>(0xABCD);
+ EXPECT_EQ(PrintPointer(p), Print(p));
+ p = NULL;
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// Tests printing (non-member) function pointers.
+
+void MyFunction(int n) {}
+
+TEST(PrintPointerTest, NonMemberFunctionPointer) {
+ EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>(&MyFunction)),
+ Print(&MyFunction));
+ int (*p)(bool) = NULL; // NOLINT
+ EXPECT_EQ("NULL", Print(p));
+}
+
+// Tests printing member variable pointers. Although they are called
+// pointers, they don't point to a location in the address space.
+// Their representation is implementation-defined. Thus they will be
+// printed as raw bytes.
+
+struct Foo {
+ public:
+ virtual ~Foo() {}
+ int MyMethod(char x) { return x + 1; }
+ virtual char MyVirtualMethod(int n) { return 'a'; }
+
+ int value;
+};
+
+TEST(PrintPointerTest, MemberVariablePointer) {
+ EXPECT_THAT(Print(&Foo::value),
+ StartsWith(Print(sizeof(&Foo::value)) + "-byte object "));
+ int (Foo::*p) = NULL; // NOLINT
+ EXPECT_THAT(Print(p),
+ StartsWith(Print(sizeof(p)) + "-byte object "));
+}
+
+// Tests printing member function pointers. Although they are called
+// pointers, they don't point to a location in the address space.
+// Their representation is implementation-defined. Thus they will be
+// printed as raw bytes.
+TEST(PrintPointerTest, MemberFunctionPointer) {
+ EXPECT_THAT(Print(&Foo::MyMethod),
+ StartsWith(Print(sizeof(&Foo::MyMethod)) + "-byte object "));
+ EXPECT_THAT(Print(&Foo::MyVirtualMethod),
+ StartsWith(Print(sizeof((&Foo::MyVirtualMethod)))
+ + "-byte object "));
+ int (Foo::*p)(char) = NULL; // NOLINT
+ EXPECT_THAT(Print(p),
+ StartsWith(Print(sizeof(p)) + "-byte object "));
+}
+
+// Tests printing C arrays.
+
+// One-dimensional array.
+
+void ArrayHelper1(int (&a)[5]) { // NOLINT
+ EXPECT_EQ("{ 1, 2, 3, 4, 5 }", Print(a));
+}
+
+TEST(PrintArrayTest, OneDimensionalArray) {
+ int a[5] = { 1, 2, 3, 4, 5 };
+ ArrayHelper1(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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// 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);
+}
+
+// Array of objects.
+TEST(PrintArrayTest, ObjectArray) {
+ string a[3] = { "Hi", "Hello", "Ni hao" };
+ EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", Print(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));
+}
+
+// Tests printing ::string and ::std::string.
+
+#if GTEST_HAS_GLOBAL_STRING
+// ::string.
+TEST(PrintStringTest, StringInGlobalNamespace) {
+ const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
+ const ::string str(s, sizeof(s));
+ EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
+ Print(str));
+}
+#endif // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_STD_STRING
+// ::std::string.
+TEST(PrintStringTest, StringInStdNamespace) {
+ const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
+ const ::std::string str(s, sizeof(s));
+ EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
+ Print(str));
+}
+#endif // GTEST_HAS_STD_STRING
+
+// Tests printing ::wstring and ::std::wstring.
+
+#if GTEST_HAS_GLOBAL_WSTRING
+// ::wstring.
+TEST(PrintWideStringTest, StringInGlobalNamespace) {
+ const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a";
+ const ::wstring str(s, sizeof(s)/sizeof(wchar_t));
+ EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v"
+ "\\xD3\\x576\\x8D3\\xC74D a\\0\"",
+ Print(str));
+}
+#endif // GTEST_HAS_GLOBAL_WSTRING
+
+#if GTEST_HAS_STD_WSTRING
+// ::std::wstring.
+TEST(PrintWideStringTest, StringInStdNamespace) {
+ const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a";
+ const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t));
+ EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v"
+ "\\xD3\\x576\\x8D3\\xC74D a\\0\"",
+ Print(str));
+}
+#endif // GTEST_HAS_STD_WSTRING
+
+// Tests printing STL containers.
+
+TEST(PrintStlContainerTest, EmptyDeque) {
+ deque<char> empty;
+ EXPECT_EQ("{}", Print(empty));
+}
+
+TEST(PrintStlContainerTest, NonEmptyDeque) {
+ deque<int> non_empty;
+ non_empty.push_back(1);
+ non_empty.push_back(3);
+ EXPECT_EQ("{ 1, 3 }", Print(non_empty));
+}
+
+#ifdef GMOCK_HAS_HASH_MAP_
+
+TEST(PrintStlContainerTest, OneElementHashMap) {
+ hash_map<int, char> map1;
+ map1[1] = 'a';
+ EXPECT_EQ("{ (1, 'a' (97)) }", Print(map1));
+}
+
+TEST(PrintStlContainerTest, HashMultiMap) {
+ hash_multimap<int, bool> map1;
+ map1.insert(make_pair(5, true));
+ map1.insert(make_pair(5, false));
+
+ // Elements of hash_multimap can be printed in any order.
+ const string result = Print(map1);
+ EXPECT_TRUE(result == "{ (5, true), (5, false) }" ||
+ result == "{ (5, false), (5, true) }")
+ << " where Print(map1) returns \"" << result << "\".";
+}
+
+#endif // GMOCK_HAS_HASH_MAP_
+
+#ifdef GMOCK_HAS_HASH_SET_
+
+TEST(PrintStlContainerTest, HashSet) {
+ hash_set<string> set1;
+ set1.insert("hello");
+ EXPECT_EQ("{ \"hello\" }", Print(set1));
+}
+
+TEST(PrintStlContainerTest, HashMultiSet) {
+ const int kSize = 5;
+ int a[kSize] = { 1, 1, 2, 5, 1 };
+ hash_multiset<int> set1(a, a + kSize);
+
+ // Elements of hash_multiset can be printed in any order.
+ const string result = Print(set1);
+ const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit.
+
+ // Verifies the result matches the expected pattern; also extracts
+ // the numbers in the result.
+ ASSERT_EQ(expected_pattern.length(), result.length());
+ std::vector<int> numbers;
+ for (size_t i = 0; i != result.length(); i++) {
+ if (expected_pattern[i] == 'd') {
+ ASSERT_TRUE(isdigit(result[i]));
+ numbers.push_back(result[i] - '0');
+ } else {
+ EXPECT_EQ(expected_pattern[i], result[i]) << " where result is "
+ << result;
+ }
+ }
+
+ // Makes sure the result contains the right numbers.
+ std::sort(numbers.begin(), numbers.end());
+ std::sort(a, a + kSize);
+ EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin()));
+}
+
+#endif // GMOCK_HAS_HASH_SET_
+
+TEST(PrintStlContainerTest, List) {
+ const char* a[] = {
+ "hello",
+ "world"
+ };
+ const list<string> strings(a, a + 2);
+ EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings));
+}
+
+TEST(PrintStlContainerTest, Map) {
+ map<int, bool> map1;
+ map1[1] = true;
+ map1[5] = false;
+ map1[3] = true;
+ EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1));
+}
+
+TEST(PrintStlContainerTest, MultiMap) {
+ multimap<bool, int> map1;
+ map1.insert(make_pair(true, 0));
+ map1.insert(make_pair(true, 1));
+ map1.insert(make_pair(false, 2));
+ EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1));
+}
+
+TEST(PrintStlContainerTest, Set) {
+ const unsigned int a[] = { 3, 0, 5 };
+ set<unsigned int> set1(a, a + 3);
+ EXPECT_EQ("{ 0, 3, 5 }", Print(set1));
+}
+
+TEST(PrintStlContainerTest, MultiSet) {
+ const int a[] = { 1, 1, 2, 5, 1 };
+ multiset<int> set1(a, a + 5);
+ EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1));
+}
+
+TEST(PrintStlContainerTest, Pair) {
+ pair<const bool, int> p(true, 5);
+ EXPECT_EQ("(true, 5)", Print(p));
+}
+
+TEST(PrintStlContainerTest, Vector) {
+ vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ EXPECT_EQ("{ 1, 2 }", Print(v));
+}
+
+TEST(PrintStlContainerTest, LongSequence) {
+ const int a[100] = { 1, 2, 3 };
+ const vector<int> v(a, a + 100);
+ EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "
+ "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v));
+}
+
+TEST(PrintStlContainerTest, NestedContainer) {
+ const int a1[] = { 1, 2 };
+ const int a2[] = { 3, 4, 5 };
+ const list<int> l1(a1, a1 + 2);
+ const list<int> l2(a2, a2 + 3);
+
+ vector<list<int> > v;
+ v.push_back(l1);
+ v.push_back(l2);
+ EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v));
+}
+
+
+// Tests printing tuples.
+
+// Tuples of various arities.
+TEST(PrintTupleTest, VariousSizes) {
+ tuple<> t0;
+ EXPECT_EQ("()", Print(t0));
+
+ tuple<int> t1(5);
+ EXPECT_EQ("(5)", Print(t1));
+
+ tuple<char, bool> t2('a', true);
+ EXPECT_EQ("('a' (97), true)", Print(t2));
+
+ const char* const str = "8";
+ tuple<bool, char, short, testing::internal::Int32, // NOLINT
+ testing::internal::Int64, float, double, const char*, void*, string>
+ t10(false, 'a', 3, 4, 5, 6.5F, 7.5, str, NULL, "10");
+ EXPECT_EQ("(false, 'a' (97), 3, 4, 5, 6.5, 7.5, " + PrintPointer(str) +
+ " pointing to \"8\", NULL, \"10\")",
+ Print(t10));
+}
+
+// Nested tuples.
+TEST(PrintTupleTest, NestedTuple) {
+ tuple<tuple<int, double>, char> nested(make_tuple(5, 9.5), 'a');
+ EXPECT_EQ("((5, 9.5), 'a' (97))", Print(nested));
+}
+
+// Tests printing user-defined unprintable types.
+
+// Unprintable types in the global namespace.
+TEST(PrintUnprintableTypeTest, InGlobalNamespace) {
+ EXPECT_EQ("1-byte object <00>",
+ Print(UnprintableTemplateInGlobal<bool>()));
+}
+
+// Unprintable types in a user namespace.
+TEST(PrintUnprintableTypeTest, InUserNamespace) {
+ EXPECT_EQ("16-byte object <EF12 0000 34AB 0000 0000 0000 0000 0000>",
+ Print(::foo::UnprintableInFoo()));
+}
+
+// Unprintable types are that too big to be printed completely.
+
+struct Big {
+ Big() { memset(array, 0, sizeof(array)); }
+ char array[257];
+};
+
+TEST(PrintUnpritableTypeTest, BigObject) {
+ EXPECT_EQ("257-byte object <0000 0000 0000 0000 0000 0000 "
+ "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
+ "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
+ "0000 0000 0000 0000 0000 0000 ... 0000 0000 0000 "
+ "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
+ "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
+ "0000 0000 0000 0000 0000 0000 0000 0000 00>",
+ Print(Big()));
+}
+
+// Tests printing user-defined streamable types.
+
+// Streamable types in the global namespace.
+TEST(PrintStreamableTypeTest, InGlobalNamespace) {
+ EXPECT_EQ("StreamableInGlobal",
+ Print(StreamableInGlobal()));
+}
+
+// Printable template types in a user namespace.
+TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) {
+ EXPECT_EQ("StreamableTemplateInFoo: 0",
+ Print(::foo::StreamableTemplateInFoo<int>()));
+}
+
+// Tests printing user-defined types that have a PrintTo() function.
+TEST(PrintPrintableTypeTest, InUserNamespace) {
+ EXPECT_EQ("PrintableViaPrintTo: 0",
+ Print(::foo::PrintableViaPrintTo()));
+}
+
+// Tests printing user-defined class template that have a PrintTo() function.
+TEST(PrintPrintableTypeTest, TemplateInUserNamespace) {
+ EXPECT_EQ("PrintableViaPrintToTemplate: 5",
+ Print(::foo::PrintableViaPrintToTemplate<int>(5)));
+}
+
+#if GMOCK_HAS_PROTOBUF_
+
+// Tests printing a protocol message.
+TEST(PrintProtocolMessageTest, PrintsShortDebugString) {
+ testing::internal::TestMessage msg;
+ msg.set_member("yes");
+ EXPECT_EQ("<member:\"yes\">", Print(msg));
+}
+
+// Tests printing a proto2 message.
+TEST(PrintProto2MessageTest, PrintsShortDebugString) {
+ testing::internal::FooMessage msg;
+ msg.set_int_field(2);
+ EXPECT_PRED2(RE::FullMatch, Print(msg),
+ "<int_field:\\s*2\\s*>");
+}
+
+#endif // GMOCK_HAS_PROTOBUF_
+
+// Tests that the universal printer prints both the address and the
+// value of a reference.
+TEST(PrintReferenceTest, PrintsAddressAndValue) {
+ int n = 5;
+ EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n));
+
+ int a[2][3] = {
+ { 0, 1, 2 },
+ { 3, 4, 5 }
+ };
+ EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }",
+ PrintByRef(a));
+
+ const ::foo::UnprintableInFoo x;
+ EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object "
+ "<EF12 0000 34AB 0000 0000 0000 0000 0000>",
+ PrintByRef(x));
+}
+
+// Tests that the universal printer prints a function pointer passed by
+// reference.
+TEST(PrintReferenceTest, HandlesFunctionPointer) {
+ void (*fp)(int n) = &MyFunction;
+ const string fp_pointer_string =
+ PrintPointer(reinterpret_cast<const void*>(&fp));
+ const string fp_string = PrintPointer(reinterpret_cast<const void*>(fp));
+ EXPECT_EQ("@" + fp_pointer_string + " " + fp_string,
+ PrintByRef(fp));
+}
+
+// Tests that the universal printer prints a member function pointer
+// passed by reference.
+TEST(PrintReferenceTest, HandlesMemberFunctionPointer) {
+ int (Foo::*p)(char ch) = &Foo::MyMethod;
+ EXPECT_THAT(PrintByRef(p),
+ StartsWith("@" + PrintPointer(reinterpret_cast<const void*>(&p))
+ + " " + Print(sizeof(p)) + "-byte object "));
+
+ char (Foo::*p2)(int n) = &Foo::MyVirtualMethod;
+ EXPECT_THAT(PrintByRef(p2),
+ StartsWith("@" + PrintPointer(reinterpret_cast<const void*>(&p2))
+ + " " + Print(sizeof(p2)) + "-byte object "));
+}
+
+// Tests that the universal printer prints a member variable pointer
+// passed by reference.
+TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
+ int (Foo::*p) = &Foo::value; // NOLINT
+ EXPECT_THAT(PrintByRef(p),
+ StartsWith("@" + PrintPointer(&p)
+ + " " + Print(sizeof(p)) + "-byte object "));
+}
+
+} // namespace gmock_printers_test
+} // namespace testing
diff --git a/test/gmock-sample.cc b/test/gmock-sample.cc
new file mode 100644
index 00000000..44d72a10
--- /dev/null
+++ b/test/gmock-sample.cc
@@ -0,0 +1,32 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+#include "test/gmock-sample.h"
diff --git a/test/gmock-sample.h b/test/gmock-sample.h
new file mode 100644
index 00000000..2183f4f9
--- /dev/null
+++ b/test/gmock-sample.h
@@ -0,0 +1,49 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+#ifndef GMOCK_TEST_GMOCK_SAMPLE_H_
+#define GMOCK_TEST_GMOCK_SAMPLE_H_
+
+#include <gmock/gmock.h>
+
+class Sample {
+ public:
+ virtual ~Sample() {}
+
+ virtual bool Foo(int n) = 0;
+};
+
+class MockSample : public Sample {
+ public:
+ MOCK_METHOD1(Foo, bool(int n));
+};
+
+#endif // GMOCK_TEST_GMOCK_SAMPLE_H_
diff --git a/test/gmock-spec-builders_test.cc b/test/gmock-spec-builders_test.cc
new file mode 100644
index 00000000..3e27aa84
--- /dev/null
+++ b/test/gmock-spec-builders_test.cc
@@ -0,0 +1,1889 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests the spec builder syntax.
+
+#include <gmock/gmock-spec-builders.h>
+
+#include <ostream> // NOLINT
+#include <sstream>
+#include <string>
+
+#include <gmock/gmock.h>
+#include <gmock/internal/gmock-port.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+namespace internal {
+
+// Helper class for testing the Expectation class template.
+class ExpectationTester {
+ public:
+ // Sets the call count of the given expectation to the given number.
+ void SetCallCount(int n, ExpectationBase* exp) {
+ exp->call_count_ = n;
+ }
+};
+
+} // namespace internal
+} // namespace testing
+
+namespace {
+
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::AtMost;
+using testing::Between;
+using testing::Cardinality;
+using testing::CardinalityInterface;
+using testing::Const;
+using testing::DoAll;
+using testing::DoDefault;
+using testing::GMOCK_FLAG(verbose);
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::IsSubstring;
+using testing::Lt;
+using testing::Message;
+using testing::Mock;
+using testing::Return;
+using testing::Sequence;
+using testing::internal::g_gmock_mutex;
+using testing::internal::kErrorVerbosity;
+using testing::internal::kInfoVerbosity;
+using testing::internal::kWarningVerbosity;
+using testing::internal::Expectation;
+using testing::internal::ExpectationTester;
+using testing::internal::string;
+
+class Result {};
+
+class MockA {
+ public:
+ MOCK_METHOD1(DoA, void(int n)); // NOLINT
+ MOCK_METHOD1(ReturnResult, Result(int n)); // NOLINT
+ MOCK_METHOD2(Binary, bool(int x, int y)); // NOLINT
+};
+
+class MockB {
+ public:
+ MOCK_CONST_METHOD0(DoB, int()); // NOLINT
+ MOCK_METHOD1(DoB, int(int n)); // NOLINT
+};
+
+// Tests that EXPECT_CALL and ON_CALL compile in a presence of macro
+// redefining a mock method name. This could happen, for example, when
+// the tested code #includes Win32 API headers which define many APIs
+// as macros, e.g. #define TextOut TextOutW.
+
+#define Method MethodW
+
+class CC {
+ public:
+ virtual ~CC() {}
+ virtual int Method() = 0;
+};
+class MockCC : public CC {
+ public:
+ MOCK_METHOD0(Method, int());
+};
+
+// Tests that a method with expanded name compiles.
+TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) {
+ MockCC cc;
+ ON_CALL(cc, Method());
+}
+
+// Tests that the method with expanded name not only compiles but runs
+// and returns a correct value, too.
+TEST(OnCallSyntaxTest, WorksWithMethodNameExpandedFromMacro) {
+ MockCC cc;
+ ON_CALL(cc, Method()).WillByDefault(Return(42));
+ EXPECT_EQ(42, cc.Method());
+}
+
+// Tests that a method with expanded name compiles.
+TEST(ExpectCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) {
+ MockCC cc;
+ EXPECT_CALL(cc, Method());
+ cc.Method();
+}
+
+// Tests that it works, too.
+TEST(ExpectCallSyntaxTest, WorksWithMethodNameExpandedFromMacro) {
+ MockCC cc;
+ EXPECT_CALL(cc, Method()).WillOnce(Return(42));
+ EXPECT_EQ(42, cc.Method());
+}
+
+#undef Method // Done with macro redefinition tests.
+
+// Tests that ON_CALL evaluates its arguments exactly once as promised
+// by Google Mock.
+TEST(OnCallSyntaxTest, EvaluatesFirstArgumentOnce) {
+ MockA a;
+ MockA* pa = &a;
+
+ ON_CALL(*pa++, DoA(_));
+ EXPECT_EQ(&a + 1, pa);
+}
+
+TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) {
+ MockA a;
+ int n = 0;
+
+ ON_CALL(a, DoA(n++));
+ EXPECT_EQ(1, n);
+}
+
+// Tests that the syntax of ON_CALL() is enforced at run time.
+
+TEST(OnCallSyntaxTest, WithArgumentsIsOptional) {
+ MockA a;
+
+ ON_CALL(a, DoA(5))
+ .WillByDefault(Return());
+ ON_CALL(a, DoA(_))
+ .WithArguments(_)
+ .WillByDefault(Return());
+}
+
+TEST(OnCallSyntaxTest, WithArgumentsCanAppearAtMostOnce) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ ON_CALL(a, ReturnResult(_))
+ .WithArguments(_)
+ .WithArguments(_)
+ .WillByDefault(Return(Result()));
+ }, ".WithArguments() cannot appear more than once in an ON_CALL()");
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) {
+ MockA a;
+
+ EXPECT_DEATH({ // NOLINT
+ ON_CALL(a, DoA(5));
+ a.DoA(5);
+ }, "");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(OnCallSyntaxTest, WillByDefaultCanAppearAtMostOnce) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ ON_CALL(a, DoA(5))
+ .WillByDefault(Return())
+ .WillByDefault(Return());
+ }, ".WillByDefault() must appear exactly once in an ON_CALL()");
+}
+
+// Tests that EXPECT_CALL evaluates its arguments exactly once as
+// promised by Google Mock.
+TEST(ExpectCallSyntaxTest, EvaluatesFirstArgumentOnce) {
+ MockA a;
+ MockA* pa = &a;
+
+ EXPECT_CALL(*pa++, DoA(_));
+ a.DoA(0);
+ EXPECT_EQ(&a + 1, pa);
+}
+
+TEST(ExpectCallSyntaxTest, EvaluatesSecondArgumentOnce) {
+ MockA a;
+ int n = 0;
+
+ EXPECT_CALL(a, DoA(n++));
+ a.DoA(0);
+ EXPECT_EQ(1, n);
+}
+
+// Tests that the syntax of EXPECT_CALL() is enforced at run time.
+
+TEST(ExpectCallSyntaxTest, WithArgumentsIsOptional) {
+ MockA a;
+
+ EXPECT_CALL(a, DoA(5))
+ .Times(0);
+ EXPECT_CALL(a, DoA(6))
+ .WithArguments(_)
+ .Times(0);
+}
+
+TEST(ExpectCallSyntaxTest, WithArgumentsCanAppearAtMostOnce) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(6))
+ .WithArguments(_)
+ .WithArguments(_);
+ }, ".WithArguments() cannot appear more than once in "
+ "an EXPECT_CALL()");
+
+ a.DoA(6);
+}
+
+TEST(ExpectCallSyntaxTest, WithArgumentsMustBeFirstClause) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .Times(1)
+ .WithArguments(_);
+ }, ".WithArguments() 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()");
+
+ a.DoA(2);
+}
+
+TEST(ExpectCallSyntaxTest, TimesCanBeInferred) {
+ MockA a;
+
+ EXPECT_CALL(a, DoA(1))
+ .WillOnce(Return());
+
+ EXPECT_CALL(a, DoA(2))
+ .WillOnce(Return())
+ .WillRepeatedly(Return());
+
+ a.DoA(1);
+ a.DoA(2);
+ a.DoA(2);
+}
+
+TEST(ExpectCallSyntaxTest, TimesCanAppearAtMostOnce) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .Times(1)
+ .Times(2);
+ }, ".Times() cannot appear more than once in an EXPECT_CALL()");
+
+ a.DoA(1);
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, TimesMustBeBeforeInSequence) {
+ MockA a;
+ Sequence s;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .InSequence(s)
+ .Times(1);
+ }, ".Times() cannot appear after ");
+
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, InSequenceIsOptional) {
+ MockA a;
+ Sequence s;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(a, DoA(2))
+ .InSequence(s);
+
+ a.DoA(1);
+ a.DoA(2);
+}
+
+TEST(ExpectCallSyntaxTest, InSequenceCanAppearMultipleTimes) {
+ MockA a;
+ Sequence s1, s2;
+
+ EXPECT_CALL(a, DoA(1))
+ .InSequence(s1, s2)
+ .InSequence(s1);
+
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, InSequenceMustBeBeforeWill) {
+ MockA a;
+ Sequence s;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .WillOnce(Return())
+ .InSequence(s);
+ }, ".InSequence() cannot appear after ");
+
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, WillIsOptional) {
+ MockA a;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(a, DoA(2))
+ .WillOnce(Return());
+
+ a.DoA(1);
+ a.DoA(2);
+}
+
+TEST(ExpectCallSyntaxTest, WillCanAppearMultipleTimes) {
+ MockA a;
+
+ EXPECT_CALL(a, DoA(1))
+ .Times(AnyNumber())
+ .WillOnce(Return())
+ .WillOnce(Return())
+ .WillOnce(Return());
+}
+
+TEST(ExpectCallSyntaxTest, WillMustBeBeforeWillRepeatedly) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .WillRepeatedly(Return())
+ .WillOnce(Return());
+ }, ".WillOnce() cannot appear after ");
+
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, WillRepeatedlyIsOptional) {
+ MockA a;
+
+ EXPECT_CALL(a, DoA(1))
+ .WillOnce(Return());
+ EXPECT_CALL(a, DoA(2))
+ .WillOnce(Return())
+ .WillRepeatedly(Return());
+
+ a.DoA(1);
+ a.DoA(2);
+ a.DoA(2);
+}
+
+TEST(ExpectCallSyntaxTest, WillRepeatedlyCannotAppearMultipleTimes) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .WillRepeatedly(Return())
+ .WillRepeatedly(Return());
+ }, ".WillRepeatedly() cannot appear more than once in an "
+ "EXPECT_CALL()");
+}
+
+TEST(ExpectCallSyntaxTest, WillRepeatedlyMustBeBeforeRetiresOnSaturation) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .RetiresOnSaturation()
+ .WillRepeatedly(Return());
+ }, ".WillRepeatedly() cannot appear after ");
+}
+
+TEST(ExpectCallSyntaxTest, RetiresOnSaturationIsOptional) {
+ MockA a;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(a, DoA(1))
+ .RetiresOnSaturation();
+
+ a.DoA(1);
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, RetiresOnSaturationCannotAppearMultipleTimes) {
+ MockA a;
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ EXPECT_CALL(a, DoA(1))
+ .RetiresOnSaturation()
+ .RetiresOnSaturation();
+ }, ".RetiresOnSaturation() cannot appear more than once");
+
+ a.DoA(1);
+}
+
+TEST(ExpectCallSyntaxTest, DefaultCardinalityIsOnce) {
+ {
+ MockA a;
+ EXPECT_CALL(a, DoA(1));
+ a.DoA(1);
+ }
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ MockA a;
+ EXPECT_CALL(a, DoA(1));
+ }, "to be called once");
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ MockA a;
+ EXPECT_CALL(a, DoA(1));
+ a.DoA(1);
+ a.DoA(1);
+ }, "to be called once");
+}
+
+// TODO(wan@google.com): find a way to re-enable these tests.
+#if 0
+
+// Tests that Google Mock doesn't print a warning when the number of
+// WillOnce() is adequate.
+TEST(ExpectCallSyntaxTest, DoesNotWarnOnAdequateActionCount) {
+ CaptureTestStdout();
+ {
+ MockB b;
+
+ // It's always fine to omit WillOnce() entirely.
+ EXPECT_CALL(b, DoB())
+ .Times(0);
+ EXPECT_CALL(b, DoB(1))
+ .Times(AtMost(1));
+ EXPECT_CALL(b, DoB(2))
+ .Times(1)
+ .WillRepeatedly(Return(1));
+
+ // It's fine for the number of WillOnce()s to equal the upper bound.
+ EXPECT_CALL(b, DoB(3))
+ .Times(Between(1, 2))
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+
+ // It's fine for the number of WillOnce()s to be smaller than the
+ // upper bound when there is a WillRepeatedly().
+ EXPECT_CALL(b, DoB(4))
+ .Times(AtMost(3))
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2));
+
+ // Satisfies the above expectations.
+ b.DoB(2);
+ b.DoB(3);
+ }
+ const string& output = GetCapturedTestStdout();
+ EXPECT_EQ("", output);
+}
+
+// Tests that Google Mock warns on having too many actions in an
+// expectation compared to its cardinality.
+TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) {
+ CaptureTestStdout();
+ {
+ MockB b;
+
+ // Warns when the number of WillOnce()s is larger than the upper bound.
+ EXPECT_CALL(b, DoB())
+ .Times(0)
+ .WillOnce(Return(1)); // #1
+ EXPECT_CALL(b, DoB())
+ .Times(AtMost(1))
+ .WillOnce(Return(1))
+ .WillOnce(Return(2)); // #2
+ EXPECT_CALL(b, DoB(1))
+ .Times(1)
+ .WillOnce(Return(1))
+ .WillOnce(Return(2))
+ .RetiresOnSaturation(); // #3
+
+ // Warns when the number of WillOnce()s equals the upper bound and
+ // there is a WillRepeatedly().
+ EXPECT_CALL(b, DoB())
+ .Times(0)
+ .WillRepeatedly(Return(1)); // #4
+ EXPECT_CALL(b, DoB(2))
+ .Times(1)
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2)); // #5
+
+ // Satisfies the above expectations.
+ b.DoB(1);
+ b.DoB(2);
+ }
+ const string& output = GetCapturedTestStdout();
+ EXPECT_PRED_FORMAT2(IsSubstring,
+ "Too many actions specified.\n"
+ "Expected to be never called, but has 1 WillOnce().",
+ output); // #1
+ EXPECT_PRED_FORMAT2(IsSubstring,
+ "Too many actions specified.\n"
+ "Expected to be called at most once, "
+ "but has 2 WillOnce()s.",
+ output); // #2
+ EXPECT_PRED_FORMAT2(IsSubstring,
+ "Too many actions specified.\n"
+ "Expected to be called once, but has 2 WillOnce()s.",
+ output); // #3
+ EXPECT_PRED_FORMAT2(IsSubstring,
+ "Too many actions specified.\n"
+ "Expected to be never called, but has 0 WillOnce()s "
+ "and a WillRepeatedly().",
+ output); // #4
+ EXPECT_PRED_FORMAT2(IsSubstring,
+ "Too many actions specified.\n"
+ "Expected to be called once, but has 1 WillOnce() "
+ "and a WillRepeatedly().",
+ output); // #5
+}
+
+// Tests that Google Mock warns on having too few actions in an
+// expectation compared to its cardinality.
+TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
+ MockB b;
+
+ EXPECT_CALL(b, DoB())
+ .Times(Between(2, 3))
+ .WillOnce(Return(1));
+
+ CaptureTestStdout();
+ b.DoB();
+ const string& output = GetCapturedTestStdout();
+ EXPECT_PRED_FORMAT2(IsSubstring,
+ "Too few actions specified.\n"
+ "Expected to be called between 2 and 3 times, "
+ "but has only 1 WillOnce().",
+ output);
+ b.DoB();
+}
+
+#endif // 0
+
+// Tests the semantics of ON_CALL().
+
+// Tests that the built-in default action is taken when no ON_CALL()
+// is specified.
+TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCall) {
+ MockB b;
+ EXPECT_CALL(b, DoB());
+
+ EXPECT_EQ(0, b.DoB());
+}
+
+// Tests that the built-in default action is taken when no ON_CALL()
+// matches the invocation.
+TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCallMatches) {
+ MockB b;
+ ON_CALL(b, DoB(1))
+ .WillByDefault(Return(1));
+ EXPECT_CALL(b, DoB(_));
+
+ EXPECT_EQ(0, b.DoB(2));
+}
+
+// Tests that the last matching ON_CALL() action is taken.
+TEST(OnCallTest, PicksLastMatchingOnCall) {
+ MockB b;
+ ON_CALL(b, DoB(_))
+ .WillByDefault(Return(3));
+ ON_CALL(b, DoB(2))
+ .WillByDefault(Return(2));
+ ON_CALL(b, DoB(1))
+ .WillByDefault(Return(1));
+ EXPECT_CALL(b, DoB(_));
+
+ EXPECT_EQ(2, b.DoB(2));
+}
+
+// Tests the semantics of EXPECT_CALL().
+
+// Tests that any call is allowed when no EXPECT_CALL() is specified.
+TEST(ExpectCallTest, AllowsAnyCallWhenNoSpec) {
+ MockB b;
+ EXPECT_CALL(b, DoB());
+ // There is no expectation on DoB(int).
+
+ b.DoB();
+
+ // DoB(int) can be called any number of times.
+ b.DoB(1);
+ b.DoB(2);
+}
+
+// Tests that the last matching EXPECT_CALL() fires.
+TEST(ExpectCallTest, PicksLastMatchingExpectCall) {
+ MockB b;
+ EXPECT_CALL(b, DoB(_))
+ .WillRepeatedly(Return(2));
+ EXPECT_CALL(b, DoB(1))
+ .WillRepeatedly(Return(1));
+
+ EXPECT_EQ(1, b.DoB(1));
+}
+
+// Tests lower-bound violation.
+TEST(ExpectCallTest, CatchesTooFewCalls) {
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ MockB b;
+ EXPECT_CALL(b, DoB(5))
+ .Times(AtLeast(2));
+
+ b.DoB(5);
+ }, "Actual function call count doesn't match this expectation.\n"
+ " Expected: to be called at least twice\n"
+ " Actual: called once - unsatisfied and active");
+}
+
+// Tests that the cardinality can be inferred when no Times(...) is
+// specified.
+TEST(ExpectCallTest, InfersCardinalityWhenThereIsNoWillRepeatedly) {
+ {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ }
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ }, "to be called twice");
+
+ { // NOLINT
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ EXPECT_NONFATAL_FAILURE(b.DoB(), "to be called twice");
+ }
+}
+
+TEST(ExpectCallTest, InfersCardinality1WhenThereIsWillRepeatedly) {
+ {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ }
+
+ { // NOLINT
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ }
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2));
+ }, "to be called at least once");
+}
+
+// Tests that the n-th action is taken for the n-th matching
+// invocation.
+TEST(ExpectCallTest, NthMatchTakesNthAction) {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillOnce(Return(2))
+ .WillOnce(Return(3));
+
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ EXPECT_EQ(3, b.DoB());
+}
+
+// TODO(wan@google.com): find a way to re-enable these tests.
+#if 0
+
+// Tests that the default action is taken when the WillOnce(...) list is
+// exhausted and there is no WillRepeatedly().
+TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) {
+ MockB b;
+ EXPECT_CALL(b, DoB(_))
+ .Times(1);
+ EXPECT_CALL(b, DoB())
+ .Times(AnyNumber())
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+
+ CaptureTestStdout();
+ EXPECT_EQ(0, b.DoB(1)); // Shouldn't generate a warning as the
+ // expectation has no action clause at all.
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ const string& output1 = GetCapturedTestStdout();
+ EXPECT_EQ("", output1);
+
+ CaptureTestStdout();
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB());
+ const string& output2 = GetCapturedTestStdout();
+ EXPECT_PRED2(RE::PartialMatch, output2,
+ "Actions ran out\\.\n"
+ "Called 3 times, but only 2 WillOnce\\(\\)s are specified - "
+ "returning default value\\.");
+ EXPECT_PRED2(RE::PartialMatch, output2,
+ "Actions ran out\\.\n"
+ "Called 4 times, but only 2 WillOnce\\(\\)s are specified - "
+ "returning default value\\.");
+}
+
+#endif // 0
+
+// Tests that the WillRepeatedly() action is taken when the WillOnce(...)
+// list is exhausted.
+TEST(ExpectCallTest, TakesRepeatedActionWhenWillListIsExhausted) {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1))
+ .WillRepeatedly(Return(2));
+
+ EXPECT_EQ(1, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+ EXPECT_EQ(2, b.DoB());
+}
+
+// Tests that an uninteresting call performs the default action.
+TEST(UninterestingCallTest, DoesDefaultAction) {
+ // When there is an ON_CALL() statement, the action specified by it
+ // should be taken.
+ MockA a;
+ ON_CALL(a, Binary(_, _))
+ .WillByDefault(Return(true));
+ EXPECT_TRUE(a.Binary(1, 2));
+
+ // When there is no ON_CALL(), the default value for the return type
+ // should be returned.
+ MockB b;
+ EXPECT_EQ(0, b.DoB());
+}
+
+// Tests that an unexpected call performs the default action.
+TEST(UnexpectedCallTest, DoesDefaultAction) {
+ // When there is an ON_CALL() statement, the action specified by it
+ // should be taken.
+ MockA a;
+ ON_CALL(a, Binary(_, _))
+ .WillByDefault(Return(true));
+ EXPECT_CALL(a, Binary(0, 0));
+ a.Binary(0, 0);
+ bool result = false;
+ EXPECT_NONFATAL_FAILURE(result = a.Binary(1, 2),
+ "Unexpected mock function call");
+ EXPECT_TRUE(result);
+
+ // When there is no ON_CALL(), the default value for the return type
+ // should be returned.
+ MockB b;
+ EXPECT_CALL(b, DoB(0))
+ .Times(0);
+ int n = -1;
+ EXPECT_NONFATAL_FAILURE(n = b.DoB(1),
+ "Unexpected mock function call");
+ EXPECT_EQ(0, n);
+}
+
+// Tests that when an unexpected void function generates the right
+// failure message.
+TEST(UnexpectedCallTest, GeneratesFailureForVoidFunction) {
+ // First, tests the message when there is only one EXPECT_CALL().
+ MockA a1;
+ EXPECT_CALL(a1, DoA(1));
+ a1.DoA(1);
+ // Ideally we should match the failure message against a regex, but
+ // EXPECT_NONFATAL_FAILURE doesn't support that, so we test for
+ // multiple sub-strings instead.
+ EXPECT_NONFATAL_FAILURE(
+ a1.DoA(9),
+ "Unexpected mock function call - returning directly.\n"
+ " Function call: DoA(9)\n"
+ "Google Mock tried the following 1 expectation, but it didn't match:");
+ EXPECT_NONFATAL_FAILURE(
+ a1.DoA(9),
+ " Expected arg #0: is equal to 1\n"
+ " Actual: 9\n"
+ " Expected: to be called once\n"
+ " Actual: called once - saturated and active");
+
+ // Next, tests the message when there are more than one EXPECT_CALL().
+ MockA a2;
+ EXPECT_CALL(a2, DoA(1));
+ EXPECT_CALL(a2, DoA(3));
+ a2.DoA(1);
+ EXPECT_NONFATAL_FAILURE(
+ a2.DoA(2),
+ "Unexpected mock function call - returning directly.\n"
+ " Function call: DoA(2)\n"
+ "Google Mock tried the following 2 expectations, but none matched:");
+ EXPECT_NONFATAL_FAILURE(
+ a2.DoA(2),
+ "tried expectation #0\n"
+ " Expected arg #0: is equal to 1\n"
+ " Actual: 2\n"
+ " Expected: to be called once\n"
+ " Actual: called once - saturated and active");
+ EXPECT_NONFATAL_FAILURE(
+ a2.DoA(2),
+ "tried expectation #1\n"
+ " Expected arg #0: is equal to 3\n"
+ " Actual: 2\n"
+ " Expected: to be called once\n"
+ " Actual: never called - unsatisfied and active");
+ a2.DoA(3);
+}
+
+// Tests that an unexpected non-void function generates the right
+// failure message.
+TEST(UnexpectedCallTest, GeneartesFailureForNonVoidFunction) {
+ MockB b1;
+ EXPECT_CALL(b1, DoB(1));
+ b1.DoB(1);
+ EXPECT_NONFATAL_FAILURE(
+ b1.DoB(2),
+ "Unexpected mock function call - returning default value.\n"
+ " Function call: DoB(2)\n"
+ " Returns: 0\n"
+ "Google Mock tried the following 1 expectation, but it didn't match:");
+ EXPECT_NONFATAL_FAILURE(
+ b1.DoB(2),
+ " Expected arg #0: is equal to 1\n"
+ " Actual: 2\n"
+ " Expected: to be called once\n"
+ " Actual: called once - saturated and active");
+}
+
+// Tests that Google Mock explains that an retired expectation doesn't
+// match the call.
+TEST(UnexpectedCallTest, RetiredExpectation) {
+ MockB b;
+ EXPECT_CALL(b, DoB(1))
+ .RetiresOnSaturation();
+
+ b.DoB(1);
+ EXPECT_NONFATAL_FAILURE(
+ b.DoB(1),
+ " Expected: the expectation is active\n"
+ " Actual: it is retired");
+}
+
+// Tests that Google Mock explains that an expectation that doesn't
+// match the arguments doesn't match the call.
+TEST(UnexpectedCallTest, UnmatchedArguments) {
+ MockB b;
+ EXPECT_CALL(b, DoB(1));
+
+ EXPECT_NONFATAL_FAILURE(
+ b.DoB(2),
+ " Expected arg #0: is equal to 1\n"
+ " Actual: 2\n");
+ b.DoB(1);
+}
+
+#ifdef GMOCK_HAS_REGEX
+
+// Tests that Google Mock explains that an expectation with
+// unsatisfied pre-requisites doesn't match the call.
+TEST(UnexpectedCallTest, UnsatisifiedPrerequisites) {
+ Sequence s1, s2;
+ MockB b;
+ EXPECT_CALL(b, DoB(1))
+ .InSequence(s1);
+ EXPECT_CALL(b, DoB(2))
+ .Times(AnyNumber())
+ .InSequence(s1);
+ EXPECT_CALL(b, DoB(3))
+ .InSequence(s2);
+ EXPECT_CALL(b, DoB(4))
+ .InSequence(s1, s2);
+
+ ::testing::TestPartResultArray failures;
+ {
+ ::testing::ScopedFakeTestPartResultReporter reporter(&failures);
+ b.DoB(4);
+ // Now 'failures' contains the Google Test failures generated by
+ // the above statement.
+ }
+
+ // There should be one non-fatal failure.
+ ASSERT_EQ(1, failures.size());
+ const ::testing::TestPartResult& r = failures.GetTestPartResult(0);
+ EXPECT_EQ(::testing::TPRT_NONFATAL_FAILURE, r.type());
+
+ // Verifies that the failure message contains the two unsatisfied
+ // pre-requisites but not the satisfied one.
+ const char* const pattern =
+#if GMOCK_USES_PCRE
+ // PCRE has trouble using (.|\n) to match any character, but
+ // supports the (?s) prefix for using . to match any character.
+ "(?s)the following immediate pre-requisites are not satisfied:\n"
+ ".*: pre-requisite #0\n"
+ ".*: pre-requisite #1";
+#else
+ // POSIX RE doesn't understand the (?s) prefix, but has no trouble
+ // with (.|\n).
+ "the following immediate pre-requisites are not satisfied:\n"
+ "(.|\n)*: pre-requisite #0\n"
+ "(.|\n)*: pre-requisite #1";
+#endif // GMOCK_USES_PCRE
+
+ EXPECT_TRUE(
+ ::testing::internal::RE::PartialMatch(r.message(), pattern))
+ << " where the message is " << r.message();
+ b.DoB(1);
+ b.DoB(3);
+ b.DoB(4);
+}
+
+#endif // GMOCK_HAS_REGEX
+
+// Tests that an excessive call (one whose arguments match the
+// matchers but is called too many times) performs the default action.
+TEST(ExcessiveCallTest, DoesDefaultAction) {
+ // When there is an ON_CALL() statement, the action specified by it
+ // should be taken.
+ MockA a;
+ ON_CALL(a, Binary(_, _))
+ .WillByDefault(Return(true));
+ EXPECT_CALL(a, Binary(0, 0));
+ a.Binary(0, 0);
+ bool result = false;
+ EXPECT_NONFATAL_FAILURE(result = a.Binary(0, 0),
+ "Mock function called more times than expected");
+ EXPECT_TRUE(result);
+
+ // When there is no ON_CALL(), the default value for the return type
+ // should be returned.
+ MockB b;
+ EXPECT_CALL(b, DoB(0))
+ .Times(0);
+ int n = -1;
+ EXPECT_NONFATAL_FAILURE(n = b.DoB(0),
+ "Mock function called more times than expected");
+ EXPECT_EQ(0, n);
+}
+
+// Tests that when a void function is called too many times,
+// the failure message contains the argument values.
+TEST(ExcessiveCallTest, GeneratesFailureForVoidFunction) {
+ MockA a;
+ EXPECT_CALL(a, DoA(_))
+ .Times(0);
+ EXPECT_NONFATAL_FAILURE(
+ a.DoA(9),
+ "Mock function called more times than expected - returning directly.\n"
+ " Function call: DoA(9)\n"
+ " Expected: to be never called\n"
+ " Actual: called once - over-saturated and active");
+}
+
+// Tests that when a non-void function is called too many times, the
+// failure message contains the argument values and the return value.
+TEST(ExcessiveCallTest, GeneratesFailureForNonVoidFunction) {
+ MockB b;
+ EXPECT_CALL(b, DoB(_));
+ b.DoB(1);
+ EXPECT_NONFATAL_FAILURE(
+ b.DoB(2),
+ "Mock function called more times than expected - "
+ "returning default value.\n"
+ " Function call: DoB(2)\n"
+ " Returns: 0\n"
+ " Expected: to be called once\n"
+ " Actual: called twice - over-saturated and active");
+}
+
+// Tests using sequences.
+
+TEST(InSequenceTest, AllExpectationInScopeAreInSequence) {
+ MockA a;
+ {
+ InSequence dummy;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(a, DoA(2));
+ }
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ a.DoA(2);
+ }, "Unexpected mock function call");
+
+ a.DoA(1);
+ a.DoA(2);
+}
+
+TEST(InSequenceTest, NestedInSequence) {
+ MockA a;
+ {
+ InSequence dummy;
+
+ EXPECT_CALL(a, DoA(1));
+ {
+ InSequence dummy2;
+
+ EXPECT_CALL(a, DoA(2));
+ EXPECT_CALL(a, DoA(3));
+ }
+ }
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ a.DoA(1);
+ a.DoA(3);
+ }, "Unexpected mock function call");
+
+ a.DoA(2);
+ a.DoA(3);
+}
+
+TEST(InSequenceTest, ExpectationsOutOfScopeAreNotAffected) {
+ MockA a;
+ {
+ InSequence dummy;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(a, DoA(2));
+ }
+ EXPECT_CALL(a, DoA(3));
+
+ EXPECT_NONFATAL_FAILURE({ // NOLINT
+ a.DoA(2);
+ }, "Unexpected mock function call");
+
+ a.DoA(3);
+ a.DoA(1);
+ a.DoA(2);
+}
+
+// Tests that any order is allowed when no sequence is used.
+TEST(SequenceTest, AnyOrderIsOkByDefault) {
+ {
+ MockA a;
+ MockB b;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(b, DoB())
+ .Times(AnyNumber());
+
+ a.DoA(1);
+ b.DoB();
+ }
+
+ { // NOLINT
+ MockA a;
+ MockB b;
+
+ EXPECT_CALL(a, DoA(1));
+ EXPECT_CALL(b, DoB())
+ .Times(AnyNumber());
+
+ b.DoB();
+ a.DoA(1);
+ }
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Tests that the calls must be in strict order when a complete order
+// is specified.
+TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo) {
+ MockA a;
+ Sequence s;
+
+ EXPECT_CALL(a, ReturnResult(1))
+ .InSequence(s)
+ .WillOnce(Return(Result()));
+
+ EXPECT_CALL(a, ReturnResult(2))
+ .InSequence(s)
+ .WillOnce(Return(Result()));
+
+ EXPECT_CALL(a, ReturnResult(3))
+ .InSequence(s)
+ .WillOnce(Return(Result()));
+
+ EXPECT_DEATH({ // NOLINT
+ a.ReturnResult(1);
+ a.ReturnResult(3);
+ a.ReturnResult(2);
+ }, "");
+
+ EXPECT_DEATH({ // NOLINT
+ a.ReturnResult(2);
+ a.ReturnResult(1);
+ a.ReturnResult(3);
+ }, "");
+
+ a.ReturnResult(1);
+ a.ReturnResult(2);
+ a.ReturnResult(3);
+}
+
+// Tests specifying a DAG using multiple sequences.
+TEST(SequenceTest, CallsMustConformToSpecifiedDag) {
+ MockA a;
+ MockB b;
+ Sequence x, y;
+
+ EXPECT_CALL(a, ReturnResult(1))
+ .InSequence(x)
+ .WillOnce(Return(Result()));
+
+ EXPECT_CALL(b, DoB())
+ .Times(2)
+ .InSequence(y);
+
+ EXPECT_CALL(a, ReturnResult(2))
+ .InSequence(x, y)
+ .WillRepeatedly(Return(Result()));
+
+ EXPECT_CALL(a, ReturnResult(3))
+ .InSequence(x)
+ .WillOnce(Return(Result()));
+
+ EXPECT_DEATH({ // NOLINT
+ a.ReturnResult(1);
+ b.DoB();
+ a.ReturnResult(2);
+ }, "");
+
+ EXPECT_DEATH({ // NOLINT
+ a.ReturnResult(2);
+ }, "");
+
+ EXPECT_DEATH({ // NOLINT
+ a.ReturnResult(3);
+ }, "");
+
+ EXPECT_DEATH({ // NOLINT
+ a.ReturnResult(1);
+ b.DoB();
+ b.DoB();
+ a.ReturnResult(3);
+ a.ReturnResult(2);
+ }, "");
+
+ b.DoB();
+ a.ReturnResult(1);
+ b.DoB();
+ a.ReturnResult(3);
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(SequenceTest, Retirement) {
+ MockA a;
+ Sequence s;
+
+ EXPECT_CALL(a, DoA(1))
+ .InSequence(s);
+ EXPECT_CALL(a, DoA(_))
+ .InSequence(s)
+ .RetiresOnSaturation();
+ EXPECT_CALL(a, DoA(1))
+ .InSequence(s);
+
+ a.DoA(1);
+ a.DoA(2);
+ a.DoA(1);
+}
+
+// Tests that Google Mock correctly handles calls to mock functions
+// after a mock object owning one of their pre-requisites has died.
+
+// Tests that calls that satisfy the original spec are successful.
+TEST(DeletingMockEarlyTest, Success1) {
+ MockB* const b1 = new MockB;
+ MockA* const a = new MockA;
+ MockB* const b2 = new MockB;
+
+ {
+ InSequence dummy;
+ EXPECT_CALL(*b1, DoB(_))
+ .WillOnce(Return(1));
+ EXPECT_CALL(*a, Binary(_, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*b2, DoB(_))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(2));
+ }
+
+ EXPECT_EQ(1, b1->DoB(1));
+ delete b1;
+ // a's pre-requisite has died.
+ EXPECT_TRUE(a->Binary(0, 1));
+ delete b2;
+ // a's successor has died.
+ EXPECT_TRUE(a->Binary(1, 2));
+ delete a;
+}
+
+// Tests that calls that satisfy the original spec are successful.
+TEST(DeletingMockEarlyTest, Success2) {
+ MockB* const b1 = new MockB;
+ MockA* const a = new MockA;
+ MockB* const b2 = new MockB;
+
+ {
+ InSequence dummy;
+ EXPECT_CALL(*b1, DoB(_))
+ .WillOnce(Return(1));
+ EXPECT_CALL(*a, Binary(_, _))
+ .Times(AnyNumber());
+ EXPECT_CALL(*b2, DoB(_))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(2));
+ }
+
+ delete a; // a is trivially satisfied.
+ EXPECT_EQ(1, b1->DoB(1));
+ EXPECT_EQ(2, b2->DoB(2));
+ delete b1;
+ delete b2;
+}
+
+// Tests that calls that violates the original spec yield failures.
+TEST(DeletingMockEarlyTest, Failure1) {
+ MockB* const b1 = new MockB;
+ MockA* const a = new MockA;
+ MockB* const b2 = new MockB;
+
+ {
+ InSequence dummy;
+ EXPECT_CALL(*b1, DoB(_))
+ .WillOnce(Return(1));
+ EXPECT_CALL(*a, Binary(_, _))
+ .Times(AnyNumber());
+ EXPECT_CALL(*b2, DoB(_))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(2));
+ }
+
+ delete a; // a is trivially satisfied.
+ EXPECT_NONFATAL_FAILURE({
+ b2->DoB(2);
+ }, "Unexpected mock function call");
+ EXPECT_EQ(1, b1->DoB(1));
+ delete b1;
+ delete b2;
+}
+
+// Tests that calls that violates the original spec yield failures.
+TEST(DeletingMockEarlyTest, Failure2) {
+ MockB* const b1 = new MockB;
+ MockA* const a = new MockA;
+ MockB* const b2 = new MockB;
+
+ {
+ InSequence dummy;
+ EXPECT_CALL(*b1, DoB(_));
+ EXPECT_CALL(*a, Binary(_, _))
+ .Times(AnyNumber());
+ EXPECT_CALL(*b2, DoB(_))
+ .Times(AnyNumber());
+ }
+
+ EXPECT_NONFATAL_FAILURE(delete b1,
+ "Actual: never called");
+ EXPECT_NONFATAL_FAILURE(a->Binary(0, 1),
+ "Unexpected mock function call");
+ EXPECT_NONFATAL_FAILURE(b2->DoB(1),
+ "Unexpected mock function call");
+ delete a;
+ delete b2;
+}
+
+class EvenNumberCardinality : public CardinalityInterface {
+ public:
+ // Returns true iff call_count calls will satisfy this cardinality.
+ virtual bool IsSatisfiedByCallCount(int call_count) const {
+ return call_count % 2 == 0;
+ }
+
+ // Returns true iff call_count calls will saturate this cardinality.
+ virtual bool IsSaturatedByCallCount(int call_count) const { return false; }
+
+ // Describes self to an ostream.
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "called even number of times";
+ }
+};
+
+Cardinality EvenNumber() {
+ return Cardinality(new EvenNumberCardinality);
+}
+
+TEST(ExpectationBaseTest,
+ AllPrerequisitesAreSatisfiedWorksForNonMonotonicCardinality) {
+ MockA* a = new MockA;
+ Sequence s;
+
+ EXPECT_CALL(*a, DoA(1))
+ .Times(EvenNumber())
+ .InSequence(s);
+ EXPECT_CALL(*a, DoA(2))
+ .Times(AnyNumber())
+ .InSequence(s);
+ EXPECT_CALL(*a, DoA(3))
+ .Times(AnyNumber());
+
+ a->DoA(3);
+ a->DoA(1);
+ EXPECT_NONFATAL_FAILURE(a->DoA(2), "Unexpected mock function call");
+ EXPECT_NONFATAL_FAILURE(delete a, "to be called even number of times");
+}
+
+// The following tests verify the message generated when a mock
+// function is called.
+
+struct Printable {
+};
+
+inline void operator<<(::std::ostream& os, const Printable&) {
+ os << "Printable";
+}
+
+struct Unprintable {
+ Unprintable() : value(0) {}
+ int value;
+};
+
+class MockC {
+ public:
+ MOCK_METHOD6(VoidMethod, void(bool cond, int n, string s, void* p,
+ const Printable& x, Unprintable y));
+ MOCK_METHOD0(NonVoidMethod, int()); // NOLINT
+};
+
+// TODO(wan@google.com): find a way to re-enable these tests.
+#if 0
+
+// Tests that an uninteresting mock function call generates a warning
+// containing the stack trace.
+TEST(FunctionCallMessageTest, UninterestingCallGeneratesFyiWithStackTrace) {
+ MockC c;
+ CaptureTestStdout();
+ c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable());
+ const string& output = GetCapturedTestStdout();
+ EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", output);
+ EXPECT_PRED_FORMAT2(IsSubstring, "Stack trace:", output);
+#ifndef NDEBUG
+ // We check the stack trace content in dbg-mode only, as opt-mode
+ // may inline the call we are interested in seeing.
+
+ // Verifies that a void mock function's name appears in the stack
+ // trace.
+ EXPECT_PRED_FORMAT2(IsSubstring, "::MockC::VoidMethod(", output);
+
+ // Verifies that a non-void mock function's name appears in the
+ // stack trace.
+ CaptureTestStdout();
+ c.NonVoidMethod();
+ const string& output2 = GetCapturedTestStdout();
+ EXPECT_PRED_FORMAT2(IsSubstring, "::MockC::NonVoidMethod(", output2);
+#endif // NDEBUG
+}
+
+// Tests that an uninteresting mock function call causes the function
+// arguments and return value to be printed.
+TEST(FunctionCallMessageTest, UninterestingCallPrintsArgumentsAndReturnValue) {
+ // A non-void mock function.
+ MockB b;
+ CaptureTestStdout();
+ b.DoB();
+ const string& output1 = GetCapturedTestStdout();
+ EXPECT_PRED_FORMAT2(
+ IsSubstring,
+ "Uninteresting mock function call - returning default value.\n"
+ " Function call: DoB()\n"
+ " Returns: 0\n", output1);
+ // Makes sure the return value is printed.
+
+ // A void mock function.
+ MockC c;
+ CaptureTestStdout();
+ c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable());
+ const string& output2 = GetCapturedTestStdout();
+ EXPECT_PRED2(RE::PartialMatch, output2,
+ "Uninteresting mock function call - returning directly\\.\n"
+ " Function call: VoidMethod"
+ "\\(false, 5, \"Hi\", NULL, @0x\\w+ "
+ "Printable, 4-byte object <0000 0000>\\)");
+ // A void function has no return value to print.
+}
+
+// Tests how the --gmock_verbose flag affects Google Mock's output.
+
+class GMockVerboseFlagTest : public testing::Test {
+ public:
+ // Verifies that the given Google Mock output is correct. (When
+ // should_print is true, the output should match the given regex and
+ // contain the given function name in the stack trace. When it's
+ // false, the output should be empty.)
+ void VerifyOutput(const string& output, bool should_print,
+ const string& regex,
+ const string& function_name) {
+ if (should_print) {
+ EXPECT_PRED2(RE::PartialMatch, output, regex);
+#ifndef NDEBUG
+ // We check the stack trace content in dbg-mode only, as opt-mode
+ // may inline the call we are interested in seeing.
+ EXPECT_PRED_FORMAT2(IsSubstring, function_name, output);
+#endif // NDEBUG
+ } else {
+ EXPECT_EQ("", output);
+ }
+ }
+
+ // Tests how the flag affects expected calls.
+ void TestExpectedCall(bool should_print) {
+ MockA a;
+ EXPECT_CALL(a, DoA(5));
+ EXPECT_CALL(a, Binary(_, 1))
+ .WillOnce(Return(true));
+
+ // A void-returning function.
+ CaptureTestStdout();
+ a.DoA(5);
+ VerifyOutput(
+ GetCapturedTestStdout(),
+ should_print,
+ "Expected mock function call\\.\n"
+ " Function call: DoA\\(5\\)\n"
+ "Stack trace:",
+ "MockA::DoA");
+
+ // A non-void-returning function.
+ CaptureTestStdout();
+ a.Binary(2, 1);
+ VerifyOutput(
+ GetCapturedTestStdout(),
+ should_print,
+ "Expected mock function call\\.\n"
+ " Function call: Binary\\(2, 1\\)\n"
+ " Returns: true\n"
+ "Stack trace:",
+ "MockA::Binary");
+ }
+
+ // Tests how the flag affects uninteresting calls.
+ void TestUninterestingCall(bool should_print) {
+ MockA a;
+
+ // A void-returning function.
+ CaptureTestStdout();
+ a.DoA(5);
+ VerifyOutput(
+ GetCapturedTestStdout(),
+ should_print,
+ "\nGMOCK WARNING:\n"
+ "Uninteresting mock function call - returning directly\\.\n"
+ " Function call: DoA\\(5\\)\n"
+ "Stack trace:\n"
+ "[\\s\\S]*",
+ "MockA::DoA");
+
+ // A non-void-returning function.
+ CaptureTestStdout();
+ a.Binary(2, 1);
+ VerifyOutput(
+ GetCapturedTestStdout(),
+ should_print,
+ "\nGMOCK WARNING:\n"
+ "Uninteresting mock function call - returning default value\\.\n"
+ " Function call: Binary\\(2, 1\\)\n"
+ " Returns: false\n"
+ "Stack trace:\n"
+ "[\\s\\S]*",
+ "MockA::Binary");
+ }
+};
+
+// Tests that --gmock_verbose=info causes both expected and
+// uninteresting calls to be reported.
+TEST_F(GMockVerboseFlagTest, Info) {
+ GMOCK_FLAG(verbose) = kInfoVerbosity;
+ TestExpectedCall(true);
+ TestUninterestingCall(true);
+}
+
+// Tests that --gmock_verbose=warning causes uninteresting calls to be
+// reported.
+TEST_F(GMockVerboseFlagTest, Warning) {
+ GMOCK_FLAG(verbose) = kWarningVerbosity;
+ TestExpectedCall(false);
+ TestUninterestingCall(true);
+}
+
+// Tests that --gmock_verbose=warning causes neither expected nor
+// uninteresting calls to be reported.
+TEST_F(GMockVerboseFlagTest, Error) {
+ GMOCK_FLAG(verbose) = kErrorVerbosity;
+ TestExpectedCall(false);
+ TestUninterestingCall(false);
+}
+
+// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect
+// as --gmock_verbose=warning.
+TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) {
+ GMOCK_FLAG(verbose) = "invalid"; // Treated as "warning".
+ TestExpectedCall(false);
+ TestUninterestingCall(true);
+}
+
+#endif // 0
+
+
+// Tests that we can verify and clear a mock object's expectations
+// when none of its methods has expectations.
+TEST(VerifyAndClearExpectationsTest, NoMethodHasExpectations) {
+ MockB b;
+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b));
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can verify and clear a mock object's expectations
+// when some, but not all, of its methods have expectations *and* the
+// verification succeeds.
+TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndSucceed) {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1));
+ b.DoB();
+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b));
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can verify and clear a mock object's expectations
+// when some, but not all, of its methods have expectations *and* the
+// verification fails.
+TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndFail) {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1));
+ bool result;
+ EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClearExpectations(&b),
+ "Actual: never called");
+ ASSERT_FALSE(result);
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can verify and clear a mock object's expectations
+// when all of its methods have expectations.
+TEST(VerifyAndClearExpectationsTest, AllMethodsHaveExpectations) {
+ MockB b;
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(1));
+ EXPECT_CALL(b, DoB(_))
+ .WillOnce(Return(2));
+ b.DoB();
+ b.DoB(1);
+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b));
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can verify and clear a mock object's expectations
+// when a method has more than one expectation.
+TEST(VerifyAndClearExpectationsTest, AMethodHasManyExpectations) {
+ MockB b;
+ EXPECT_CALL(b, DoB(0))
+ .WillOnce(Return(1));
+ EXPECT_CALL(b, DoB(_))
+ .WillOnce(Return(2));
+ b.DoB(1);
+ bool result;
+ EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClearExpectations(&b),
+ "Actual: never called");
+ ASSERT_FALSE(result);
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can call VerifyAndClearExpectations() on the same
+// mock object multiple times.
+TEST(VerifyAndClearExpectationsTest, CanCallManyTimes) {
+ MockB b;
+ EXPECT_CALL(b, DoB());
+ b.DoB();
+ Mock::VerifyAndClearExpectations(&b);
+
+ EXPECT_CALL(b, DoB(_))
+ .WillOnce(Return(1));
+ b.DoB(1);
+ Mock::VerifyAndClearExpectations(&b);
+ Mock::VerifyAndClearExpectations(&b);
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can clear a mock object's default actions when none
+// of its methods has default actions.
+TEST(VerifyAndClearTest, NoMethodHasDefaultActions) {
+ MockB b;
+ // If this crashes or generates a failure, the test will catch it.
+ Mock::VerifyAndClear(&b);
+ EXPECT_EQ(0, b.DoB());
+}
+
+// Tests that we can clear a mock object's default actions when some,
+// but not all of its methods have default actions.
+TEST(VerifyAndClearTest, SomeMethodsHaveDefaultActions) {
+ MockB b;
+ ON_CALL(b, DoB())
+ .WillByDefault(Return(1));
+
+ Mock::VerifyAndClear(&b);
+
+ // Verifies that the default action of int DoB() was removed.
+ EXPECT_EQ(0, b.DoB());
+}
+
+// Tests that we can clear a mock object's default actions when all of
+// its methods have default actions.
+TEST(VerifyAndClearTest, AllMethodsHaveDefaultActions) {
+ MockB b;
+ ON_CALL(b, DoB())
+ .WillByDefault(Return(1));
+ ON_CALL(b, DoB(_))
+ .WillByDefault(Return(2));
+
+ Mock::VerifyAndClear(&b);
+
+ // Verifies that the default action of int DoB() was removed.
+ EXPECT_EQ(0, b.DoB());
+
+ // Verifies that the default action of int DoB(int) was removed.
+ EXPECT_EQ(0, b.DoB(0));
+}
+
+// Tests that we can clear a mock object's default actions when a
+// method has more than one ON_CALL() set on it.
+TEST(VerifyAndClearTest, AMethodHasManyDefaultActions) {
+ MockB b;
+ ON_CALL(b, DoB(0))
+ .WillByDefault(Return(1));
+ ON_CALL(b, DoB(_))
+ .WillByDefault(Return(2));
+
+ Mock::VerifyAndClear(&b);
+
+ // Verifies that the default actions (there are two) of int DoB(int)
+ // were removed.
+ EXPECT_EQ(0, b.DoB(0));
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can call VerifyAndClear() on a mock object multiple
+// times.
+TEST(VerifyAndClearTest, CanCallManyTimes) {
+ MockB b;
+ ON_CALL(b, DoB())
+ .WillByDefault(Return(1));
+ Mock::VerifyAndClear(&b);
+ Mock::VerifyAndClear(&b);
+
+ ON_CALL(b, DoB(_))
+ .WillByDefault(Return(1));
+ Mock::VerifyAndClear(&b);
+
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that VerifyAndClear() works when the verification succeeds.
+TEST(VerifyAndClearTest, Success) {
+ MockB b;
+ ON_CALL(b, DoB())
+ .WillByDefault(Return(1));
+ EXPECT_CALL(b, DoB(1))
+ .WillOnce(Return(2));
+
+ b.DoB();
+ b.DoB(1);
+ ASSERT_TRUE(Mock::VerifyAndClear(&b));
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that VerifyAndClear() works when the verification fails.
+TEST(VerifyAndClearTest, Failure) {
+ MockB b;
+ ON_CALL(b, DoB(_))
+ .WillByDefault(Return(1));
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(2));
+
+ b.DoB(1);
+ bool result;
+ EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClear(&b),
+ "Actual: never called");
+ ASSERT_FALSE(result);
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that VerifyAndClear() works when the default actions and
+// expectations are set on a const mock object.
+TEST(VerifyAndClearTest, Const) {
+ MockB b;
+ ON_CALL(Const(b), DoB())
+ .WillByDefault(Return(1));
+
+ EXPECT_CALL(Const(b), DoB())
+ .WillOnce(DoDefault())
+ .WillOnce(Return(2));
+
+ b.DoB();
+ b.DoB();
+ ASSERT_TRUE(Mock::VerifyAndClear(&b));
+
+ // There should be no expectations on the methods now, so we can
+ // freely call them.
+ EXPECT_EQ(0, b.DoB());
+ EXPECT_EQ(0, b.DoB(1));
+}
+
+// Tests that we can set default actions and expectations on a mock
+// object after VerifyAndClear() has been called on it.
+TEST(VerifyAndClearTest, CanSetDefaultActionsAndExpectationsAfterwards) {
+ MockB b;
+ ON_CALL(b, DoB())
+ .WillByDefault(Return(1));
+ EXPECT_CALL(b, DoB(_))
+ .WillOnce(Return(2));
+ b.DoB(1);
+
+ Mock::VerifyAndClear(&b);
+
+ EXPECT_CALL(b, DoB())
+ .WillOnce(Return(3));
+ ON_CALL(b, DoB(_))
+ .WillByDefault(Return(4));
+
+ EXPECT_EQ(3, b.DoB());
+ EXPECT_EQ(4, b.DoB(1));
+}
+
+// Tests that calling VerifyAndClear() on one mock object does not
+// affect other mock objects (either of the same type or not).
+TEST(VerifyAndClearTest, DoesNotAffectOtherMockObjects) {
+ MockA a;
+ MockB b1;
+ MockB b2;
+
+ ON_CALL(a, Binary(_, _))
+ .WillByDefault(Return(true));
+ EXPECT_CALL(a, Binary(_, _))
+ .WillOnce(DoDefault())
+ .WillOnce(Return(false));
+
+ ON_CALL(b1, DoB())
+ .WillByDefault(Return(1));
+ EXPECT_CALL(b1, DoB(_))
+ .WillOnce(Return(2));
+
+ ON_CALL(b2, DoB())
+ .WillByDefault(Return(3));
+ EXPECT_CALL(b2, DoB(_));
+
+ b2.DoB(0);
+ Mock::VerifyAndClear(&b2);
+
+ // Verifies that the default actions and expectations of a and b1
+ // are still in effect.
+ EXPECT_TRUE(a.Binary(0, 0));
+ EXPECT_FALSE(a.Binary(0, 0));
+
+ EXPECT_EQ(1, b1.DoB());
+ EXPECT_EQ(2, b1.DoB(0));
+}
+
+// Tests that a mock function's action can call a mock function
+// (either the same function or a different one) either as an explicit
+// action or as a default action without causing a dead lock. It
+// verifies that the action is not performed inside the critical
+// section.
+
+void Helper(MockC* c) {
+ c->NonVoidMethod();
+}
+
+} // namespace
diff --git a/test/gmock_link_test.cc b/test/gmock_link_test.cc
new file mode 100644
index 00000000..8a60e8bf
--- /dev/null
+++ b/test/gmock_link_test.cc
@@ -0,0 +1,37 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+// This file is for verifying that a header file defining a mock class
+// can be included in multiple translation units without causing a
+// link error. It doesn't have to actually do anything - we are only
+// checking that the test links correctly.
+
+#include "test/gmock-sample.h"
diff --git a/test/gmock_output_test.py b/test/gmock_output_test.py
new file mode 100755
index 00000000..f7f37abb
--- /dev/null
+++ b/test/gmock_output_test.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Tests the text output of Google C++ Mocking Framework.
+
+SYNOPSIS
+ gmock_output_test.py --gmock_build_dir=BUILD/DIR --gengolden
+ # where BUILD/DIR contains the built gmock_output_test_ file.
+ gmock_output_test.py --gengolden
+ gmock_output_test.py
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import gmock_test_utils
+import os
+import re
+import string
+import sys
+import unittest
+
+
+# The flag for generating the golden file
+GENGOLDEN_FLAG = '--gengolden'
+
+IS_WINDOWS = os.name == 'nt'
+
+if IS_WINDOWS:
+ PROGRAM = r'..\build.dbg\gmock_output_test_.exe'
+else:
+ PROGRAM = 'gmock_output_test_'
+
+PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
+COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0'
+GOLDEN_NAME = 'gmock_output_test_golden.txt'
+GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(),
+ GOLDEN_NAME)
+
+def ToUnixLineEnding(s):
+ """Changes all Windows/Mac line endings in s to UNIX line endings."""
+
+ return s.replace('\r\n', '\n').replace('\r', '\n')
+
+
+def RemoveReportHeaderAndFooter(output):
+ """Removes Google Test result report's header and footer from the output."""
+
+ output = re.sub(r'.*gtest_main.*\n', '', output)
+ output = re.sub(r'\[.*\d+ tests.*\n', '', output)
+ output = re.sub(r'\[.* test environment .*\n', '', output)
+ output = re.sub(r'\[=+\] \d+ tests .* ran.*', '', output)
+ output = re.sub(r'.* FAILED TESTS\n', '', output)
+ return output
+
+
+def RemoveLocations(output):
+ """Removes all file location info from a Google Test program's output.
+
+ Args:
+ output: the output of a Google Test program.
+
+ Returns:
+ output with all file location info (in the form of
+ 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or
+ 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by
+ 'FILE:#: '.
+ """
+
+ return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\:', 'FILE:#:', output)
+
+
+def NormalizeErrorMarker(output):
+ """Normalizes the error marker, which is different on Windows vs on Linux."""
+
+ return re.sub(r' error: ', ' Failure\n', output)
+
+
+def RemoveMemoryAddresses(output):
+ """Removes memory addresses from the test output."""
+
+ return re.sub(r'@\w+', '@0x#', output)
+
+
+def NormalizeOutput(output):
+ """Normalizes output (the output of gmock_output_test_.exe)."""
+
+ output = ToUnixLineEnding(output)
+ output = RemoveReportHeaderAndFooter(output)
+ output = NormalizeErrorMarker(output)
+ output = RemoveLocations(output)
+ output = RemoveMemoryAddresses(output)
+ return output
+
+
+def IterShellCommandOutput(cmd, stdin_string=None):
+ """Runs a command in a sub-process, and iterates the lines in its STDOUT.
+
+ Args:
+
+ cmd: The shell command.
+ stdin_string: The string to be fed to the STDIN of the sub-process;
+ If None, the sub-process will inherit the STDIN
+ from the parent process.
+ """
+
+ # Spawns cmd in a sub-process, and gets its standard I/O file objects.
+ stdin_file, stdout_file = os.popen2(cmd, 'b')
+
+ # If the caller didn't specify a string for STDIN, gets it from the
+ # parent process.
+ if stdin_string is None:
+ stdin_string = sys.stdin.read()
+
+ # Feeds the STDIN string to the sub-process.
+ stdin_file.write(stdin_string)
+ stdin_file.close()
+
+ while True:
+ line = stdout_file.readline()
+ if not line: # EOF
+ stdout_file.close()
+ break
+
+ yield line
+
+
+def GetShellCommandOutput(cmd, stdin_string=None):
+ """Runs a command in a sub-process, and returns its STDOUT in a string.
+
+ Args:
+
+ cmd: The shell command.
+ stdin_string: The string to be fed to the STDIN of the sub-process;
+ If None, the sub-process will inherit the STDIN
+ from the parent process.
+ """
+
+ lines = list(IterShellCommandOutput(cmd, stdin_string))
+ return string.join(lines, '')
+
+
+def GetCommandOutput(cmd):
+ """Runs a command and returns its output with all file location
+ info stripped off.
+
+ Args:
+ cmd: the shell command.
+ """
+
+ # Disables exception pop-ups on Windows.
+ os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
+ return NormalizeOutput(GetShellCommandOutput(cmd, ''))
+
+
+class GMockOutputTest(unittest.TestCase):
+ def testOutput(self):
+ output = GetCommandOutput(COMMAND)
+ golden_file = open(GOLDEN_PATH, 'rb')
+ golden = golden_file.read()
+ golden_file.close()
+
+ self.assertEquals(golden, output)
+
+
+if __name__ == '__main__':
+ if sys.argv[1:] == [GENGOLDEN_FLAG]:
+ output = GetCommandOutput(COMMAND)
+ golden_file = open(GOLDEN_PATH, 'wb')
+ golden_file.write(output)
+ golden_file.close()
+ else:
+ gmock_test_utils.Main()
diff --git a/test/gmock_output_test_.cc b/test/gmock_output_test_.cc
new file mode 100644
index 00000000..bb56b7cd
--- /dev/null
+++ b/test/gmock_output_test_.cc
@@ -0,0 +1,241 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+// Tests Google Mock's output in various scenarios. This ensures that
+// Google Mock's messages are readable and useful.
+
+#include <gmock/gmock.h>
+
+#include <stdio.h>
+#include <string>
+
+#include <gtest/gtest.h>
+
+using testing::_;
+using testing::Ge;
+using testing::InSequence;
+using testing::Ref;
+using testing::Return;
+using testing::Sequence;
+
+class MockFoo {
+ public:
+ MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
+ MOCK_METHOD2(Bar2, bool(int x, int y));
+ MOCK_METHOD2(Bar3, void(int x, int y));
+};
+
+class GMockOutputTest : public testing::Test {
+ protected:
+ MockFoo foo_;
+};
+
+TEST_F(GMockOutputTest, ExpectedCall) {
+ testing::GMOCK_FLAG(verbose) = "info";
+
+ EXPECT_CALL(foo_, Bar2(0, _));
+ foo_.Bar2(0, 0); // Expected call
+
+ testing::GMOCK_FLAG(verbose) = "warning";
+}
+
+TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
+ testing::GMOCK_FLAG(verbose) = "info";
+
+ EXPECT_CALL(foo_, Bar3(0, _));
+ foo_.Bar3(0, 0); // Expected call
+
+ testing::GMOCK_FLAG(verbose) = "warning";
+}
+
+TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
+ EXPECT_CALL(foo_, Bar2(_, _))
+ .Times(2)
+ .WillOnce(Return(false));
+ foo_.Bar2(2, 2);
+ foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out.
+}
+
+TEST_F(GMockOutputTest, UnexpectedCall) {
+ EXPECT_CALL(foo_, Bar2(0, _));
+
+ foo_.Bar2(1, 0); // Unexpected call
+ foo_.Bar2(0, 0); // Expected call
+}
+
+TEST_F(GMockOutputTest, UnexpectedCallToVoidFunction) {
+ EXPECT_CALL(foo_, Bar3(0, _));
+
+ foo_.Bar3(1, 0); // Unexpected call
+ foo_.Bar3(0, 0); // Expected call
+}
+
+TEST_F(GMockOutputTest, ExcessiveCall) {
+ EXPECT_CALL(foo_, Bar2(0, _));
+
+ foo_.Bar2(0, 0); // Expected call
+ foo_.Bar2(0, 1); // Excessive call
+}
+
+TEST_F(GMockOutputTest, ExcessiveCallToVoidFunction) {
+ EXPECT_CALL(foo_, Bar3(0, _));
+
+ foo_.Bar3(0, 0); // Expected call
+ foo_.Bar3(0, 1); // Excessive call
+}
+
+TEST_F(GMockOutputTest, UninterestingCall) {
+ foo_.Bar2(0, 1); // Uninteresting call
+}
+
+TEST_F(GMockOutputTest, UninterestingCallToVoidFunction) {
+ foo_.Bar3(0, 1); // Uninteresting call
+}
+
+TEST_F(GMockOutputTest, RetiredExpectation) {
+ EXPECT_CALL(foo_, Bar2(_, _))
+ .RetiresOnSaturation();
+ EXPECT_CALL(foo_, Bar2(0, 0));
+
+ foo_.Bar2(1, 1);
+ foo_.Bar2(1, 1); // Matches a retired expectation
+ foo_.Bar2(0, 0);
+}
+
+TEST_F(GMockOutputTest, UnsatisfiedPrerequisite) {
+ {
+ InSequence s;
+ EXPECT_CALL(foo_, Bar(_, 0, _));
+ EXPECT_CALL(foo_, Bar2(0, 0));
+ EXPECT_CALL(foo_, Bar2(1, _));
+ }
+
+ foo_.Bar2(1, 0); // Has one immediate unsatisfied pre-requisite
+ foo_.Bar("Hi", 0, 0);
+ foo_.Bar2(0, 0);
+ foo_.Bar2(1, 0);
+}
+
+TEST_F(GMockOutputTest, UnsatisfiedPrerequisites) {
+ Sequence s1, s2;
+
+ EXPECT_CALL(foo_, Bar(_, 0, _))
+ .InSequence(s1);
+ EXPECT_CALL(foo_, Bar2(0, 0))
+ .InSequence(s2);
+ EXPECT_CALL(foo_, Bar2(1, _))
+ .InSequence(s1, s2);
+
+ foo_.Bar2(1, 0); // Has two immediate unsatisfied pre-requisites
+ foo_.Bar("Hi", 0, 0);
+ foo_.Bar2(0, 0);
+ foo_.Bar2(1, 0);
+}
+
+TEST_F(GMockOutputTest, UnsatisfiedExpectation) {
+ EXPECT_CALL(foo_, Bar(_, _, _));
+ EXPECT_CALL(foo_, Bar2(0, _))
+ .Times(2);
+
+ foo_.Bar2(0, 1);
+}
+
+TEST_F(GMockOutputTest, MismatchArguments) {
+ const std::string s = "Hi";
+ EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)));
+
+ foo_.Bar("Ho", 0, -0.1); // Mismatch arguments
+ foo_.Bar(s, 0, 0);
+}
+
+TEST_F(GMockOutputTest, MismatchWithArguments) {
+ EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
+ .WithArguments(Ge());
+
+ foo_.Bar2(2, 3); // Mismatch WithArguments()
+ foo_.Bar2(2, 1);
+}
+
+TEST_F(GMockOutputTest, MismatchArgumentsAndWithArguments) {
+ EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
+ .WithArguments(Ge());
+
+ foo_.Bar2(1, 3); // Mismatch arguments and mismatch WithArguments()
+ foo_.Bar2(2, 1);
+}
+
+TEST_F(GMockOutputTest, UnexpectedCallWithDefaultAction) {
+ ON_CALL(foo_, Bar2(_, _))
+ .WillByDefault(Return(true)); // Default action #1
+ ON_CALL(foo_, Bar2(1, _))
+ .WillByDefault(Return(false)); // Default action #2
+
+ EXPECT_CALL(foo_, Bar2(2, 2));
+ foo_.Bar2(1, 0); // Unexpected call, takes default action #2.
+ foo_.Bar2(0, 0); // Unexpected call, takes default action #1.
+ foo_.Bar2(2, 2); // Expected call.
+}
+
+TEST_F(GMockOutputTest, ExcessiveCallWithDefaultAction) {
+ ON_CALL(foo_, Bar2(_, _))
+ .WillByDefault(Return(true)); // Default action #1
+ ON_CALL(foo_, Bar2(1, _))
+ .WillByDefault(Return(false)); // Default action #2
+
+ EXPECT_CALL(foo_, Bar2(2, 2));
+ EXPECT_CALL(foo_, Bar2(1, 1));
+
+ foo_.Bar2(2, 2); // Expected call.
+ foo_.Bar2(2, 2); // Excessive call, takes default action #1.
+ foo_.Bar2(1, 1); // Expected call.
+ foo_.Bar2(1, 1); // Excessive call, takes default action #2.
+}
+
+TEST_F(GMockOutputTest, UninterestingCallWithDefaultAction) {
+ ON_CALL(foo_, Bar2(_, _))
+ .WillByDefault(Return(true)); // Default action #1
+ ON_CALL(foo_, Bar2(1, _))
+ .WillByDefault(Return(false)); // Default action #2
+
+ foo_.Bar2(2, 2); // Uninteresting call, takes default action #1.
+ foo_.Bar2(1, 1); // Uninteresting call, takes default action #2.
+}
+
+TEST_F(GMockOutputTest, ExplicitActionsRunOutWithDefaultAction) {
+ ON_CALL(foo_, Bar2(_, _))
+ .WillByDefault(Return(true)); // Default action #1
+
+ EXPECT_CALL(foo_, Bar2(_, _))
+ .Times(2)
+ .WillOnce(Return(false));
+ foo_.Bar2(2, 2);
+ foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out.
+}
diff --git a/test/gmock_output_test_golden.txt b/test/gmock_output_test_golden.txt
new file mode 100644
index 00000000..374e6659
--- /dev/null
+++ b/test/gmock_output_test_golden.txt
@@ -0,0 +1,296 @@
+Running main() from gmock_main.cc
+[ RUN ] GMockOutputTest.ExpectedCall
+
+FILE:#: EXPECT_CALL(foo_, Bar2(0, _)) invoked
+Stack trace:
+
+FILE:#: Expected mock function call.
+ Function call: Bar2(0, 0)
+ Returns: false
+Stack trace:
+[ OK ] GMockOutputTest.ExpectedCall
+[ RUN ] GMockOutputTest.ExpectedCallToVoidFunction
+
+FILE:#: EXPECT_CALL(foo_, Bar3(0, _)) invoked
+Stack trace:
+
+FILE:#: Expected mock function call.
+ Function call: Bar3(0, 0)
+Stack trace:
+[ OK ] GMockOutputTest.ExpectedCallToVoidFunction
+[ RUN ] GMockOutputTest.ExplicitActionsRunOut
+
+GMOCK WARNING:
+FILE:#: Too few actions specified.
+Expected to be called twice, but has only 1 WillOnce().
+GMOCK WARNING:
+FILE:#: Actions ran out.
+Called 2 times, but only 1 WillOnce() is specified - returning default value.
+Stack trace:
+[ OK ] GMockOutputTest.ExplicitActionsRunOut
+[ RUN ] GMockOutputTest.UnexpectedCall
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar2(1, 0)
+ Returns: false
+Google Mock tried the following 1 expectation, but it didn't match:
+
+FILE:#:
+ Expected arg #0: is equal to 0
+ Actual: 1
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.UnexpectedCall
+[ RUN ] GMockOutputTest.UnexpectedCallToVoidFunction
+unknown file: Failure
+
+Unexpected mock function call - returning directly.
+ Function call: Bar3(1, 0)
+Google Mock tried the following 1 expectation, but it didn't match:
+
+FILE:#:
+ Expected arg #0: is equal to 0
+ Actual: 1
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
+[ RUN ] GMockOutputTest.ExcessiveCall
+FILE:#: Failure
+Mock function called more times than expected - returning default value.
+ Function call: Bar2(0, 1)
+ Returns: false
+ Expected: to be called once
+ Actual: called twice - over-saturated and active
+[ FAILED ] GMockOutputTest.ExcessiveCall
+[ RUN ] GMockOutputTest.ExcessiveCallToVoidFunction
+FILE:#: Failure
+Mock function called more times than expected - returning directly.
+ Function call: Bar3(0, 1)
+ Expected: to be called once
+ Actual: called twice - over-saturated and active
+[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
+[ RUN ] GMockOutputTest.UninterestingCall
+
+GMOCK WARNING:
+Uninteresting mock function call - returning default value.
+ Function call: Bar2(0, 1)
+ Returns: false
+Stack trace:
+[ OK ] GMockOutputTest.UninterestingCall
+[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
+
+GMOCK WARNING:
+Uninteresting mock function call - returning directly.
+ Function call: Bar3(0, 1)
+Stack trace:
+[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
+[ RUN ] GMockOutputTest.RetiredExpectation
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar2(1, 1)
+ Returns: false
+Google Mock tried the following 2 expectations, but none matched:
+
+FILE:#: tried expectation #0
+ Expected: the expectation is active
+ Actual: it is retired
+ Expected: to be called once
+ Actual: called once - saturated and retired
+FILE:#: tried expectation #1
+ Expected arg #0: is equal to 0
+ Actual: 1
+ Expected arg #1: is equal to 0
+ Actual: 1
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.RetiredExpectation
+[ RUN ] GMockOutputTest.UnsatisfiedPrerequisite
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar2(1, 0)
+ Returns: false
+Google Mock tried the following 2 expectations, but none matched:
+
+FILE:#: tried expectation #0
+ Expected arg #0: is equal to 0
+ Actual: 1
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+FILE:#: tried expectation #1
+ Expected: all pre-requisites are satisfied
+ Actual: the following immediate pre-requisites are not satisfied:
+FILE:#: pre-requisite #0
+ (end of pre-requisites)
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
+[ RUN ] GMockOutputTest.UnsatisfiedPrerequisites
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar2(1, 0)
+ Returns: false
+Google Mock tried the following 2 expectations, but none matched:
+
+FILE:#: tried expectation #0
+ Expected arg #0: is equal to 0
+ Actual: 1
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+FILE:#: tried expectation #1
+ Expected: all pre-requisites are satisfied
+ Actual: the following immediate pre-requisites are not satisfied:
+FILE:#: pre-requisite #0
+FILE:#: pre-requisite #1
+ (end of pre-requisites)
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
+[ RUN ] GMockOutputTest.UnsatisfiedExpectation
+FILE:#: Failure
+Actual function call count doesn't match this expectation.
+ Expected: to be called twice
+ Actual: called once - unsatisfied and active
+FILE:#: Failure
+Actual function call count doesn't match this expectation.
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
+[ RUN ] GMockOutputTest.MismatchArguments
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar(@0x# "Ho", 0, -0.1)
+ Returns: '\0'
+Google Mock tried the following 1 expectation, but it didn't match:
+
+FILE:#:
+ Expected arg #0: references the variable @0x# "Hi"
+ Actual: "Ho" (is located @0x#)
+ Expected arg #2: is greater than or equal to 0
+ Actual: -0.1
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.MismatchArguments
+[ RUN ] GMockOutputTest.MismatchWithArguments
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar2(2, 3)
+ Returns: false
+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: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.MismatchWithArguments
+[ RUN ] GMockOutputTest.MismatchArgumentsAndWithArguments
+unknown file: Failure
+
+Unexpected mock function call - returning default value.
+ Function call: Bar2(1, 3)
+ Returns: false
+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: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
+[ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction
+unknown file: Failure
+
+Unexpected mock function call - taking default action specified at:
+FILE:#:
+ Function call: Bar2(1, 0)
+ Returns: false
+Google Mock tried the following 1 expectation, but it didn't match:
+
+FILE:#:
+ Expected arg #0: is equal to 2
+ Actual: 1
+ Expected arg #1: is equal to 2
+ Actual: 0
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+unknown file: Failure
+
+Unexpected mock function call - taking default action specified at:
+FILE:#:
+ Function call: Bar2(0, 0)
+ Returns: true
+Google Mock tried the following 1 expectation, but it didn't match:
+
+FILE:#:
+ Expected arg #0: is equal to 2
+ Actual: 0
+ Expected arg #1: is equal to 2
+ Actual: 0
+ Expected: to be called once
+ Actual: never called - unsatisfied and active
+[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
+[ RUN ] GMockOutputTest.ExcessiveCallWithDefaultAction
+FILE:#: Failure
+Mock function called more times than expected - taking default action specified at:
+FILE:#:
+ Function call: Bar2(2, 2)
+ Returns: true
+ Expected: to be called once
+ Actual: called twice - over-saturated and active
+FILE:#: Failure
+Mock function called more times than expected - taking default action specified at:
+FILE:#:
+ Function call: Bar2(1, 1)
+ Returns: false
+ Expected: to be called once
+ Actual: called twice - over-saturated and active
+[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
+[ RUN ] GMockOutputTest.UninterestingCallWithDefaultAction
+
+GMOCK WARNING:
+Uninteresting mock function call - taking default action specified at:
+FILE:#:
+ Function call: Bar2(2, 2)
+ Returns: true
+Stack trace:
+
+GMOCK WARNING:
+Uninteresting mock function call - taking default action specified at:
+FILE:#:
+ Function call: Bar2(1, 1)
+ Returns: false
+Stack trace:
+[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
+[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
+
+GMOCK WARNING:
+FILE:#: Too few actions specified.
+Expected to be called twice, but has only 1 WillOnce().
+GMOCK WARNING:
+FILE:#: Actions ran out.
+Called 2 times, but only 1 WillOnce() is specified - taking default action specified at:
+FILE:#:
+Stack trace:
+[ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
+[ FAILED ] GMockOutputTest.UnexpectedCall
+[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
+[ FAILED ] GMockOutputTest.ExcessiveCall
+[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
+[ FAILED ] GMockOutputTest.RetiredExpectation
+[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
+[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
+[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
+[ FAILED ] GMockOutputTest.MismatchArguments
+[ FAILED ] GMockOutputTest.MismatchWithArguments
+[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
+[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
+[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
+
diff --git a/test/gmock_test.cc b/test/gmock_test.cc
new file mode 100644
index 00000000..63c3fe8d
--- /dev/null
+++ b/test/gmock_test.cc
@@ -0,0 +1,248 @@
+// 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: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file tests code in gmock.cc.
+
+#include <gmock/gmock.h>
+
+#include <string>
+#include <gtest/gtest.h>
+
+using testing::GMOCK_FLAG(verbose);
+using testing::InitGoogleMock;
+using testing::internal::g_init_gtest_count;
+
+// Verifies that calling InitGoogleMock() on argv results in new_argv,
+// and the gmock_verbose flag's value is set to expected_gmock_verbose.
+template <typename Char, int M, int N>
+void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
+ const ::std::string& expected_gmock_verbose) {
+ const ::std::string old_verbose = GMOCK_FLAG(verbose);
+
+ int argc = M;
+ InitGoogleMock(&argc, const_cast<Char**>(argv));
+ ASSERT_EQ(N, argc) << "The new argv has wrong number of elements.";
+
+ for (int i = 0; i < N; i++) {
+ EXPECT_STREQ(new_argv[i], argv[i]);
+ }
+
+ EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
+ GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
+}
+
+TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
+ const char* argv[] = {
+ NULL
+ };
+
+ const char* new_argv[] = {
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
+}
+
+TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
+ const char* argv[] = {
+ "foo.exe",
+ NULL
+ };
+
+ const char* new_argv[] = {
+ "foo.exe",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
+}
+
+TEST(InitGoogleMockTest, ParsesSingleFlag) {
+ const char* argv[] = {
+ "foo.exe",
+ "--gmock_verbose=info",
+ NULL
+ };
+
+ const char* new_argv[] = {
+ "foo.exe",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, "info");
+}
+
+TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
+ const char* argv[] = {
+ "foo.exe",
+ "--non_gmock_flag=blah",
+ NULL
+ };
+
+ const char* new_argv[] = {
+ "foo.exe",
+ "--non_gmock_flag=blah",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
+}
+
+TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
+ const char* argv[] = {
+ "foo.exe",
+ "--non_gmock_flag=blah",
+ "--gmock_verbose=error",
+ NULL
+ };
+
+ const char* new_argv[] = {
+ "foo.exe",
+ "--non_gmock_flag=blah",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, "error");
+}
+
+TEST(InitGoogleMockTest, CallsInitGoogleTest) {
+ const int old_init_gtest_count = g_init_gtest_count;
+ const char* argv[] = {
+ "foo.exe",
+ "--non_gmock_flag=blah",
+ "--gmock_verbose=error",
+ NULL
+ };
+
+ const char* new_argv[] = {
+ "foo.exe",
+ "--non_gmock_flag=blah",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, "error");
+ EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
+}
+
+TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
+ const wchar_t* argv[] = {
+ NULL
+ };
+
+ const wchar_t* new_argv[] = {
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
+}
+
+TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
+ const wchar_t* argv[] = {
+ L"foo.exe",
+ NULL
+ };
+
+ const wchar_t* new_argv[] = {
+ L"foo.exe",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
+}
+
+TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
+ const wchar_t* argv[] = {
+ L"foo.exe",
+ L"--gmock_verbose=info",
+ NULL
+ };
+
+ const wchar_t* new_argv[] = {
+ L"foo.exe",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, "info");
+}
+
+TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
+ const wchar_t* argv[] = {
+ L"foo.exe",
+ L"--non_gmock_flag=blah",
+ NULL
+ };
+
+ const wchar_t* new_argv[] = {
+ L"foo.exe",
+ L"--non_gmock_flag=blah",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
+}
+
+TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
+ const wchar_t* argv[] = {
+ L"foo.exe",
+ L"--non_gmock_flag=blah",
+ L"--gmock_verbose=error",
+ NULL
+ };
+
+ const wchar_t* new_argv[] = {
+ L"foo.exe",
+ L"--non_gmock_flag=blah",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, "error");
+}
+
+TEST(WideInitGoogleMockTest, CallsInitGoogleTest) {
+ const int old_init_gtest_count = g_init_gtest_count;
+ const wchar_t* argv[] = {
+ L"foo.exe",
+ L"--non_gmock_flag=blah",
+ L"--gmock_verbose=error",
+ NULL
+ };
+
+ const wchar_t* new_argv[] = {
+ L"foo.exe",
+ L"--non_gmock_flag=blah",
+ NULL
+ };
+
+ TestInitGoogleMock(argv, new_argv, "error");
+ EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
+}
diff --git a/test/gmock_test_utils.py b/test/gmock_test_utils.py
new file mode 100755
index 00000000..4c09e39d
--- /dev/null
+++ b/test/gmock_test_utils.py
@@ -0,0 +1,126 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2006, 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.
+
+"""Unit test utilities for Google C++ Mocking Framework."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import sys
+import unittest
+
+
+# Initially maps a flag to its default value. After
+# _ParseAndStripGMockFlags() is called, maps a flag to its actual
+# value.
+_flag_map = {'gmock_source_dir': os.path.dirname(sys.argv[0]),
+ 'gmock_build_dir': os.path.dirname(sys.argv[0])}
+_gmock_flags_are_parsed = False
+
+
+def _ParseAndStripGMockFlags(argv):
+ """Parses and strips Google Test flags from argv. This is idempotent."""
+
+ global _gmock_flags_are_parsed
+ if _gmock_flags_are_parsed:
+ return
+
+ _gmock_flags_are_parsed = True
+ for flag in _flag_map:
+ # The environment variable overrides the default value.
+ if flag.upper() in os.environ:
+ _flag_map[flag] = os.environ[flag.upper()]
+
+ # The command line flag overrides the environment variable.
+ i = 1 # Skips the program name.
+ while i < len(argv):
+ prefix = '--' + flag + '='
+ if argv[i].startswith(prefix):
+ _flag_map[flag] = argv[i][len(prefix):]
+ del argv[i]
+ break
+ else:
+ # We don't increment i in case we just found a --gmock_* flag
+ # and removed it from argv.
+ i += 1
+
+
+def GetFlag(flag):
+ """Returns the value of the given flag."""
+
+ # In case GetFlag() is called before Main(), we always call
+ # _ParseAndStripGMockFlags() here to make sure the --gmock_* flags
+ # are parsed.
+ _ParseAndStripGMockFlags(sys.argv)
+
+ return _flag_map[flag]
+
+
+def GetSourceDir():
+ """Returns the absolute path of the directory where the .py files are."""
+
+ return os.path.abspath(GetFlag('gmock_source_dir'))
+
+
+def GetBuildDir():
+ """Returns the absolute path of the directory where the test binaries are."""
+
+ return os.path.abspath(GetFlag('gmock_build_dir'))
+
+
+def GetExitStatus(exit_code):
+ """Returns the argument to exit(), or -1 if exit() wasn't called.
+
+ Args:
+ exit_code: the result value of os.system(command).
+ """
+
+ if os.name == 'nt':
+ # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns
+ # the argument to exit() directly.
+ return exit_code
+ else:
+ # On Unix, os.WEXITSTATUS() must be used to extract the exit status
+ # from the result of os.system().
+ if os.WIFEXITED(exit_code):
+ return os.WEXITSTATUS(exit_code)
+ else:
+ return -1
+
+
+def Main():
+ """Runs the unit test."""
+
+ # We must call _ParseAndStripGMockFlags() before calling
+ # unittest.main(). Otherwise the latter will be confused by the
+ # --gmock_* flags.
+ _ParseAndStripGMockFlags(sys.argv)
+ unittest.main()