Commit e35fdd93 authored by shiqian's avatar shiqian
Browse files

Initial drop of Google Mock. The files are incomplete and thus may not build correctly yet.

parents
Changes for 1.0.0:
* Initial Open Source release of Google Mock
# 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>
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.
# 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.
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!
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
// 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_
// 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_
// 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_
$$ -*- 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_
// 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_
$$ -*- 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_
// 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_
$$ -*- 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_
// 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_
$$ -*- 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_
// 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_
// 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_
// 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_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment