mirror of
https://github.com/google/googletest.git
synced 2024-12-27 02:01:25 +08:00
Initial drop of Google Mock. The files are incomplete and thus may not build correctly yet.
This commit is contained in:
commit
e35fdd936d
3
CHANGES
Normal file
3
CHANGES
Normal file
@ -0,0 +1,3 @@
|
||||
Changes for 1.0.0:
|
||||
|
||||
* Initial Open Source release of Google Mock
|
37
CONTRIBUTORS
Normal file
37
CONTRIBUTORS
Normal file
@ -0,0 +1,37 @@
|
||||
# This file contains a list of people who've made non-trivial
|
||||
# contribution to the Google C++ Mocking Framework project. People
|
||||
# who commit code to the project are encouraged to add their names
|
||||
# here. Please keep the list sorted by first names.
|
||||
|
||||
Benoit Sigoure <tsuna@google.com>
|
||||
Bogdan Piloca <boo@google.com>
|
||||
Chandler Carruth <chandlerc@google.com>
|
||||
Dave MacLachlan <dmaclach@gmail.com>
|
||||
David Anderson <danderson@google.com>
|
||||
Dean Sturtevant
|
||||
Gene Volovich <gv@cite.com>
|
||||
Hal Burch <gmock@hburch.com>
|
||||
Jeffrey Yasskin <jyasskin@google.com>
|
||||
Jim Keller <jimkeller@google.com>
|
||||
Joe Walnes <joe@truemesh.com>
|
||||
Jon Wray <jwray@google.com>
|
||||
Keir Mierle <mierle@gmail.com>
|
||||
Keith Ray <keith.ray@gmail.com>
|
||||
Kostya Serebryany <kcc@google.com>
|
||||
Lev Makhlis
|
||||
Mario Tanev <radix@google.com>
|
||||
Mark Paskin
|
||||
Markus Heule <markus.heule@gmail.com>
|
||||
Matthew Simmons <simmonmt@acm.org>
|
||||
Mike Bland <mbland@google.com>
|
||||
Neal Norwitz <nnorwitz@gmail.com>
|
||||
Owen Carlsen <ocarlsen@google.com>
|
||||
Paneendra Ba <paneendra@google.com>
|
||||
Paul Menage <menage@google.com>
|
||||
Piotr Kaminski <piotrk@google.com>
|
||||
Russ Rufer <russ@pentad.com>
|
||||
Takeshi Yoshino <tyoshino@google.com>
|
||||
Vadim Berman <vadimb@google.com>
|
||||
Vlad Losev <vladl@google.com>
|
||||
Wolfgang Klier <wklier@google.com>
|
||||
Zhanyong Wan <wan@google.com>
|
28
COPYING
Normal file
28
COPYING
Normal file
@ -0,0 +1,28 @@
|
||||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
181
Makefile.am
Normal file
181
Makefile.am
Normal file
@ -0,0 +1,181 @@
|
||||
# Nonstandard package files for distribution.
|
||||
EXTRA_DIST =
|
||||
|
||||
# Scripts and utilities to be installed by 'make install'.
|
||||
dist_bin_SCRIPTS = scripts/gmock_doctor.py
|
||||
|
||||
# We define the global AM_CPPFLAGS as everything we compile includes from these
|
||||
# directories.
|
||||
AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I$(srcdir)/include
|
||||
|
||||
# Build rules for libraries.
|
||||
lib_LTLIBRARIES = lib/libgmock.la lib/libgmock_main.la
|
||||
|
||||
lib_libgmock_la_SOURCES = src/gmock.cc \
|
||||
src/gmock-cardinalities.cc \
|
||||
src/gmock-internal-utils.cc \
|
||||
src/gmock-matchers.cc \
|
||||
src/gmock-printers.cc \
|
||||
src/gmock-spec-builders.cc
|
||||
|
||||
pkginclude_HEADERS = include/gmock/gmock.h \
|
||||
include/gmock/gmock-actions.h \
|
||||
include/gmock/gmock-cardinalities.h \
|
||||
include/gmock/gmock-generated-actions.h \
|
||||
include/gmock/gmock-generated-function-mockers.h \
|
||||
include/gmock/gmock-generated-matchers.h \
|
||||
include/gmock/gmock-generated-nice-strict.h \
|
||||
include/gmock/gmock-matchers.h \
|
||||
include/gmock/gmock-printers.h \
|
||||
include/gmock/gmock-spec-builders.h
|
||||
|
||||
pkginclude_internaldir = $(pkgincludedir)/internal
|
||||
pkginclude_internal_HEADERS = \
|
||||
include/gmock/internal/gmock-generated-internal-utils.h \
|
||||
include/gmock/internal/gmock-internal-utils.h \
|
||||
include/gmock/internal/gmock-port.h
|
||||
|
||||
lib_libgmock_main_la_SOURCES = src/gmock_main.cc
|
||||
lib_libgmock_main_la_LIBADD = lib/libgmock.la
|
||||
|
||||
# Build rules for tests. Automake's naming for some of these variables isn't
|
||||
# terribly obvious, so this is a brief reference:
|
||||
#
|
||||
# TESTS -- Programs run automatically by "make check"
|
||||
# check_PROGRAMS -- Programs built by "make check" but not necessarily run
|
||||
|
||||
TESTS=
|
||||
TESTS_ENVIRONMENT = GMOCK_SOURCE_DIR="$(srcdir)/test" \
|
||||
GMOCK_BUILD_DIR="$(top_builddir)/test"
|
||||
check_PROGRAMS=
|
||||
AM_LDFLAGS = $(GTEST_LDFLAGS)
|
||||
|
||||
TESTS += test/gmock-actions_test
|
||||
check_PROGRAMS += test/gmock-actions_test
|
||||
test_gmock_actions_test_SOURCES = test/gmock-actions_test.cc
|
||||
test_gmock_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-cardinalities_test
|
||||
check_PROGRAMS += test/gmock-cardinalities_test
|
||||
test_gmock_cardinalities_test_SOURCES = test/gmock-cardinalities_test.cc
|
||||
test_gmock_cardinalities_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-actions_test
|
||||
check_PROGRAMS += test/gmock-generated-actions_test
|
||||
test_gmock_generated_actions_test_SOURCES = test/gmock-generated-actions_test.cc
|
||||
test_gmock_generated_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-function-mockers_test
|
||||
check_PROGRAMS += test/gmock-generated-function-mockers_test
|
||||
test_gmock_generated_function_mockers_test_SOURCES = \
|
||||
test/gmock-generated-function-mockers_test.cc
|
||||
test_gmock_generated_function_mockers_test_LDADD = $(GTEST_LIBS) \
|
||||
lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-internal-utils_test
|
||||
check_PROGRAMS += test/gmock-generated-internal-utils_test
|
||||
test_gmock_generated_internal_utils_test_SOURCES = \
|
||||
test/gmock-generated-internal-utils_test.cc
|
||||
test_gmock_generated_internal_utils_test_LDADD = $(GTEST_LIBS) \
|
||||
lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-generated-matchers_test
|
||||
check_PROGRAMS += test/gmock-generated-matchers_test
|
||||
test_gmock_generated_matchers_test_SOURCES = \
|
||||
test/gmock-generated-matchers_test.cc
|
||||
test_gmock_generated_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-internal-utils_test
|
||||
check_PROGRAMS += test/gmock-internal-utils_test
|
||||
test_gmock_internal_utils_test_SOURCES = test/gmock-internal-utils_test.cc
|
||||
test_gmock_internal_utils_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock_link_test
|
||||
check_PROGRAMS += test/gmock_link_test
|
||||
test_gmock_link_test_SOURCES = test/gmock_link_test.cc \
|
||||
test/gmock-sample.cc \
|
||||
test/gmock-sample.h
|
||||
test_gmock_link_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-matchers_test
|
||||
check_PROGRAMS += test/gmock-matchers_test
|
||||
test_gmock_matchers_test_SOURCES = test/gmock-matchers_test.cc
|
||||
test_gmock_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-nice-strict_test
|
||||
check_PROGRAMS += test/gmock-nice-strict_test
|
||||
test_gmock_nice_strict_test_SOURCES = test/gmock-nice-strict_test.cc
|
||||
test_gmock_nice_strict_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-port_test
|
||||
check_PROGRAMS += test/gmock-port_test
|
||||
test_gmock_port_test_SOURCES = test/gmock-port_test.cc
|
||||
test_gmock_port_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-printers_test
|
||||
check_PROGRAMS += test/gmock-printers_test
|
||||
test_gmock_printers_test_SOURCES = test/gmock-printers_test.cc
|
||||
test_gmock_printers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock-spec-builders_test
|
||||
check_PROGRAMS += test/gmock-spec-builders_test
|
||||
test_gmock_spec_builders_test_SOURCES = test/gmock-spec-builders_test.cc
|
||||
test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
TESTS += test/gmock_test
|
||||
check_PROGRAMS += test/gmock_test
|
||||
test_gmock_test_SOURCES = test/gmock_test.cc
|
||||
test_gmock_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
|
||||
# The following tests depend on the presence of a Python installation and are
|
||||
# keyed off of it. We only add them to the TESTS variable when a Python
|
||||
# interpreter is available. TODO(chandlerc@google.com): While we currently only
|
||||
# attempt to build and execute these tests if Autoconf has found Python v2.3 on
|
||||
# the system, we don't use the PYTHON variable it specified as the valid
|
||||
# interpreter. The problem is that TESTS_ENVIRONMENT is a global variable, and
|
||||
# thus we cannot distinguish between C++ unit tests and Python unit tests.
|
||||
dist_check_SCRIPTS =
|
||||
|
||||
# Python modules used by multiple Python tests below.
|
||||
dist_check_SCRIPTS += test/gmock_test_utils.py
|
||||
|
||||
check_PROGRAMS += test/gmock_output_test_
|
||||
test_gmock_output_test__SOURCES = test/gmock_output_test_.cc
|
||||
test_gmock_output_test__LDADD = $(GTEST_LIBS) lib/libgmock_main.la
|
||||
dist_check_SCRIPTS += test/gmock_output_test.py
|
||||
EXTRA_DIST += test/gmock_output_test_golden.txt
|
||||
|
||||
# Enable all the python driven tests when we can run them.
|
||||
if HAVE_PYTHON
|
||||
TESTS += test/gmock_output_test.py
|
||||
endif
|
||||
|
||||
# Nonstandard package files for distribution.
|
||||
EXTRA_DIST += \
|
||||
CHANGES \
|
||||
CONTRIBUTORS \
|
||||
make/Makefile \
|
||||
src/gmock-all.cc
|
||||
|
||||
# Pump scripts for generating Google Mock headers.
|
||||
# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
|
||||
EXTRA_DIST += include/gmock/gmock-generated-actions.h.pump \
|
||||
include/gmock/gmock-generated-function-mockers.h.pump \
|
||||
include/gmock/gmock-generated-matchers.h.pump \
|
||||
include/gmock/gmock-generated-nice-strict.h.pump \
|
||||
include/gmock/internal/gmock-generated-internal-utils.h.pump
|
||||
|
||||
# The Google Mock Generator tool from the cppclean project.
|
||||
EXTRA_DIST += \
|
||||
scripts/generator/COPYING \
|
||||
scripts/generator/README \
|
||||
scripts/generator/README.cppclean \
|
||||
scripts/generator/cpp/__init__.py \
|
||||
scripts/generator/cpp/ast.py \
|
||||
scripts/generator/cpp/gmock_class.py \
|
||||
scripts/generator/cpp/keywords.py \
|
||||
scripts/generator/cpp/tokenize.py \
|
||||
scripts/generator/cpp/utils.py \
|
||||
scripts/generator/gmock_gen.py
|
||||
|
||||
# TODO(wan@google.com): add the MSVC projects to EXTRA_DIST.
|
242
README
Normal file
242
README
Normal file
@ -0,0 +1,242 @@
|
||||
Google C++ Mocking Framework
|
||||
============================
|
||||
http://code.google.com/p/googlemock/
|
||||
|
||||
Overview
|
||||
--------
|
||||
Google's framework for writing and using C++ mock classes on Linux,
|
||||
Mac OS X, and Windows. Inspired by jMock, EasyMock, and Hamcrest, and
|
||||
designed with C++'s specifics in mind, it can help you derive better
|
||||
designs of your system and write better tests.
|
||||
|
||||
Google Mock:
|
||||
|
||||
- provides a declarative syntax for defining mocks,
|
||||
- can easily define partial (hybrid) mocks, which are a cross of real
|
||||
and mock objects,
|
||||
- handles functions of arbitrary types and overloaded functions,
|
||||
- comes with a rich set of matchers for validating function arguments,
|
||||
- uses an intuitive syntax for controlling the behavior of a mock,
|
||||
- does automatic verification of expectations (no record-and-replay
|
||||
needed),
|
||||
- allows arbitrary (partial) ordering constraints on
|
||||
function calls to be expressed,
|
||||
- lets a user extend it by defining new matchers and actions.
|
||||
- does not use exceptions, and
|
||||
- is easy to learn and use.
|
||||
|
||||
Please see the project page above for more information as well as mailing lists
|
||||
for questions, discussions, and development. There is also an IRC channel on
|
||||
OFTC (irc.oftc.net) #gtest available. Please join us!
|
||||
|
||||
Please note that code under scripts/generator/ is from the cppclean
|
||||
project (http://code.google.com/p/cppclean/) and under the Apache
|
||||
License.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
Google Mock is not a testing framework itself. Instead, it needs a
|
||||
testing framework for writing tests. Currently Google Mock only works
|
||||
with Google Test (http://code.google.com/p/googletest/), although
|
||||
eventually we plan to support other C++ testing frameworks. You can
|
||||
use either the copy of Google Test that comes with Google Mock, or a
|
||||
compatible version you already have.
|
||||
|
||||
TODO(wan@google.com): describe which Google Test versions are
|
||||
compatible with the latest Google Mock release.
|
||||
|
||||
Google Mock depends on advanced C++ features and thus requires a more
|
||||
modern compiler. The following are needed to use Google Mock:
|
||||
|
||||
### Linux Requirements ###
|
||||
These are the base requirements to build and use Google Mock from a source
|
||||
package (as described below):
|
||||
* GNU-compatible Make or "gmake"
|
||||
* POSIX-standard shell
|
||||
* POSIX(-2) Regular Expressions (regex.h)
|
||||
* gcc 4.0 or newer
|
||||
|
||||
Furthermore, if you are building Google Mock from a VCS Checkout (also
|
||||
described below), there are further requirements:
|
||||
* Automake version 1.9 or newer
|
||||
* Autoconf version 2.59 or newer
|
||||
* Libtool / Libtoolize
|
||||
* Python version 2.3 or newer
|
||||
|
||||
### Windows Requirements ###
|
||||
* Microsoft Visual C++ 8.0 SP1 or newer
|
||||
* An implementation of the tr1 C++ library (You can get it for free
|
||||
from http://www.boost.org/. We have verified that version 1.36.0
|
||||
works. One caveat is this implementation exposes a bug in Visual
|
||||
C++'s <type_info> header when exceptions are disabled. Therefore
|
||||
your project must enable exceptions for this configuration to work.)
|
||||
|
||||
### Mac OS X Requirements ###
|
||||
* Mac OS X 10.4 Tiger or newer
|
||||
* Developer Tools Installed
|
||||
|
||||
Getting the Source
|
||||
------------------
|
||||
There are two primary ways of getting Google Mock's source code: you can
|
||||
download a source release in your preferred archive format, or directly check
|
||||
out the source from a Version Control System (VCS, we use Google Code's
|
||||
Subversion hosting). The VCS checkout requires a few extra steps and some extra
|
||||
software packages on your system, but lets you track development, and make
|
||||
patches to contribute much more easily, so we highly encourage it.
|
||||
|
||||
### VCS Checkout: ###
|
||||
The first step is to select whether you want to check out the main line of
|
||||
development on Google Mock, or one of the released branches. The former will be
|
||||
much more active and have the latest features, but the latter provides much
|
||||
more stability and predictability. Choose whichever fits your needs best, and
|
||||
proceed with the following Subversion commands:
|
||||
|
||||
$ svn checkout http://googlemock.googlecode.com/svn/trunk/ gmock-svn
|
||||
|
||||
or for a release version X.Y.*'s branch:
|
||||
|
||||
$ svn checkout http://googlemock.googlecode.com/svn/branches/release-X.Y/ \
|
||||
gmock-X.Y-svn
|
||||
|
||||
Next you will need to prepare the GNU Autotools build system, if you
|
||||
are using Linux or Mac OS X. Enter the target directory of the
|
||||
checkout command you used ('gmock-svn' or 'gmock-X.Y-svn' above) and
|
||||
proceed with the following commands:
|
||||
|
||||
$ aclocal-1.9 # Where "1.9" must match the following automake command.
|
||||
$ libtoolize -c # Use "glibtoolize -c" instead on Mac OS X.
|
||||
$ autoheader
|
||||
$ automake-1.9 -ac # See Automake version requirements above.
|
||||
$ autoconf
|
||||
|
||||
While this is a bit complicated, it will most often be automatically re-run by
|
||||
your "make" invocations, so in practice you shouldn't need to worry too much.
|
||||
Once you have completed these steps, you are ready to build the library.
|
||||
|
||||
TODO(chandlerc@google.com): Update the above with instructions on
|
||||
preparing the build system for Google Test.
|
||||
|
||||
### Source Package: ###
|
||||
Google Mock is also released in source packages which can be downloaded from
|
||||
its Google Code download page[1]. Several different archive formats are
|
||||
provided, but the only difference is the tools used to manipulate them, and the
|
||||
size of the resulting file. Download whichever you are most comfortable with.
|
||||
|
||||
[1] Google Mock Downloads: http://code.google.com/p/googlemock/downloads/list
|
||||
|
||||
Once downloaded expand the archive using whichever tools you prefer for that
|
||||
type. This will always result in a new directory with the name "gmock-X.Y.Z"
|
||||
which contains all of the source code. Here are some examples in Linux:
|
||||
|
||||
$ tar -xvzf gmock-X.Y.Z.tar.gz
|
||||
$ tar -xvjf gmock-X.Y.Z.tar.bz2
|
||||
$ unzip gmock-X.Y.Z.zip
|
||||
|
||||
Building the Source
|
||||
-------------------
|
||||
### Linux and Mac OS X (without Xcode) ###
|
||||
There are two primary options for building the source at this point: build it
|
||||
inside the source code tree, or in a separate directory. We recommend building
|
||||
in a separate directory as that tends to produce both more consistent results
|
||||
and be easier to clean up should anything go wrong, but both patterns are
|
||||
supported. The only hard restriction is that while the build directory can be
|
||||
a subdirectory of the source directory, the opposite is not possible and will
|
||||
result in errors. Once you have selected where you wish to build Google Mock,
|
||||
create the directory if necessary, and enter it. The following steps apply for
|
||||
either approach by simply substituting the shell variable SRCDIR with "." for
|
||||
building inside the source directory, and the relative path to the source
|
||||
directory otherwise.
|
||||
|
||||
$ ${SRCDIR}/configure # Standard GNU configure script, --help for more info
|
||||
$ make # Standard makefile following GNU conventions
|
||||
$ make check # Builds and runs all tests - all should pass
|
||||
|
||||
Other programs will only be able to use Google Mock's functionality if you
|
||||
install it in a location which they can access, in Linux this is typically
|
||||
under '/usr/local'. The following command will install all of the Google Mock
|
||||
libraries, public headers, and utilities necessary for other programs and
|
||||
libraries to leverage it:
|
||||
|
||||
$ sudo make install # Not necessary, but allows use by other programs
|
||||
|
||||
TODO(chandlerc@google.com): This section needs to be expanded when the
|
||||
'gmock-config' script is finished and Autoconf macro's are provided (or not
|
||||
provided) in order to properly reflect the process for other programs to
|
||||
locate, include, and link against Google Mock.
|
||||
|
||||
Finally, should you need to remove Google Mock from your system after having
|
||||
installed it, run the following command, and it will back out its changes.
|
||||
However, note carefully that you must run this command on the *same* Google
|
||||
Mock build that you ran the install from, or the results are not predictable.
|
||||
If you install Google Mock on your system, and are working from a VCS checkout,
|
||||
make sure you run this *before* updating your checkout of the source in order
|
||||
to uninstall the same version which you installed.
|
||||
|
||||
$ sudo make uninstall # Must be run against the exact same build as "install"
|
||||
|
||||
TODO(chandlerc@google.com): Fixes the above instructions to match the
|
||||
actual implementation.
|
||||
|
||||
### Windows ###
|
||||
We don't have the Visual Studio project files for Google Mock ready
|
||||
yet. Please see the next two sections on how you can integrate Google
|
||||
Mock into your project's build system.
|
||||
|
||||
### Using GNU Make ###
|
||||
The make/ directory contains a Makefile that you can use to build
|
||||
Google Mock on systems where GNU make is available (e.g. Linux and Mac
|
||||
OS X). It doesn't try to build Google Mock's own tests. Instead, it
|
||||
just builds the Google Mock libraries and some sample tests. You can
|
||||
use it as a starting point for your own Makefile.
|
||||
|
||||
If the default settings are correct for your environment, the
|
||||
following commands should succeed:
|
||||
|
||||
$ cd ${SRCDIR}/make
|
||||
$ make
|
||||
$ ./gmock_test
|
||||
|
||||
If you see errors, try to tweak the contents of make/Makefile to make
|
||||
them go away. There are instructions in make/Makefile on how to do
|
||||
it.
|
||||
|
||||
### Using Your Own Build System ###
|
||||
If none of the build solutions we provide works for you, or if you
|
||||
prefer your own build system, you just need to compile
|
||||
${GTEST_SRCDIR}/src/gtest-all.cc (where GTEST_SRCDIR is the root of
|
||||
the Google Test source tree) and src/gmock-all.cc into a library and
|
||||
link your tests with it. Assuming a Linux-like system and gcc,
|
||||
something like the following will do:
|
||||
|
||||
$ cd ${SRCDIR}
|
||||
$ g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
|
||||
-c {GTEST_SRCDIR}/src/gtest-all.cc
|
||||
$ g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
|
||||
-c src/gmock-all.cc
|
||||
$ ar -rv libgmock.a gtest-all.o gmock-all.o
|
||||
$ g++ -I. -I./include -I${GTEST_SRCDIR} -I${GTEST_SRCDIR}/include \
|
||||
path/to/your_test.cc libgmock.a -o your_test
|
||||
|
||||
On Windows, you'll also need to add the include path for the boost
|
||||
headers to the compiler command line. See
|
||||
http://www.boost.org/doc/libs/1_36_0/doc/html/boost_tr1/usage.html for
|
||||
how to do it.
|
||||
|
||||
Regenerating Source Files
|
||||
-------------------------
|
||||
Some of Google Mock's source files are generated from templates (not
|
||||
in the C++ sense) using a script. A template file is named FOO.pump,
|
||||
where FOO is the name of the file it will generate. For example, the
|
||||
file include/gmock/gmock-generated-actions.h.pump is used to generate
|
||||
gmock-generated-actions.h in the same directory.
|
||||
|
||||
Normally you don't need to worry about regenerating the source files,
|
||||
unless you need to modify them (e.g. if you are working on a patch for
|
||||
Google Mock). In that case, you should modify the corresponding .pump
|
||||
files instead and run the 'pump' script (for Pump is Useful for Meta
|
||||
Programming) to regenerate them. We are still working on releasing
|
||||
the script and its documentation. If you need it now, please email
|
||||
googlemock@googlegroups.com such that we know to make it happen
|
||||
sooner.
|
||||
|
||||
Happy testing!
|
0
build-aux/.keep
Normal file
0
build-aux/.keep
Normal file
115
configure.ac
Normal file
115
configure.ac
Normal file
@ -0,0 +1,115 @@
|
||||
AC_INIT([Google C++ Mocking Framework],
|
||||
[1.0.0],
|
||||
[googlemock@googlegroups.com],
|
||||
[gmock])
|
||||
|
||||
# Provide various options to initialize the Autoconf and configure processes.
|
||||
AC_PREREQ([2.59])
|
||||
AC_CONFIG_SRCDIR([./COPYING])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([build-aux/config.h])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
|
||||
# Initialize Automake with various options. We require at least v1.9, prevent
|
||||
# pedantic complaints about package files, and enable various distribution
|
||||
# targets.
|
||||
AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects])
|
||||
|
||||
# Check for programs used in building Google Test.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_LANG([C++])
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# TODO(chandlerc@google.com): Currently we aren't running the Python tests
|
||||
# against the interpreter detected by AM_PATH_PYTHON, and so we condition
|
||||
# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's
|
||||
# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env"
|
||||
# hashbang.
|
||||
PYTHON= # We *do not* allow the user to specify a python interpreter
|
||||
AC_PATH_PROG([PYTHON],[python],[:])
|
||||
AS_IF([test "$PYTHON" != ":"],
|
||||
[AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
|
||||
AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
|
||||
|
||||
# TODO(chandlerc@google.com) Check for the necessary system headers.
|
||||
|
||||
# GoogleMock currently has hard dependencies upon GoogleTest above and beyond
|
||||
# running its own test suite, so we both provide our own version in
|
||||
# a subdirectory and provide some logic to use a custom version or a system
|
||||
# installed version.
|
||||
AC_ARG_WITH([gtest],
|
||||
[AS_HELP_STRING([--with-gtest],
|
||||
[Specifies how to find the gtest package. If no
|
||||
arguments are given, the default behavior, a
|
||||
system installed gtest will be used if present,
|
||||
and an internal version built otherwise. If a
|
||||
path is provided, the gtest built or installed at
|
||||
that prefix will be used.])],
|
||||
[],
|
||||
[with_gtest=yes])
|
||||
AS_IF([test "x$with_gtest" == "xno"],
|
||||
[AC_MSG_ERROR([
|
||||
Support for GoogleTest was explicitly disabled. Currently GoogleMock has a hard
|
||||
dependency upon GoogleTest to build, please provide a version, or allow
|
||||
GoogleMock to use any installed version and fall back upon its internal
|
||||
version.])])
|
||||
|
||||
# Setup various GTEST variables. TODO(chandlerc@google.com): When these are
|
||||
# used below, they should be used such that any pre-existing values always
|
||||
# trump values we set them to, so that they can be used to selectively override
|
||||
# details of the detection process.
|
||||
AC_ARG_VAR([GTEST_CONFIG],
|
||||
[The exact path of Google Test's 'gtest-config' script.])
|
||||
AC_ARG_VAR([GTEST_CPPFLAGS],
|
||||
[C-like preprocessor flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_CXXFLAGS],
|
||||
[C++ compile flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_LDFLAGS],
|
||||
[Linker path and option flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_LIBS],
|
||||
[Library linking flags for Google Test.])
|
||||
AC_ARG_VAR([GTEST_VERSION],
|
||||
[The version of Google Test available.])
|
||||
HAVE_BUILT_GTEST="no"
|
||||
|
||||
# TODO(chandlerc@google.com): This is arbitrary, but we will need to introduce
|
||||
# some features to the GoogleTest build system to help support GoogleMock, and
|
||||
# at that point it will become more meaningful.
|
||||
GTEST_MIN_VERSION="1.0.0"
|
||||
|
||||
# Begin filling in variables as we are able.
|
||||
AS_IF([test "x${with_gtest}" != "xyes"],
|
||||
[AS_IF([test -x "${with_gtest}/scripts/gtest-config"],
|
||||
[GTEST_CONFIG="${with_gtest}/scripts/gtest-config"],
|
||||
[GTEST_CONFIG="${with_gtest}/bin/gtest-config"])
|
||||
AS_IF([test -x "${GTEST_CONFIG}"], [],
|
||||
[AC_MSG_ERROR([
|
||||
Unable to locate either a built or installed Google Test at '${with_gtest}'.])
|
||||
])])
|
||||
|
||||
AS_IF([test -x "${GTEST_CONFIG}"], [],
|
||||
[AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])
|
||||
AS_IF([test -x "${GTEST_CONFIG}"],
|
||||
[AC_MSG_CHECKING([for Google Test with version >= ${GTEST_MIN_VERSION}])
|
||||
AS_IF([${GTEST_CONFIG} --min-version=${GTEST_MIN_VERSION}],
|
||||
[AC_MSG_RESULT([yes])
|
||||
HAVE_BUILT_GTEST="yes"],
|
||||
[AC_MSG_RESULT([no])])])
|
||||
|
||||
# TODO(chandlerc@google.com): Need to add support for passing a custom prefix
|
||||
# into the gtest-config script..
|
||||
AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"],
|
||||
[GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`
|
||||
GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`
|
||||
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
|
||||
GTEST_LIBS=`${GTEST_CONFIG} --libs`
|
||||
GTEST_VERSION=`${GTEST_CONFIG} --version`],
|
||||
[AC_MSG_ERROR([TODO(chandlerc@google.com): Need to add support for
|
||||
building the internal gtest.])])
|
||||
|
||||
# TODO(chandlerc@google.com) Check the types, structures, and other compiler
|
||||
# and architecture characteristics.
|
||||
|
||||
# Output the generated files. No further autoconf macros may be used.
|
||||
AC_OUTPUT
|
900
include/gmock/gmock-actions.h
Normal file
900
include/gmock/gmock-actions.h
Normal file
@ -0,0 +1,900 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used actions.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <errno.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement an action Foo, define:
|
||||
// 1. a class FooAction that implements the ActionInterface interface, and
|
||||
// 2. a factory function that creates an Action object from a
|
||||
// const FooAction*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Action objects can now be copied like plain values.
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class MonomorphicDoDefaultActionImpl;
|
||||
|
||||
template <typename F1, typename F2>
|
||||
class ActionAdaptor;
|
||||
|
||||
// BuiltInDefaultValue<T>::Get() returns the "built-in" default
|
||||
// value for type T, which is NULL when T is a pointer type, 0 when T
|
||||
// is a numeric type, false when T is bool, or "" when T is string or
|
||||
// std::string. For any other type T, this value is undefined and the
|
||||
// function will abort the process.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue {
|
||||
public:
|
||||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
return internal::Invalid<T>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
}
|
||||
};
|
||||
|
||||
// This partial specialization says that we use the same built-in
|
||||
// default value for T and const T.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<const T> {
|
||||
public:
|
||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||
};
|
||||
|
||||
// This partial specialization defines the default values for pointer
|
||||
// types.
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<T*> {
|
||||
public:
|
||||
static T* Get() { return NULL; }
|
||||
};
|
||||
|
||||
// The following specializations define the default values for
|
||||
// specific types we care about.
|
||||
#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(type, value) \
|
||||
template <> \
|
||||
class BuiltInDefaultValue<type> { \
|
||||
public: \
|
||||
static type Get() { return value; } \
|
||||
}
|
||||
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(void, ); // NOLINT
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(::string, "");
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
#if GTEST_HAS_STD_STRING
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(::std::string, "");
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(bool, false);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned char, '\0');
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed char, '\0');
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(char, '\0');
|
||||
|
||||
// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
|
||||
// Using them is a bad practice and not portable. So don't use them.
|
||||
//
|
||||
// Still, Google Mock is designed to work even if the user uses signed
|
||||
// wchar_t or unsigned wchar_t (obviously, assuming the compiler
|
||||
// supports them).
|
||||
//
|
||||
// To gcc,
|
||||
//
|
||||
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
|
||||
//
|
||||
// MSVC does not recognize signed wchar_t or unsigned wchar_t. It
|
||||
// treats wchar_t as a native type usually, but treats it as the same
|
||||
// as unsigned short when the compiler option /Zc:wchar_t- is
|
||||
// specified.
|
||||
//
|
||||
// Therefore we provide a default action for wchar_t when compiled
|
||||
// with gcc or _NATIVE_WCHAR_T_DEFINED is defined.
|
||||
//
|
||||
// There's no need for a default action for signed wchar_t, as that
|
||||
// type is the same as wchar_t for gcc, and invalid for MSVC.
|
||||
//
|
||||
// There's also no need for a default action for unsigned wchar_t, as
|
||||
// that type is the same as unsigned int for gcc, and invalid for
|
||||
// MSVC.
|
||||
#if defined(__GNUC__) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(wchar_t, 0U); // NOLINT
|
||||
#endif
|
||||
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned short, 0U); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed short, 0); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned int, 0U);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed int, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(unsigned long, 0UL); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(signed long, 0L); // NOLINT
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(UInt64, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(Int64, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(float, 0);
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE(double, 0);
|
||||
|
||||
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// When an unexpected function call is encountered, Google Mock will
|
||||
// let it return a default value if the user has specified one for its
|
||||
// return type, or if the return type has a built-in default value;
|
||||
// otherwise Google Mock won't know what value to return and will have
|
||||
// to abort the process.
|
||||
//
|
||||
// The DefaultValue<T> class allows a user to specify the
|
||||
// default value for a type T that is both copyable and publicly
|
||||
// destructible (i.e. anything that can be used as a function return
|
||||
// type). The usage is:
|
||||
//
|
||||
// // Sets the default value for type T to be foo.
|
||||
// DefaultValue<T>::Set(foo);
|
||||
template <typename T>
|
||||
class DefaultValue {
|
||||
public:
|
||||
// Sets the default value for type T; requires T to be
|
||||
// copy-constructable and have a public destructor.
|
||||
static void Set(T x) {
|
||||
delete value_;
|
||||
value_ = new T(x);
|
||||
}
|
||||
|
||||
// Unsets the default value for type T.
|
||||
static void Clear() {
|
||||
delete value_;
|
||||
value_ = NULL;
|
||||
}
|
||||
|
||||
// Returns true iff the user has set the default value for type T.
|
||||
static bool IsSet() { return value_ != NULL; }
|
||||
|
||||
// Returns the default value for type T if the user has set one;
|
||||
// otherwise returns the built-in default value if there is one;
|
||||
// otherwise aborts the process.
|
||||
static T Get() {
|
||||
return value_ == NULL ?
|
||||
internal::BuiltInDefaultValue<T>::Get() : *value_;
|
||||
}
|
||||
private:
|
||||
static const T* value_;
|
||||
};
|
||||
|
||||
// This partial specialization allows a user to set default values for
|
||||
// reference types.
|
||||
template <typename T>
|
||||
class DefaultValue<T&> {
|
||||
public:
|
||||
// Sets the default value for type T&.
|
||||
static void Set(T& x) { // NOLINT
|
||||
address_ = &x;
|
||||
}
|
||||
|
||||
// Unsets the default value for type T&.
|
||||
static void Clear() {
|
||||
address_ = NULL;
|
||||
}
|
||||
|
||||
// Returns true iff the user has set the default value for type T&.
|
||||
static bool IsSet() { return address_ != NULL; }
|
||||
|
||||
// Returns the default value for type T& if the user has set one;
|
||||
// otherwise returns the built-in default value if there is one;
|
||||
// otherwise aborts the process.
|
||||
static T& Get() {
|
||||
return address_ == NULL ?
|
||||
internal::BuiltInDefaultValue<T&>::Get() : *address_;
|
||||
}
|
||||
private:
|
||||
static T* address_;
|
||||
};
|
||||
|
||||
// This specialization allows DefaultValue<void>::Get() to
|
||||
// compile.
|
||||
template <>
|
||||
class DefaultValue<void> {
|
||||
public:
|
||||
static void Get() {}
|
||||
};
|
||||
|
||||
// Points to the user-set default value for type T.
|
||||
template <typename T>
|
||||
const T* DefaultValue<T>::value_ = NULL;
|
||||
|
||||
// Points to the user-set default value for type T&.
|
||||
template <typename T>
|
||||
T* DefaultValue<T&>::address_ = NULL;
|
||||
|
||||
// Implement this interface to define an action for function type F.
|
||||
template <typename F>
|
||||
class ActionInterface {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
ActionInterface() : is_do_default_(false) {}
|
||||
|
||||
virtual ~ActionInterface() {}
|
||||
|
||||
// Performs the action. This method is not const, as in general an
|
||||
// action can have side effects and be stateful. For example, a
|
||||
// get-the-next-element-from-the-collection action will need to
|
||||
// remember the current element.
|
||||
virtual Result Perform(const ArgumentTuple& args) = 0;
|
||||
|
||||
// Returns true iff this is the DoDefault() action.
|
||||
bool IsDoDefault() const { return is_do_default_; }
|
||||
private:
|
||||
template <typename Function>
|
||||
friend class internal::MonomorphicDoDefaultActionImpl;
|
||||
|
||||
// This private constructor is reserved for implementing
|
||||
// DoDefault(), the default action for a given mock function.
|
||||
explicit ActionInterface(bool is_do_default)
|
||||
: is_do_default_(is_do_default) {}
|
||||
|
||||
// True iff this action is DoDefault().
|
||||
const bool is_do_default_;
|
||||
};
|
||||
|
||||
// An Action<F> is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that represents an action to be taken when a mock function
|
||||
// of type F is called. The implementation of Action<T> is just a
|
||||
// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
|
||||
// Don't inherit from Action!
|
||||
//
|
||||
// You can view an object implementing ActionInterface<F> as a
|
||||
// concrete action (including its current state), and an Action<F>
|
||||
// object as a handle to it.
|
||||
template <typename F>
|
||||
class Action {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
// Constructs a null Action. Needed for storing Action objects in
|
||||
// STL containers.
|
||||
Action() : impl_(NULL) {}
|
||||
|
||||
// Constructs an Action from its implementation.
|
||||
explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
|
||||
|
||||
// Copy constructor.
|
||||
Action(const Action& action) : impl_(action.impl_) {}
|
||||
|
||||
// This constructor allows us to turn an Action<Func> object into an
|
||||
// Action<F>, as long as F's arguments can be implicitly converted
|
||||
// to Func's and Func's return type cann be implicitly converted to
|
||||
// F's.
|
||||
template <typename Func>
|
||||
explicit Action(const Action<Func>& action);
|
||||
|
||||
// Returns true iff this is the DoDefault() action.
|
||||
bool IsDoDefault() const { return impl_->IsDoDefault(); }
|
||||
|
||||
// Performs the action. Note that this method is const even though
|
||||
// the corresponding method in ActionInterface is not. The reason
|
||||
// is that a const Action<F> means that it cannot be re-bound to
|
||||
// another concrete action, not that the concrete action it binds to
|
||||
// cannot change state. (Think of the difference between a const
|
||||
// pointer and a pointer to const.)
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return impl_->Perform(args);
|
||||
}
|
||||
private:
|
||||
template <typename F1, typename F2>
|
||||
friend class internal::ActionAdaptor;
|
||||
|
||||
internal::linked_ptr<ActionInterface<F> > impl_;
|
||||
};
|
||||
|
||||
// The PolymorphicAction class template makes it easy to implement a
|
||||
// polymorphic action (i.e. an action that can be used in mock
|
||||
// functions of than one type, e.g. Return()).
|
||||
//
|
||||
// To define a polymorphic action, a user first provides a COPYABLE
|
||||
// implementation class that has a Perform() method template:
|
||||
//
|
||||
// class FooAction {
|
||||
// public:
|
||||
// template <typename Result, typename ArgumentTuple>
|
||||
// Result Perform(const ArgumentTuple& args) const {
|
||||
// // Processes the arguments and returns a result, using
|
||||
// // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
|
||||
// }
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// Then the user creates the polymorphic action using
|
||||
// MakePolymorphicAction(object) where object has type FooAction. See
|
||||
// the definition of Return(void) and SetArgumentPointee<N>(value) for
|
||||
// complete examples.
|
||||
template <typename Impl>
|
||||
class PolymorphicAction {
|
||||
public:
|
||||
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new MonomorphicImpl<F>(impl_));
|
||||
}
|
||||
private:
|
||||
template <typename F>
|
||||
class MonomorphicImpl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return impl_.template Perform<Result>(args);
|
||||
}
|
||||
|
||||
private:
|
||||
Impl impl_;
|
||||
};
|
||||
|
||||
Impl impl_;
|
||||
};
|
||||
|
||||
// Creates an Action from its implementation and returns it. The
|
||||
// created Action object owns the implementation.
|
||||
template <typename F>
|
||||
Action<F> MakeAction(ActionInterface<F>* impl) {
|
||||
return Action<F>(impl);
|
||||
}
|
||||
|
||||
// Creates a polymorphic action from its implementation. This is
|
||||
// easier to use than the PolymorphicAction<Impl> constructor as it
|
||||
// doesn't require you to explicitly write the template argument, e.g.
|
||||
//
|
||||
// MakePolymorphicAction(foo);
|
||||
// vs
|
||||
// PolymorphicAction<TypeOfFoo>(foo);
|
||||
template <typename Impl>
|
||||
inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
|
||||
return PolymorphicAction<Impl>(impl);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
|
||||
// and F1 are compatible.
|
||||
template <typename F1, typename F2>
|
||||
class ActionAdaptor : public ActionInterface<F1> {
|
||||
public:
|
||||
typedef typename internal::Function<F1>::Result Result;
|
||||
typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return impl_->Perform(args);
|
||||
}
|
||||
private:
|
||||
const internal::linked_ptr<ActionInterface<F2> > impl_;
|
||||
};
|
||||
|
||||
// Implements the polymorphic Return(x) action, which can be used in
|
||||
// any function that returns the type of x, regardless of the argument
|
||||
// types.
|
||||
template <typename R>
|
||||
class ReturnAction {
|
||||
public:
|
||||
// Constructs a ReturnAction object from the value to be returned.
|
||||
// 'value' is passed by value instead of by const reference in order
|
||||
// to allow Return("string literal") to compile.
|
||||
explicit ReturnAction(R value) : value_(value) {}
|
||||
|
||||
// This template type conversion operator allows Return(x) to be
|
||||
// used in ANY function that returns x's type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
// Assert statement belongs here because this is the best place to verify
|
||||
// conditions on F. It produces the clearest error messages
|
||||
// in most compilers.
|
||||
// Impl really belongs in this scope as a local class but can't
|
||||
// because MSVC produces duplicate symbols in different translation units
|
||||
// in this case. Until MS fixes that bug we put Impl into the class scope
|
||||
// and put the typedef both here (for use in assert statement) and
|
||||
// in the Impl class. But both definitions must be the same.
|
||||
typedef typename Function<F>::Result Result;
|
||||
GMOCK_COMPILE_ASSERT(!internal::is_reference<Result>::value,
|
||||
use_ReturnRef_instead_of_Return_to_return_a_reference);
|
||||
return Action<F>(new Impl<F>(value_));
|
||||
}
|
||||
private:
|
||||
// Implements the Return(x) action for a particular function type F.
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(R value) : value_(value) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple&) { return value_; }
|
||||
|
||||
private:
|
||||
R value_;
|
||||
};
|
||||
|
||||
R value_;
|
||||
};
|
||||
|
||||
// Implements the ReturnNull() action.
|
||||
class ReturnNullAction {
|
||||
public:
|
||||
// Allows ReturnNull() to be used in any pointer-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
static Result Perform(const ArgumentTuple&) {
|
||||
GMOCK_COMPILE_ASSERT(internal::is_pointer<Result>::value,
|
||||
ReturnNull_can_be_used_to_return_a_pointer_only);
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the Return() action.
|
||||
class ReturnVoidAction {
|
||||
public:
|
||||
// Allows Return() to be used in any void-returning function.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
static void Perform(const ArgumentTuple&) {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the polymorphic ReturnRef(x) action, which can be used
|
||||
// in any function that returns a reference to the type of x,
|
||||
// regardless of the argument types.
|
||||
template <typename T>
|
||||
class ReturnRefAction {
|
||||
public:
|
||||
// Constructs a ReturnRefAction object from the reference to be returned.
|
||||
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT
|
||||
|
||||
// This template type conversion operator allows ReturnRef(x) to be
|
||||
// used in ANY function that returns a reference to x's type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
typedef typename Function<F>::Result Result;
|
||||
// Asserts that the function return type is a reference. This
|
||||
// catches the user error of using ReturnRef(x) when Return(x)
|
||||
// should be used, and generates some helpful error message.
|
||||
GMOCK_COMPILE_ASSERT(internal::is_reference<Result>::value,
|
||||
use_Return_instead_of_ReturnRef_to_return_a_value);
|
||||
return Action<F>(new Impl<F>(ref_));
|
||||
}
|
||||
private:
|
||||
// Implements the ReturnRef(x) action for a particular function type F.
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(T& ref) : ref_(ref) {} // NOLINT
|
||||
|
||||
virtual Result Perform(const ArgumentTuple&) {
|
||||
return ref_;
|
||||
}
|
||||
private:
|
||||
T& ref_;
|
||||
};
|
||||
|
||||
T& ref_;
|
||||
};
|
||||
|
||||
// Implements the DoDefault() action for a particular function type F.
|
||||
template <typename F>
|
||||
class MonomorphicDoDefaultActionImpl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MonomorphicDoDefaultActionImpl() : ActionInterface<F>(true) {}
|
||||
|
||||
// For technical reasons, DoDefault() cannot be used inside a
|
||||
// composite action (e.g. DoAll(...)). It can only be used at the
|
||||
// top level in an EXPECT_CALL(). If this function is called, the
|
||||
// user must be using DoDefault() inside a composite action, and we
|
||||
// have to generate a run-time error.
|
||||
virtual Result Perform(const ArgumentTuple&) {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"You are using DoDefault() inside a composite action like "
|
||||
"DoAll() or WithArgs(). This is not supported for technical "
|
||||
"reasons. Please instead spell out the default action, or "
|
||||
"assign the default action to an Action variable and use "
|
||||
"the variable in various places.");
|
||||
return internal::Invalid<Result>();
|
||||
// The above statement will never be reached, but is required in
|
||||
// order for this function to compile.
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the polymorphic DoDefault() action.
|
||||
class DoDefaultAction {
|
||||
public:
|
||||
// This template type conversion operator allows DoDefault() to be
|
||||
// used in any function.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
return Action<F>(new MonomorphicDoDefaultActionImpl<F>);
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the Assign action to set a given pointer referent to a
|
||||
// particular value.
|
||||
template <typename T1, typename T2>
|
||||
class AssignAction {
|
||||
public:
|
||||
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple &args) const {
|
||||
*ptr_ = value_;
|
||||
}
|
||||
private:
|
||||
T1* const ptr_;
|
||||
const T2 value_;
|
||||
};
|
||||
|
||||
// Implements the SetErrnoAndReturn action to simulate return from
|
||||
// various system calls and libc functions.
|
||||
template <typename T>
|
||||
class SetErrnoAndReturnAction {
|
||||
public:
|
||||
SetErrnoAndReturnAction(int errno_value, T result)
|
||||
: errno_(errno_value),
|
||||
result_(result) {}
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple &args) const {
|
||||
errno = errno_;
|
||||
return result_;
|
||||
}
|
||||
private:
|
||||
const int errno_;
|
||||
const T result_;
|
||||
};
|
||||
|
||||
// Implements the SetArgumentPointee<N>(x) action for any function
|
||||
// whose N-th argument (0-based) is a pointer to x's type. The
|
||||
// template parameter kIsProto is true iff type A is ProtocolMessage,
|
||||
// proto2::Message, or a sub-class of those.
|
||||
template <size_t N, typename A, bool kIsProto>
|
||||
class SetArgumentPointeeAction {
|
||||
public:
|
||||
// Constructs an action that sets the variable pointed to by the
|
||||
// N-th function argument to 'value'.
|
||||
explicit SetArgumentPointeeAction(const A& value) : value_(value) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& args) const {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
*::std::tr1::get<N>(args) = value_;
|
||||
}
|
||||
|
||||
private:
|
||||
const A value_;
|
||||
};
|
||||
|
||||
template <size_t N, typename Proto>
|
||||
class SetArgumentPointeeAction<N, Proto, true> {
|
||||
public:
|
||||
// Constructs an action that sets the variable pointed to by the
|
||||
// N-th function argument to 'proto'. Both ProtocolMessage and
|
||||
// proto2::Message have the CopyFrom() method, so the same
|
||||
// implementation works for both.
|
||||
explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) {
|
||||
proto_->CopyFrom(proto);
|
||||
}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& args) const {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
::std::tr1::get<N>(args)->CopyFrom(*proto_);
|
||||
}
|
||||
private:
|
||||
const internal::linked_ptr<Proto> proto_;
|
||||
};
|
||||
|
||||
// Implements the SetArrayArgument<N>(first, last) action for any function
|
||||
// whose N-th argument (0-based) is a pointer or iterator to a type that can be
|
||||
// implicitly converted from *first.
|
||||
template <size_t N, typename InputIterator>
|
||||
class SetArrayArgumentAction {
|
||||
public:
|
||||
// Constructs an action that sets the variable pointed to by the
|
||||
// N-th function argument to 'value'.
|
||||
explicit SetArrayArgumentAction(InputIterator first, InputIterator last)
|
||||
: first_(first), last_(last) {
|
||||
}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
void Perform(const ArgumentTuple& args) const {
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
::std::copy(first_, last_, ::std::tr1::get<N>(args));
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
}
|
||||
|
||||
private:
|
||||
const InputIterator first_;
|
||||
const InputIterator last_;
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeWithoutArgsAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
|
||||
// compatible with f.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple&) { return function_impl_(); }
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
};
|
||||
|
||||
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodWithoutArgsAction {
|
||||
public:
|
||||
InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple&) const {
|
||||
return (obj_ptr_->*method_ptr_)();
|
||||
}
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
};
|
||||
|
||||
// Implements the IgnoreResult(action) action.
|
||||
template <typename A>
|
||||
class IgnoreResultAction {
|
||||
public:
|
||||
explicit IgnoreResultAction(const A& action) : action_(action) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
// Assert statement belongs here because this is the best place to verify
|
||||
// conditions on F. It produces the clearest error messages
|
||||
// in most compilers.
|
||||
// Impl really belongs in this scope as a local class but can't
|
||||
// because MSVC produces duplicate symbols in different translation units
|
||||
// in this case. Until MS fixes that bug we put Impl into the class scope
|
||||
// and put the typedef both here (for use in assert statement) and
|
||||
// in the Impl class. But both definitions must be the same.
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
|
||||
// Asserts at compile time that F returns void.
|
||||
CompileAssertTypesEqual<void, Result>();
|
||||
|
||||
return Action<F>(new Impl<F>(action_));
|
||||
}
|
||||
private:
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename internal::Function<F>::Result Result;
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(const A& action) : action_(action) {}
|
||||
|
||||
virtual void Perform(const ArgumentTuple& args) {
|
||||
// Performs the action and ignores its result.
|
||||
action_.Perform(args);
|
||||
}
|
||||
|
||||
private:
|
||||
// Type OriginalFunction is the same as F except that its return
|
||||
// type is IgnoredValue.
|
||||
typedef typename internal::Function<F>::MakeResultIgnoredValue
|
||||
OriginalFunction;
|
||||
|
||||
const Action<OriginalFunction> action_;
|
||||
};
|
||||
|
||||
const A action_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// An Unused object can be implicitly constructed from ANY value.
|
||||
// This is handy when defining actions that ignore some or all of the
|
||||
// mock function arguments. For example, given
|
||||
//
|
||||
// MOCK_METHOD3(Foo, double(const string& label, double x, double y));
|
||||
// MOCK_METHOD3(Bar, double(int index, double x, double y));
|
||||
//
|
||||
// instead of
|
||||
//
|
||||
// double DistanceToOriginWithLabel(const string& label, double x, double y) {
|
||||
// return sqrt(x*x + y*y);
|
||||
// }
|
||||
// double DistanceToOriginWithIndex(int index, double x, double y) {
|
||||
// return sqrt(x*x + y*y);
|
||||
// }
|
||||
// ...
|
||||
// EXEPCT_CALL(mock, Foo("abc", _, _))
|
||||
// .WillOnce(Invoke(DistanceToOriginWithLabel));
|
||||
// EXEPCT_CALL(mock, Bar(5, _, _))
|
||||
// .WillOnce(Invoke(DistanceToOriginWithIndex));
|
||||
//
|
||||
// you could write
|
||||
//
|
||||
// // We can declare any uninteresting argument as Unused.
|
||||
// double DistanceToOrigin(Unused, double x, double y) {
|
||||
// return sqrt(x*x + y*y);
|
||||
// }
|
||||
// ...
|
||||
// EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
// EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
|
||||
typedef internal::IgnoredValue Unused;
|
||||
|
||||
// This constructor allows us to turn an Action<From> object into an
|
||||
// Action<To>, as long as To's arguments can be implicitly converted
|
||||
// to From's and From's return type cann be implicitly converted to
|
||||
// To's.
|
||||
template <typename To>
|
||||
template <typename From>
|
||||
Action<To>::Action(const Action<From>& from)
|
||||
: impl_(new internal::ActionAdaptor<To, From>(from)) {}
|
||||
|
||||
// Creates an action that returns 'value'. 'value' is passed by value
|
||||
// instead of const reference - otherwise Return("string literal")
|
||||
// will trigger a compiler error about using array as initializer.
|
||||
template <typename R>
|
||||
internal::ReturnAction<R> Return(R value) {
|
||||
return internal::ReturnAction<R>(value);
|
||||
}
|
||||
|
||||
// Creates an action that returns NULL.
|
||||
inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {
|
||||
return MakePolymorphicAction(internal::ReturnNullAction());
|
||||
}
|
||||
|
||||
// Creates an action that returns from a void function.
|
||||
inline PolymorphicAction<internal::ReturnVoidAction> Return() {
|
||||
return MakePolymorphicAction(internal::ReturnVoidAction());
|
||||
}
|
||||
|
||||
// Creates an action that returns the reference to a variable.
|
||||
template <typename R>
|
||||
inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
|
||||
return internal::ReturnRefAction<R>(x);
|
||||
}
|
||||
|
||||
// Creates an action that does the default action for the give mock function.
|
||||
inline internal::DoDefaultAction DoDefault() {
|
||||
return internal::DoDefaultAction();
|
||||
}
|
||||
|
||||
// Creates an action that sets the variable pointed by the N-th
|
||||
// (0-based) function argument to 'value'.
|
||||
template <size_t N, typename T>
|
||||
PolymorphicAction<
|
||||
internal::SetArgumentPointeeAction<
|
||||
N, T, internal::IsAProtocolMessage<T>::value> >
|
||||
SetArgumentPointee(const T& x) {
|
||||
return MakePolymorphicAction(internal::SetArgumentPointeeAction<
|
||||
N, T, internal::IsAProtocolMessage<T>::value>(x));
|
||||
}
|
||||
|
||||
// Creates an action that sets the elements of the array pointed to by the N-th
|
||||
// (0-based) function argument, which can be either a pointer or an iterator,
|
||||
// to the values of the elements in the source range [first, last).
|
||||
template <size_t N, typename InputIterator>
|
||||
PolymorphicAction<internal::SetArrayArgumentAction<N, InputIterator> >
|
||||
SetArrayArgument(InputIterator first, InputIterator last) {
|
||||
return MakePolymorphicAction(internal::SetArrayArgumentAction<
|
||||
N, InputIterator>(first, last));
|
||||
}
|
||||
|
||||
// Creates an action that sets a pointer referent to a given value.
|
||||
template <typename T1, typename T2>
|
||||
PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) {
|
||||
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
|
||||
}
|
||||
|
||||
// Creates an action that sets errno and returns the appropriate error.
|
||||
template <typename T>
|
||||
PolymorphicAction<internal::SetErrnoAndReturnAction<T> >
|
||||
SetErrnoAndReturn(int errval, T result) {
|
||||
return MakePolymorphicAction(
|
||||
internal::SetErrnoAndReturnAction<T>(errval, result));
|
||||
}
|
||||
|
||||
// Various overloads for InvokeWithoutArgs().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with no argument.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
|
||||
InvokeWithoutArgs(FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with no argument.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
|
||||
InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
|
||||
obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// Creates an action that performs an_action and throws away its
|
||||
// result. In other words, it changes the return type of an_action to
|
||||
// void. an_action MUST NOT return void, or the code won't compile.
|
||||
template <typename A>
|
||||
inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
|
||||
return internal::IgnoreResultAction<A>(an_action);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
|
146
include/gmock/gmock-cardinalities.h
Normal file
146
include/gmock/gmock-cardinalities.h
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used cardinalities. More
|
||||
// cardinalities can be defined by the user implementing the
|
||||
// CardinalityInterface interface if necessary.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement a cardinality Foo, define:
|
||||
// 1. a class FooCardinality that implements the
|
||||
// CardinalityInterface interface, and
|
||||
// 2. a factory function that creates a Cardinality object from a
|
||||
// const FooCardinality*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return 0; }
|
||||
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
};
|
||||
|
||||
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a linked_ptr
|
||||
// to const CardinalityInterface, so copying is fairly cheap.
|
||||
// Don't inherit from Cardinality!
|
||||
class Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
bool IsSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will over-saturate this
|
||||
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||
!impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Describes self to an ostream
|
||||
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||
|
||||
// Describes the given actual call count to an ostream.
|
||||
static void DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os);
|
||||
private:
|
||||
internal::linked_ptr<const CardinalityInterface> impl_;
|
||||
};
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
Cardinality AtLeast(int n);
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
Cardinality AtMost(int n);
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
Cardinality AnyNumber();
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
Cardinality Between(int min, int max);
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
Cardinality Exactly(int n);
|
||||
|
||||
// Creates a cardinality from its implementation.
|
||||
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
||||
return Cardinality(c);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
1329
include/gmock/gmock-generated-actions.h
Normal file
1329
include/gmock/gmock-generated-actions.h
Normal file
File diff suppressed because it is too large
Load Diff
567
include/gmock/gmock-generated-actions.h.pump
Normal file
567
include/gmock/gmock-generated-actions.h.pump
Normal file
@ -0,0 +1,567 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-variadic-actions.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic actions.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
#include <gmock/gmock-actions.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
|
||||
// function or method with the unpacked values, where F is a function
|
||||
// type that takes N arguments.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
class InvokeHelper;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var types = [[$for j [[, typename A$j]]]]
|
||||
$var as = [[$for j, [[A$j]]]]
|
||||
$var args = [[$if i==0 [[]] $else [[ args]]]]
|
||||
$var import = [[$if i==0 [[]] $else [[
|
||||
using ::std::tr1::get;
|
||||
|
||||
]]]]
|
||||
$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
|
||||
template <typename R$types>
|
||||
class InvokeHelper<R, ::std::tr1::tuple<$as> > {
|
||||
public:
|
||||
template <typename Function>
|
||||
static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
|
||||
$import return function($gets);
|
||||
}
|
||||
|
||||
template <class Class, typename MethodPtr>
|
||||
static R InvokeMethod(Class* obj_ptr,
|
||||
MethodPtr method_ptr,
|
||||
const ::std::tr1::tuple<$as>&$args) {
|
||||
$import return (obj_ptr->*method_ptr)($gets);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Implements the Invoke(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. Invoke(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
||||
}
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
};
|
||||
|
||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodAction {
|
||||
public:
|
||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
||||
obj_ptr_, method_ptr_, args);
|
||||
}
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
};
|
||||
|
||||
// A ReferenceWrapper<T> object represents a reference to type T,
|
||||
// which can be either const or not. It can be explicitly converted
|
||||
// from, and implicitly converted to, a T&. Unlike a reference,
|
||||
// ReferenceWrapper<T> can be copied and can survive template type
|
||||
// inference. This is used to support by-reference arguments in the
|
||||
// InvokeArgument<N>(...) action. The idea was from "reference
|
||||
// wrappers" in tr1, which we don't have in our source tree yet.
|
||||
template <typename T>
|
||||
class ReferenceWrapper {
|
||||
public:
|
||||
// Constructs a ReferenceWrapper<T> object from a T&.
|
||||
explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
|
||||
|
||||
// Allows a ReferenceWrapper<T> object to be implicitly converted to
|
||||
// a T&.
|
||||
operator T&() const { return *pointer_; }
|
||||
private:
|
||||
T* pointer_;
|
||||
};
|
||||
|
||||
// CallableHelper has static methods for invoking "callables",
|
||||
// i.e. function pointers and functors. It uses overloading to
|
||||
// provide a uniform interface for invoking different kinds of
|
||||
// callables. In particular, you can use:
|
||||
//
|
||||
// CallableHelper<R>::Call(callable, a1, a2, ..., an)
|
||||
//
|
||||
// to invoke an n-ary callable, where R is its return type. If an
|
||||
// argument, say a2, needs to be passed by reference, you should write
|
||||
// ByRef(a2) instead of a2 in the above expression.
|
||||
template <typename R>
|
||||
class CallableHelper {
|
||||
public:
|
||||
// Calls a nullary callable.
|
||||
template <typename Function>
|
||||
static R Call(Function function) { return function(); }
|
||||
|
||||
// Calls a unary callable.
|
||||
|
||||
// We deliberately pass a1 by value instead of const reference here
|
||||
// in case it is a C-string literal. If we had declared the
|
||||
// parameter as 'const A1& a1' and write Call(function, "Hi"), the
|
||||
// compiler would've thought A1 is 'char[3]', which causes trouble
|
||||
// when you need to copy a value of type A1. By declaring the
|
||||
// parameter as 'A1 a1', the compiler will correctly infer that A1
|
||||
// is 'const char*' when it sees Call(function, "Hi").
|
||||
//
|
||||
// Since this function is defined inline, the compiler can get rid
|
||||
// of the copying of the arguments. Therefore the performance won't
|
||||
// be hurt.
|
||||
template <typename Function, typename A1>
|
||||
static R Call(Function function, A1 a1) { return function(a1); }
|
||||
|
||||
$range i 2..n
|
||||
$for i
|
||||
[[
|
||||
$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
|
||||
|
||||
// Calls a $arity callable.
|
||||
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var as = [[$for j, [[a$j]]]]
|
||||
$var typename_Ts = [[$for j, [[typename T$j]]]]
|
||||
$var Ts = [[$for j, [[T$j]]]]
|
||||
template <typename Function, $typename_As>
|
||||
static R Call(Function function, $Aas) {
|
||||
return function($as);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
}; // class CallableHelper
|
||||
|
||||
// Invokes a nullary callable argument.
|
||||
template <size_t N>
|
||||
class InvokeArgumentAction0 {
|
||||
public:
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
static Result Perform(const ArgumentTuple& args) {
|
||||
return CallableHelper<Result>::Call(::std::tr1::get<N>(args));
|
||||
}
|
||||
};
|
||||
|
||||
// Invokes a unary callable argument with the given argument.
|
||||
template <size_t N, typename A1>
|
||||
class InvokeArgumentAction1 {
|
||||
public:
|
||||
// We deliberately pass a1 by value instead of const reference here
|
||||
// in case it is a C-string literal.
|
||||
//
|
||||
// Since this function is defined inline, the compiler can get rid
|
||||
// of the copying of the arguments. Therefore the performance won't
|
||||
// be hurt.
|
||||
explicit InvokeArgumentAction1(A1 a1) : arg1_(a1) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_);
|
||||
}
|
||||
private:
|
||||
const A1 arg1_;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var args_ = [[$for j, [[arg$j[[]]_]]]]
|
||||
|
||||
// Invokes a $arity callable argument with the given arguments.
|
||||
template <size_t N, $typename_As>
|
||||
class InvokeArgumentAction$i {
|
||||
public:
|
||||
InvokeArgumentAction$i($for j, [[A$j a$j]]) :
|
||||
$for j, [[arg$j[[]]_(a$j)]] {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
$if i <= 4 [[
|
||||
|
||||
return CallableHelper<Result>::Call(::std::tr1::get<N>(args), $args_);
|
||||
|
||||
]] $else [[
|
||||
|
||||
// We extract the callable to a variable before invoking it, in
|
||||
// case it is a functor passed by value and its operator() is not
|
||||
// const.
|
||||
typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
|
||||
::std::tr1::get<N>(args);
|
||||
return function($args_);
|
||||
|
||||
]]
|
||||
}
|
||||
private:
|
||||
$for j [[
|
||||
|
||||
const A$j arg$j[[]]_;
|
||||
]]
|
||||
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// An INTERNAL macro for extracting the type of a tuple field. It's
|
||||
// subject to change without notice - DO NOT USE IN USER CODE!
|
||||
#define GMOCK_FIELD(Tuple, N) \
|
||||
typename ::std::tr1::tuple_element<N, Tuple>::type
|
||||
|
||||
$range i 1..n
|
||||
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
|
||||
// type of an n-ary function whose i-th (1-based) argument type is the
|
||||
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
|
||||
// type, and whose return type is Result. For example,
|
||||
// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
|
||||
// is int(bool, long).
|
||||
//
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
|
||||
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
|
||||
// For example,
|
||||
// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
|
||||
// ::std::tr1::make_tuple(true, 'a', 2.5))
|
||||
// returns ::std::tr1::tuple (2.5, true).
|
||||
//
|
||||
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
|
||||
// in the range [0, $n]. Duplicates are allowed and they don't have
|
||||
// to be in an ascending or descending order.
|
||||
|
||||
template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
|
||||
class SelectArgs {
|
||||
public:
|
||||
typedef Result type($for i, [[GMOCK_FIELD(ArgumentTuple, k$i)]]);
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
using ::std::tr1::get;
|
||||
return SelectedArgs($for i, [[get<k$i>(args)]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..n
|
||||
$range j1 1..i-1
|
||||
template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
$for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
|
||||
public:
|
||||
typedef Result type($for j1, [[GMOCK_FIELD(ArgumentTuple, k$j1)]]);
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
using ::std::tr1::get;
|
||||
return SelectedArgs($for j1, [[get<k$j1>(args)]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
#undef GMOCK_FIELD
|
||||
|
||||
$var ks = [[$for i, [[k$i]]]]
|
||||
|
||||
// Implements the WithArgs action.
|
||||
template <typename InnerAction, $for i, [[int k$i = -1]]>
|
||||
class WithArgsAction {
|
||||
public:
|
||||
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
typedef typename SelectArgs<Result, ArgumentTuple,
|
||||
$ks>::type
|
||||
InnerFunctionType;
|
||||
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
explicit Impl(const InnerAction& action) : action_(action) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
|
||||
}
|
||||
private:
|
||||
Action<InnerFunctionType> action_;
|
||||
};
|
||||
|
||||
return MakeAction(new Impl(action_));
|
||||
}
|
||||
private:
|
||||
const InnerAction action_;
|
||||
};
|
||||
|
||||
// Does two actions sequentially. Used for implementing the DoAll(a1,
|
||||
// a2, ...) action.
|
||||
template <typename Action1, typename Action2>
|
||||
class DoBothAction {
|
||||
public:
|
||||
DoBothAction(Action1 action1, Action2 action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
// This template type conversion operator allows DoAll(a1, ..., a_n)
|
||||
// to be used in ANY function of compatible type.
|
||||
template <typename F>
|
||||
operator Action<F>() const {
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
typedef typename Function<F>::MakeResultVoid VoidResult;
|
||||
|
||||
// Implements the DoAll(...) action for a particular function type F.
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
Impl(const Action<VoidResult>& action1, const Action<F>& action2)
|
||||
: action1_(action1), action2_(action2) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
action1_.Perform(args);
|
||||
return action2_.Perform(args);
|
||||
}
|
||||
private:
|
||||
const Action<VoidResult> action1_;
|
||||
const Action<F> action2_;
|
||||
};
|
||||
|
||||
return Action<F>(new Impl(action1_, action2_));
|
||||
}
|
||||
private:
|
||||
Action1 action1_;
|
||||
Action2 action2_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with the mock
|
||||
// function's arguments.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
||||
FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with the mock function's arguments.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||
Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// Creates a reference wrapper for the given L-value. If necessary,
|
||||
// you can explicitly specify the type of the reference. For example,
|
||||
// suppose 'derived' is an object of type Derived, ByRef(derived)
|
||||
// would wrap a Derived&. If you want to wrap a const Base& instead,
|
||||
// where Base is a base class of Derived, just write:
|
||||
//
|
||||
// ByRef<const Base>(derived)
|
||||
template <typename T>
|
||||
inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
|
||||
return internal::ReferenceWrapper<T>(l_value);
|
||||
}
|
||||
|
||||
// Various overloads for InvokeArgument<N>().
|
||||
//
|
||||
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
|
||||
// (0-based) argument, which must be a k-ary callable, of the mock
|
||||
// function, with arguments a1, a2, ..., a_k.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1. The arguments are passed by value by default. If you need to
|
||||
// pass an argument by reference, wrap it inside ByRef(). For
|
||||
// example,
|
||||
//
|
||||
// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
|
||||
//
|
||||
// passes 5 and string("Hello") by value, and passes foo by
|
||||
// reference.
|
||||
//
|
||||
// 2. If the callable takes an argument by reference but ByRef() is
|
||||
// not used, it will receive the reference to a copy of the value,
|
||||
// instead of the original value. For example, when the 0-th
|
||||
// argument of the mock function takes a const string&, the action
|
||||
//
|
||||
// InvokeArgument<0>(string("Hello"))
|
||||
//
|
||||
// makes a copy of the temporary string("Hello") object and passes a
|
||||
// reference of the copy, instead of the original temporary object,
|
||||
// to the callable. This makes it easy for a user to define an
|
||||
// InvokeArgument action from temporary values and have it performed
|
||||
// later.
|
||||
template <size_t N>
|
||||
inline PolymorphicAction<internal::InvokeArgumentAction0<N> > InvokeArgument() {
|
||||
return MakePolymorphicAction(internal::InvokeArgumentAction0<N>());
|
||||
}
|
||||
|
||||
// We deliberately pass a1 by value instead of const reference here in
|
||||
// case it is a C-string literal. If we had declared the parameter as
|
||||
// 'const A1& a1' and write InvokeArgument<0>("Hi"), the compiler
|
||||
// would've thought A1 is 'char[3]', which causes trouble as the
|
||||
// implementation needs to copy a value of type A1. By declaring the
|
||||
// parameter as 'A1 a1', the compiler will correctly infer that A1 is
|
||||
// 'const char*' when it sees InvokeArgument<0>("Hi").
|
||||
//
|
||||
// Since this function is defined inline, the compiler can get rid of
|
||||
// the copying of the arguments. Therefore the performance won't be
|
||||
// hurt.
|
||||
template <size_t N, typename A1>
|
||||
inline PolymorphicAction<internal::InvokeArgumentAction1<N, A1> >
|
||||
InvokeArgument(A1 a1) {
|
||||
return MakePolymorphicAction(internal::InvokeArgumentAction1<N, A1>(a1));
|
||||
}
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var as = [[$for j, [[a$j]]]]
|
||||
|
||||
template <size_t N, $typename_As>
|
||||
inline PolymorphicAction<internal::InvokeArgumentAction$i<N, $As> >
|
||||
InvokeArgument($Aas) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeArgumentAction$i<N, $As>($as));
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction>
|
||||
WithoutArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction>(action);
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <int k, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k>
|
||||
WithArg(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k>(action);
|
||||
}
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
// different argument lists. C++ doesn't support default arguments for
|
||||
// function templates, so we have to overload it.
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j [[int k$j, ]]typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var types = [[$for j, [[typename Action$j]]]]
|
||||
$var Aas = [[$for j [[, Action$j a$j]]]]
|
||||
|
||||
template <typename Action1, $types>
|
||||
$range k 1..i-1
|
||||
|
||||
inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
|
||||
|
||||
DoAll(Action1 a1$Aas) {
|
||||
$if i==2 [[
|
||||
|
||||
return internal::DoBothAction<Action1, Action2>(a1, a2);
|
||||
]] $else [[
|
||||
$range j2 2..i
|
||||
|
||||
return DoAll(a1, DoAll($for j2, [[a$j2]]));
|
||||
]]
|
||||
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
706
include/gmock/gmock-generated-function-mockers.h
Normal file
706
include/gmock/gmock-generated-function-mockers.h
Normal file
@ -0,0 +1,706 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements function mockers of various arities.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
|
||||
#include <gmock/gmock-spec-builders.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename F>
|
||||
class MockSpec;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
template <typename R>
|
||||
class FunctionMocker<R()> : public
|
||||
internal::FunctionMockerBase<R()> {
|
||||
public:
|
||||
typedef R F();
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With() {
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke() {
|
||||
return InvokeWith(ArgumentTuple());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
class FunctionMocker<R(A1)> : public
|
||||
internal::FunctionMockerBase<R(A1)> {
|
||||
public:
|
||||
typedef R F(A1);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1) {
|
||||
return InvokeWith(ArgumentTuple(a1));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
class FunctionMocker<R(A1, A2)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2)> {
|
||||
public:
|
||||
typedef R F(A1, A2);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
class FunctionMocker<R(A1, A2, A3)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
class FunctionMocker<R(A1, A2, A3, A4)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4,
|
||||
m5));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8, m9));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9, const Matcher<A10>& m10) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8, m9, m10));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
||||
A10 a10) {
|
||||
return InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
|
||||
// The result type of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT(tn, F) tn ::testing::internal::Function<F>::Result
|
||||
|
||||
// The type of argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
|
||||
|
||||
// The matcher type for argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER(tn, F, N) const ::testing::Matcher<GMOCK_ARG(tn, F, N)>&
|
||||
|
||||
// The variable for mocking the given method.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MOCKER(Method) GMOCK_CONCAT_TOKEN(gmock_##Method##_, __LINE__)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD0(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method() constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 0, \
|
||||
this_method_does_not_take_0_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method() constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD1(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 1, \
|
||||
this_method_does_not_take_1_argument); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD2(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 2, \
|
||||
this_method_does_not_take_2_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD3(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 3, \
|
||||
this_method_does_not_take_3_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD4(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 4, \
|
||||
this_method_does_not_take_4_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD5(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG(tn, F, 5) gmock_a5) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 5, \
|
||||
this_method_does_not_take_5_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4, gmock_a5); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER(tn, F, 5) gmock_a5) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD6(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG(tn, F, 6) gmock_a6) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 6, \
|
||||
this_method_does_not_take_6_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4, gmock_a5, gmock_a6); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER(tn, F, 6) gmock_a6) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD7(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG(tn, F, 7) gmock_a7) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 7, \
|
||||
this_method_does_not_take_7_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER(tn, F, 6) gmock_a6, \
|
||||
GMOCK_MATCHER(tn, F, 7) gmock_a7) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD8(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG(tn, F, 7) gmock_a7, \
|
||||
GMOCK_ARG(tn, F, 8) gmock_a8) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 8, \
|
||||
this_method_does_not_take_8_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER(tn, F, 6) gmock_a6, \
|
||||
GMOCK_MATCHER(tn, F, 7) gmock_a7, \
|
||||
GMOCK_MATCHER(tn, F, 8) gmock_a8) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD9(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG(tn, F, 7) gmock_a7, \
|
||||
GMOCK_ARG(tn, F, 8) gmock_a8, \
|
||||
GMOCK_ARG(tn, F, 9) gmock_a9) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 9, \
|
||||
this_method_does_not_take_9_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER(tn, F, 6) gmock_a6, \
|
||||
GMOCK_MATCHER(tn, F, 7) gmock_a7, \
|
||||
GMOCK_MATCHER(tn, F, 8) gmock_a8, \
|
||||
GMOCK_MATCHER(tn, F, 9) gmock_a9) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||
gmock_a9); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD10(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method(GMOCK_ARG(tn, F, 1) gmock_a1, \
|
||||
GMOCK_ARG(tn, F, 2) gmock_a2, \
|
||||
GMOCK_ARG(tn, F, 3) gmock_a3, \
|
||||
GMOCK_ARG(tn, F, 4) gmock_a4, \
|
||||
GMOCK_ARG(tn, F, 5) gmock_a5, \
|
||||
GMOCK_ARG(tn, F, 6) gmock_a6, \
|
||||
GMOCK_ARG(tn, F, 7) gmock_a7, \
|
||||
GMOCK_ARG(tn, F, 8) gmock_a8, \
|
||||
GMOCK_ARG(tn, F, 9) gmock_a9, \
|
||||
GMOCK_ARG(tn, F, 10) gmock_a10) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == 10, \
|
||||
this_method_does_not_take_10_arguments); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke(gmock_a1, gmock_a2, gmock_a3, \
|
||||
gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||
gmock_a10); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method(GMOCK_MATCHER(tn, F, 1) gmock_a1, \
|
||||
GMOCK_MATCHER(tn, F, 2) gmock_a2, \
|
||||
GMOCK_MATCHER(tn, F, 3) gmock_a3, \
|
||||
GMOCK_MATCHER(tn, F, 4) gmock_a4, \
|
||||
GMOCK_MATCHER(tn, F, 5) gmock_a5, \
|
||||
GMOCK_MATCHER(tn, F, 6) gmock_a6, \
|
||||
GMOCK_MATCHER(tn, F, 7) gmock_a7, \
|
||||
GMOCK_MATCHER(tn, F, 8) gmock_a8, \
|
||||
GMOCK_MATCHER(tn, F, 9) gmock_a9, \
|
||||
GMOCK_MATCHER(tn, F, 10) gmock_a10) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||
gmock_a10); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
#define MOCK_METHOD0(m, F) GMOCK_METHOD0(, , , m, F)
|
||||
#define MOCK_METHOD1(m, F) GMOCK_METHOD1(, , , m, F)
|
||||
#define MOCK_METHOD2(m, F) GMOCK_METHOD2(, , , m, F)
|
||||
#define MOCK_METHOD3(m, F) GMOCK_METHOD3(, , , m, F)
|
||||
#define MOCK_METHOD4(m, F) GMOCK_METHOD4(, , , m, F)
|
||||
#define MOCK_METHOD5(m, F) GMOCK_METHOD5(, , , m, F)
|
||||
#define MOCK_METHOD6(m, F) GMOCK_METHOD6(, , , m, F)
|
||||
#define MOCK_METHOD7(m, F) GMOCK_METHOD7(, , , m, F)
|
||||
#define MOCK_METHOD8(m, F) GMOCK_METHOD8(, , , m, F)
|
||||
#define MOCK_METHOD9(m, F) GMOCK_METHOD9(, , , m, F)
|
||||
#define MOCK_METHOD10(m, F) GMOCK_METHOD10(, , , m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0(m, F) GMOCK_METHOD0(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD1(m, F) GMOCK_METHOD1(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD2(m, F) GMOCK_METHOD2(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD3(m, F) GMOCK_METHOD3(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD4(m, F) GMOCK_METHOD4(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD5(m, F) GMOCK_METHOD5(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD6(m, F) GMOCK_METHOD6(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD7(m, F) GMOCK_METHOD7(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD8(m, F) GMOCK_METHOD8(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD9(m, F) GMOCK_METHOD9(, const, , m, F)
|
||||
#define MOCK_CONST_METHOD10(m, F) GMOCK_METHOD10(, const, , m, F)
|
||||
|
||||
#define MOCK_METHOD0_T(m, F) GMOCK_METHOD0(typename, , , m, F)
|
||||
#define MOCK_METHOD1_T(m, F) GMOCK_METHOD1(typename, , , m, F)
|
||||
#define MOCK_METHOD2_T(m, F) GMOCK_METHOD2(typename, , , m, F)
|
||||
#define MOCK_METHOD3_T(m, F) GMOCK_METHOD3(typename, , , m, F)
|
||||
#define MOCK_METHOD4_T(m, F) GMOCK_METHOD4(typename, , , m, F)
|
||||
#define MOCK_METHOD5_T(m, F) GMOCK_METHOD5(typename, , , m, F)
|
||||
#define MOCK_METHOD6_T(m, F) GMOCK_METHOD6(typename, , , m, F)
|
||||
#define MOCK_METHOD7_T(m, F) GMOCK_METHOD7(typename, , , m, F)
|
||||
#define MOCK_METHOD8_T(m, F) GMOCK_METHOD8(typename, , , m, F)
|
||||
#define MOCK_METHOD9_T(m, F) GMOCK_METHOD9(typename, , , m, F)
|
||||
#define MOCK_METHOD10_T(m, F) GMOCK_METHOD10(typename, , , m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T(m, F) GMOCK_METHOD0(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD1_T(m, F) GMOCK_METHOD1(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD2_T(m, F) GMOCK_METHOD2(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD3_T(m, F) GMOCK_METHOD3(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD4_T(m, F) GMOCK_METHOD4(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD5_T(m, F) GMOCK_METHOD5(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD6_T(m, F) GMOCK_METHOD6(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD7_T(m, F) GMOCK_METHOD7(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD8_T(m, F) GMOCK_METHOD8(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD9_T(m, F) GMOCK_METHOD9(typename, const, , m, F)
|
||||
#define MOCK_CONST_METHOD10_T(m, F) GMOCK_METHOD10(typename, const, , m, F)
|
||||
|
||||
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD0(, , ct, m, F)
|
||||
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD1(, , ct, m, F)
|
||||
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD2(, , ct, m, F)
|
||||
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD3(, , ct, m, F)
|
||||
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD4(, , ct, m, F)
|
||||
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD5(, , ct, m, F)
|
||||
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD6(, , ct, m, F)
|
||||
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD7(, , ct, m, F)
|
||||
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD8(, , ct, m, F)
|
||||
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD9(, , ct, m, F)
|
||||
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD10(, , ct, m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD0(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD1(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD2(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD3(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD4(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD5(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD6(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD7(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD8(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD9(, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD10(, const, ct, m, F)
|
||||
|
||||
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD0(typename, , ct, m, F)
|
||||
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD1(typename, , ct, m, F)
|
||||
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD2(typename, , ct, m, F)
|
||||
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD3(typename, , ct, m, F)
|
||||
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD4(typename, , ct, m, F)
|
||||
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD5(typename, , ct, m, F)
|
||||
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD6(typename, , ct, m, F)
|
||||
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD7(typename, , ct, m, F)
|
||||
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD8(typename, , ct, m, F)
|
||||
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD9(typename, , ct, m, F)
|
||||
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD10(typename, , ct, m, F)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD0(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD1(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD2(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD3(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD4(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD5(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD6(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD7(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD8(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD9(typename, const, ct, m, F)
|
||||
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD10(typename, const, ct, m, F)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
200
include/gmock/gmock-generated-function-mockers.h.pump
Normal file
200
include/gmock/gmock-generated-function-mockers.h.pump
Normal file
@ -0,0 +1,200 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements function mockers of various arities.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
|
||||
#include <gmock/gmock-spec-builders.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename F>
|
||||
class MockSpec;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var as = [[$for j, [[a$j]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var ms = [[$for j, [[m$j]]]]
|
||||
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
|
||||
template <typename R$typename_As>
|
||||
class FunctionMocker<R($As)> : public
|
||||
internal::FunctionMockerBase<R($As)> {
|
||||
public:
|
||||
typedef R F($As);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With($matchers) {
|
||||
|
||||
$if i >= 1 [[
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple($ms));
|
||||
|
||||
]]
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke($Aas) {
|
||||
return InvokeWith(ArgumentTuple($as));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
|
||||
// The result type of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT(tn, F) tn ::testing::internal::Function<F>::Result
|
||||
|
||||
// The type of argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG(tn, F, N) tn ::testing::internal::Function<F>::Argument##N
|
||||
|
||||
// The matcher type for argument N of function type F.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER(tn, F, N) const ::testing::Matcher<GMOCK_ARG(tn, F, N)>&
|
||||
|
||||
// The variable for mocking the given method.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MOCKER(Method) GMOCK_CONCAT_TOKEN(gmock_##Method##_, __LINE__)
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var arg_as = [[$for j, \
|
||||
[[GMOCK_ARG(tn, F, $j) gmock_a$j]]]]
|
||||
$var as = [[$for j, [[gmock_a$j]]]]
|
||||
$var matcher_as = [[$for j, \
|
||||
[[GMOCK_MATCHER(tn, F, $j) gmock_a$j]]]]
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD$i(tn, constness, ct, Method, F) \
|
||||
GMOCK_RESULT(tn, F) ct Method($arg_as) constness { \
|
||||
GMOCK_COMPILE_ASSERT(::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<F>::ArgumentTuple>::value == $i, \
|
||||
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
|
||||
GMOCK_MOCKER(Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER(Method).Invoke($as); \
|
||||
} \
|
||||
::testing::MockSpec<F>& \
|
||||
gmock_##Method($matcher_as) constness { \
|
||||
return GMOCK_MOCKER(Method).RegisterOwner(this).With($as); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<F> GMOCK_MOCKER(Method)
|
||||
|
||||
|
||||
]]
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i(m, F) GMOCK_METHOD$i(, , , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i(m, F) GMOCK_METHOD$i(, const, , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i(typename, , , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T(m, F) GMOCK_METHOD$i(typename, const, , m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) GMOCK_METHOD$i(, , ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD$i(, const, ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD$i(typename, , ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, F) \
|
||||
GMOCK_METHOD$i(typename, const, ct, m, F)
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
650
include/gmock/gmock-generated-matchers.h
Normal file
650
include/gmock/gmock-generated-matchers.h
Normal file
@ -0,0 +1,650 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic matchers.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Implements ElementsAre() and ElementsAreArray().
|
||||
template <typename Container>
|
||||
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
public:
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
// Constructs the matcher from a sequence of element values or
|
||||
// element matchers.
|
||||
template <typename InputIter>
|
||||
ElementsAreMatcherImpl(InputIter first, size_t count) {
|
||||
matchers_.reserve(count);
|
||||
InputIter it = first;
|
||||
for (size_t i = 0; i != count; ++i, ++it) {
|
||||
matchers_.push_back(MatcherCast<const Element&>(*it));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff 'container' matches.
|
||||
virtual bool Matches(Container container) const {
|
||||
if (container.size() != count())
|
||||
return false;
|
||||
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
if (!matchers_[i].Matches(*container_iter))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Describes what this matcher does.
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
if (count() == 0) {
|
||||
*os << "is empty";
|
||||
} else if (count() == 1) {
|
||||
*os << "has 1 element that ";
|
||||
matchers_[0].DescribeTo(os);
|
||||
} else {
|
||||
*os << "has " << Elements(count()) << " where\n";
|
||||
for (size_t i = 0; i != count(); ++i) {
|
||||
*os << "element " << i << " ";
|
||||
matchers_[i].DescribeTo(os);
|
||||
if (i + 1 < count()) {
|
||||
*os << ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Describes what the negation of this matcher does.
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
if (count() == 0) {
|
||||
*os << "is not empty";
|
||||
return;
|
||||
}
|
||||
|
||||
*os << "does not have " << Elements(count()) << ", or\n";
|
||||
for (size_t i = 0; i != count(); ++i) {
|
||||
*os << "element " << i << " ";
|
||||
matchers_[i].DescribeNegationTo(os);
|
||||
if (i + 1 < count()) {
|
||||
*os << ", or\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Explains why 'container' matches, or doesn't match, this matcher.
|
||||
virtual void ExplainMatchResultTo(Container container,
|
||||
::std::ostream* os) const {
|
||||
if (Matches(container)) {
|
||||
// We need to explain why *each* element matches (the obvious
|
||||
// ones can be skipped).
|
||||
|
||||
bool reason_printed = false;
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
::std::stringstream ss;
|
||||
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
|
||||
|
||||
const string s = ss.str();
|
||||
if (!s.empty()) {
|
||||
if (reason_printed) {
|
||||
*os << ",\n";
|
||||
}
|
||||
*os << "element " << i << " " << s;
|
||||
reason_printed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We need to explain why the container doesn't match.
|
||||
const size_t actual_count = container.size();
|
||||
if (actual_count != count()) {
|
||||
// The element count doesn't match. If the container is
|
||||
// empty, there's no need to explain anything as Google Mock
|
||||
// already prints the empty container. Otherwise we just need
|
||||
// to show how many elements there actually are.
|
||||
if (actual_count != 0) {
|
||||
*os << "has " << Elements(actual_count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// The container has the right size but at least one element
|
||||
// doesn't match expectation. We need to find this element and
|
||||
// explain why it doesn't match.
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
if (matchers_[i].Matches(*container_iter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*os << "element " << i << " doesn't match";
|
||||
|
||||
::std::stringstream ss;
|
||||
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
|
||||
const string s = ss.str();
|
||||
if (!s.empty()) {
|
||||
*os << " (" << s << ")";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static Message Elements(size_t count) {
|
||||
return Message() << count << (count == 1 ? " element" : " elements");
|
||||
}
|
||||
|
||||
size_t count() const { return matchers_.size(); }
|
||||
std::vector<Matcher<const Element&> > matchers_;
|
||||
};
|
||||
|
||||
// Implements ElementsAre() of 0-10 arguments.
|
||||
|
||||
class ElementsAreMatcher0 {
|
||||
public:
|
||||
ElementsAreMatcher0() {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&>* const matchers = NULL;
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
class ElementsAreMatcher1 {
|
||||
public:
|
||||
explicit ElementsAreMatcher1(const T1& e1) : e1_(e1) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 1));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class ElementsAreMatcher2 {
|
||||
public:
|
||||
ElementsAreMatcher2(const T1& e1, const T2& e2) : e1_(e1), e2_(e2) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 2));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class ElementsAreMatcher3 {
|
||||
public:
|
||||
ElementsAreMatcher3(const T1& e1, const T2& e2, const T3& e3) : e1_(e1),
|
||||
e2_(e2), e3_(e3) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 3));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class ElementsAreMatcher4 {
|
||||
public:
|
||||
ElementsAreMatcher4(const T1& e1, const T2& e2, const T3& e3,
|
||||
const T4& e4) : e1_(e1), e2_(e2), e3_(e3), e4_(e4) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 4));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class ElementsAreMatcher5 {
|
||||
public:
|
||||
ElementsAreMatcher5(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
MatcherCast<const Element&>(e5_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 5));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
const T5& e5_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6>
|
||||
class ElementsAreMatcher6 {
|
||||
public:
|
||||
ElementsAreMatcher6(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6) : e1_(e1), e2_(e2), e3_(e3), e4_(e4),
|
||||
e5_(e5), e6_(e6) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
MatcherCast<const Element&>(e5_),
|
||||
MatcherCast<const Element&>(e6_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 6));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
const T5& e5_;
|
||||
const T6& e6_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
class ElementsAreMatcher7 {
|
||||
public:
|
||||
ElementsAreMatcher7(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7) : e1_(e1), e2_(e2), e3_(e3),
|
||||
e4_(e4), e5_(e5), e6_(e6), e7_(e7) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
MatcherCast<const Element&>(e5_),
|
||||
MatcherCast<const Element&>(e6_),
|
||||
MatcherCast<const Element&>(e7_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 7));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
const T5& e5_;
|
||||
const T6& e6_;
|
||||
const T7& e7_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
class ElementsAreMatcher8 {
|
||||
public:
|
||||
ElementsAreMatcher8(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7, const T8& e8) : e1_(e1),
|
||||
e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6), e7_(e7), e8_(e8) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
MatcherCast<const Element&>(e5_),
|
||||
MatcherCast<const Element&>(e6_),
|
||||
MatcherCast<const Element&>(e7_),
|
||||
MatcherCast<const Element&>(e8_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 8));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
const T5& e5_;
|
||||
const T6& e6_;
|
||||
const T7& e7_;
|
||||
const T8& e8_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
class ElementsAreMatcher9 {
|
||||
public:
|
||||
ElementsAreMatcher9(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7, const T8& e8,
|
||||
const T9& e9) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6),
|
||||
e7_(e7), e8_(e8), e9_(e9) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
MatcherCast<const Element&>(e5_),
|
||||
MatcherCast<const Element&>(e6_),
|
||||
MatcherCast<const Element&>(e7_),
|
||||
MatcherCast<const Element&>(e8_),
|
||||
MatcherCast<const Element&>(e9_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 9));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
const T5& e5_;
|
||||
const T6& e6_;
|
||||
const T7& e7_;
|
||||
const T8& e8_;
|
||||
const T9& e9_;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
class ElementsAreMatcher10 {
|
||||
public:
|
||||
ElementsAreMatcher10(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
|
||||
const T10& e10) : e1_(e1), e2_(e2), e3_(e3), e4_(e4), e5_(e5), e6_(e6),
|
||||
e7_(e7), e8_(e8), e9_(e9), e10_(e10) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
MatcherCast<const Element&>(e1_),
|
||||
MatcherCast<const Element&>(e2_),
|
||||
MatcherCast<const Element&>(e3_),
|
||||
MatcherCast<const Element&>(e4_),
|
||||
MatcherCast<const Element&>(e5_),
|
||||
MatcherCast<const Element&>(e6_),
|
||||
MatcherCast<const Element&>(e7_),
|
||||
MatcherCast<const Element&>(e8_),
|
||||
MatcherCast<const Element&>(e9_),
|
||||
MatcherCast<const Element&>(e10_),
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 10));
|
||||
}
|
||||
|
||||
private:
|
||||
const T1& e1_;
|
||||
const T2& e2_;
|
||||
const T3& e3_;
|
||||
const T4& e4_;
|
||||
const T5& e5_;
|
||||
const T6& e6_;
|
||||
const T7& e7_;
|
||||
const T8& e8_;
|
||||
const T9& e9_;
|
||||
const T10& e10_;
|
||||
};
|
||||
|
||||
// Implements ElementsAreArray().
|
||||
template <typename T>
|
||||
class ElementsAreArrayMatcher {
|
||||
public:
|
||||
ElementsAreArrayMatcher(const T* first, size_t count) :
|
||||
first_(first), count_(count) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
|
||||
}
|
||||
|
||||
private:
|
||||
const T* const first_;
|
||||
const size_t count_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with
|
||||
// (n + 1) elements, where the i-th element in the container must
|
||||
// match the i-th argument in the list. Each argument of
|
||||
// ElementsAre() can be either a value or a matcher. We support up to
|
||||
// 10 arguments.
|
||||
//
|
||||
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
||||
// must not be used with containers whose elements's order is
|
||||
// undefined (e.g. hash_map).
|
||||
|
||||
inline internal::ElementsAreMatcher0 ElementsAre() {
|
||||
return internal::ElementsAreMatcher0();
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
inline internal::ElementsAreMatcher1<T1> ElementsAre(const T1& e1) {
|
||||
return internal::ElementsAreMatcher1<T1>(e1);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline internal::ElementsAreMatcher2<T1, T2> ElementsAre(const T1& e1,
|
||||
const T2& e2) {
|
||||
return internal::ElementsAreMatcher2<T1, T2>(e1, e2);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline internal::ElementsAreMatcher3<T1, T2, T3> ElementsAre(const T1& e1,
|
||||
const T2& e2, const T3& e3) {
|
||||
return internal::ElementsAreMatcher3<T1, T2, T3>(e1, e2, e3);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
inline internal::ElementsAreMatcher4<T1, T2, T3, T4> ElementsAre(const T1& e1,
|
||||
const T2& e2, const T3& e3, const T4& e4) {
|
||||
return internal::ElementsAreMatcher4<T1, T2, T3, T4>(e1, e2, e3, e4);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline internal::ElementsAreMatcher5<T1, T2, T3, T4,
|
||||
T5> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5) {
|
||||
return internal::ElementsAreMatcher5<T1, T2, T3, T4, T5>(e1, e2, e3, e4, e5);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6>
|
||||
inline internal::ElementsAreMatcher6<T1, T2, T3, T4, T5,
|
||||
T6> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6) {
|
||||
return internal::ElementsAreMatcher6<T1, T2, T3, T4, T5, T6>(e1, e2, e3, e4,
|
||||
e5, e6);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
inline internal::ElementsAreMatcher7<T1, T2, T3, T4, T5, T6,
|
||||
T7> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7) {
|
||||
return internal::ElementsAreMatcher7<T1, T2, T3, T4, T5, T6, T7>(e1, e2, e3,
|
||||
e4, e5, e6, e7);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
inline internal::ElementsAreMatcher8<T1, T2, T3, T4, T5, T6, T7,
|
||||
T8> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
|
||||
return internal::ElementsAreMatcher8<T1, T2, T3, T4, T5, T6, T7, T8>(e1, e2,
|
||||
e3, e4, e5, e6, e7, e8);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
inline internal::ElementsAreMatcher9<T1, T2, T3, T4, T5, T6, T7, T8,
|
||||
T9> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
|
||||
return internal::ElementsAreMatcher9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(e1,
|
||||
e2, e3, e4, e5, e6, e7, e8, e9);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
inline internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
||||
T10> ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
|
||||
const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
|
||||
const T10& e10) {
|
||||
return internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
||||
T10>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
|
||||
}
|
||||
|
||||
// ElementsAreArray(array) and ElementAreArray(array, count) are like
|
||||
// ElementsAre(), except that they take an array of values or
|
||||
// matchers. The former form infers the size of 'array', which must
|
||||
// be a static C-style array. In the latter form, 'array' can either
|
||||
// be a static array or a pointer to a dynamically created array.
|
||||
|
||||
template <typename T>
|
||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
||||
const T* first, size_t count) {
|
||||
return internal::ElementsAreArrayMatcher<T>(first, count);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline internal::ElementsAreArrayMatcher<T>
|
||||
ElementsAreArray(const T (&array)[N]) {
|
||||
return internal::ElementsAreArrayMatcher<T>(array, N);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
303
include/gmock/gmock-generated-matchers.h.pump
Normal file
303
include/gmock/gmock-generated-matchers.h.pump
Normal file
@ -0,0 +1,303 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-variadic-actions.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic matchers.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Implements ElementsAre() and ElementsAreArray().
|
||||
template <typename Container>
|
||||
class ElementsAreMatcherImpl : public MatcherInterface<Container> {
|
||||
public:
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
// Constructs the matcher from a sequence of element values or
|
||||
// element matchers.
|
||||
template <typename InputIter>
|
||||
ElementsAreMatcherImpl(InputIter first, size_t count) {
|
||||
matchers_.reserve(count);
|
||||
InputIter it = first;
|
||||
for (size_t i = 0; i != count; ++i, ++it) {
|
||||
matchers_.push_back(MatcherCast<const Element&>(*it));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff 'container' matches.
|
||||
virtual bool Matches(Container container) const {
|
||||
if (container.size() != count())
|
||||
return false;
|
||||
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
if (!matchers_[i].Matches(*container_iter))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Describes what this matcher does.
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
if (count() == 0) {
|
||||
*os << "is empty";
|
||||
} else if (count() == 1) {
|
||||
*os << "has 1 element that ";
|
||||
matchers_[0].DescribeTo(os);
|
||||
} else {
|
||||
*os << "has " << Elements(count()) << " where\n";
|
||||
for (size_t i = 0; i != count(); ++i) {
|
||||
*os << "element " << i << " ";
|
||||
matchers_[i].DescribeTo(os);
|
||||
if (i + 1 < count()) {
|
||||
*os << ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Describes what the negation of this matcher does.
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
if (count() == 0) {
|
||||
*os << "is not empty";
|
||||
return;
|
||||
}
|
||||
|
||||
*os << "does not have " << Elements(count()) << ", or\n";
|
||||
for (size_t i = 0; i != count(); ++i) {
|
||||
*os << "element " << i << " ";
|
||||
matchers_[i].DescribeNegationTo(os);
|
||||
if (i + 1 < count()) {
|
||||
*os << ", or\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Explains why 'container' matches, or doesn't match, this matcher.
|
||||
virtual void ExplainMatchResultTo(Container container,
|
||||
::std::ostream* os) const {
|
||||
if (Matches(container)) {
|
||||
// We need to explain why *each* element matches (the obvious
|
||||
// ones can be skipped).
|
||||
|
||||
bool reason_printed = false;
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
::std::stringstream ss;
|
||||
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
|
||||
|
||||
const string s = ss.str();
|
||||
if (!s.empty()) {
|
||||
if (reason_printed) {
|
||||
*os << ",\n";
|
||||
}
|
||||
*os << "element " << i << " " << s;
|
||||
reason_printed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We need to explain why the container doesn't match.
|
||||
const size_t actual_count = container.size();
|
||||
if (actual_count != count()) {
|
||||
// The element count doesn't match. If the container is
|
||||
// empty, there's no need to explain anything as Google Mock
|
||||
// already prints the empty container. Otherwise we just need
|
||||
// to show how many elements there actually are.
|
||||
if (actual_count != 0) {
|
||||
*os << "has " << Elements(actual_count);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// The container has the right size but at least one element
|
||||
// doesn't match expectation. We need to find this element and
|
||||
// explain why it doesn't match.
|
||||
typename RawContainer::const_iterator container_iter = container.begin();
|
||||
for (size_t i = 0; i != count(); ++container_iter, ++i) {
|
||||
if (matchers_[i].Matches(*container_iter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*os << "element " << i << " doesn't match";
|
||||
|
||||
::std::stringstream ss;
|
||||
matchers_[i].ExplainMatchResultTo(*container_iter, &ss);
|
||||
const string s = ss.str();
|
||||
if (!s.empty()) {
|
||||
*os << " (" << s << ")";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static Message Elements(size_t count) {
|
||||
return Message() << count << (count == 1 ? " element" : " elements");
|
||||
}
|
||||
|
||||
size_t count() const { return matchers_.size(); }
|
||||
std::vector<Matcher<const Element&> > matchers_;
|
||||
};
|
||||
|
||||
// Implements ElementsAre() of 0-10 arguments.
|
||||
|
||||
class ElementsAreMatcher0 {
|
||||
public:
|
||||
ElementsAreMatcher0() {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&>* const matchers = NULL;
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename T$j]]>
|
||||
class ElementsAreMatcher$i {
|
||||
public:
|
||||
$if i==1 [[explicit ]]ElementsAreMatcher$i($for j, [[const T$j& e$j]])$if i > 0 [[ : ]]
|
||||
$for j, [[e$j[[]]_(e$j)]] {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
const Matcher<const Element&> matchers[] = {
|
||||
|
||||
$for j [[
|
||||
MatcherCast<const Element&>(e$j[[]]_),
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
$for j [[
|
||||
const T$j& e$j[[]]_;
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// Implements ElementsAreArray().
|
||||
template <typename T>
|
||||
class ElementsAreArrayMatcher {
|
||||
public:
|
||||
ElementsAreArrayMatcher(const T* first, size_t count) :
|
||||
first_(first), count_(count) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
typedef GMOCK_REMOVE_CONST(GMOCK_REMOVE_REFERENCE(Container)) RawContainer;
|
||||
typedef typename RawContainer::value_type Element;
|
||||
|
||||
return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
|
||||
}
|
||||
|
||||
private:
|
||||
const T* const first_;
|
||||
const size_t count_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// ElementsAre(e0, e1, ..., e_n) matches an STL-style container with
|
||||
// (n + 1) elements, where the i-th element in the container must
|
||||
// match the i-th argument in the list. Each argument of
|
||||
// ElementsAre() can be either a value or a matcher. We support up to
|
||||
// $n arguments.
|
||||
//
|
||||
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
||||
// must not be used with containers whose elements's order is
|
||||
// undefined (e.g. hash_map).
|
||||
|
||||
inline internal::ElementsAreMatcher0 ElementsAre() {
|
||||
return internal::ElementsAreMatcher0();
|
||||
}
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[const T$j& e$j]]) {
|
||||
return internal::ElementsAreMatcher$i<$for j, [[T$j]]>($for j, [[e$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// ElementsAreArray(array) and ElementAreArray(array, count) are like
|
||||
// ElementsAre(), except that they take an array of values or
|
||||
// matchers. The former form infers the size of 'array', which must
|
||||
// be a static C-style array. In the latter form, 'array' can either
|
||||
// be a static array or a pointer to a dynamically created array.
|
||||
|
||||
template <typename T>
|
||||
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
|
||||
const T* first, size_t count) {
|
||||
return internal::ElementsAreArrayMatcher<T>(first, count);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
inline internal::ElementsAreArrayMatcher<T>
|
||||
ElementsAreArray(const T (&array)[N]) {
|
||||
return internal::ElementsAreArrayMatcher<T>(array, N);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
244
include/gmock/gmock-generated-nice-strict.h
Normal file
244
include/gmock/gmock-generated-nice-strict.h
Normal file
@ -0,0 +1,244 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements class templates NiceMock and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of
|
||||
// MockFoo that treats all uninteresting calls as errors.
|
||||
//
|
||||
// NiceMock and StrictMock "inherits" the constructors of their
|
||||
// respective base class, with up-to 10 arguments. Therefore you can
|
||||
// write NiceMock<MockFoo>(5, "a") to construct a nice mock where
|
||||
// MockFoo has a constructor that accepts (int, const char*), for
|
||||
// example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo> and
|
||||
// StrictMock<MockFoo> only works for mock methods defined using the
|
||||
// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a
|
||||
// mock method is defined in a base class of MockFoo, the "nice" or
|
||||
// "strict" modifier may not affect it, depending on the compiler. In
|
||||
// particular, nesting NiceMock and StrictMock is NOT supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// cannot have arguments passed by non-const reference, which are
|
||||
// banned by the Google C++ style guide anyway.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
|
||||
#include <gmock/gmock-spec-builders.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <class MockClass>
|
||||
class NiceMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NiceMock() {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3,
|
||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~NiceMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class StrictMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
StrictMock() {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1>
|
||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3,
|
||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~StrictMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock and
|
||||
// StrictMock cannot be nested.
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
146
include/gmock/gmock-generated-nice-strict.h.pump
Normal file
146
include/gmock/gmock-generated-nice-strict.h.pump
Normal file
@ -0,0 +1,146 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-nice-strict.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements class templates NiceMock and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), and StrictMock<MockFoo> is a subclass of
|
||||
// MockFoo that treats all uninteresting calls as errors.
|
||||
//
|
||||
// NiceMock and StrictMock "inherits" the constructors of their
|
||||
// respective base class, with up-to $n arguments. Therefore you can
|
||||
// write NiceMock<MockFoo>(5, "a") to construct a nice mock where
|
||||
// MockFoo has a constructor that accepts (int, const char*), for
|
||||
// example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo> and
|
||||
// StrictMock<MockFoo> only works for mock methods defined using the
|
||||
// MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. If a
|
||||
// mock method is defined in a base class of MockFoo, the "nice" or
|
||||
// "strict" modifier may not affect it, depending on the compiler. In
|
||||
// particular, nesting NiceMock and StrictMock is NOT supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// cannot have arguments passed by non-const reference, which are
|
||||
// banned by the Google C++ style guide anyway.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
|
||||
#include <gmock/gmock-spec-builders.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <class MockClass>
|
||||
class NiceMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NiceMock() {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename A$j]]>
|
||||
NiceMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||
Mock::AllowUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
virtual ~NiceMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class StrictMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
StrictMock() {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1>
|
||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename A$j]]>
|
||||
StrictMock($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||
Mock::FailUninterestingCalls(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
virtual ~StrictMock() {
|
||||
Mock::UnregisterCallReaction(internal::implicit_cast<MockClass*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock and
|
||||
// StrictMock cannot be nested.
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
2094
include/gmock/gmock-matchers.h
Normal file
2094
include/gmock/gmock-matchers.h
Normal file
File diff suppressed because it is too large
Load Diff
514
include/gmock/gmock-printers.h
Normal file
514
include/gmock/gmock-printers.h
Normal file
@ -0,0 +1,514 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// It uses the << operator when possible, and prints the bytes in the
|
||||
// object otherwise. A user can override its behavior for a class
|
||||
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||
// defines Foo. If both are defined, PrintTo() takes precedence.
|
||||
// When T is a reference type, the address of the value is also
|
||||
// printed.
|
||||
//
|
||||
// We also provide a convenient wrapper
|
||||
//
|
||||
// string ::testing::internal::UniversalPrinter<T>::PrintAsString(value);
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Makes sure there is at least one << operator declared in the global
|
||||
// namespace. This has no implementation and won't be called
|
||||
// anywhere. We just need the declaration such that we can say "using
|
||||
// ::operator <<;" in the definition of PrintTo() below.
|
||||
void operator<<(::testing::internal::Unused, int);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||
// subject to change without notice. DO NOT USE THEM IN USER CODE!
|
||||
namespace internal2 {
|
||||
|
||||
// Prints the given number of bytes in the given object to the given
|
||||
// ostream.
|
||||
void PrintBytesInObjectTo(const unsigned char* obj_bytes,
|
||||
size_t count,
|
||||
::std::ostream* os);
|
||||
|
||||
// TypeWithoutFormatter<T, kIsProto>::PrintValue(value, os) is called
|
||||
// by the universal printer to print a value of type T when neither
|
||||
// operator<< nor PrintTo() is defined for type T. When T is
|
||||
// ProtocolMessage, proto2::Message, or a subclass of those, kIsProto
|
||||
// will be true and the short debug string of the protocol message
|
||||
// value will be printed; otherwise kIsProto will be false and the
|
||||
// bytes in the value will be printed.
|
||||
template <typename T, bool kIsProto>
|
||||
class TypeWithoutFormatter {
|
||||
public:
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
|
||||
sizeof(value), os);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
class TypeWithoutFormatter<T, true> {
|
||||
public:
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
// Both ProtocolMessage and proto2::Message have the
|
||||
// ShortDebugString() method, so the same implementation works for
|
||||
// both.
|
||||
::std::operator<<(*os, "<" + value.ShortDebugString() + ">");
|
||||
}
|
||||
};
|
||||
|
||||
// Prints the given value to the given ostream. If the value is a
|
||||
// protocol message, its short debug string is printed; otherwise the
|
||||
// bytes in the value are printed. This is what
|
||||
// UniversalPrinter<T>::Print() does when it knows nothing about type
|
||||
// T and T has no << operator.
|
||||
//
|
||||
// A user can override this behavior for a class type Foo by defining
|
||||
// a << operator in the namespace where Foo is defined.
|
||||
//
|
||||
// We put this operator in namespace 'internal2' instead of 'internal'
|
||||
// to simplify the implementation, as much code in 'internal' needs to
|
||||
// use << in STL, which would conflict with our own << were it defined
|
||||
// in 'internal'.
|
||||
template <typename T>
|
||||
::std::ostream& operator<<(::std::ostream& os, const T& x) {
|
||||
TypeWithoutFormatter<T, ::testing::internal::IsAProtocolMessage<T>::value>::
|
||||
PrintValue(x, &os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
|
||||
namespace internal {
|
||||
|
||||
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
||||
// value to the given ostream. The caller must ensure that
|
||||
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
||||
//
|
||||
// We define UniversalPrinter as a class template (as opposed to a
|
||||
// function template), as we need to partially specialize it for
|
||||
// reference types, which cannot be done with function templates.
|
||||
template <typename T>
|
||||
class UniversalPrinter;
|
||||
|
||||
// Used to print an STL-style container when the user doesn't define
|
||||
// a PrintTo() for it.
|
||||
template <typename C>
|
||||
void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) {
|
||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||
*os << '{';
|
||||
size_t count = 0;
|
||||
for (typename C::const_iterator it = container.begin();
|
||||
it != container.end(); ++it, ++count) {
|
||||
if (count > 0) {
|
||||
*os << ',';
|
||||
if (count == kMaxCount) { // Enough has been printed.
|
||||
*os << " ...";
|
||||
break;
|
||||
}
|
||||
}
|
||||
*os << ' ';
|
||||
PrintTo(*it, os);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
*os << ' ';
|
||||
}
|
||||
*os << '}';
|
||||
}
|
||||
|
||||
// Used to print a value when the user doesn't define PrintTo() for it.
|
||||
template <typename T>
|
||||
void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) {
|
||||
// If T has its << operator defined in the global namespace, which
|
||||
// is not recommended but sometimes unavoidable (as in
|
||||
// util/gtl/stl_logging-inl.h), the following statement makes it
|
||||
// visible in this function.
|
||||
//
|
||||
// Without the statement, << in the global namespace would be hidden
|
||||
// by the one in ::testing::internal2, due to the next using
|
||||
// statement.
|
||||
using ::operator <<;
|
||||
|
||||
// When T doesn't come with a << operator, we want to fall back to
|
||||
// the one defined in ::testing::internal2, which prints the bytes in
|
||||
// the value.
|
||||
using ::testing::internal2::operator <<;
|
||||
|
||||
// Thanks to Koenig look-up, if type T has its own << operator
|
||||
// defined in its namespace, which is the recommended way, that
|
||||
// operator will be visible here. Since it is more specific than
|
||||
// the generic one, it will be picked by the compiler in the
|
||||
// following statement - exactly what we want.
|
||||
*os << value;
|
||||
}
|
||||
|
||||
// Prints the given value using the << operator if it has one;
|
||||
// otherwise prints the bytes in it. This is what
|
||||
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
|
||||
// or overloaded for type T.
|
||||
//
|
||||
// A user can override this behavior for a class type Foo by defining
|
||||
// an overload of PrintTo() in the namespace where Foo is defined. We
|
||||
// give the user this option as sometimes defining a << operator for
|
||||
// Foo is not desirable (e.g. the coding style may prevent doing it,
|
||||
// or there is already a << operator but it doesn't do what the user
|
||||
// wants).
|
||||
template <typename T>
|
||||
void PrintTo(const T& value, ::std::ostream* os) {
|
||||
// DefaultPrintTo() is overloaded. The type of its first argument
|
||||
// determines which version will be picked. If T is an STL-style
|
||||
// container, the version for container will be called. Otherwise
|
||||
// the generic version will be called.
|
||||
//
|
||||
// Note that we check for container types here, prior to we check
|
||||
// for protocol message types in our operator<<. The rationale is:
|
||||
//
|
||||
// For protocol messages, we want to give people a chance to
|
||||
// override Google Mock's format by defining a PrintTo() or
|
||||
// operator<<. For STL containers, we believe the Google Mock's
|
||||
// format is superior to what util/gtl/stl-logging.h offers.
|
||||
// Therefore we don't want it to be accidentally overridden by the
|
||||
// latter (even if the user includes stl-logging.h through other
|
||||
// headers indirectly, Google Mock's format will still be used).
|
||||
DefaultPrintTo(IsContainerTest<T>(0), value, os);
|
||||
}
|
||||
|
||||
// The following list of PrintTo() overloads tells
|
||||
// UniversalPrinter<T>::Print() how to print standard types (built-in
|
||||
// types, strings, plain arrays, and pointers).
|
||||
|
||||
// Overloads for various char types.
|
||||
void PrintCharTo(char c, int char_code, ::std::ostream* os);
|
||||
inline void PrintTo(unsigned char c, ::std::ostream* os) {
|
||||
PrintCharTo(c, c, os);
|
||||
}
|
||||
inline void PrintTo(signed char c, ::std::ostream* os) {
|
||||
PrintCharTo(c, c, os);
|
||||
}
|
||||
inline void PrintTo(char c, ::std::ostream* os) {
|
||||
// When printing a plain char, we always treat it as unsigned. This
|
||||
// way, the output won't be affected by whether the compiler thinks
|
||||
// char is signed or not.
|
||||
PrintTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Overloads for other simple built-in types.
|
||||
inline void PrintTo(bool x, ::std::ostream* os) {
|
||||
*os << (x ? "true" : "false");
|
||||
}
|
||||
|
||||
// Overload for wchar_t type.
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its decimal code (except for L'\0').
|
||||
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||
// as signed integer when wchar_t is implemented by the compiler
|
||||
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||
// is implemented as an unsigned type.
|
||||
void PrintTo(wchar_t wc, ::std::ostream* os);
|
||||
|
||||
// Overloads for C strings.
|
||||
void PrintTo(const char* s, ::std::ostream* os);
|
||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const char*>(s), os);
|
||||
}
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// possibly accessing more memory than intended and causing invalid
|
||||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
// wchar_t is implemented as a native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Overloads for wide C strings
|
||||
void PrintTo(const wchar_t* s, ::std::ostream* os);
|
||||
inline void PrintTo(wchar_t* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const wchar_t*>(s), os);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Overload for pointers that are neither char pointers nor member
|
||||
// pointers. (A member variable pointer or member function pointer
|
||||
// doesn't really points to a location in the address space. Their
|
||||
// representation is implementation-defined. Therefore they will be
|
||||
// printed as raw bytes.)
|
||||
template <typename T>
|
||||
void PrintTo(T* p, ::std::ostream* os) {
|
||||
if (p == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
// We cannot use implicit_cast or static_cast here, as they don't
|
||||
// work when p is a function pointer.
|
||||
*os << reinterpret_cast<const void*>(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Overload for C arrays. Multi-dimensional arrays are printed
|
||||
// properly.
|
||||
|
||||
// Prints the given number of elements in an array, without printing
|
||||
// the curly braces.
|
||||
template <typename T>
|
||||
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
||||
UniversalPrinter<T>::Print(a[0], os);
|
||||
for (size_t i = 1; i != count; i++) {
|
||||
*os << ", ";
|
||||
UniversalPrinter<T>::Print(a[i], os);
|
||||
}
|
||||
}
|
||||
|
||||
// Overloads for ::string and ::std::string.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::string& s, ::std::ostream* os) {
|
||||
PrintStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
void PrintStringTo(const ::std::string&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||
PrintStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
// Overloads for ::wstring and ::std::wstring.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Overload for ::std::tr1::tuple. Needed for printing function
|
||||
// arguments, which are packed as tuples.
|
||||
|
||||
// This helper template allows PrintTo() for tuples to be defined by
|
||||
// induction on the number of tuple fields. The idea is that
|
||||
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
||||
// fields in tuple t, and can be defined in terms of
|
||||
// TuplePrefixPrinter<N - 1>.
|
||||
template <size_t N>
|
||||
struct TuplePrefixPrinter {
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
|
||||
*os << ", ";
|
||||
UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
|
||||
::Print(::std::tr1::get<N - 1>(t), os);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TuplePrefixPrinter<0> {
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
|
||||
};
|
||||
template <>
|
||||
struct TuplePrefixPrinter<1> {
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||
UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
|
||||
Print(::std::tr1::get<0>(t), os);
|
||||
}
|
||||
};
|
||||
|
||||
// We support tuples of up-to 10 fields. Note that an N-tuple type is
|
||||
// just an (N + 1)-tuple type where the last field has a special,
|
||||
// unused type.
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
void PrintTo(
|
||||
const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
|
||||
::std::ostream* os) {
|
||||
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Tuple;
|
||||
*os << "(";
|
||||
TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
|
||||
PrintPrefixTo(t, os);
|
||||
*os << ")";
|
||||
}
|
||||
|
||||
// Overload for std::pair.
|
||||
template <typename T1, typename T2>
|
||||
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
UniversalPrinter<T1>::Print(value.first, os);
|
||||
*os << ", ";
|
||||
UniversalPrinter<T2>::Print(value.second, os);
|
||||
*os << ')';
|
||||
}
|
||||
|
||||
// Implements printing a non-reference type T by letting the compiler
|
||||
// pick the right overload of PrintTo() for T.
|
||||
template <typename T>
|
||||
class UniversalPrinter {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4180) // Temporarily disables warning 4180.
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Note: we deliberately don't call this PrintTo(), as that name
|
||||
// conflicts with ::testing::internal::PrintTo in the body of the
|
||||
// function.
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
// By default, ::testing::internal::PrintTo() is used for printing
|
||||
// the value.
|
||||
//
|
||||
// Thanks to Koenig look-up, if T is a class and has its own
|
||||
// PrintTo() function defined in its namespace, that function will
|
||||
// be visible here. Since it is more specific than the generic ones
|
||||
// in ::testing::internal, it will be picked by the compiler in the
|
||||
// following statement - exactly what we want.
|
||||
PrintTo(value, os);
|
||||
}
|
||||
|
||||
// A convenient wrapper for Print() that returns the print-out as a
|
||||
// string.
|
||||
static string PrintAsString(const T& value) {
|
||||
::std::stringstream ss;
|
||||
Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
// Implements printing an array type T[N].
|
||||
template <typename T, size_t N>
|
||||
class UniversalPrinter<T[N]> {
|
||||
public:
|
||||
// Prints the given array, omitting some elements when there are too
|
||||
// many.
|
||||
static void Print(const T (&a)[N], ::std::ostream* os) {
|
||||
// Prints a char array as a C string. Note that we compare 'const
|
||||
// T' with 'const char' instead of comparing T with char, in case
|
||||
// that T is already a const type.
|
||||
if (internal::type_equals<const T, const char>::value) {
|
||||
UniversalPrinter<const T*>::Print(a, os);
|
||||
return;
|
||||
}
|
||||
|
||||
if (N == 0) {
|
||||
*os << "{}";
|
||||
} else {
|
||||
*os << "{ ";
|
||||
const size_t kThreshold = 18;
|
||||
const size_t kChunkSize = 8;
|
||||
// If the array has more than kThreshold elements, we'll have to
|
||||
// omit some details by printing only the first and the last
|
||||
// kChunkSize elements.
|
||||
// TODO(wan): let the user control the threshold using a flag.
|
||||
if (N <= kThreshold) {
|
||||
PrintRawArrayTo(a, N, os);
|
||||
} else {
|
||||
PrintRawArrayTo(a, kChunkSize, os);
|
||||
*os << ", ..., ";
|
||||
PrintRawArrayTo(a + N - kChunkSize, kChunkSize, os);
|
||||
}
|
||||
*os << " }";
|
||||
}
|
||||
}
|
||||
|
||||
// A convenient wrapper for Print() that returns the print-out as a
|
||||
// string.
|
||||
static string PrintAsString(const T (&a)[N]) {
|
||||
::std::stringstream ss;
|
||||
Print(a, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements printing a reference type T&.
|
||||
template <typename T>
|
||||
class UniversalPrinter<T&> {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4180) // Temporarily disables warning 4180.
|
||||
#endif // _MSC_VER
|
||||
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
// Prints the address of the value. We use reinterpret_cast here
|
||||
// as static_cast doesn't compile when T is a function type.
|
||||
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
|
||||
|
||||
// Then prints the value itself.
|
||||
UniversalPrinter<T>::Print(value, os);
|
||||
}
|
||||
|
||||
// A convenient wrapper for Print() that returns the print-out as a
|
||||
// string.
|
||||
static string PrintAsString(const T& value) {
|
||||
::std::stringstream ss;
|
||||
Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
|
1568
include/gmock/gmock-spec-builders.h
Normal file
1568
include/gmock/gmock-spec-builders.h
Normal file
File diff suppressed because it is too large
Load Diff
92
include/gmock/gmock.h
Normal file
92
include/gmock/gmock.h
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This is the main header file a user should include.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
|
||||
// This file implements the following syntax:
|
||||
//
|
||||
// ON_CALL(mock_object.Method(...))
|
||||
// .WithArguments(...) ?
|
||||
// .WillByDefault(...);
|
||||
//
|
||||
// where WithArguments() is optional and WillByDefault() must appear
|
||||
// exactly once.
|
||||
//
|
||||
// EXPECT_CALL(mock_object.Method(...))
|
||||
// .WithArguments(...) ?
|
||||
// .Times(...) ?
|
||||
// .InSequence(...) *
|
||||
// .WillOnce(...) *
|
||||
// .WillRepeatedly(...) ?
|
||||
// .RetiresOnSaturation() ? ;
|
||||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include <gmock/gmock-actions.h>
|
||||
#include <gmock/gmock-cardinalities.h>
|
||||
#include <gmock/gmock-generated-actions.h>
|
||||
#include <gmock/gmock-generated-function-mockers.h>
|
||||
#include <gmock/gmock-generated-matchers.h>
|
||||
#include <gmock/gmock-generated-nice-strict.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_string(verbose);
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||
// it is removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
void InitGoogleMock(int* argc, char** argv);
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
void InitGoogleMock(int* argc, wchar_t** argv);
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
277
include/gmock/internal/gmock-generated-internal-utils.h
Normal file
277
include/gmock/internal/gmock-generated-internal-utils.h
Normal file
@ -0,0 +1,277 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file contains template meta-programming utility classes needed
|
||||
// for implementing Google Mock.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename T>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
// This is used in implementing the IgnoreResult(a) action.
|
||||
class IgnoredValue {
|
||||
public:
|
||||
// This constructor template allows any value to be implicitly
|
||||
// converted to IgnoredValue. The object has no data member and
|
||||
// doesn't try to remember anything about the argument. We
|
||||
// deliberately omit the 'explicit' keyword in order to allow the
|
||||
// conversion to be implicit.
|
||||
template <typename T>
|
||||
IgnoredValue(const T&) {}
|
||||
};
|
||||
|
||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||
// for the corresponding field in tuple type T.
|
||||
template <typename Tuple>
|
||||
struct MatcherTuple;
|
||||
|
||||
template <>
|
||||
struct MatcherTuple< ::std::tr1::tuple<> > {
|
||||
typedef ::std::tr1::tuple< > type;
|
||||
};
|
||||
|
||||
template <typename A1>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
|
||||
Matcher<A4> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
||||
Matcher<A10> > type;
|
||||
};
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename F>
|
||||
struct Function;
|
||||
|
||||
template <typename R>
|
||||
struct Function<R()> {
|
||||
typedef R Result;
|
||||
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid();
|
||||
typedef IgnoredValue MakeResultIgnoredValue();
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct Function<R(A1)>
|
||||
: Function<R()> {
|
||||
typedef A1 Argument1;
|
||||
typedef ::std::tr1::tuple<A1> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct Function<R(A1, A2)>
|
||||
: Function<R(A1)> {
|
||||
typedef A2 Argument2;
|
||||
typedef ::std::tr1::tuple<A1, A2> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
struct Function<R(A1, A2, A3)>
|
||||
: Function<R(A1, A2)> {
|
||||
typedef A3 Argument3;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
struct Function<R(A1, A2, A3, A4)>
|
||||
: Function<R(A1, A2, A3)> {
|
||||
typedef A4 Argument4;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
struct Function<R(A1, A2, A3, A4, A5)>
|
||||
: Function<R(A1, A2, A3, A4)> {
|
||||
typedef A5 Argument5;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6)>
|
||||
: Function<R(A1, A2, A3, A4, A5)> {
|
||||
typedef A6 Argument6;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6)> {
|
||||
typedef A7 Argument7;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
typedef A8 Argument8;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
typedef A9 Argument9;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
typedef A10 Argument10;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9, A10);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
136
include/gmock/internal/gmock-generated-internal-utils.h.pump
Normal file
136
include/gmock/internal/gmock-generated-internal-utils.h.pump
Normal file
@ -0,0 +1,136 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file contains template meta-programming utility classes needed
|
||||
// for implementing Google Mock.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename T>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
// This is used in implementing the IgnoreResult(a) action.
|
||||
class IgnoredValue {
|
||||
public:
|
||||
// This constructor template allows any value to be implicitly
|
||||
// converted to IgnoredValue. The object has no data member and
|
||||
// doesn't try to remember anything about the argument. We
|
||||
// deliberately omit the 'explicit' keyword in order to allow the
|
||||
// conversion to be implicit.
|
||||
template <typename T>
|
||||
IgnoredValue(const T&) {}
|
||||
};
|
||||
|
||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||
// for the corresponding field in tuple type T.
|
||||
template <typename Tuple>
|
||||
struct MatcherTuple;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||
template <$typename_As>
|
||||
struct MatcherTuple< ::std::tr1::tuple<$As> > {
|
||||
typedef ::std::tr1::tuple<$matcher_As > type;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename F>
|
||||
struct Function;
|
||||
|
||||
template <typename R>
|
||||
struct Function<R()> {
|
||||
typedef R Result;
|
||||
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid();
|
||||
typedef IgnoredValue MakeResultIgnoredValue();
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||
$range k 1..i-1
|
||||
$var prev_As = [[$for k, [[A$k]]]]
|
||||
template <typename R$typename_As>
|
||||
struct Function<R($As)>
|
||||
: Function<R($prev_As)> {
|
||||
typedef A$i Argument$i;
|
||||
typedef ::std::tr1::tuple<$As> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid($As);
|
||||
typedef IgnoredValue MakeResultIgnoredValue($As);
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
339
include/gmock/internal/gmock-internal-utils.h
Normal file
339
include/gmock/internal/gmock-internal-utils.h
Normal file
@ -0,0 +1,339 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
|
||||
#include <gmock/internal/gmock-generated-internal-utils.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Concatenates two pre-processor symbols; works for concatenating
|
||||
// built-in macros like __FILE__ and __LINE__.
|
||||
#define GMOCK_CONCAT_TOKEN_IMPL(foo, bar) foo##bar
|
||||
#define GMOCK_CONCAT_TOKEN(foo, bar) GMOCK_CONCAT_TOKEN_IMPL(foo, bar)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GMOCK_ATTRIBUTE_UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
#define GMOCK_ATTRIBUTE_UNUSED
|
||||
#endif // __GNUC__
|
||||
|
||||
class ProtocolMessage;
|
||||
namespace proto2 { class Message; }
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
|
||||
// compiler error iff T1 and T2 are different types.
|
||||
template <typename T1, typename T2>
|
||||
struct CompileAssertTypesEqual;
|
||||
|
||||
template <typename T>
|
||||
struct CompileAssertTypesEqual<T, T> {
|
||||
};
|
||||
|
||||
// Removes the reference from a type if it is a reference type,
|
||||
// otherwise leaves it unchanged. This is the same as
|
||||
// tr1::remove_reference, which is not widely available yet.
|
||||
template <typename T>
|
||||
struct RemoveReference { typedef T type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct RemoveReference<T&> { typedef T type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around RemoveReference that works when the argument
|
||||
// T depends on template parameters.
|
||||
#define GMOCK_REMOVE_REFERENCE(T) \
|
||||
typename ::testing::internal::RemoveReference<T>::type
|
||||
|
||||
// Removes const from a type if it is a const type, otherwise leaves
|
||||
// it unchanged. This is the same as tr1::remove_const, which is not
|
||||
// widely available yet.
|
||||
template <typename T>
|
||||
struct RemoveConst { typedef T type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct RemoveConst<const T> { typedef T type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around RemoveConst that works when the argument
|
||||
// T depends on template parameters.
|
||||
#define GMOCK_REMOVE_CONST(T) \
|
||||
typename ::testing::internal::RemoveConst<T>::type
|
||||
|
||||
// Adds reference to a type if it is not a reference type,
|
||||
// otherwise leaves it unchanged. This is the same as
|
||||
// tr1::add_reference, which is not widely available yet.
|
||||
template <typename T>
|
||||
struct AddReference { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddReference<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper around AddReference that works when the argument T
|
||||
// depends on template parameters.
|
||||
#define GMOCK_ADD_REFERENCE(T) \
|
||||
typename ::testing::internal::AddReference<T>::type
|
||||
|
||||
// Adds a reference to const on top of T as necessary. For example,
|
||||
// it transforms
|
||||
//
|
||||
// char ==> const char&
|
||||
// const char ==> const char&
|
||||
// char& ==> const char&
|
||||
// const char& ==> const char&
|
||||
//
|
||||
// The argument T must depend on some template parameters.
|
||||
#define GMOCK_REFERENCE_TO_CONST(T) \
|
||||
GMOCK_ADD_REFERENCE(const GMOCK_REMOVE_REFERENCE(T))
|
||||
|
||||
// PointeeOf<Pointer>::type is the type of a value pointed to by a
|
||||
// Pointer, which can be either a smart pointer or a raw pointer. The
|
||||
// following default implementation is for the case where Pointer is a
|
||||
// smart pointer.
|
||||
template <typename Pointer>
|
||||
struct PointeeOf {
|
||||
// Smart pointer classes define type element_type as the type of
|
||||
// their pointees.
|
||||
typedef typename Pointer::element_type type;
|
||||
};
|
||||
// This specialization is for the raw pointer case.
|
||||
template <typename T>
|
||||
struct PointeeOf<T*> { typedef T type; }; // NOLINT
|
||||
|
||||
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||
// The following default implementation is for the smart pointer case.
|
||||
template <typename Pointer>
|
||||
inline typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
||||
return p.get();
|
||||
}
|
||||
// This overloaded version is for the raw pointer case.
|
||||
template <typename Element>
|
||||
inline Element* GetRawPointer(Element* p) { return p; }
|
||||
|
||||
// This comparator allows linked_ptr to be stored in sets.
|
||||
template <typename T>
|
||||
struct LinkedPtrLessThan {
|
||||
bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
|
||||
const ::testing::internal::linked_ptr<T>& rhs) const {
|
||||
return lhs.get() < rhs.get();
|
||||
}
|
||||
};
|
||||
|
||||
// ImplicitlyConvertible<From, To>::value is a compile-time bool
|
||||
// constant that's true iff type From can be implicitly converted to
|
||||
// type To.
|
||||
template <typename From, typename To>
|
||||
class ImplicitlyConvertible {
|
||||
private:
|
||||
// We need the following helper functions only for their types.
|
||||
// They have no implementations.
|
||||
|
||||
// MakeFrom() is an expression whose type is From. We cannot simply
|
||||
// use From(), as the type From may not have a public default
|
||||
// constructor.
|
||||
static From MakeFrom();
|
||||
|
||||
// These two functions are overloaded. Given an expression
|
||||
// Helper(x), the compiler will pick the first version if x can be
|
||||
// implicitly converted to type To; otherwise it will pick the
|
||||
// second version.
|
||||
//
|
||||
// The first version returns a value of size 1, and the second
|
||||
// version returns a value of size 2. Therefore, by checking the
|
||||
// size of Helper(x), which can be done at compile time, we can tell
|
||||
// which version of Helper() is used, and hence whether x can be
|
||||
// implicitly converted to type To.
|
||||
static char Helper(To);
|
||||
static char (&Helper(...))[2]; // NOLINT
|
||||
|
||||
// We have to put the 'public' section after the 'private' section,
|
||||
// or MSVC refuses to compile the code.
|
||||
public:
|
||||
// MSVC warns about implicitly converting from double to int for
|
||||
// possible loss of data, so we need to temporarily disable the
|
||||
// warning.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4244) // Temporarily disables warning 4244.
|
||||
static const bool value =
|
||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#else
|
||||
static const bool value =
|
||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||
#endif // _MSV_VER
|
||||
};
|
||||
template <typename From, typename To>
|
||||
const bool ImplicitlyConvertible<From, To>::value;
|
||||
|
||||
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
|
||||
// true iff T is type ProtocolMessage, proto2::Message, or a subclass
|
||||
// of those.
|
||||
template <typename T>
|
||||
struct IsAProtocolMessage {
|
||||
static const bool value =
|
||||
ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
|
||||
ImplicitlyConvertible<const T*, const ::proto2::Message*>::value;
|
||||
};
|
||||
template <typename T>
|
||||
const bool IsAProtocolMessage<T>::value;
|
||||
|
||||
// When the compiler sees expression IsContainerTest<C>(0), the first
|
||||
// overload of IsContainerTest will be picked if C is an STL-style
|
||||
// container class (since C::const_iterator* is a valid type and 0 can
|
||||
// be converted to it), while the second overload will be picked
|
||||
// otherwise (since C::const_iterator will be an invalid type in this
|
||||
// case). Therefore, we can determine whether C is a container class
|
||||
// by checking the type of IsContainerTest<C>(0). The value of the
|
||||
// expression is insignificant.
|
||||
typedef int IsContainer;
|
||||
template <class C>
|
||||
IsContainer IsContainerTest(typename C::const_iterator*) { return 0; }
|
||||
|
||||
typedef char IsNotContainer;
|
||||
template <class C>
|
||||
IsNotContainer IsContainerTest(...) { return '\0'; }
|
||||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType {
|
||||
NONFATAL, FATAL
|
||||
};
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) = 0;
|
||||
};
|
||||
|
||||
// Returns the failure reporter used by Google Mock.
|
||||
FailureReporterInterface* GetFailureReporter();
|
||||
|
||||
// Asserts that condition is true; aborts the process with the given
|
||||
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
|
||||
// as Google Mock might be used to mock the log sink itself. We
|
||||
// inline this function to prevent it from showing up in the stack
|
||||
// trace.
|
||||
inline void Assert(bool condition, const char* file, int line,
|
||||
const string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::FATAL,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Assert(bool condition, const char* file, int line) {
|
||||
Assert(condition, file, line, "Assertion failed.");
|
||||
}
|
||||
|
||||
// Verifies that condition is true; generates a non-fatal failure if
|
||||
// condition is false.
|
||||
inline void Expect(bool condition, const char* file, int line,
|
||||
const string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::NONFATAL,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Expect(bool condition, const char* file, int line) {
|
||||
Expect(condition, file, line, "Expectation failed.");
|
||||
}
|
||||
|
||||
// Severity level of a log.
|
||||
enum LogSeverity {
|
||||
INFO = 0,
|
||||
WARNING = 1,
|
||||
};
|
||||
|
||||
// Valid values for the --gmock_verbose flag.
|
||||
|
||||
// All logs (informational and warnings) are printed.
|
||||
const char kInfoVerbosity[] = "info";
|
||||
// Only warnings are printed.
|
||||
const char kWarningVerbosity[] = "warning";
|
||||
// No logs are printed.
|
||||
const char kErrorVerbosity[] = "error";
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
void Log(LogSeverity severity, const string& message, int stack_frames_to_skip);
|
||||
|
||||
// The universal value printer (public/gmock-printers.h) needs this
|
||||
// to declare an unused << operator in the global namespace.
|
||||
struct Unused {};
|
||||
|
||||
// Type traits.
|
||||
|
||||
// is_reference<T>::value is non-zero iff T is a reference type.
|
||||
template <typename T> struct is_reference : public false_type {};
|
||||
template <typename T> struct is_reference<T&> : public true_type {};
|
||||
|
||||
// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
|
||||
template <typename T1, typename T2> struct type_equals : public false_type {};
|
||||
template <typename T> struct type_equals<T, T> : public true_type {};
|
||||
|
||||
// remove_reference<T>::type removes the reference from type T, if any.
|
||||
template <typename T> struct remove_reference { typedef T type; };
|
||||
template <typename T> struct remove_reference<T&> { typedef T type; };
|
||||
|
||||
// Invalid<T>() returns an invalid value of type T. This is useful
|
||||
// when a value of type T is needed for compilation, but the statement
|
||||
// will not really be executed (or we don't care if the statement
|
||||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
return *static_cast<typename remove_reference<T>::type*>(NULL);
|
||||
}
|
||||
template <>
|
||||
inline void Invalid<void>() {}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
314
include/gmock/internal/gmock-port.h
Normal file
314
include/gmock/internal/gmock-port.h
Normal file
@ -0,0 +1,314 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vadimb@google.com (Vadim Berman)
|
||||
//
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. They are subject to change without notice. DO NOT USE
|
||||
// THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
// Most of the types needed for porting Google Mock are also required
|
||||
// for Google Test and are defined in gtest-port.h.
|
||||
#include <gtest/internal/gtest-linked_ptr.h>
|
||||
#include <gtest/internal/gtest-port.h>
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gmock-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple.
|
||||
#if defined(__GNUC__)
|
||||
// GCC implements tr1/tuple in the <tr1/tuple> header. This does not
|
||||
// conform to the TR1 spec, which requires the header to be <tuple>.
|
||||
#include <tr1/tuple>
|
||||
#else
|
||||
// If the compiler is not GCC, we assume the user is using a
|
||||
// spec-conforming TR1 implementation.
|
||||
#include <tuple>
|
||||
#endif // __GNUC__
|
||||
|
||||
#ifdef GTEST_OS_LINUX
|
||||
|
||||
// On some platforms, <regex.h> needs someone to define size_t, and
|
||||
// won't compile otherwise. We can #include it here as we already
|
||||
// included <stdlib.h>, which is guaranteed to define size_t through
|
||||
// <stddef.h>.
|
||||
#include <regex.h> // NOLINT
|
||||
|
||||
// Defines this iff Google Mock uses the enhanced POSIX regular
|
||||
// expression syntax. This is public as it affects how a user uses
|
||||
// regular expression matchers.
|
||||
#define GMOCK_USES_POSIX_RE 1
|
||||
|
||||
#endif // GTEST_OS_LINUX
|
||||
|
||||
#if defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
|
||||
// Defines this iff regular expression matchers are supported. This
|
||||
// is public as it tells a user whether he can use regular expression
|
||||
// matchers.
|
||||
#define GMOCK_HAS_REGEX 1
|
||||
#endif // defined(GMOCK_USES_PCRE) || defined(GMOCK_USES_POSIX_RE)
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// For Windows, check the compiler version. At least VS 2005 SP1 is
|
||||
// required to compile Google Mock.
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
|
||||
#if _MSC_VER < 1400
|
||||
#error "At least Visual Studio 2005 SP1 is required to compile Google Mock."
|
||||
#elif _MSC_VER == 1400
|
||||
|
||||
// Unfortunately there is no unique _MSC_VER number for SP1. So for VS 2005
|
||||
// we have to check if it has SP1 by checking whether a bug fixed in SP1
|
||||
// is present. The bug in question is
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702
|
||||
// where the compiler incorrectly reports sizeof(poiter to an array).
|
||||
|
||||
class TestForSP1 {
|
||||
private: // GCC complains if x_ is used by sizeof before defining it.
|
||||
static char x_[100];
|
||||
// VS 2005 RTM incorrectly reports sizeof(&x) as 100, and that value
|
||||
// is used to trigger 'invalid negative array size' error. If you
|
||||
// see this error, upgrade to VS 2005 SP1 since Google Mock will not
|
||||
// compile in VS 2005 RTM.
|
||||
static char Google_Mock_requires_Visual_Studio_2005_SP1_or_later_to_compile_[
|
||||
sizeof(&x_) != 100 ? 1 : -1];
|
||||
};
|
||||
|
||||
#endif // _MSC_VER
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Use implicit_cast as a safe version of static_cast or const_cast
|
||||
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
|
||||
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
|
||||
// a const pointer to Foo).
|
||||
// When you use implicit_cast, the compiler checks that the cast is safe.
|
||||
// Such explicit implicit_casts are necessary in surprisingly many
|
||||
// situations where C++ demands an exact type match instead of an
|
||||
// argument type convertable to a target type.
|
||||
//
|
||||
// The From type can be inferred, so the preferred syntax for using
|
||||
// implicit_cast is the same as for static_cast etc.:
|
||||
//
|
||||
// implicit_cast<ToType>(expr)
|
||||
//
|
||||
// implicit_cast would have been part of the C++ standard library,
|
||||
// but the proposal was submitted too late. It will probably make
|
||||
// its way into the language in the future.
|
||||
template<typename To, typename From>
|
||||
inline To implicit_cast(From const &f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
// When you upcast (that is, cast a pointer from type Foo to type
|
||||
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
|
||||
// always succeed. When you downcast (that is, cast a pointer from
|
||||
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
|
||||
// how do you know the pointer is really of type SubclassOfFoo? It
|
||||
// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
|
||||
// when you downcast, you should use this macro. In debug mode, we
|
||||
// use dynamic_cast<> to double-check the downcast is legal (we die
|
||||
// if it's not). In normal mode, we do the efficient static_cast<>
|
||||
// instead. Thus, it's important to test in debug mode to make sure
|
||||
// the cast is legal!
|
||||
// This is the only place in the code we should use dynamic_cast<>.
|
||||
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
|
||||
// do RTTI (eg code like this:
|
||||
// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
|
||||
// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
|
||||
// You should design the code some other way not to need this.
|
||||
template<typename To, typename From> // use like this: down_cast<T*>(foo);
|
||||
inline To down_cast(From* f) { // so we only accept pointers
|
||||
// Ensures that To is a sub-type of From *. This test is here only
|
||||
// for compile-time type checking, and has no overhead in an
|
||||
// optimized build at run-time, as it will be optimized away
|
||||
// completely.
|
||||
if (false) {
|
||||
implicit_cast<From*, To>(0);
|
||||
}
|
||||
|
||||
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
|
||||
return static_cast<To>(f);
|
||||
}
|
||||
|
||||
// The GMOCK_COMPILE_ASSERT macro can be used to verify that a compile time
|
||||
// expression is true. For example, you could use it to verify the
|
||||
// size of a static array:
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
|
||||
// content_type_names_incorrect_size);
|
||||
//
|
||||
// or to make sure a struct is smaller than a certain size:
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
|
||||
//
|
||||
// The second argument to the macro is the name of the variable. If
|
||||
// the expression is false, most compilers will issue a warning/error
|
||||
// containing the name of the variable.
|
||||
|
||||
template <bool>
|
||||
struct CompileAssert {
|
||||
};
|
||||
|
||||
#define GMOCK_COMPILE_ASSERT(expr, msg) \
|
||||
typedef ::testing::internal::CompileAssert<(bool(expr))> \
|
||||
msg[bool(expr) ? 1 : -1]
|
||||
|
||||
// Implementation details of GMOCK_COMPILE_ASSERT:
|
||||
//
|
||||
// - GMOCK_COMPILE_ASSERT works by defining an array type that has -1
|
||||
// elements (and thus is invalid) when the expression is false.
|
||||
//
|
||||
// - The simpler definition
|
||||
//
|
||||
// #define GMOCK_COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
|
||||
//
|
||||
// does not work, as gcc supports variable-length arrays whose sizes
|
||||
// are determined at run-time (this is gcc's extension and not part
|
||||
// of the C++ standard). As a result, gcc fails to reject the
|
||||
// following code with the simple definition:
|
||||
//
|
||||
// int foo;
|
||||
// GMOCK_COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
|
||||
// // not a compile-time constant.
|
||||
//
|
||||
// - By using the type CompileAssert<(bool(expr))>, we ensures that
|
||||
// expr is a compile-time constant. (Template arguments must be
|
||||
// determined at compile-time.)
|
||||
//
|
||||
// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
|
||||
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
|
||||
//
|
||||
// CompileAssert<bool(expr)>
|
||||
//
|
||||
// instead, these compilers will refuse to compile
|
||||
//
|
||||
// GMOCK_COMPILE_ASSERT(5 > 0, some_message);
|
||||
//
|
||||
// (They seem to think the ">" in "5 > 0" marks the end of the
|
||||
// template argument list.)
|
||||
//
|
||||
// - The array size is (bool(expr) ? 1 : -1), instead of simply
|
||||
//
|
||||
// ((expr) ? 1 : -1).
|
||||
//
|
||||
// This is to avoid running into a bug in MS VC 7.1, which
|
||||
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
typedef ::string string;
|
||||
#elif GTEST_HAS_STD_STRING
|
||||
typedef ::std::string string;
|
||||
#else
|
||||
#error "Google Mock requires ::std::string to compile."
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
typedef ::wstring wstring;
|
||||
#elif GTEST_HAS_STD_WSTRING
|
||||
typedef ::std::wstring wstring;
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||
//
|
||||
// GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
|
||||
// is not satisfied.
|
||||
// Synopsys:
|
||||
// GMOCK_CHECK_(boolean_condition);
|
||||
// or
|
||||
// GMOCK_CHECK_(boolean_condition) << "Additional message";
|
||||
//
|
||||
// This checks the condition and if the condition is not satisfied
|
||||
// it prints message about the condition violation, including the
|
||||
// condition itself, plus additional message streamed into it, if any,
|
||||
// and then it aborts the program. It aborts the program irrespective of
|
||||
// whether it is built in the debug mode or not.
|
||||
|
||||
class GMockCheckProvider {
|
||||
public:
|
||||
GMockCheckProvider(const char* condition, const char* file, int line) {
|
||||
FormatFileLocation(file, line);
|
||||
::std::cerr << " ERROR: Condition " << condition << " failed. ";
|
||||
}
|
||||
~GMockCheckProvider() {
|
||||
::std::cerr << ::std::endl;
|
||||
abort();
|
||||
}
|
||||
void FormatFileLocation(const char* file, int line) {
|
||||
if (file == NULL)
|
||||
file = "unknown file";
|
||||
if (line < 0) {
|
||||
::std::cerr << file << ":";
|
||||
} else {
|
||||
#if _MSC_VER
|
||||
::std::cerr << file << "(" << line << "):";
|
||||
#else
|
||||
::std::cerr << file << ":" << line << ":";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
::std::ostream& GetStream() { return ::std::cerr; }
|
||||
};
|
||||
#define GMOCK_CHECK_(condition) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (condition) \
|
||||
; \
|
||||
else \
|
||||
::testing::internal::GMockCheckProvider(\
|
||||
#condition, __FILE__, __LINE__).GetStream()
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
// Macro for referencing flags.
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool(name) extern bool GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_int32(name) \
|
||||
extern ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_string(name) \
|
||||
extern ::testing::internal::String GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool(name, default_val, doc) \
|
||||
bool GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_int32(name, default_val, doc) \
|
||||
::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_string(name, default_val, doc) \
|
||||
::testing::internal::String GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
109
make/Makefile
Normal file
109
make/Makefile
Normal file
@ -0,0 +1,109 @@
|
||||
# A sample Makefile for building both Google Mock and Google Test and
|
||||
# using them in user tests. This file is self-contained, so you don't
|
||||
# need to use the Makefile in Google Test's source tree. Please tweak
|
||||
# it to suit your environment and project. You may want to move it to
|
||||
# your project's root directory.
|
||||
#
|
||||
# SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
# Please tweak the following variable definitions as needed by your
|
||||
# project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use
|
||||
# in your own targets but shouldn't modify.
|
||||
|
||||
# Points to the root of Google Test, relative to where this file is.
|
||||
# Remember to tweak this if you move this file, or if you want to use
|
||||
# a copy of Google Test at a different location.
|
||||
GTEST_DIR = ../gtest
|
||||
|
||||
# Points to the root of Google Mock, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
GMOCK_DIR = ..
|
||||
|
||||
# Where to find user code.
|
||||
USER_DIR = ../test
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
CPPFLAGS += -I$(GMOCK_DIR) -I$(GMOCK_DIR)/include \
|
||||
-I$(GTEST_DIR) -I$(GTEST_DIR)/include
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
# created to the list.
|
||||
TESTS = gmock_link_test gmock_test
|
||||
|
||||
# All Google Test headers. Usually you shouldn't change this
|
||||
# definition.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
|
||||
# All Google Mock headers. Note that all Google Test headers are
|
||||
# included here too, as they are #included by Google Mock headers.
|
||||
# Usually you shouldn't change this definition.
|
||||
GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
|
||||
$(GMOCK_DIR)/include/gmock/internal/*.h \
|
||||
$(GTEST_HEADERS)
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : $(TESTS)
|
||||
|
||||
clean :
|
||||
rm -f $(TESTS) gmock.a gmock_main.a *.o
|
||||
|
||||
# Builds gmock.a and gmock_main.a. These libraries contain both
|
||||
# Google Mock and Google Test. A test should link with either gmock.a
|
||||
# or gmock_main.a, depending on whether it defines its own main()
|
||||
# function. It's fine if your test only uses features from Google
|
||||
# Test (and not Google Mock).
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
|
||||
|
||||
# For simplicity and to avoid depending on implementation details of
|
||||
# Google Mock and Google Test, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Mock and
|
||||
# Google Test compile fast and for ordinary users their source rarely
|
||||
# changes.
|
||||
gtest-all.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gmock-all.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock-all.cc
|
||||
|
||||
gmock_main.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GMOCK_DIR)/src/gmock_main.cc
|
||||
|
||||
gmock.a : gmock-all.o gtest-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gmock_main.a : gmock-all.o gtest-all.o gmock_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Builds a sample test.
|
||||
|
||||
gmock-sample.o : $(USER_DIR)/gmock-sample.cc $(USER_DIR)/gmock-sample.h \
|
||||
$(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock-sample.cc
|
||||
|
||||
gmock_link_test.o : $(USER_DIR)/gmock_link_test.cc \
|
||||
$(USER_DIR)/gmock-sample.h $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_link_test.cc
|
||||
|
||||
gmock_link_test : gmock-sample.o gmock_link_test.o gmock_main.a
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
||||
|
||||
# Builds another sample test.
|
||||
|
||||
gmock_test.o : $(USER_DIR)/gmock_test.cc $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_test.cc
|
||||
|
||||
gmock_test : gmock_test.o gmock_main.a
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
|
203
scripts/generator/COPYING
Normal file
203
scripts/generator/COPYING
Normal file
@ -0,0 +1,203 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [2007] Neal Norwitz
|
||||
Portions Copyright [2007] Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
33
scripts/generator/README
Normal file
33
scripts/generator/README
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
The Google Mock class generator is an application that is part of cppclean.
|
||||
For more information about cppclean, see the README.cppclean file or
|
||||
visit http://code.google.com/p/cppclean/
|
||||
|
||||
cppclean requires Python 2.4 or later. If you don't have Python installed
|
||||
on your system, you will also need to install it. You can download Python
|
||||
from: http://www.python.org/download/releases/
|
||||
|
||||
To use the Google Mock class generator, you need to call it
|
||||
on the command line passing the header file and class for which you want
|
||||
to generate a Google Mock class.
|
||||
|
||||
Make sure to install the scripts somewhere in your path. Then you can
|
||||
run the program.
|
||||
|
||||
gmock_gen.py header-file.h ClassName
|
||||
|
||||
To change the indentation from the default of 2, set INDENT in
|
||||
the environment. For example to use an indent of 4 spaces:
|
||||
|
||||
INDENT=4 gmock_gen.py header-file.h ClassName
|
||||
|
||||
This version was made from SVN revision 279 in the cppclean repository.
|
||||
|
||||
Known Limitations
|
||||
-----------------
|
||||
Not all code will be generated properly. For example, when mocking templated
|
||||
classes, the template information is lost. You will need to add the template
|
||||
information manually.
|
||||
|
||||
Not all permutations of using multiple pointers/references will be rendered
|
||||
properly. These will also have to be fixed manually.
|
115
scripts/generator/README.cppclean
Normal file
115
scripts/generator/README.cppclean
Normal file
@ -0,0 +1,115 @@
|
||||
Goal:
|
||||
-----
|
||||
CppClean attempts to find problems in C++ source that slow development
|
||||
in large code bases, for example various forms of unused code.
|
||||
Unused code can be unused functions, methods, data members, types, etc
|
||||
to unnecessary #include directives. Unnecessary #includes can cause
|
||||
considerable extra compiles increasing the edit-compile-run cycle.
|
||||
|
||||
The project home page is: http://code.google.com/p/cppclean/
|
||||
|
||||
|
||||
Features:
|
||||
---------
|
||||
* Find and print C++ language constructs: classes, methods, functions, etc.
|
||||
* Find classes with virtual methods, no virtual destructor, and no bases
|
||||
* Find global/static data that are potential problems when using threads
|
||||
* Unnecessary forward class declarations
|
||||
* Unnecessary function declarations
|
||||
* Undeclared function definitions
|
||||
* (planned) Find unnecessary header files #included
|
||||
- No direct reference to anything in the header
|
||||
- Header is unnecessary if classes were forward declared instead
|
||||
* (planned) Source files that reference headers not directly #included,
|
||||
ie, files that rely on a transitive #include from another header
|
||||
* (planned) Unused members (private, protected, & public) methods and data
|
||||
* (planned) Store AST in a SQL database so relationships can be queried
|
||||
|
||||
AST is Abstract Syntax Tree, a representation of parsed source code.
|
||||
http://en.wikipedia.org/wiki/Abstract_syntax_tree
|
||||
|
||||
|
||||
System Requirements:
|
||||
--------------------
|
||||
* Python 2.4 or later (2.3 probably works too)
|
||||
* Works on Windows (untested), Mac OS X, and Unix
|
||||
|
||||
|
||||
How to Run:
|
||||
-----------
|
||||
For all examples, it is assumed that cppclean resides in a directory called
|
||||
/cppclean.
|
||||
|
||||
To print warnings for classes with virtual methods, no virtual destructor and
|
||||
no base classes:
|
||||
|
||||
/cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ...
|
||||
|
||||
To print all the functions defined in header file(s):
|
||||
|
||||
/cppclean/run.sh functions.py file1.h file2.h ...
|
||||
|
||||
All the commands take multiple files on the command line. Other programs
|
||||
include: find_warnings, headers, methods, and types. Some other programs
|
||||
are available, but used primarily for debugging.
|
||||
|
||||
run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then
|
||||
runs the program in /cppclean/cpp/PROGRAM.py. There is currently
|
||||
no equivalent for Windows. Contributions for a run.bat file
|
||||
would be greatly appreciated.
|
||||
|
||||
|
||||
How to Configure:
|
||||
-----------------
|
||||
You can add a siteheaders.py file in /cppclean/cpp to configure where
|
||||
to look for other headers (typically -I options passed to a compiler).
|
||||
Currently two values are supported: _TRANSITIVE and GetIncludeDirs.
|
||||
_TRANSITIVE should be set to a boolean value (True or False) indicating
|
||||
whether to transitively process all header files. The default is False.
|
||||
|
||||
GetIncludeDirs is a function that takes a single argument and returns
|
||||
a sequence of directories to include. This can be a generator or
|
||||
return a static list.
|
||||
|
||||
def GetIncludeDirs(filename):
|
||||
return ['/some/path/with/other/headers']
|
||||
|
||||
# Here is a more complicated example.
|
||||
def GetIncludeDirs(filename):
|
||||
yield '/path1'
|
||||
yield os.path.join('/path2', os.path.dirname(filename))
|
||||
yield '/path3'
|
||||
|
||||
|
||||
How to Test:
|
||||
------------
|
||||
For all examples, it is assumed that cppclean resides in a directory called
|
||||
/cppclean. The tests require
|
||||
|
||||
cd /cppclean
|
||||
make test
|
||||
# To generate expected results after a change:
|
||||
make expected
|
||||
|
||||
|
||||
Current Status:
|
||||
---------------
|
||||
The parser works pretty well for header files, parsing about 99% of Google's
|
||||
header files. Anything which inspects structure of C++ source files should
|
||||
work reasonably well. Function bodies are not transformed to an AST,
|
||||
but left as tokens. Much work is still needed on finding unused header files
|
||||
and storing an AST in a database.
|
||||
|
||||
|
||||
Non-goals:
|
||||
----------
|
||||
* Parsing all valid C++ source
|
||||
* Handling invalid C++ source gracefully
|
||||
* Compiling to machine code (or anything beyond an AST)
|
||||
|
||||
|
||||
Contact:
|
||||
--------
|
||||
If you used cppclean, I would love to hear about your experiences
|
||||
cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to
|
||||
hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com)
|
0
scripts/generator/cpp/__init__.py
Executable file
0
scripts/generator/cpp/__init__.py
Executable file
1713
scripts/generator/cpp/ast.py
Executable file
1713
scripts/generator/cpp/ast.py
Executable file
File diff suppressed because it is too large
Load Diff
148
scripts/generator/cpp/gmock_class.py
Executable file
148
scripts/generator/cpp/gmock_class.py
Executable file
@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Generate a Google Mock class from a production class.
|
||||
|
||||
This program will read in a C++ source file and output the Google Mock class
|
||||
for the specified class.
|
||||
|
||||
Usage:
|
||||
gmock_class.py header-file.h ClassName
|
||||
|
||||
Output is sent to stdout.
|
||||
"""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from cpp import ast
|
||||
from cpp import utils
|
||||
|
||||
# How many spaces to indent. Can me set with INDENT environment variable.
|
||||
_INDENT = 2
|
||||
|
||||
|
||||
def _GenerateMethods(output_lines, source, class_node):
|
||||
function_type = ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL
|
||||
ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR
|
||||
|
||||
for node in class_node.body:
|
||||
# We only care about virtual functions.
|
||||
if (isinstance(node, ast.Function) and
|
||||
node.modifiers & function_type and
|
||||
not node.modifiers & ctor_or_dtor):
|
||||
# Pick out all the elements we need from the original function.
|
||||
const = ''
|
||||
if node.modifiers & ast.FUNCTION_CONST:
|
||||
const = 'CONST_'
|
||||
return_type = 'void'
|
||||
if node.return_type:
|
||||
return_type = node.return_type.name
|
||||
if node.return_type.pointer:
|
||||
return_type += '*'
|
||||
if node.return_type.reference:
|
||||
return_type += '&'
|
||||
prefix = 'MOCK_%sMETHOD%d' % (const, len(node.parameters))
|
||||
args = ''
|
||||
if node.parameters:
|
||||
# Get the full text of the parameters from the start
|
||||
# of the first parameter to the end of the last parameter.
|
||||
start = node.parameters[0].start
|
||||
end = node.parameters[-1].end
|
||||
args = re.sub(' +', ' ', source[start:end].replace('\n', ''))
|
||||
|
||||
# Create the prototype.
|
||||
indent = ' ' * _INDENT
|
||||
line = ('%s%s(%s,\n%s%s(%s));' %
|
||||
(indent, prefix, node.name, indent*3, return_type, args))
|
||||
output_lines.append(line)
|
||||
|
||||
|
||||
def _GenerateMock(filename, source, ast_list, class_name):
|
||||
lines = []
|
||||
for node in ast_list:
|
||||
if isinstance(node, ast.Class) and node.body and node.name == class_name:
|
||||
class_node = node
|
||||
# Add namespace before the class.
|
||||
if class_node.namespace:
|
||||
lines.extend(['namespace %s {' % n for n in class_node.namespace]) # }
|
||||
lines.append('')
|
||||
|
||||
# Add the class prolog.
|
||||
lines.append('class Mock%s : public %s {' % (class_name, class_name)) # }
|
||||
lines.append('%spublic:' % (' ' * (_INDENT // 2)))
|
||||
|
||||
# Add all the methods.
|
||||
_GenerateMethods(lines, source, class_node)
|
||||
|
||||
# Close the class.
|
||||
if lines:
|
||||
# If there are no virtual methods, no need for a public label.
|
||||
if len(lines) == 2:
|
||||
del lines[-1]
|
||||
|
||||
# Only close the class if there really is a class.
|
||||
lines.append('};')
|
||||
lines.append('') # Add an extra newline.
|
||||
|
||||
# Close the namespace.
|
||||
if class_node.namespace:
|
||||
for i in range(len(class_node.namespace)-1, -1, -1):
|
||||
lines.append('} // namespace %s' % class_node.namespace[i])
|
||||
lines.append('') # Add an extra newline.
|
||||
|
||||
if lines:
|
||||
sys.stdout.write('\n'.join(lines))
|
||||
else:
|
||||
sys.stderr.write('Class %s not found\n' % class_name)
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
if len(argv) != 3:
|
||||
sys.stdout.write(__doc__)
|
||||
return 1
|
||||
|
||||
global _INDENT
|
||||
try:
|
||||
_INDENT = int(os.environ['INDENT'])
|
||||
except KeyError:
|
||||
pass
|
||||
except:
|
||||
sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT'))
|
||||
|
||||
filename, class_name = argv[1:]
|
||||
source = utils.ReadFile(filename)
|
||||
if source is None:
|
||||
return 1
|
||||
|
||||
builder = ast.BuilderFromSource(source, filename)
|
||||
try:
|
||||
entire_ast = filter(None, builder.Generate())
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
except:
|
||||
# An error message was already printed since we couldn't parse.
|
||||
pass
|
||||
else:
|
||||
_GenerateMock(filename, source, entire_ast, class_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
58
scripts/generator/cpp/keywords.py
Executable file
58
scripts/generator/cpp/keywords.py
Executable file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""C++ keywords and helper utilities for determining keywords."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
try:
|
||||
# Python 3.x
|
||||
import builtins
|
||||
except ImportError:
|
||||
# Python 2.x
|
||||
import __builtin__ as builtins
|
||||
|
||||
|
||||
if not hasattr(builtins, 'set'):
|
||||
# Nominal support for Python 2.3.
|
||||
from sets import Set as set
|
||||
|
||||
|
||||
TYPES = set('bool char int long short double float void wchar_t unsigned signed'.split())
|
||||
TYPE_MODIFIERS = set('auto register const inline extern static virtual volatile mutable'.split())
|
||||
ACCESS = set('public protected private friend'.split())
|
||||
|
||||
CASTS = set('static_cast const_cast dynamic_cast reinterpret_cast'.split())
|
||||
|
||||
OTHERS = set('true false asm class namespace using explicit this operator sizeof'.split())
|
||||
OTHER_TYPES = set('new delete typedef struct union enum typeid typename template'.split())
|
||||
|
||||
CONTROL = set('case switch default if else return goto'.split())
|
||||
EXCEPTION = set('try catch throw'.split())
|
||||
LOOP = set('while do for break continue'.split())
|
||||
|
||||
ALL = TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | CONTROL | EXCEPTION | LOOP
|
||||
|
||||
|
||||
def IsKeyword(token):
|
||||
return token in ALL
|
||||
|
||||
def IsBuiltinType(token):
|
||||
if token in ('virtual', 'inline'):
|
||||
# These only apply to methods, they can't be types by themselves.
|
||||
return False
|
||||
return token in TYPES or token in TYPE_MODIFIERS
|
287
scripts/generator/cpp/tokenize.py
Executable file
287
scripts/generator/cpp/tokenize.py
Executable file
@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Tokenize C++ source code."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
try:
|
||||
# Python 3.x
|
||||
import builtins
|
||||
except ImportError:
|
||||
# Python 2.x
|
||||
import __builtin__ as builtins
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from cpp import utils
|
||||
|
||||
|
||||
if not hasattr(builtins, 'set'):
|
||||
# Nominal support for Python 2.3.
|
||||
from sets import Set as set
|
||||
|
||||
|
||||
# Add $ as a valid identifier char since so much code uses it.
|
||||
_letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
VALID_IDENTIFIER_CHARS = set(_letters + _letters.upper() + '_0123456789$')
|
||||
HEX_DIGITS = set('0123456789abcdefABCDEF')
|
||||
INT_OR_FLOAT_DIGITS = set('01234567890eE-+')
|
||||
|
||||
|
||||
# C++0x string preffixes.
|
||||
_STR_PREFIXES = set(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR'))
|
||||
|
||||
|
||||
# Token types.
|
||||
UNKNOWN = 'UNKNOWN'
|
||||
SYNTAX = 'SYNTAX'
|
||||
CONSTANT = 'CONSTANT'
|
||||
NAME = 'NAME'
|
||||
PREPROCESSOR = 'PREPROCESSOR'
|
||||
|
||||
# Where the token originated from. This can be used for backtracking.
|
||||
# It is always set to WHENCE_STREAM in this code.
|
||||
WHENCE_STREAM, WHENCE_QUEUE = range(2)
|
||||
|
||||
|
||||
class Token(object):
|
||||
"""Data container to represent a C++ token.
|
||||
|
||||
Tokens can be identifiers, syntax char(s), constants, or
|
||||
pre-processor directives.
|
||||
|
||||
start contains the index of the first char of the token in the source
|
||||
end contains the index of the last char of the token in the source
|
||||
"""
|
||||
|
||||
def __init__(self, token_type, name, start, end):
|
||||
self.token_type = token_type
|
||||
self.name = name
|
||||
self.start = start
|
||||
self.end = end
|
||||
self.whence = WHENCE_STREAM
|
||||
|
||||
def __str__(self):
|
||||
if not utils.DEBUG:
|
||||
return 'Token(%r)' % self.name
|
||||
return 'Token(%r, %s, %s)' % (self.name, self.start, self.end)
|
||||
|
||||
__repr__ = __str__
|
||||
|
||||
|
||||
def _GetString(source, start, i):
|
||||
i = source.find('"', i+1)
|
||||
while source[i-1] == '\\':
|
||||
# Count the trailing backslashes.
|
||||
backslash_count = 1
|
||||
j = i - 2
|
||||
while source[j] == '\\':
|
||||
backslash_count += 1
|
||||
j -= 1
|
||||
# When trailing backslashes are even, they escape each other.
|
||||
if (backslash_count % 2) == 0:
|
||||
break
|
||||
i = source.find('"', i+1)
|
||||
return i + 1
|
||||
|
||||
|
||||
def _GetChar(source, start, i):
|
||||
# NOTE(nnorwitz): may not be quite correct, should be good enough.
|
||||
i = source.find("'", i+1)
|
||||
while source[i-1] == '\\':
|
||||
# Need to special case '\\'.
|
||||
if (i - 2) > start and source[i-2] == '\\':
|
||||
break
|
||||
i = source.find("'", i+1)
|
||||
# Try to handle unterminated single quotes (in a #if 0 block).
|
||||
if i < 0:
|
||||
i = start
|
||||
return i + 1
|
||||
|
||||
|
||||
def GetTokens(source):
|
||||
"""Returns a sequence of Tokens.
|
||||
|
||||
Args:
|
||||
source: string of C++ source code.
|
||||
|
||||
Yields:
|
||||
Token that represents the next token in the source.
|
||||
"""
|
||||
# Cache various valid character sets for speed.
|
||||
valid_identifier_chars = VALID_IDENTIFIER_CHARS
|
||||
hex_digits = HEX_DIGITS
|
||||
int_or_float_digits = INT_OR_FLOAT_DIGITS
|
||||
int_or_float_digits2 = int_or_float_digits | set('.')
|
||||
|
||||
# Only ignore errors while in a #if 0 block.
|
||||
ignore_errors = False
|
||||
count_ifs = 0
|
||||
|
||||
i = 0
|
||||
end = len(source)
|
||||
while i < end:
|
||||
# Skip whitespace.
|
||||
while i < end and source[i].isspace():
|
||||
i += 1
|
||||
if i >= end:
|
||||
return
|
||||
|
||||
token_type = UNKNOWN
|
||||
start = i
|
||||
c = source[i]
|
||||
if c.isalpha() or c == '_': # Find a string token.
|
||||
token_type = NAME
|
||||
while source[i] in valid_identifier_chars:
|
||||
i += 1
|
||||
# String and character constants can look like a name if
|
||||
# they are something like L"".
|
||||
if (source[i] == "'" and (i - start) == 1 and
|
||||
source[start:i] in 'uUL'):
|
||||
# u, U, and L are valid C++0x character preffixes.
|
||||
token_type = CONSTANT
|
||||
i = _GetChar(source, start, i)
|
||||
elif source[i] == "'" and source[start:i] in _STR_PREFIXES:
|
||||
token_type = CONSTANT
|
||||
i = _GetString(source, start, i)
|
||||
elif c == '/' and source[i+1] == '/': # Find // comments.
|
||||
i = source.find('\n', i)
|
||||
if i == -1: # Handle EOF.
|
||||
i = end
|
||||
continue
|
||||
elif c == '/' and source[i+1] == '*': # Find /* comments. */
|
||||
i = source.find('*/', i) + 2
|
||||
continue
|
||||
elif c in ':+-<>&|*=': # : or :: (plus other chars).
|
||||
token_type = SYNTAX
|
||||
i += 1
|
||||
new_ch = source[i]
|
||||
if new_ch == c:
|
||||
i += 1
|
||||
elif c == '-' and new_ch == '>':
|
||||
i += 1
|
||||
elif new_ch == '=':
|
||||
i += 1
|
||||
elif c in '()[]{}~!?^%;/.,': # Handle single char tokens.
|
||||
token_type = SYNTAX
|
||||
i += 1
|
||||
if c == '.' and source[i].isdigit():
|
||||
token_type = CONSTANT
|
||||
i += 1
|
||||
while source[i] in int_or_float_digits:
|
||||
i += 1
|
||||
# Handle float suffixes.
|
||||
for suffix in ('l', 'f'):
|
||||
if suffix == source[i:i+1].lower():
|
||||
i += 1
|
||||
break
|
||||
elif c.isdigit(): # Find integer.
|
||||
token_type = CONSTANT
|
||||
if c == '0' and source[i+1] in 'xX':
|
||||
# Handle hex digits.
|
||||
i += 2
|
||||
while source[i] in hex_digits:
|
||||
i += 1
|
||||
else:
|
||||
while source[i] in int_or_float_digits2:
|
||||
i += 1
|
||||
# Handle integer (and float) suffixes.
|
||||
for suffix in ('ull', 'll', 'ul', 'l', 'f', 'u'):
|
||||
size = len(suffix)
|
||||
if suffix == source[i:i+size].lower():
|
||||
i += size
|
||||
break
|
||||
elif c == '"': # Find string.
|
||||
token_type = CONSTANT
|
||||
i = _GetString(source, start, i)
|
||||
elif c == "'": # Find char.
|
||||
token_type = CONSTANT
|
||||
i = _GetChar(source, start, i)
|
||||
elif c == '#': # Find pre-processor command.
|
||||
token_type = PREPROCESSOR
|
||||
got_if = source[i:i+3] == '#if' and source[i+3:i+4].isspace()
|
||||
if got_if:
|
||||
count_ifs += 1
|
||||
elif source[i:i+6] == '#endif':
|
||||
count_ifs -= 1
|
||||
if count_ifs == 0:
|
||||
ignore_errors = False
|
||||
|
||||
# TODO(nnorwitz): handle preprocessor statements (\ continuations).
|
||||
while 1:
|
||||
i1 = source.find('\n', i)
|
||||
i2 = source.find('//', i)
|
||||
i3 = source.find('/*', i)
|
||||
i4 = source.find('"', i)
|
||||
# NOTE(nnorwitz): doesn't handle comments in #define macros.
|
||||
# Get the first important symbol (newline, comment, EOF/end).
|
||||
i = min([x for x in (i1, i2, i3, i4, end) if x != -1])
|
||||
|
||||
# Handle #include "dir//foo.h" properly.
|
||||
if source[i] == '"':
|
||||
i = source.find('"', i+1) + 1
|
||||
assert i > 0
|
||||
continue
|
||||
# Keep going if end of the line and the line ends with \.
|
||||
if not (i == i1 and source[i-1] == '\\'):
|
||||
if got_if:
|
||||
condition = source[start+4:i].lstrip()
|
||||
if (condition.startswith('0') or
|
||||
condition.startswith('(0)')):
|
||||
ignore_errors = True
|
||||
break
|
||||
i += 1
|
||||
elif c == '\\': # Handle \ in code.
|
||||
# This is different from the pre-processor \ handling.
|
||||
i += 1
|
||||
continue
|
||||
elif ignore_errors:
|
||||
# The tokenizer seems to be in pretty good shape. This
|
||||
# raise is conditionally disabled so that bogus code
|
||||
# in an #if 0 block can be handled. Since we will ignore
|
||||
# it anyways, this is probably fine. So disable the
|
||||
# exception and return the bogus char.
|
||||
i += 1
|
||||
else:
|
||||
sys.stderr.write('Got invalid token in %s @ %d token:%s: %r\n' %
|
||||
('?', i, c, source[i-10:i+10]))
|
||||
raise RuntimeError('unexpected token')
|
||||
|
||||
if i <= 0:
|
||||
print('Invalid index, exiting now.')
|
||||
return
|
||||
yield Token(token_type, source[start:i], start, i)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main(argv):
|
||||
"""Driver mostly for testing purposes."""
|
||||
for filename in argv[1:]:
|
||||
source = utils.ReadFile(filename)
|
||||
if source is None:
|
||||
continue
|
||||
|
||||
for token in GetTokens(source):
|
||||
print('%-12s: %s' % (token.token_type, token.name))
|
||||
# print('\r%6.2f%%' % (100.0 * index / token.end),)
|
||||
sys.stdout.write('\n')
|
||||
|
||||
|
||||
main(sys.argv)
|
41
scripts/generator/cpp/utils.py
Executable file
41
scripts/generator/cpp/utils.py
Executable file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007 Neal Norwitz
|
||||
# Portions Copyright 2007 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Generic utilities for C++ parsing."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
# Set to True to see the start/end token indices.
|
||||
DEBUG = True
|
||||
|
||||
|
||||
def ReadFile(filename, print_error=True):
|
||||
"""Returns the contents of a file."""
|
||||
try:
|
||||
fp = open(filename)
|
||||
try:
|
||||
return fp.read()
|
||||
finally:
|
||||
fp.close()
|
||||
except IOError:
|
||||
if print_error:
|
||||
print('Error reading %s: %s' % (filename, sys.exc_info()[1]))
|
||||
return None
|
31
scripts/generator/gmock_gen.py
Executable file
31
scripts/generator/gmock_gen.py
Executable file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/python2.4
|
||||
#
|
||||
# Copyright 2008 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Driver for starting up Google Mock class generator."""
|
||||
|
||||
__author__ = 'nnorwitz@google.com (Neal Norwitz)'
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Add the directory of this script to the path so we can import gmock_class.
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
from cpp import gmock_class
|
||||
# Fix the docstring in case they require the usage.
|
||||
gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__)
|
||||
gmock_class.main()
|
376
scripts/gmock_doctor.py
Executable file
376
scripts/gmock_doctor.py
Executable file
@ -0,0 +1,376 @@
|
||||
#!/usr/bin/python2.4
|
||||
#
|
||||
# Copyright 2008, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Converts gcc errors in code using Google Mock to plain English."""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
_VERSION = '0.1.0.80421'
|
||||
|
||||
_COMMON_GMOCK_SYMBOLS = [
|
||||
# Matchers
|
||||
'_',
|
||||
'A',
|
||||
'AddressSatisfies',
|
||||
'AllOf',
|
||||
'An',
|
||||
'AnyOf',
|
||||
'ContainsRegex',
|
||||
'DoubleEq',
|
||||
'EndsWith',
|
||||
'Eq',
|
||||
'Field',
|
||||
'FloatEq',
|
||||
'Ge',
|
||||
'Gt',
|
||||
'HasSubstr',
|
||||
'Le',
|
||||
'Lt',
|
||||
'MatcherCast',
|
||||
'MatchesRegex',
|
||||
'Ne',
|
||||
'Not',
|
||||
'NotNull',
|
||||
'Pointee',
|
||||
'Property',
|
||||
'Ref',
|
||||
'StartsWith',
|
||||
'StrCaseEq',
|
||||
'StrCaseNe',
|
||||
'StrEq',
|
||||
'StrNe',
|
||||
'Truly',
|
||||
'TypedEq',
|
||||
|
||||
# Actions
|
||||
'ByRef',
|
||||
'DoAll',
|
||||
'DoDefault',
|
||||
'IgnoreResult',
|
||||
'Invoke',
|
||||
'InvokeArgument',
|
||||
'InvokeWithoutArgs',
|
||||
'Return',
|
||||
'ReturnNull',
|
||||
'ReturnRef',
|
||||
'SetArgumentPointee',
|
||||
'SetArrayArgument',
|
||||
'WithArgs',
|
||||
|
||||
# Cardinalities
|
||||
'AnyNumber',
|
||||
'AtLeast',
|
||||
'AtMost',
|
||||
'Between',
|
||||
'Exactly',
|
||||
|
||||
# Sequences
|
||||
'InSequence',
|
||||
'Sequence',
|
||||
|
||||
# Misc
|
||||
'DefaultValue',
|
||||
'Mock',
|
||||
]
|
||||
|
||||
|
||||
def _FindAllMatches(regex, s):
|
||||
"""Generates all matches of regex in string s."""
|
||||
|
||||
r = re.compile(regex)
|
||||
return r.finditer(s)
|
||||
|
||||
|
||||
def _GenericDiagnoser(short_name, long_name, regex, diagnosis, msg):
|
||||
"""Diagnoses the given disease by pattern matching.
|
||||
|
||||
Args:
|
||||
short_name: Short name of the disease.
|
||||
long_name: Long name of the disease.
|
||||
regex: Regex for matching the symptoms.
|
||||
diagnosis: Pattern for formatting the diagnosis.
|
||||
msg: Gcc's error messages.
|
||||
Yields:
|
||||
Tuples of the form
|
||||
(short name of disease, long name of disease, diagnosis).
|
||||
"""
|
||||
|
||||
for m in _FindAllMatches(regex, msg):
|
||||
yield (short_name, long_name, diagnosis % m.groupdict())
|
||||
|
||||
|
||||
def _NeedToReturnReferenceDiagnoser(msg):
|
||||
"""Diagnoses the NRR disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
|
||||
r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: creating array with negative size')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are using an Return() action in a function that returns a reference.
|
||||
Please use ReturnRef() instead."""
|
||||
return _GenericDiagnoser('NRR', 'Need to Return Reference',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _NeedToReturnSomethingDiagnoser(msg):
|
||||
"""Diagnoses the NRS disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: void value not ignored')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are using an action that returns void, but it needs to return
|
||||
*something*. Please tell it *what* to return."""
|
||||
return _GenericDiagnoser('NRS', 'Need to Return Something',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _NeedToReturnNothingDiagnoser(msg):
|
||||
"""Diagnoses the NRN disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: return-statement with a value, '
|
||||
r'in function returning \'void\'')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are using an action that returns *something*, but it needs to return
|
||||
void. Please use a void-returning action instead.
|
||||
|
||||
All actions but the last in DoAll(...) must return void. Perhaps you need
|
||||
to re-arrange the order of actions in a DoAll(), if you are using one?"""
|
||||
return _GenericDiagnoser('NRN', 'Need to Return Nothing',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _IncompleteByReferenceArgumentDiagnoser(msg):
|
||||
"""Diagnoses the IBRA disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+):\s+instantiated from here\n'
|
||||
r'.*gmock-printers\.h.*error: invalid application of '
|
||||
r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
In order to mock this function, Google Mock needs to see the definition
|
||||
of type "%(type)s" - declaration alone is not enough. Either #include
|
||||
the header that defines it, or change the argument to be passed
|
||||
by pointer."""
|
||||
return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _OverloadedFunctionMatcherDiagnoser(msg):
|
||||
"""Diagnoses the OFM disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: no matching function for '
|
||||
r'call to \'Truly\(<unresolved overloaded function type>\)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
The argument you gave to Truly() is an overloaded function. Please tell
|
||||
gcc which overloaded version you want to use.
|
||||
|
||||
For example, if you want to use the version whose signature is
|
||||
bool Foo(int n);
|
||||
you should write
|
||||
Truly(static_cast<bool (*)(int n)>(Foo))"""
|
||||
return _GenericDiagnoser('OFM', 'Overloaded Function Matcher',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _OverloadedFunctionActionDiagnoser(msg):
|
||||
"""Diagnoses the OFA disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: '
|
||||
r'no matching function for call to \'Invoke\('
|
||||
r'<unresolved overloaded function type>')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
You are passing an overloaded function to Invoke(). Please tell gcc
|
||||
which overloaded version you want to use.
|
||||
|
||||
For example, if you want to use the version whose signature is
|
||||
bool MyFunction(int n, double x);
|
||||
you should write something like
|
||||
Invoke(static_cast<bool (*)(int n, double x)>(MyFunction))"""
|
||||
return _GenericDiagnoser('OFA', 'Overloaded Function Action',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _OverloadedMethodActionDiagnoser1(msg):
|
||||
"""Diagnoses the OMA disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: '
|
||||
r'.*no matching function for call to \'Invoke\(.*, '
|
||||
r'unresolved overloaded function type>')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
The second argument you gave to Invoke() is an overloaded method. Please
|
||||
tell gcc which overloaded version you want to use.
|
||||
|
||||
For example, if you want to use the version whose signature is
|
||||
class Foo {
|
||||
...
|
||||
bool Bar(int n, double x);
|
||||
};
|
||||
you should write something like
|
||||
Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
|
||||
return _GenericDiagnoser('OMA', 'Overloaded Method Action',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _MockObjectPointerDiagnoser(msg):
|
||||
"""Diagnoses the MOP disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: request for member '
|
||||
r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
|
||||
r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*,
|
||||
not a *pointer* to it. Please write '*(%(mock_object)s)' instead of
|
||||
'%(mock_object)s' as your first argument.
|
||||
|
||||
For example, given the mock class:
|
||||
|
||||
class %(class_name)s : public ... {
|
||||
...
|
||||
MOCK_METHOD0(%(method)s, ...);
|
||||
};
|
||||
|
||||
and the following mock instance:
|
||||
|
||||
%(class_name)s* mock_ptr = ...
|
||||
|
||||
you should use the EXPECT_CALL like this:
|
||||
|
||||
EXPECT_CALL(*mock_ptr, %(method)s(...));"""
|
||||
return _GenericDiagnoser('MOP', 'Mock Object Pointer',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _OverloadedMethodActionDiagnoser2(msg):
|
||||
"""Diagnoses the OMA disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: no matching function for '
|
||||
r'call to \'Invoke\(.+, <unresolved overloaded function type>\)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
The second argument you gave to Invoke() is an overloaded method. Please
|
||||
tell gcc which overloaded version you want to use.
|
||||
|
||||
For example, if you want to use the version whose signature is
|
||||
class Foo {
|
||||
...
|
||||
bool Bar(int n, double x);
|
||||
};
|
||||
you should write something like
|
||||
Invoke(foo, static_cast<bool (Foo::*)(int n, double x)>(&Foo::Bar))"""
|
||||
return _GenericDiagnoser('OMA', 'Overloaded Method Action',
|
||||
regex, diagnosis, msg)
|
||||
|
||||
|
||||
def _NeedToUseSymbolDiagnoser(msg):
|
||||
"""Diagnoses the NUS disease, given the error messages by gcc."""
|
||||
|
||||
regex = (r'(?P<file>.*):(?P<line>\d+): error: \'(?P<symbol>.+)\' '
|
||||
r'(was not declared in this scope|has not been declared)')
|
||||
diagnosis = """%(file)s:%(line)s:
|
||||
'%(symbol)s' is defined by Google Mock in the testing namespace.
|
||||
Did you forget to write
|
||||
using testing::%(symbol)s;
|
||||
?"""
|
||||
for m in _FindAllMatches(regex, msg):
|
||||
symbol = m.groupdict()['symbol']
|
||||
if symbol in _COMMON_GMOCK_SYMBOLS:
|
||||
yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict())
|
||||
|
||||
|
||||
_DIAGNOSERS = [
|
||||
_IncompleteByReferenceArgumentDiagnoser,
|
||||
_MockObjectPointerDiagnoser,
|
||||
_NeedToReturnNothingDiagnoser,
|
||||
_NeedToReturnReferenceDiagnoser,
|
||||
_NeedToReturnSomethingDiagnoser,
|
||||
_NeedToUseSymbolDiagnoser,
|
||||
_OverloadedFunctionActionDiagnoser,
|
||||
_OverloadedFunctionMatcherDiagnoser,
|
||||
_OverloadedMethodActionDiagnoser1,
|
||||
_OverloadedMethodActionDiagnoser2,
|
||||
]
|
||||
|
||||
|
||||
def Diagnose(msg):
|
||||
"""Generates all possible diagnoses given the gcc error message."""
|
||||
|
||||
for diagnoser in _DIAGNOSERS:
|
||||
for diagnosis in diagnoser(msg):
|
||||
yield '[%s - %s]\n%s' % diagnosis
|
||||
|
||||
|
||||
def main():
|
||||
print ('Google Mock Doctor v%s - '
|
||||
'diagnoses problems in code using Google Mock.' % _VERSION)
|
||||
|
||||
if sys.stdin.isatty():
|
||||
print ('Please copy and paste the compiler errors here. Press c-D when '
|
||||
'you are done:')
|
||||
else:
|
||||
print 'Waiting for compiler errors on stdin . . .'
|
||||
|
||||
msg = sys.stdin.read().strip()
|
||||
diagnoses = list(Diagnose(msg))
|
||||
count = len(diagnoses)
|
||||
if not count:
|
||||
print '\nGcc complained:'
|
||||
print '8<------------------------------------------------------------'
|
||||
print msg
|
||||
print '------------------------------------------------------------>8'
|
||||
print """
|
||||
Uh-oh, I'm not smart enough to figure out what the problem is. :-(
|
||||
However...
|
||||
If you send your source code and gcc's error messages to
|
||||
googlemock@googlegroups.com, you can be helped and I can get smarter --
|
||||
win-win for us!"""
|
||||
else:
|
||||
print '------------------------------------------------------------'
|
||||
print 'Your code appears to have the following',
|
||||
if count > 1:
|
||||
print '%s diseases:' % (count,)
|
||||
else:
|
||||
print 'disease:'
|
||||
i = 0
|
||||
for d in diagnoses:
|
||||
i += 1
|
||||
if count > 1:
|
||||
print '\n#%s:' % (i,)
|
||||
print d
|
||||
print """
|
||||
How did I do? If you think I'm wrong or unhelpful, please send your
|
||||
source code and gcc's error messages to googlemock@googlegroups.com. Then
|
||||
you can be helped and I can get smarter -- I promise I won't be upset!"""
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
43
src/gmock-all.cc
Normal file
43
src/gmock-all.cc
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Google C++ Mocking Framework (Google Mock)
|
||||
//
|
||||
// This file #includes all Google Mock implementation .cc files. The
|
||||
// purpose is to allow a user to build Google Mock by compiling this
|
||||
// file alone.
|
||||
|
||||
#include "src/gmock-cardinalities.cc"
|
||||
#include "src/gmock-internal-utils.cc"
|
||||
#include "src/gmock-matchers.cc"
|
||||
#include "src/gmock-printers.cc"
|
||||
#include "src/gmock-spec-builders.cc"
|
||||
#include "src/gmock.cc"
|
155
src/gmock-cardinalities.cc
Normal file
155
src/gmock-cardinalities.cc
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements cardinalities.
|
||||
|
||||
#include <gmock/gmock-cardinalities.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
// Implements the Between(m, n) cardinality.
|
||||
class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
public:
|
||||
BetweenCardinalityImpl(int min, int max)
|
||||
: min_(min >= 0 ? min : 0),
|
||||
max_(max >= min_ ? max : min_) {
|
||||
std::stringstream ss;
|
||||
if (min < 0) {
|
||||
ss << "The invocation lower bound must be >= 0, "
|
||||
<< "but is actually " << min << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (max < 0) {
|
||||
ss << "The invocation upper bound must be >= 0, "
|
||||
<< "but is actually " << max << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (min > max) {
|
||||
ss << "The invocation upper bound (" << max
|
||||
<< ") must be >= the invocation lower bound (" << min
|
||||
<< ").";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return min_; }
|
||||
virtual int ConservativeUpperBound() const { return max_; }
|
||||
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return min_ <= call_count && call_count <= max_ ;
|
||||
}
|
||||
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const {
|
||||
return call_count >= max_;
|
||||
}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const;
|
||||
private:
|
||||
const int min_;
|
||||
const int max_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
|
||||
};
|
||||
|
||||
// Formats "n times" in a human-friendly way.
|
||||
inline internal::string FormatTimes(int n) {
|
||||
if (n == 1) {
|
||||
return "once";
|
||||
} else if (n == 2) {
|
||||
return "twice";
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << n << " times";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the Between(m, n) cardinality in human-friendly text.
|
||||
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
|
||||
if (min_ == 0) {
|
||||
if (max_ == 0) {
|
||||
*os << "never called";
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called any number of times";
|
||||
} else {
|
||||
*os << "called at most " << FormatTimes(max_);
|
||||
}
|
||||
} else if (min_ == max_) {
|
||||
*os << "called " << FormatTimes(min_);
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called at least " << FormatTimes(min_);
|
||||
} else {
|
||||
// 0 < min_ < max_ < INT_MAX
|
||||
*os << "called between " << min_ << " and " << max_ << " times";
|
||||
}
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
|
||||
// Describes the given call count to an ostream.
|
||||
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os) {
|
||||
if (actual_call_count > 0) {
|
||||
*os << "called " << FormatTimes(actual_call_count);
|
||||
} else {
|
||||
*os << "never called";
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
Cardinality AtMost(int n) { return Between(0, n); }
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
Cardinality AnyNumber() { return AtLeast(0); }
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
Cardinality Between(int min, int max) {
|
||||
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
Cardinality Exactly(int n) { return Between(n, n); }
|
||||
|
||||
} // namespace testing
|
135
src/gmock-internal-utils.cc
Normal file
135
src/gmock-internal-utils.cc
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// This class reports Google Mock failures as Google Test failures. A
|
||||
// user can define another class in a similar fashion if he intends to
|
||||
// use Google Mock with a testing framework other than Google Test.
|
||||
class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||
public:
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) {
|
||||
AssertHelper(type == FATAL ? TPRT_FATAL_FAILURE : TPRT_NONFATAL_FAILURE,
|
||||
file, line, message.c_str()) = Message();
|
||||
if (type == FATAL) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the global failure reporter. Will create a
|
||||
// GoogleTestFailureReporter and return it the first time called.
|
||||
FailureReporterInterface* GetFailureReporter() {
|
||||
// Points to the global failure reporter used by Google Mock. gcc
|
||||
// guarantees that the following use of failure_reporter is
|
||||
// thread-safe. We may need to add additional synchronization to
|
||||
// protect failure_reporter if we port Google Mock to other
|
||||
// compilers.
|
||||
static FailureReporterInterface* const failure_reporter =
|
||||
new GoogleTestFailureReporter();
|
||||
return failure_reporter;
|
||||
}
|
||||
|
||||
// Protects global resources (stdout in particular) used by Log().
|
||||
static Mutex g_log_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
void Log(LogSeverity severity, const string& message,
|
||||
int stack_frames_to_skip) {
|
||||
if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
// The user is not interested in logs.
|
||||
return;
|
||||
} else if (GMOCK_FLAG(verbose) != kInfoVerbosity) {
|
||||
// The user is interested in warnings but not informational logs.
|
||||
// Note that invalid values of GMOCK_FLAG(verbose) are treated as
|
||||
// "warning", which is the default value of the flag.
|
||||
if (severity == INFO) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
using ::std::cout;
|
||||
if (severity == WARNING) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
cout << "\nGMOCK WARNING:";
|
||||
}
|
||||
// Pre-pends a new-line to message if it doesn't start with one.
|
||||
if (message.empty() || message[0] != '\n') {
|
||||
cout << "\n";
|
||||
}
|
||||
cout << message;
|
||||
if (stack_frames_to_skip >= 0) {
|
||||
#ifdef NDEBUG
|
||||
// In opt mode, we have to be conservative and skip no stack frame.
|
||||
const int actual_to_skip = 0;
|
||||
#else
|
||||
// In dbg mode, we can do what the caller tell us to do (plus one
|
||||
// for skipping this function's stack frame).
|
||||
const int actual_to_skip = stack_frames_to_skip + 1;
|
||||
#endif // NDEBUG
|
||||
|
||||
// Appends a new-line to message if it doesn't end with one.
|
||||
if (!message.empty() && *message.rbegin() != '\n') {
|
||||
cout << "\n";
|
||||
}
|
||||
cout << "Stack trace:\n"
|
||||
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||
::testing::UnitTest::GetInstance(), actual_to_skip);
|
||||
}
|
||||
cout << ::std::flush;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
61
src/gmock-matchers.cc
Normal file
61
src/gmock-matchers.cc
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements the Matcher<const string&> and
|
||||
// Matcher<string>.
|
||||
|
||||
#include <gmock/gmock-matchers.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Constructs a matcher that matches a const string& whose value is
|
||||
// equal to s.
|
||||
Matcher<const internal::string&>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const string& whose value is
|
||||
// equal to s.
|
||||
Matcher<const internal::string&>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a string whose value is equal to s.
|
||||
Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
|
||||
|
||||
// Constructs a matcher that matches a string whose value is equal to s.
|
||||
Matcher<internal::string>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
} // namespace testing
|
309
src/gmock-printers.cc
Normal file
309
src/gmock-printers.cc
Normal file
@ -0,0 +1,309 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// It uses the << operator when possible, and prints the bytes in the
|
||||
// object otherwise. A user can override its behavior for a class
|
||||
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||
// defines Foo.
|
||||
|
||||
#include <gmock/gmock-printers.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::ostream;
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
#define snprintf _snprintf_s
|
||||
#endif
|
||||
|
||||
// Prints a segment of bytes in the given object.
|
||||
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||
size_t count, ostream* os) {
|
||||
char text[5] = "";
|
||||
for (size_t i = 0; i != count; i++) {
|
||||
const size_t j = start + i;
|
||||
if (i != 0) {
|
||||
// Organizes the bytes into groups of 2 for easy parsing by
|
||||
// human.
|
||||
if ((j % 2) == 0) {
|
||||
*os << " ";
|
||||
}
|
||||
}
|
||||
snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
|
||||
*os << text;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the bytes in the given value to the given ostream.
|
||||
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
// Tells the user how big the object is.
|
||||
*os << count << "-byte object <";
|
||||
|
||||
const size_t kThreshold = 132;
|
||||
const size_t kChunkSize = 64;
|
||||
// If the object size is bigger than kThreshold, we'll have to omit
|
||||
// some details by printing only the first and the last kChunkSize
|
||||
// bytes.
|
||||
// TODO(wan): let the user control the threshold using a flag.
|
||||
if (count < kThreshold) {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
|
||||
} else {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
|
||||
*os << " ... ";
|
||||
// Rounds up to 2-byte boundary.
|
||||
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
|
||||
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
|
||||
}
|
||||
*os << ">";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal2 {
|
||||
|
||||
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
||||
// given object. The delegation simplifies the implementation, which
|
||||
// uses the << operator and thus is easier done outside of the
|
||||
// ::testing::internal namespace, which contains a << operator that
|
||||
// sometimes conflicts with the one in STL.
|
||||
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
PrintBytesInObjectToImpl(obj_bytes, count, os);
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Prints a wide char as a char literal without the quotes, escaping it
|
||||
// when necessary.
|
||||
static void PrintAsWideCharLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\0':
|
||||
*os << "\\0";
|
||||
break;
|
||||
case L'\'':
|
||||
*os << "\\'";
|
||||
break;
|
||||
case L'\?':
|
||||
*os << "\\?";
|
||||
break;
|
||||
case L'\\':
|
||||
*os << "\\\\";
|
||||
break;
|
||||
case L'\a':
|
||||
*os << "\\a";
|
||||
break;
|
||||
case L'\b':
|
||||
*os << "\\b";
|
||||
break;
|
||||
case L'\f':
|
||||
*os << "\\f";
|
||||
break;
|
||||
case L'\n':
|
||||
*os << "\\n";
|
||||
break;
|
||||
case L'\r':
|
||||
*os << "\\r";
|
||||
break;
|
||||
case L'\t':
|
||||
*os << "\\t";
|
||||
break;
|
||||
case L'\v':
|
||||
*os << "\\v";
|
||||
break;
|
||||
default:
|
||||
// isprint() takes an int and requires it to be either EOF or in
|
||||
// the range [0, 255]. We check that c is in this range before calling it.
|
||||
if ((c & 0xFF) == c && isprint(c)) {
|
||||
*os << static_cast<char>(c);
|
||||
} else {
|
||||
// Buffer size enough for the maximum number of digits and \0.
|
||||
char text[2 * sizeof(unsigned long) + 1] = "";
|
||||
snprintf(text, sizeof(text), "%lX", static_cast<unsigned long>(c));
|
||||
*os << "\\x" << text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a char as if it's part of a string literal, escaping it when
|
||||
// necessary.
|
||||
static void PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\'':
|
||||
*os << "'";
|
||||
break;
|
||||
case L'"':
|
||||
*os << "\\\"";
|
||||
break;
|
||||
default:
|
||||
PrintAsWideCharLiteralTo(c, os);
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a char as a char literal without the quotes, escaping it
|
||||
// when necessary.
|
||||
static void PrintAsCharLiteralTo(char c, ostream* os) {
|
||||
PrintAsWideCharLiteralTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Prints a char as if it's part of a string literal, escaping it when
|
||||
// necessary.
|
||||
static void PrintAsStringLiteralTo(char c, ostream* os) {
|
||||
PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Prints a char and its code. The '\0' char is printed as "'\\0'",
|
||||
// other unprintable characters are also properly escaped using the
|
||||
// standard C++ escape sequence.
|
||||
void PrintCharTo(char c, int char_code, ostream* os) {
|
||||
*os << "'";
|
||||
PrintAsCharLiteralTo(c, os);
|
||||
*os << "'";
|
||||
if (c != '\0')
|
||||
*os << " (" << char_code << ")";
|
||||
}
|
||||
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its decimal code (except for L'\0').
|
||||
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||
// as signed integer when wchar_t is implemented by the compiler
|
||||
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||
// is implemented as an unsigned type.
|
||||
void PrintTo(wchar_t wc, ostream* os) {
|
||||
*os << "L'";
|
||||
PrintAsWideCharLiteralTo(wc, os);
|
||||
*os << "'";
|
||||
if (wc != L'\0') {
|
||||
// Type Int64 is used because it provides more storage than wchar_t thus
|
||||
// when the compiler converts signed or unsigned implementation of wchar_t
|
||||
// to Int64 it fills higher bits with either zeros or the sign bit
|
||||
// passing it to operator <<() as either signed or unsigned integer.
|
||||
*os << " (" << static_cast<Int64>(wc) << ")";
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the given array of characters to the ostream.
|
||||
// The array starts at *begin, the length is len, it may include '\0' characters
|
||||
// and may not be null-terminated.
|
||||
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
|
||||
*os << "\"";
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
PrintAsStringLiteralTo(begin[index], os);
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints the given array of wide characters to the ostream.
|
||||
// The array starts at *begin, the length is len, it may include L'\0'
|
||||
// characters and may not be null-terminated.
|
||||
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
|
||||
ostream* os) {
|
||||
*os << "L\"";
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
PrintAsWideStringLiteralTo(begin[index], os);
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints the given C string to the ostream.
|
||||
void PrintTo(const char* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << implicit_cast<const void*>(s) << " pointing to ";
|
||||
PrintCharsAsStringTo(s, strlen(s), os);
|
||||
}
|
||||
}
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// possibly accessing more memory than intended and causing invalid
|
||||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
// wchar_t is implemented as a native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Prints the given wide C string to the ostream.
|
||||
void PrintTo(const wchar_t* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << implicit_cast<const void*>(s) << " pointing to ";
|
||||
PrintWideCharsAsStringTo(s, wcslen(s), os);
|
||||
}
|
||||
}
|
||||
#endif // wchar_t is native
|
||||
|
||||
// Prints a ::string object.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
// Prints a ::wstring object.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
337
src/gmock-spec-builders.cc
Normal file
337
src/gmock-spec-builders.cc
Normal file
@ -0,0 +1,337 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements the spec builder syntax (ON_CALL and
|
||||
// EXPECT_CALL).
|
||||
|
||||
#include <gmock/gmock-spec-builders.h>
|
||||
|
||||
#include <set>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
Mutex g_gmock_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
|
||||
|
||||
// Constructs an ExpectationBase object.
|
||||
ExpectationBase::ExpectationBase(const char* file, int line)
|
||||
: file_(file),
|
||||
line_(line),
|
||||
cardinality_specified_(false),
|
||||
cardinality_(Exactly(1)),
|
||||
call_count_(0),
|
||||
retired_(false) {
|
||||
}
|
||||
|
||||
// Destructs an ExpectationBase object.
|
||||
ExpectationBase::~ExpectationBase() {}
|
||||
|
||||
// Explicitly specifies the cardinality of this expectation. Used by
|
||||
// the subclasses to implement the .Times() clause.
|
||||
void ExpectationBase::SpecifyCardinality(const Cardinality& cardinality) {
|
||||
cardinality_specified_ = true;
|
||||
cardinality_ = cardinality;
|
||||
}
|
||||
|
||||
// Retires all pre-requisites of this expectation.
|
||||
void ExpectationBase::RetireAllPreRequisites() {
|
||||
if (is_retired()) {
|
||||
// We can take this short-cut as we never retire an expectation
|
||||
// until we have retired all its pre-requisites.
|
||||
return;
|
||||
}
|
||||
|
||||
for (ExpectationBaseSet::const_iterator it =
|
||||
immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end();
|
||||
++it) {
|
||||
ExpectationBase* const prerequisite = (*it).get();
|
||||
if (!prerequisite->is_retired()) {
|
||||
prerequisite->RetireAllPreRequisites();
|
||||
prerequisite->Retire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff all pre-requisites of this expectation have been
|
||||
// satisfied.
|
||||
// L >= g_gmock_mutex
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if (!(*it)->IsSatisfied() ||
|
||||
!(*it)->AllPrerequisitesAreSatisfied())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||
// L >= g_gmock_mutex
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(
|
||||
ExpectationBaseSet* result) const {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationBaseSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if ((*it)->IsSatisfied()) {
|
||||
// If *it is satisfied and has a call count of 0, some of its
|
||||
// pre-requisites may not be satisfied yet.
|
||||
if ((*it)->call_count_ == 0) {
|
||||
(*it)->FindUnsatisfiedPrerequisites(result);
|
||||
}
|
||||
} else {
|
||||
// Now that we know *it is unsatisfied, we are not so interested
|
||||
// in whether its pre-requisites are satisfied. Therefore we
|
||||
// don't recursively call FindUnsatisfiedPrerequisites() here.
|
||||
result->insert(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Points to the implicit sequence introduced by a living InSequence
|
||||
// object (if any) in the current thread or NULL.
|
||||
ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
|
||||
// Reports an uninteresting call (whose description is in msg) in the
|
||||
// manner specified by 'reaction'.
|
||||
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
|
||||
switch (reaction) {
|
||||
case ALLOW:
|
||||
Log(INFO, msg, 4);
|
||||
break;
|
||||
case WARN:
|
||||
Log(WARNING, msg, 4);
|
||||
break;
|
||||
default: // FAIL
|
||||
Expect(false, NULL, -1, msg);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Class Mock.
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
|
||||
typedef std::map<const void*, FunctionMockers> MockObjectRegistry;
|
||||
|
||||
// Maps a mock object to the set of mock methods it owns. Protected
|
||||
// by g_gmock_mutex.
|
||||
MockObjectRegistry g_mock_object_registry;
|
||||
|
||||
// Maps a mock object to the reaction Google Mock should have when an
|
||||
// uninteresting method is called. Protected by g_gmock_mutex.
|
||||
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
|
||||
|
||||
// Sets the reaction Google Mock should have when an uninteresting
|
||||
// method of the given mock object is called.
|
||||
// L < g_gmock_mutex
|
||||
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
internal::CallReaction reaction) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction[mock_obj] = reaction;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Tells Google Mock to allow uninteresting calls on the given mock
|
||||
// object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
|
||||
}
|
||||
|
||||
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||
// given mock object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
|
||||
}
|
||||
|
||||
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||
// object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
|
||||
}
|
||||
|
||||
// Tells Google Mock the given mock object is being destroyed and its
|
||||
// entry in the call-reaction table should be removed.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction.erase(mock_obj);
|
||||
}
|
||||
|
||||
// Returns the reaction Google Mock will have on uninteresting calls
|
||||
// made on the given mock object.
|
||||
// L < g_gmock_mutex
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::WARN : g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
// L < g_gmock_mutex
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies all expectations on the given mock object and clears its
|
||||
// default actions and expectations. Returns true iff the
|
||||
// verification was successful.
|
||||
// L < g_gmock_mutex
|
||||
bool Mock::VerifyAndClear(void* mock_obj) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
// L >= g_gmock_mutex
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
if (g_mock_object_registry.count(mock_obj) == 0) {
|
||||
// No EXPECT_CALL() was set on the given mock object.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verifies and clears the expectations on each mock method in the
|
||||
// given mock object.
|
||||
bool expectations_met = true;
|
||||
FunctionMockers& mockers = g_mock_object_registry[mock_obj];
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
if (!(*it)->VerifyAndClearExpectationsLocked()) {
|
||||
expectations_met = false;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by ClearDefaultActionsLocked().
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
// Registers a mock object and a mock method it owns.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry[mock_obj].insert(mocker);
|
||||
}
|
||||
|
||||
// Unregisters a mock method; removes the owning mock object from the
|
||||
// registry when the last mock method associated with it has been
|
||||
// unregistered. This is called only in the destructor of
|
||||
// FunctionMockerBase.
|
||||
// L >= g_gmock_mutex
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
for (MockObjectRegistry::iterator it = g_mock_object_registry.begin();
|
||||
it != g_mock_object_registry.end(); ++it) {
|
||||
FunctionMockers& mockers = it->second;
|
||||
if (mockers.erase(mocker) > 0) {
|
||||
// mocker was in mockers and has been just removed.
|
||||
if (mockers.empty()) {
|
||||
g_mock_object_registry.erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clears all ON_CALL()s set on the given mock object.
|
||||
// L >= g_gmock_mutex
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
|
||||
if (g_mock_object_registry.count(mock_obj) == 0) {
|
||||
// No ON_CALL() was set on the given mock object.
|
||||
return;
|
||||
}
|
||||
|
||||
// Clears the default actions for each mock method in the given mock
|
||||
// object.
|
||||
FunctionMockers& mockers = g_mock_object_registry[mock_obj];
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
(*it)->ClearDefaultActionsLocked();
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by VerifyAndClearExpectationsLocked().
|
||||
}
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(
|
||||
const internal::linked_ptr<internal::ExpectationBase>& expectation) const {
|
||||
if (*last_expectation_ != expectation) {
|
||||
if (*last_expectation_ != NULL) {
|
||||
expectation->immediate_prerequisites_.insert(*last_expectation_);
|
||||
}
|
||||
*last_expectation_ = expectation;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the implicit sequence if there isn't one.
|
||||
InSequence::InSequence() {
|
||||
if (internal::g_gmock_implicit_sequence.get() == NULL) {
|
||||
internal::g_gmock_implicit_sequence.set(new Sequence);
|
||||
sequence_created_ = true;
|
||||
} else {
|
||||
sequence_created_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes the implicit sequence if it was created by the constructor
|
||||
// of this object.
|
||||
InSequence::~InSequence() {
|
||||
if (sequence_created_) {
|
||||
delete internal::g_gmock_implicit_sequence.get();
|
||||
internal::g_gmock_implicit_sequence.set(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
155
src/gmock.cc
Normal file
155
src/gmock.cc
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
|
||||
namespace testing {
|
||||
|
||||
GMOCK_DEFINE_string(verbose, internal::kWarningVerbosity,
|
||||
"Controls how verbose Google Mock's output is."
|
||||
" Valid values:\n"
|
||||
" info - prints all messages.\n"
|
||||
" warning - prints warnings and errors.\n"
|
||||
" error - prints errors only.");
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Parses a string as a command line flag. The string should have the
|
||||
// format "--gmock_flag=value". When def_optional is true, the
|
||||
// "=value" part can be omitted.
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == NULL || flag == NULL) return NULL;
|
||||
|
||||
// The flag must start with "--gmock_".
|
||||
const String flag_str = String::Format("--gmock_%s", flag);
|
||||
const size_t flag_len = flag_str.GetLength();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
|
||||
|
||||
// Skips the flag name.
|
||||
const char* flag_end = str + flag_len;
|
||||
|
||||
// When def_optional is true, it's OK to not have a "=value" part.
|
||||
if (def_optional && (flag_end[0] == '\0')) {
|
||||
return flag_end;
|
||||
}
|
||||
|
||||
// If def_optional is true and there are more characters after the
|
||||
// flag name, or if def_optional is false, there must be a '=' after
|
||||
// the flag name.
|
||||
if (flag_end[0] != '=') return NULL;
|
||||
|
||||
// Returns the string after "=".
|
||||
return flag_end + 1;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock string flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
String* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == NULL) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
*value = value_str;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The internal implementation of InitGoogleMock().
|
||||
//
|
||||
// The type parameter CharType can be instantiated to either char or
|
||||
// wchar_t.
|
||||
template <typename CharType>
|
||||
void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
// Makes sure Google Test is initialized. InitGoogleTest() is
|
||||
// idempotent, so it's fine if the user has already called it.
|
||||
InitGoogleTest(argc, argv);
|
||||
if (*argc <= 0) return;
|
||||
|
||||
for (int i = 1; i != *argc; i++) {
|
||||
const String arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
if (ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
|
||||
// Yes. Shift the remainder of the argv list left by one. Note
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
// NULL. The following loop moves the trailing NULL element as
|
||||
// well.
|
||||
for (int j = i; j != *argc; j++) {
|
||||
argv[j] = argv[j + 1];
|
||||
}
|
||||
|
||||
// Decrements the argument count.
|
||||
(*argc)--;
|
||||
|
||||
// We also need to decrement the iterator as we just removed
|
||||
// an element.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses a command line for the flags that
|
||||
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
|
||||
// removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
void InitGoogleMock(int* argc, char** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
} // namespace testing
|
43
src/gmock_main.cc
Normal file
43
src/gmock_main.cc
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <iostream>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::cout << "Running main() from gmock_main.cc\n";
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
// also responsible for initializing Google Test. Therefore there's
|
||||
// no need for calling testing::InitGoogleTest() separately.
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
902
test/gmock-actions_test.cc
Normal file
902
test/gmock-actions_test.cc
Normal file
@ -0,0 +1,902 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in actions.
|
||||
|
||||
#include <gmock/gmock-actions.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::tr1::get;
|
||||
using ::std::tr1::make_tuple;
|
||||
using ::std::tr1::tuple;
|
||||
using ::std::tr1::tuple_element;
|
||||
using testing::internal::BuiltInDefaultValue;
|
||||
using testing::internal::Int64;
|
||||
using testing::internal::UInt64;
|
||||
// This list should be kept sorted.
|
||||
using testing::_;
|
||||
using testing::Action;
|
||||
using testing::ActionInterface;
|
||||
using testing::Assign;
|
||||
using testing::DefaultValue;
|
||||
using testing::DoDefault;
|
||||
using testing::IgnoreResult;
|
||||
using testing::Invoke;
|
||||
using testing::InvokeWithoutArgs;
|
||||
using testing::MakePolymorphicAction;
|
||||
using testing::Ne;
|
||||
using testing::PolymorphicAction;
|
||||
using testing::Return;
|
||||
using testing::ReturnNull;
|
||||
using testing::ReturnRef;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::SetArrayArgument;
|
||||
using testing::SetErrnoAndReturn;
|
||||
|
||||
#if GMOCK_HAS_PROTOBUF_
|
||||
using testing::internal::TestMessage;
|
||||
#endif // GMOCK_HAS_PROTOBUF_
|
||||
|
||||
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
|
||||
TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
|
||||
EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == NULL);
|
||||
EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == NULL);
|
||||
EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == NULL);
|
||||
}
|
||||
|
||||
// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a
|
||||
// built-in numeric type.
|
||||
TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<unsigned char>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
|
||||
#ifndef GTEST_OS_WINDOWS
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<unsigned wchar_t>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get());
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<unsigned int>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<int>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<UInt64>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<float>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<double>::Get());
|
||||
}
|
||||
|
||||
// Tests that BuiltInDefaultValue<bool>::Get() returns false.
|
||||
TEST(BuiltInDefaultValueTest, IsFalseForBool) {
|
||||
EXPECT_FALSE(BuiltInDefaultValue<bool>::Get());
|
||||
}
|
||||
|
||||
// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a
|
||||
// string type.
|
||||
TEST(BuiltInDefaultValueTest, IsEmptyStringForString) {
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
EXPECT_EQ("", BuiltInDefaultValue< ::string>::Get());
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get());
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
}
|
||||
|
||||
// Tests that BuiltInDefaultValue<const T>::Get() returns the same
|
||||
// value as BuiltInDefaultValue<T>::Get() does.
|
||||
TEST(BuiltInDefaultValueTest, WorksForConstTypes) {
|
||||
EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get());
|
||||
EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == NULL);
|
||||
EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get());
|
||||
}
|
||||
|
||||
// Tests that BuiltInDefaultValue<T>::Get() aborts the program with
|
||||
// the correct error message when T is a user-defined type.
|
||||
struct UserType {
|
||||
UserType() : value(0) {}
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that BuiltInDefaultValue<T&>::Get() aborts the program.
|
||||
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) {
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
BuiltInDefaultValue<int&>::Get();
|
||||
}, "");
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
BuiltInDefaultValue<const char&>::Get();
|
||||
}, "");
|
||||
}
|
||||
|
||||
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForUserTypes) {
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
BuiltInDefaultValue<UserType>::Get();
|
||||
}, "");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that DefaultValue<T>::IsSet() is false initially.
|
||||
TEST(DefaultValueTest, IsInitiallyUnset) {
|
||||
EXPECT_FALSE(DefaultValue<int>::IsSet());
|
||||
EXPECT_FALSE(DefaultValue<const UserType>::IsSet());
|
||||
}
|
||||
|
||||
// Tests that DefaultValue<T> can be set and then unset.
|
||||
TEST(DefaultValueTest, CanBeSetAndUnset) {
|
||||
DefaultValue<int>::Set(1);
|
||||
DefaultValue<const UserType>::Set(UserType());
|
||||
|
||||
EXPECT_EQ(1, DefaultValue<int>::Get());
|
||||
EXPECT_EQ(0, DefaultValue<const UserType>::Get().value);
|
||||
|
||||
DefaultValue<int>::Clear();
|
||||
DefaultValue<const UserType>::Clear();
|
||||
|
||||
EXPECT_FALSE(DefaultValue<int>::IsSet());
|
||||
EXPECT_FALSE(DefaultValue<const UserType>::IsSet());
|
||||
}
|
||||
|
||||
// Tests that DefaultValue<T>::Get() returns the
|
||||
// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is
|
||||
// false.
|
||||
TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
|
||||
EXPECT_FALSE(DefaultValue<int>::IsSet());
|
||||
EXPECT_FALSE(DefaultValue<UserType>::IsSet());
|
||||
|
||||
EXPECT_EQ(0, DefaultValue<int>::Get());
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
DefaultValue<UserType>::Get();
|
||||
}, "");
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
}
|
||||
|
||||
// Tests that DefaultValue<void>::Get() returns void.
|
||||
TEST(DefaultValueTest, GetWorksForVoid) {
|
||||
return DefaultValue<void>::Get();
|
||||
}
|
||||
|
||||
// Tests using DefaultValue with a reference type.
|
||||
|
||||
// Tests that DefaultValue<T&>::IsSet() is false initially.
|
||||
TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) {
|
||||
EXPECT_FALSE(DefaultValue<int&>::IsSet());
|
||||
EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
|
||||
}
|
||||
|
||||
// Tests that DefaultValue<T&> can be set and then unset.
|
||||
TEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) {
|
||||
int n = 1;
|
||||
DefaultValue<const int&>::Set(n);
|
||||
UserType u;
|
||||
DefaultValue<UserType&>::Set(u);
|
||||
|
||||
EXPECT_EQ(&n, &(DefaultValue<const int&>::Get()));
|
||||
EXPECT_EQ(&u, &(DefaultValue<UserType&>::Get()));
|
||||
|
||||
DefaultValue<const int&>::Clear();
|
||||
DefaultValue<UserType&>::Clear();
|
||||
|
||||
EXPECT_FALSE(DefaultValue<const int&>::IsSet());
|
||||
EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
|
||||
}
|
||||
|
||||
// Tests that DefaultValue<T&>::Get() returns the
|
||||
// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is
|
||||
// false.
|
||||
TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
|
||||
EXPECT_FALSE(DefaultValue<int&>::IsSet());
|
||||
EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
DefaultValue<int&>::Get();
|
||||
}, "");
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
DefaultValue<UserType>::Get();
|
||||
}, "");
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
}
|
||||
|
||||
// Tests that ActionInterface can be implemented by defining the
|
||||
// Perform method.
|
||||
|
||||
typedef int MyFunction(bool, int);
|
||||
|
||||
class MyActionImpl : public ActionInterface<MyFunction> {
|
||||
public:
|
||||
virtual int Perform(const tuple<bool, int>& args) {
|
||||
return get<0>(args) ? get<1>(args) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) {
|
||||
MyActionImpl my_action_impl;
|
||||
|
||||
EXPECT_FALSE(my_action_impl.IsDoDefault());
|
||||
}
|
||||
|
||||
TEST(ActionInterfaceTest, MakeAction) {
|
||||
Action<MyFunction> action = MakeAction(new MyActionImpl);
|
||||
|
||||
// When exercising the Perform() method of Action<F>, we must pass
|
||||
// it a tuple whose size and type are compatible with F's argument
|
||||
// types. For example, if F is int(), then Perform() takes a
|
||||
// 0-tuple; if F is void(bool, int), then Perform() takes a
|
||||
// tuple<bool, int>, and so on.
|
||||
EXPECT_EQ(5, action.Perform(make_tuple(true, 5)));
|
||||
}
|
||||
|
||||
// Tests that Action<F> can be contructed from a pointer to
|
||||
// ActionInterface<F>.
|
||||
TEST(ActionTest, CanBeConstructedFromActionInterface) {
|
||||
Action<MyFunction> action(new MyActionImpl);
|
||||
}
|
||||
|
||||
// Tests that Action<F> delegates actual work to ActionInterface<F>.
|
||||
TEST(ActionTest, DelegatesWorkToActionInterface) {
|
||||
const Action<MyFunction> action(new MyActionImpl);
|
||||
|
||||
EXPECT_EQ(5, action.Perform(make_tuple(true, 5)));
|
||||
EXPECT_EQ(0, action.Perform(make_tuple(false, 1)));
|
||||
}
|
||||
|
||||
// Tests that Action<F> can be copied.
|
||||
TEST(ActionTest, IsCopyable) {
|
||||
Action<MyFunction> a1(new MyActionImpl);
|
||||
Action<MyFunction> a2(a1); // Tests the copy constructor.
|
||||
|
||||
// a1 should continue to work after being copied from.
|
||||
EXPECT_EQ(5, a1.Perform(make_tuple(true, 5)));
|
||||
EXPECT_EQ(0, a1.Perform(make_tuple(false, 1)));
|
||||
|
||||
// a2 should work like the action it was copied from.
|
||||
EXPECT_EQ(5, a2.Perform(make_tuple(true, 5)));
|
||||
EXPECT_EQ(0, a2.Perform(make_tuple(false, 1)));
|
||||
|
||||
a2 = a1; // Tests the assignment operator.
|
||||
|
||||
// a1 should continue to work after being copied from.
|
||||
EXPECT_EQ(5, a1.Perform(make_tuple(true, 5)));
|
||||
EXPECT_EQ(0, a1.Perform(make_tuple(false, 1)));
|
||||
|
||||
// a2 should work like the action it was copied from.
|
||||
EXPECT_EQ(5, a2.Perform(make_tuple(true, 5)));
|
||||
EXPECT_EQ(0, a2.Perform(make_tuple(false, 1)));
|
||||
}
|
||||
|
||||
// Tests that an Action<From> object can be converted to a
|
||||
// compatible Action<To> object.
|
||||
|
||||
class IsNotZero : public ActionInterface<bool(int)> { // NOLINT
|
||||
public:
|
||||
virtual bool Perform(const tuple<int>& arg) {
|
||||
return get<0>(arg) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ActionTest, CanBeConvertedToOtherActionType) {
|
||||
const Action<bool(int)> a1(new IsNotZero); // NOLINT
|
||||
const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT
|
||||
EXPECT_EQ(1, a2.Perform(make_tuple('a')));
|
||||
EXPECT_EQ(0, a2.Perform(make_tuple('\0')));
|
||||
}
|
||||
|
||||
// The following two classes are for testing MakePolymorphicAction().
|
||||
|
||||
// Implements a polymorphic action that returns the second of the
|
||||
// arguments it receives.
|
||||
class ReturnSecondArgumentAction {
|
||||
public:
|
||||
// We want to verify that MakePolymorphicAction() can work with a
|
||||
// polymorphic action whose Perform() method template is either
|
||||
// const or not. This lets us verify the non-const case.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) { return get<1>(args); }
|
||||
};
|
||||
|
||||
// Implements a polymorphic action that can be used in a nullary
|
||||
// function to return 0.
|
||||
class ReturnZeroFromNullaryFunctionAction {
|
||||
public:
|
||||
// For testing that MakePolymorphicAction() works when the
|
||||
// implementation class' Perform() method template takes only one
|
||||
// template parameter.
|
||||
//
|
||||
// We want to verify that MakePolymorphicAction() can work with a
|
||||
// polymorphic action whose Perform() method template is either
|
||||
// const or not. This lets us verify the const case.
|
||||
template <typename Result>
|
||||
Result Perform(const tuple<>&) const { return 0; }
|
||||
};
|
||||
|
||||
// These functions verify that MakePolymorphicAction() returns a
|
||||
// PolymorphicAction<T> where T is the argument's type.
|
||||
|
||||
PolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() {
|
||||
return MakePolymorphicAction(ReturnSecondArgumentAction());
|
||||
}
|
||||
|
||||
PolymorphicAction<ReturnZeroFromNullaryFunctionAction>
|
||||
ReturnZeroFromNullaryFunction() {
|
||||
return MakePolymorphicAction(ReturnZeroFromNullaryFunctionAction());
|
||||
}
|
||||
|
||||
// Tests that MakePolymorphicAction() turns a polymorphic action
|
||||
// implementation class into a polymorphic action.
|
||||
TEST(MakePolymorphicActionTest, ConstructsActionFromImpl) {
|
||||
Action<int(bool, int, double)> a1 = ReturnSecondArgument(); // NOLINT
|
||||
EXPECT_EQ(5, a1.Perform(make_tuple(false, 5, 2.0)));
|
||||
}
|
||||
|
||||
// Tests that MakePolymorphicAction() works when the implementation
|
||||
// class' Perform() method template has only one template parameter.
|
||||
TEST(MakePolymorphicActionTest, WorksWhenPerformHasOneTemplateParameter) {
|
||||
Action<int()> a1 = ReturnZeroFromNullaryFunction();
|
||||
EXPECT_EQ(0, a1.Perform(make_tuple()));
|
||||
|
||||
Action<void*()> a2 = ReturnZeroFromNullaryFunction();
|
||||
EXPECT_TRUE(a2.Perform(make_tuple()) == NULL);
|
||||
}
|
||||
|
||||
// Tests that Return() works as an action for void-returning
|
||||
// functions.
|
||||
TEST(ReturnTest, WorksForVoid) {
|
||||
const Action<void(int)> ret = Return(); // NOLINT
|
||||
return ret.Perform(make_tuple(1));
|
||||
}
|
||||
|
||||
// Tests that Return(v) returns v.
|
||||
TEST(ReturnTest, ReturnsGivenValue) {
|
||||
Action<int()> ret = Return(1); // NOLINT
|
||||
EXPECT_EQ(1, ret.Perform(make_tuple()));
|
||||
|
||||
ret = Return(-5);
|
||||
EXPECT_EQ(-5, ret.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests that Return("string literal") works.
|
||||
TEST(ReturnTest, AcceptsStringLiteral) {
|
||||
Action<const char*()> a1 = Return("Hello");
|
||||
EXPECT_STREQ("Hello", a1.Perform(make_tuple()));
|
||||
|
||||
Action<std::string()> a2 = Return("world");
|
||||
EXPECT_EQ("world", a2.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests that Return(v) is covaraint.
|
||||
|
||||
struct Base {
|
||||
bool operator==(const Base&) { return true; }
|
||||
};
|
||||
|
||||
struct Derived : public Base {
|
||||
bool operator==(const Derived&) { return true; }
|
||||
};
|
||||
|
||||
TEST(ReturnTest, IsCovariant) {
|
||||
Base base;
|
||||
Derived derived;
|
||||
Action<Base*()> ret = Return(&base);
|
||||
EXPECT_EQ(&base, ret.Perform(make_tuple()));
|
||||
|
||||
ret = Return(&derived);
|
||||
EXPECT_EQ(&derived, ret.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests that ReturnNull() returns NULL in a pointer-returning function.
|
||||
TEST(ReturnNullTest, WorksInPointerReturningFunction) {
|
||||
const Action<int*()> a1 = ReturnNull();
|
||||
EXPECT_TRUE(a1.Perform(make_tuple()) == NULL);
|
||||
|
||||
const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT
|
||||
EXPECT_TRUE(a2.Perform(make_tuple(true)) == NULL);
|
||||
}
|
||||
|
||||
// Tests that ReturnRef(v) works for reference types.
|
||||
TEST(ReturnRefTest, WorksForReference) {
|
||||
const int n = 0;
|
||||
const Action<const int&(bool)> ret = ReturnRef(n); // NOLINT
|
||||
|
||||
EXPECT_EQ(&n, &ret.Perform(make_tuple(true)));
|
||||
}
|
||||
|
||||
// Tests that ReturnRef(v) is covariant.
|
||||
TEST(ReturnRefTest, IsCovariant) {
|
||||
Base base;
|
||||
Derived derived;
|
||||
Action<Base&()> a = ReturnRef(base);
|
||||
EXPECT_EQ(&base, &a.Perform(make_tuple()));
|
||||
|
||||
a = ReturnRef(derived);
|
||||
EXPECT_EQ(&derived, &a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests that DoDefault() does the default action for the mock method.
|
||||
|
||||
class MyClass {};
|
||||
|
||||
class MockClass {
|
||||
public:
|
||||
MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
|
||||
MOCK_METHOD0(Foo, MyClass());
|
||||
};
|
||||
|
||||
// Tests that DoDefault() returns the built-in default value for the
|
||||
// return type by default.
|
||||
TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) {
|
||||
MockClass mock;
|
||||
EXPECT_CALL(mock, IntFunc(_))
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_EQ(0, mock.IntFunc(true));
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that DoDefault() aborts the process when there is no built-in
|
||||
// default value for the return type.
|
||||
TEST(DoDefaultDeathTest, DiesForUnknowType) {
|
||||
MockClass mock;
|
||||
EXPECT_CALL(mock, Foo())
|
||||
.WillRepeatedly(DoDefault());
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
mock.Foo();
|
||||
}, "");
|
||||
}
|
||||
|
||||
// Tests that using DoDefault() inside a composite action leads to a
|
||||
// run-time error.
|
||||
|
||||
void VoidFunc(bool flag) {}
|
||||
|
||||
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
|
||||
MockClass mock;
|
||||
EXPECT_CALL(mock, IntFunc(_))
|
||||
.WillRepeatedly(DoAll(Invoke(VoidFunc),
|
||||
DoDefault()));
|
||||
|
||||
// Ideally we should verify the error message as well. Sadly,
|
||||
// EXPECT_DEATH() can only capture stderr, while Google Mock's
|
||||
// errors are printed on stdout. Therefore we have to settle for
|
||||
// not verifying the message.
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
mock.IntFunc(true);
|
||||
}, "");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that DoDefault() returns the default value set by
|
||||
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
|
||||
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
|
||||
DefaultValue<int>::Set(1);
|
||||
MockClass mock;
|
||||
EXPECT_CALL(mock, IntFunc(_))
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_EQ(1, mock.IntFunc(false));
|
||||
DefaultValue<int>::Clear();
|
||||
}
|
||||
|
||||
// Tests that DoDefault() does the action specified by ON_CALL().
|
||||
TEST(DoDefaultTest, DoesWhatOnCallSpecifies) {
|
||||
MockClass mock;
|
||||
ON_CALL(mock, IntFunc(_))
|
||||
.WillByDefault(Return(2));
|
||||
EXPECT_CALL(mock, IntFunc(_))
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_EQ(2, mock.IntFunc(false));
|
||||
}
|
||||
|
||||
// Tests that using DoDefault() in ON_CALL() leads to a run-time failure.
|
||||
TEST(DoDefaultTest, CannotBeUsedInOnCall) {
|
||||
MockClass mock;
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
ON_CALL(mock, IntFunc(_))
|
||||
.WillByDefault(DoDefault());
|
||||
}, "DoDefault() cannot be used in ON_CALL()");
|
||||
}
|
||||
|
||||
// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
|
||||
// the N-th (0-based) argument to v.
|
||||
TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
|
||||
typedef void MyFunction(bool, int*, char*);
|
||||
Action<MyFunction> a = SetArgumentPointee<1>(2);
|
||||
|
||||
int n = 0;
|
||||
char ch = '\0';
|
||||
a.Perform(make_tuple(true, &n, &ch));
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('\0', ch);
|
||||
|
||||
a = SetArgumentPointee<2>('a');
|
||||
n = 0;
|
||||
ch = '\0';
|
||||
a.Perform(make_tuple(true, &n, &ch));
|
||||
EXPECT_EQ(0, n);
|
||||
EXPECT_EQ('a', ch);
|
||||
}
|
||||
|
||||
#if GMOCK_HAS_PROTOBUF_
|
||||
|
||||
// Tests that SetArgumentPointee<N>(proto_buffer) sets the variable
|
||||
// pointed to by the N-th (0-based) argument to proto_buffer.
|
||||
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
|
||||
typedef void MyFunction(bool, TestMessage*);
|
||||
TestMessage* const msg = new TestMessage;
|
||||
msg->set_member("yes");
|
||||
TestMessage orig_msg;
|
||||
orig_msg.CopyFrom(*msg);
|
||||
|
||||
Action<MyFunction> a = SetArgumentPointee<1>(*msg);
|
||||
// SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
|
||||
// s.t. the action works even when the original proto_buffer has
|
||||
// died. We ensure this behavior by deleting msg before using the
|
||||
// action.
|
||||
delete msg;
|
||||
|
||||
TestMessage dest;
|
||||
EXPECT_FALSE(orig_msg.Equals(dest));
|
||||
a.Perform(make_tuple(true, &dest));
|
||||
EXPECT_TRUE(orig_msg.Equals(dest));
|
||||
}
|
||||
|
||||
// Tests that SetArgumentPointee<N>(proto2_buffer) sets the variable
|
||||
// pointed to by the N-th (0-based) argument to proto2_buffer.
|
||||
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
|
||||
using testing::internal::FooMessage;
|
||||
typedef void MyFunction(bool, FooMessage*);
|
||||
FooMessage* const msg = new FooMessage;
|
||||
msg->set_int_field(2);
|
||||
msg->set_string_field("hi");
|
||||
FooMessage orig_msg;
|
||||
orig_msg.CopyFrom(*msg);
|
||||
|
||||
Action<MyFunction> a = SetArgumentPointee<1>(*msg);
|
||||
// SetArgumentPointee<N>(proto2_buffer) makes a copy of
|
||||
// proto2_buffer s.t. the action works even when the original
|
||||
// proto2_buffer has died. We ensure this behavior by deleting msg
|
||||
// before using the action.
|
||||
delete msg;
|
||||
|
||||
FooMessage dest;
|
||||
dest.set_int_field(0);
|
||||
a.Perform(make_tuple(true, &dest));
|
||||
EXPECT_EQ(2, dest.int_field());
|
||||
EXPECT_EQ("hi", dest.string_field());
|
||||
}
|
||||
|
||||
#endif // GMOCK_HAS_PROTOBUF_
|
||||
|
||||
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
|
||||
// pointed to by the N-th (0-based) argument to values in range [first, last).
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArray) {
|
||||
typedef void MyFunction(bool, int*, char*);
|
||||
int numbers[] = { 1, 2, 3 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
|
||||
|
||||
int n[4] = {};
|
||||
int* pn = n;
|
||||
char ch[4] = {};
|
||||
char* pch = ch;
|
||||
a.Perform(make_tuple(true, pn, pch));
|
||||
EXPECT_EQ(1, n[0]);
|
||||
EXPECT_EQ(2, n[1]);
|
||||
EXPECT_EQ(3, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
EXPECT_EQ('\0', ch[0]);
|
||||
EXPECT_EQ('\0', ch[1]);
|
||||
EXPECT_EQ('\0', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
|
||||
// Tests first and last are iterators.
|
||||
std::string letters = "abc";
|
||||
a = SetArrayArgument<2>(letters.begin(), letters.end());
|
||||
std::fill_n(n, 4, 0);
|
||||
std::fill_n(ch, 4, '\0');
|
||||
a.Perform(make_tuple(true, pn, pch));
|
||||
EXPECT_EQ(0, n[0]);
|
||||
EXPECT_EQ(0, n[1]);
|
||||
EXPECT_EQ(0, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
EXPECT_EQ('a', ch[0]);
|
||||
EXPECT_EQ('b', ch[1]);
|
||||
EXPECT_EQ('c', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
}
|
||||
|
||||
// Tests SetArrayArgument<N>(first, last) where first == last.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
|
||||
typedef void MyFunction(bool, int*);
|
||||
int numbers[] = { 1, 2, 3 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
|
||||
|
||||
int n[4] = {};
|
||||
int* pn = n;
|
||||
a.Perform(make_tuple(true, pn));
|
||||
EXPECT_EQ(0, n[0]);
|
||||
EXPECT_EQ(0, n[1]);
|
||||
EXPECT_EQ(0, n[2]);
|
||||
EXPECT_EQ(0, n[3]);
|
||||
}
|
||||
|
||||
// Tests SetArrayArgument<N>(first, last) where *first is convertible
|
||||
// (but not equal) to the argument type.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
|
||||
typedef void MyFunction(bool, char*);
|
||||
int codes[] = { 97, 98, 99 };
|
||||
Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
|
||||
|
||||
char ch[4] = {};
|
||||
char* pch = ch;
|
||||
a.Perform(make_tuple(true, pch));
|
||||
EXPECT_EQ('a', ch[0]);
|
||||
EXPECT_EQ('b', ch[1]);
|
||||
EXPECT_EQ('c', ch[2]);
|
||||
EXPECT_EQ('\0', ch[3]);
|
||||
}
|
||||
|
||||
// Test SetArrayArgument<N>(first, last) with iterator as argument.
|
||||
TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
|
||||
typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
|
||||
std::string letters = "abc";
|
||||
Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
|
||||
|
||||
std::string s;
|
||||
a.Perform(make_tuple(true, back_inserter(s)));
|
||||
EXPECT_EQ(letters, s);
|
||||
}
|
||||
|
||||
// Sample functions and functors for testing Invoke() and etc.
|
||||
int Nullary() { return 1; }
|
||||
|
||||
class NullaryFunctor {
|
||||
public:
|
||||
int operator()() { return 2; }
|
||||
};
|
||||
|
||||
bool g_done = false;
|
||||
void VoidNullary() { g_done = true; }
|
||||
|
||||
class VoidNullaryFunctor {
|
||||
public:
|
||||
void operator()() { g_done = true; }
|
||||
};
|
||||
|
||||
bool Unary(int x) { return x < 0; }
|
||||
|
||||
const char* Plus1(const char* s) { return s + 1; }
|
||||
|
||||
void VoidUnary(int n) { g_done = true; }
|
||||
|
||||
bool ByConstRef(const std::string& s) { return s == "Hi"; }
|
||||
|
||||
const double g_double = 0;
|
||||
bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
|
||||
|
||||
std::string ByNonConstRef(std::string& s) { return s += "+"; } // NOLINT
|
||||
|
||||
struct UnaryFunctor {
|
||||
int operator()(bool x) { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
|
||||
|
||||
void VoidBinary(int, char) { g_done = true; }
|
||||
|
||||
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
|
||||
|
||||
void VoidTernary(int, char, bool) { g_done = true; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
|
||||
|
||||
void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
|
||||
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
|
||||
struct SumOf5Functor {
|
||||
int operator()(int a, int b, int c, int d, int e) {
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
};
|
||||
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
struct SumOf6Functor {
|
||||
int operator()(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo() : value_(123) {}
|
||||
|
||||
int Nullary() const { return value_; }
|
||||
short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
|
||||
std::string Binary(const std::string& str, char c) const { return str + c; }
|
||||
int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
|
||||
int SumOf4(int a, int b, int c, int d) const {
|
||||
return a + b + c + d + value_;
|
||||
}
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
// Tests InvokeWithoutArgs(function).
|
||||
TEST(InvokeWithoutArgsTest, Function) {
|
||||
// As an action that takes one argument.
|
||||
Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple(2)));
|
||||
|
||||
// As an action that takes two arguments.
|
||||
Action<short(int, double)> a2 = InvokeWithoutArgs(Nullary); // NOLINT
|
||||
EXPECT_EQ(1, a2.Perform(make_tuple(2, 3.5)));
|
||||
|
||||
// As an action that returns void.
|
||||
Action<void(int)> a3 = InvokeWithoutArgs(VoidNullary); // NOLINT
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple(1));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests InvokeWithoutArgs(functor).
|
||||
TEST(InvokeWithoutArgsTest, Functor) {
|
||||
// As an action that takes no argument.
|
||||
Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT
|
||||
EXPECT_EQ(2, a.Perform(make_tuple()));
|
||||
|
||||
// As an action that takes three arguments.
|
||||
Action<short(int, double, char)> a2 = // NOLINT
|
||||
InvokeWithoutArgs(NullaryFunctor());
|
||||
EXPECT_EQ(2, a2.Perform(make_tuple(3, 3.5, 'a')));
|
||||
|
||||
// As an action that returns void.
|
||||
Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor());
|
||||
g_done = false;
|
||||
a3.Perform(make_tuple());
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests InvokeWithoutArgs(obj_ptr, method).
|
||||
TEST(InvokeWithoutArgsTest, Method) {
|
||||
Foo foo;
|
||||
Action<int(bool, char)> a = // NOLINT
|
||||
InvokeWithoutArgs(&foo, &Foo::Nullary);
|
||||
EXPECT_EQ(123, a.Perform(make_tuple(true, 'a')));
|
||||
}
|
||||
|
||||
// Tests using IgnoreResult() on a polymorphic action.
|
||||
TEST(IgnoreResultTest, PolymorphicAction) {
|
||||
Action<void(int)> a = IgnoreResult(Return(5)); // NOLINT
|
||||
a.Perform(make_tuple(1));
|
||||
}
|
||||
|
||||
// Tests using IgnoreResult() on a monomorphic action.
|
||||
|
||||
int ReturnOne() {
|
||||
g_done = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(IgnoreResultTest, MonomorphicAction) {
|
||||
g_done = false;
|
||||
Action<void()> a = IgnoreResult(Invoke(ReturnOne));
|
||||
a.Perform(make_tuple());
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests using IgnoreResult() on an action that returns a class type.
|
||||
|
||||
MyClass ReturnMyClass(double x) {
|
||||
g_done = true;
|
||||
return MyClass();
|
||||
}
|
||||
|
||||
TEST(IgnoreResultTest, ActionReturningClass) {
|
||||
g_done = false;
|
||||
Action<void(int)> a = IgnoreResult(Invoke(ReturnMyClass)); // NOLINT
|
||||
a.Perform(make_tuple(2));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
TEST(AssignTest, Int) {
|
||||
int x = 0;
|
||||
Action<void(int)> a = Assign(&x, 5);
|
||||
a.Perform(make_tuple(0));
|
||||
EXPECT_EQ(5, x);
|
||||
}
|
||||
|
||||
TEST(AssignTest, String) {
|
||||
::std::string x;
|
||||
Action<void(void)> a = Assign(&x, "Hello, world");
|
||||
a.Perform(make_tuple());
|
||||
EXPECT_EQ("Hello, world", x);
|
||||
}
|
||||
|
||||
TEST(AssignTest, CompatibleTypes) {
|
||||
double x = 0;
|
||||
Action<void(int)> a = Assign(&x, 5);
|
||||
a.Perform(make_tuple(0));
|
||||
EXPECT_DOUBLE_EQ(5, x);
|
||||
}
|
||||
|
||||
class SetErrnoAndReturnTest : public testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() { errno = 0; }
|
||||
virtual void TearDown() { errno = 0; }
|
||||
};
|
||||
|
||||
TEST_F(SetErrnoAndReturnTest, Int) {
|
||||
Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5);
|
||||
EXPECT_EQ(-5, a.Perform(make_tuple()));
|
||||
EXPECT_EQ(ENOTTY, errno);
|
||||
}
|
||||
|
||||
TEST_F(SetErrnoAndReturnTest, Ptr) {
|
||||
int x;
|
||||
Action<int*(void)> a = SetErrnoAndReturn(ENOTTY, &x);
|
||||
EXPECT_EQ(&x, a.Perform(make_tuple()));
|
||||
EXPECT_EQ(ENOTTY, errno);
|
||||
}
|
||||
|
||||
TEST_F(SetErrnoAndReturnTest, CompatibleTypes) {
|
||||
Action<double()> a = SetErrnoAndReturn(EINVAL, 5);
|
||||
EXPECT_DOUBLE_EQ(5.0, a.Perform(make_tuple()));
|
||||
EXPECT_EQ(EINVAL, errno);
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
422
test/gmock-cardinalities_test.cc
Normal file
422
test/gmock-cardinalities_test.cc
Normal file
@ -0,0 +1,422 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in cardinalities.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using std::stringstream;
|
||||
using testing::AnyNumber;
|
||||
using testing::AtLeast;
|
||||
using testing::AtMost;
|
||||
using testing::Between;
|
||||
using testing::Cardinality;
|
||||
using testing::CardinalityInterface;
|
||||
using testing::Exactly;
|
||||
using testing::IsSubstring;
|
||||
using testing::MakeCardinality;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MOCK_METHOD0(Bar, int()); // NOLINT
|
||||
};
|
||||
|
||||
// Tests that Cardinality objects can be default constructed.
|
||||
TEST(CardinalityTest, IsDefaultConstructable) {
|
||||
Cardinality c;
|
||||
}
|
||||
|
||||
// Tests that Cardinality objects are copyable.
|
||||
TEST(CardinalityTest, IsCopyable) {
|
||||
// Tests the copy constructor.
|
||||
Cardinality c = Exactly(1);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
// Tests the assignment operator.
|
||||
c = Exactly(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
}
|
||||
|
||||
TEST(CardinalityTest, IsOverSaturatedByCallCountWorks) {
|
||||
const Cardinality c = AtMost(5);
|
||||
EXPECT_FALSE(c.IsOverSaturatedByCallCount(4));
|
||||
EXPECT_FALSE(c.IsOverSaturatedByCallCount(5));
|
||||
EXPECT_TRUE(c.IsOverSaturatedByCallCount(6));
|
||||
}
|
||||
|
||||
// Tests that Cardinality::DescribeActualCallCountTo() creates the
|
||||
// correct description.
|
||||
TEST(CardinalityTest, CanDescribeActualCallCount) {
|
||||
stringstream ss0;
|
||||
Cardinality::DescribeActualCallCountTo(0, &ss0);
|
||||
EXPECT_EQ("never called", ss0.str());
|
||||
|
||||
stringstream ss1;
|
||||
Cardinality::DescribeActualCallCountTo(1, &ss1);
|
||||
EXPECT_EQ("called once", ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
Cardinality::DescribeActualCallCountTo(2, &ss2);
|
||||
EXPECT_EQ("called twice", ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
Cardinality::DescribeActualCallCountTo(3, &ss3);
|
||||
EXPECT_EQ("called 3 times", ss3.str());
|
||||
}
|
||||
|
||||
// Tests AnyNumber()
|
||||
TEST(AnyNumber, Works) {
|
||||
const Cardinality c = AnyNumber();
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(9));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(9));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AnyNumberTest, HasCorrectBounds) {
|
||||
const Cardinality c = AnyNumber();
|
||||
EXPECT_EQ(0, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests AtLeast(n).
|
||||
|
||||
TEST(AtLeastTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
AtLeast(-1);
|
||||
}, "The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, OnZero) {
|
||||
const Cardinality c = AtLeast(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "any number of times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, OnPositiveNumber) {
|
||||
const Cardinality c = AtLeast(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
AtLeast(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
AtLeast(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(AtLeastTest, HasCorrectBounds) {
|
||||
const Cardinality c = AtLeast(2);
|
||||
EXPECT_EQ(2, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(INT_MAX, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests AtMost(n).
|
||||
|
||||
TEST(AtMostTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
AtMost(-1);
|
||||
}, "The invocation upper bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(AtMostTest, OnZero) {
|
||||
const Cardinality c = AtMost(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(AtMostTest, OnPositiveNumber) {
|
||||
const Cardinality c = AtMost(2);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
AtMost(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
AtMost(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(AtMostTest, HasCorrectBounds) {
|
||||
const Cardinality c = AtMost(2);
|
||||
EXPECT_EQ(0, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(2, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests Between(m, n).
|
||||
|
||||
TEST(BetweenTest, OnNegativeStart) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(-1, 2);
|
||||
}, "The invocation lower bound must be >= 0, but is actually -1");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnNegativeEnd) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(1, -2);
|
||||
}, "The invocation upper bound must be >= 0, but is actually -2");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnStartBiggerThanEnd) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Between(2, 1);
|
||||
}, "The invocation upper bound (1) must be >= "
|
||||
"the invocation lower bound (2)");
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnZeroStartAndZeroEnd) {
|
||||
const Cardinality c = Between(0, 0);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnZeroStartAndNonZeroEnd) {
|
||||
const Cardinality c = Between(0, 2);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnSameStartAndEnd) {
|
||||
const Cardinality c = Between(3, 3);
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(3));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(4));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(4));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, OnDifferentStartAndEnd) {
|
||||
const Cardinality c = Between(3, 5);
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(3));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(3));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(5));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(5));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(6));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(6));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(BetweenTest, HasCorrectBounds) {
|
||||
const Cardinality c = Between(3, 5);
|
||||
EXPECT_EQ(3, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(5, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests Exactly(n).
|
||||
|
||||
TEST(ExactlyTest, OnNegativeNumber) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Exactly(-1);
|
||||
}, "The invocation lower bound must be >= 0");
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, OnZero) {
|
||||
const Cardinality c = Exactly(0);
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(1));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(1));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "never called",
|
||||
ss.str());
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, OnPositiveNumber) {
|
||||
const Cardinality c = Exactly(2);
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(0));
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(0));
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_TRUE(c.IsSaturatedByCallCount(2));
|
||||
|
||||
stringstream ss1;
|
||||
Exactly(1).DescribeTo(&ss1);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called once",
|
||||
ss1.str());
|
||||
|
||||
stringstream ss2;
|
||||
c.DescribeTo(&ss2);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called twice",
|
||||
ss2.str());
|
||||
|
||||
stringstream ss3;
|
||||
Exactly(3).DescribeTo(&ss3);
|
||||
EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times",
|
||||
ss3.str());
|
||||
}
|
||||
|
||||
TEST(ExactlyTest, HasCorrectBounds) {
|
||||
const Cardinality c = Exactly(3);
|
||||
EXPECT_EQ(3, c.ConservativeLowerBound());
|
||||
EXPECT_EQ(3, c.ConservativeUpperBound());
|
||||
}
|
||||
|
||||
// Tests that a user can make his own cardinality by implementing
|
||||
// CardinalityInterface and calling MakeCardinality().
|
||||
|
||||
class EvenCardinality : public CardinalityInterface {
|
||||
public:
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return (call_count % 2 == 0);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const { return false; }
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* ss) const {
|
||||
*ss << "called even number of times";
|
||||
}
|
||||
};
|
||||
|
||||
TEST(MakeCardinalityTest, ConstructsCardinalityFromInterface) {
|
||||
const Cardinality c = MakeCardinality(new EvenCardinality);
|
||||
|
||||
EXPECT_TRUE(c.IsSatisfiedByCallCount(2));
|
||||
EXPECT_FALSE(c.IsSatisfiedByCallCount(3));
|
||||
|
||||
EXPECT_FALSE(c.IsSaturatedByCallCount(10000));
|
||||
|
||||
stringstream ss;
|
||||
c.DescribeTo(&ss);
|
||||
EXPECT_EQ("called even number of times", ss.str());
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
946
test/gmock-generated-actions_test.cc
Normal file
946
test/gmock-generated-actions_test.cc
Normal file
@ -0,0 +1,946 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in actions generated by a script.
|
||||
|
||||
#include <gmock/gmock-generated-actions.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_generated_actions_test {
|
||||
|
||||
using ::std::plus;
|
||||
using ::std::string;
|
||||
using ::std::tr1::get;
|
||||
using ::std::tr1::make_tuple;
|
||||
using ::std::tr1::tuple;
|
||||
using ::std::tr1::tuple_element;
|
||||
using testing::_;
|
||||
using testing::Action;
|
||||
using testing::ActionInterface;
|
||||
using testing::ByRef;
|
||||
using testing::DoAll;
|
||||
using testing::Invoke;
|
||||
using testing::InvokeArgument;
|
||||
using testing::Return;
|
||||
using testing::SetArgumentPointee;
|
||||
using testing::Unused;
|
||||
using testing::WithArg;
|
||||
using testing::WithArgs;
|
||||
using testing::WithoutArgs;
|
||||
|
||||
// Sample functions and functors for testing Invoke() and etc.
|
||||
int Nullary() { return 1; }
|
||||
|
||||
class NullaryFunctor {
|
||||
public:
|
||||
int operator()() { return 2; }
|
||||
};
|
||||
|
||||
bool g_done = false;
|
||||
void VoidNullary() { g_done = true; }
|
||||
|
||||
class VoidNullaryFunctor {
|
||||
public:
|
||||
void operator()() { g_done = true; }
|
||||
};
|
||||
|
||||
bool Unary(int x) { return x < 0; }
|
||||
|
||||
const char* Plus1(const char* s) { return s + 1; }
|
||||
|
||||
void VoidUnary(int n) { g_done = true; }
|
||||
|
||||
bool ByConstRef(const string& s) { return s == "Hi"; }
|
||||
|
||||
const double g_double = 0;
|
||||
bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
|
||||
|
||||
string ByNonConstRef(string& s) { return s += "+"; } // NOLINT
|
||||
|
||||
struct UnaryFunctor {
|
||||
int operator()(bool x) { return x ? 1 : -1; }
|
||||
};
|
||||
|
||||
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
|
||||
|
||||
void VoidBinary(int, char) { g_done = true; }
|
||||
|
||||
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
|
||||
|
||||
void VoidTernary(int, char, bool) { g_done = true; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
|
||||
|
||||
int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
|
||||
|
||||
void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
|
||||
|
||||
string Concat4(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4) {
|
||||
return string(s1) + s2 + s3 + s4;
|
||||
}
|
||||
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
|
||||
struct SumOf5Functor {
|
||||
int operator()(int a, int b, int c, int d, int e) {
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
};
|
||||
|
||||
string Concat5(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5) {
|
||||
return string(s1) + s2 + s3 + s4 + s5;
|
||||
}
|
||||
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
struct SumOf6Functor {
|
||||
int operator()(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
};
|
||||
|
||||
string Concat6(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6;
|
||||
}
|
||||
|
||||
string Concat7(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
|
||||
}
|
||||
|
||||
string Concat8(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
|
||||
}
|
||||
|
||||
string Concat9(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
|
||||
}
|
||||
|
||||
string Concat10(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9,
|
||||
const char* s10) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo() : value_(123) {}
|
||||
|
||||
int Nullary() const { return value_; }
|
||||
|
||||
short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
|
||||
|
||||
string Binary(const string& str, char c) const { return str + c; }
|
||||
|
||||
int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
|
||||
|
||||
int SumOf4(int a, int b, int c, int d) const {
|
||||
return a + b + c + d + value_;
|
||||
}
|
||||
|
||||
int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
|
||||
|
||||
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
|
||||
|
||||
int SumOf6(int a, int b, int c, int d, int e, int f) {
|
||||
return a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
string Concat7(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
|
||||
}
|
||||
|
||||
string Concat8(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
|
||||
}
|
||||
|
||||
string Concat9(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
|
||||
}
|
||||
|
||||
string Concat10(const char* s1, const char* s2, const char* s3,
|
||||
const char* s4, const char* s5, const char* s6,
|
||||
const char* s7, const char* s8, const char* s9,
|
||||
const char* s10) {
|
||||
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
|
||||
}
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
// Tests using Invoke() with a nullary function.
|
||||
TEST(InvokeTest, Nullary) {
|
||||
Action<int()> a = Invoke(Nullary); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary function.
|
||||
TEST(InvokeTest, Unary) {
|
||||
Action<bool(int)> a = Invoke(Unary); // NOLINT
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1)));
|
||||
EXPECT_TRUE(a.Perform(make_tuple(-1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary function.
|
||||
TEST(InvokeTest, Binary) {
|
||||
Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
|
||||
const char* p = "Hello";
|
||||
EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary function.
|
||||
TEST(InvokeTest, Ternary) {
|
||||
Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
|
||||
EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes4Arguments) {
|
||||
Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
|
||||
EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes5Arguments) {
|
||||
Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes6Arguments) {
|
||||
Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 7-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes7Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)> a =
|
||||
Invoke(Concat7);
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 8-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes8Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)> a =
|
||||
Invoke(Concat8);
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 9-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes9Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)> a = Invoke(Concat9);
|
||||
EXPECT_EQ("123456789",
|
||||
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8", "9")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 10-argument function.
|
||||
TEST(InvokeTest, FunctionThatTakes10Arguments) {
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)> a = Invoke(Concat10);
|
||||
EXPECT_EQ("1234567890", a.Perform(make_tuple("1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with functions with parameters declared as Unused.
|
||||
TEST(InvokeTest, FunctionWithUnusedParameters) {
|
||||
Action<int(int, int, double, const string&)> a1 =
|
||||
Invoke(SumOfFirst2);
|
||||
EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, "hi")));
|
||||
|
||||
Action<int(int, int, bool, int*)> a2 =
|
||||
Invoke(SumOfFirst2);
|
||||
EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with methods with parameters declared as Unused.
|
||||
TEST(InvokeTest, MethodWithUnusedParameters) {
|
||||
Foo foo;
|
||||
Action<int(string, bool, int, int)> a1 =
|
||||
Invoke(&foo, &Foo::SumOfLast2);
|
||||
EXPECT_EQ(12, a1.Perform(make_tuple("hi", true, 10, 2)));
|
||||
|
||||
Action<int(char, double, int, int)> a2 =
|
||||
Invoke(&foo, &Foo::SumOfLast2);
|
||||
EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a functor.
|
||||
TEST(InvokeTest, Functor) {
|
||||
Action<int(short, char)> a = Invoke(plus<short>()); // NOLINT
|
||||
EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeTest, FunctionWithCompatibleType) {
|
||||
Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
|
||||
EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with an object pointer and a method pointer.
|
||||
|
||||
// Tests using Invoke() with a nullary method.
|
||||
TEST(InvokeMethodTest, Nullary) {
|
||||
Foo foo;
|
||||
Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT
|
||||
EXPECT_EQ(123, a.Perform(make_tuple()));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a unary method.
|
||||
TEST(InvokeMethodTest, Unary) {
|
||||
Foo foo;
|
||||
Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT
|
||||
EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a binary method.
|
||||
TEST(InvokeMethodTest, Binary) {
|
||||
Foo foo;
|
||||
Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
|
||||
string s("Hell");
|
||||
EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a ternary method.
|
||||
TEST(InvokeMethodTest, Ternary) {
|
||||
Foo foo;
|
||||
Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT
|
||||
EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 4-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT
|
||||
EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 5-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5); // NOLINT
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 6-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
|
||||
Foo foo;
|
||||
Action<int(int, int, int, int, int, int)> a = // NOLINT
|
||||
Invoke(&foo, &Foo::SumOf6);
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 7-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*)> a =
|
||||
Invoke(&foo, &Foo::Concat7);
|
||||
EXPECT_EQ("1234567",
|
||||
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 8-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*)> a =
|
||||
Invoke(&foo, &Foo::Concat8);
|
||||
EXPECT_EQ("12345678",
|
||||
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 9-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*)> a = Invoke(&foo, &Foo::Concat9);
|
||||
EXPECT_EQ("123456789",
|
||||
a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8", "9")));
|
||||
}
|
||||
|
||||
// Tests using Invoke() with a 10-argument method.
|
||||
TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
|
||||
Foo foo;
|
||||
Action<string(const char*, const char*, const char*, const char*,
|
||||
const char*, const char*, const char*, const char*,
|
||||
const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
|
||||
EXPECT_EQ("1234567890", a.Perform(make_tuple("1", "2", "3", "4", "5", "6",
|
||||
"7", "8", "9", "0")));
|
||||
}
|
||||
|
||||
// Tests using Invoke(f) as an action of a compatible type.
|
||||
TEST(InvokeMethodTest, MethodWithCompatibleType) {
|
||||
Foo foo;
|
||||
Action<long(int, short, char, bool)> a = // NOLINT
|
||||
Invoke(&foo, &Foo::SumOf4);
|
||||
EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
|
||||
}
|
||||
|
||||
// Tests ByRef().
|
||||
|
||||
// Tests that ReferenceWrapper<T> is copyable.
|
||||
TEST(ByRefTest, IsCopyable) {
|
||||
const string s1 = "Hi";
|
||||
const string s2 = "Hello";
|
||||
|
||||
::testing::internal::ReferenceWrapper<const string> ref_wrapper = ByRef(s1);
|
||||
const string& r1 = ref_wrapper;
|
||||
EXPECT_EQ(&s1, &r1);
|
||||
|
||||
// Assigns a new value to ref_wrapper.
|
||||
ref_wrapper = ByRef(s2);
|
||||
const string& r2 = ref_wrapper;
|
||||
EXPECT_EQ(&s2, &r2);
|
||||
|
||||
::testing::internal::ReferenceWrapper<const string> ref_wrapper1 = ByRef(s1);
|
||||
// Copies ref_wrapper1 to ref_wrapper.
|
||||
ref_wrapper = ref_wrapper1;
|
||||
const string& r3 = ref_wrapper;
|
||||
EXPECT_EQ(&s1, &r3);
|
||||
}
|
||||
|
||||
// Tests using ByRef() on a const value.
|
||||
TEST(ByRefTest, ConstValue) {
|
||||
const int n = 0;
|
||||
// int& ref = ByRef(n); // This shouldn't compile - we have a
|
||||
// negative compilation test to catch it.
|
||||
const int& const_ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &const_ref);
|
||||
}
|
||||
|
||||
// Tests using ByRef() on a non-const value.
|
||||
TEST(ByRefTest, NonConstValue) {
|
||||
int n = 0;
|
||||
|
||||
// ByRef(n) can be used as either an int&,
|
||||
int& ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &ref);
|
||||
|
||||
// or a const int&.
|
||||
const int& const_ref = ByRef(n);
|
||||
EXPECT_EQ(&n, &const_ref);
|
||||
}
|
||||
|
||||
struct Base {
|
||||
bool operator==(const Base&) { return true; }
|
||||
};
|
||||
|
||||
struct Derived : public Base {
|
||||
bool operator==(const Derived&) { return true; }
|
||||
};
|
||||
|
||||
// Tests explicitly specifying the type when using ByRef().
|
||||
TEST(ByRefTest, ExplicitType) {
|
||||
int n = 0;
|
||||
const int& r1 = ByRef<const int>(n);
|
||||
EXPECT_EQ(&n, &r1);
|
||||
|
||||
// ByRef<char>(n); // This shouldn't compile - we have a negative
|
||||
// compilation test to catch it.
|
||||
|
||||
|
||||
Derived d;
|
||||
Derived& r2 = ByRef<Derived>(d);
|
||||
EXPECT_EQ(&d, &r2);
|
||||
|
||||
const Derived& r3 = ByRef<const Derived>(d);
|
||||
EXPECT_EQ(&d, &r3);
|
||||
|
||||
Base& r4 = ByRef<Base>(d);
|
||||
EXPECT_EQ(&d, &r4);
|
||||
|
||||
const Base& r5 = ByRef<const Base>(d);
|
||||
EXPECT_EQ(&d, &r5);
|
||||
|
||||
// The following shouldn't compile - we have a negative compilation
|
||||
// test for it.
|
||||
//
|
||||
// Base b;
|
||||
// ByRef<Derived>(b);
|
||||
}
|
||||
|
||||
// Tests InvokeArgument<N>(...).
|
||||
|
||||
// Tests using InvokeArgument with a nullary function.
|
||||
TEST(InvokeArgumentTest, Function0) {
|
||||
Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a unary function.
|
||||
TEST(InvokeArgumentTest, Functor1) {
|
||||
Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 5-ary function.
|
||||
TEST(InvokeArgumentTest, Function5) {
|
||||
Action<int(int(*)(int, int, int, int, int))> a = // NOLINT
|
||||
InvokeArgument<0>(10000, 2000, 300, 40, 5);
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 5-ary functor.
|
||||
TEST(InvokeArgumentTest, Functor5) {
|
||||
Action<int(SumOf5Functor)> a = // NOLINT
|
||||
InvokeArgument<0>(10000, 2000, 300, 40, 5);
|
||||
EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 6-ary function.
|
||||
TEST(InvokeArgumentTest, Function6) {
|
||||
Action<int(int(*)(int, int, int, int, int, int))> a = // NOLINT
|
||||
InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 6-ary functor.
|
||||
TEST(InvokeArgumentTest, Functor6) {
|
||||
Action<int(SumOf6Functor)> a = // NOLINT
|
||||
InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
|
||||
EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor())));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 7-ary function.
|
||||
TEST(InvokeArgumentTest, Function7) {
|
||||
Action<string(string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*))> a =
|
||||
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
|
||||
EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 8-ary function.
|
||||
TEST(InvokeArgumentTest, Function8) {
|
||||
Action<string(string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*))> a =
|
||||
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
|
||||
EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 9-ary function.
|
||||
TEST(InvokeArgumentTest, Function9) {
|
||||
Action<string(string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*))> a =
|
||||
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a 10-ary function.
|
||||
TEST(InvokeArgumentTest, Function10) {
|
||||
Action<string(string(*)(const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*, const char*, const char*,
|
||||
const char*))> a =
|
||||
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
|
||||
EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a function that takes a pointer argument.
|
||||
TEST(InvokeArgumentTest, ByPointerFunction) {
|
||||
Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
|
||||
InvokeArgument<0>(static_cast<const char*>("Hi"), 1);
|
||||
EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a function that takes a const char*
|
||||
// by passing it a C-string literal.
|
||||
TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
|
||||
Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
|
||||
InvokeArgument<0>("Hi", 1);
|
||||
EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with a function that takes a const reference.
|
||||
TEST(InvokeArgumentTest, ByConstReferenceFunction) {
|
||||
Action<bool(bool(*function)(const string& s))> a = // NOLINT
|
||||
InvokeArgument<0>(string("Hi"));
|
||||
// When action 'a' is constructed, it makes a copy of the temporary
|
||||
// string object passed to it, so it's OK to use 'a' later, when the
|
||||
// temporary object has already died.
|
||||
EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef)));
|
||||
}
|
||||
|
||||
// Tests using InvokeArgument with ByRef() and a function that takes a
|
||||
// const reference.
|
||||
TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
|
||||
Action<bool(bool(*)(const double& x))> a = // NOLINT
|
||||
InvokeArgument<0>(ByRef(g_double));
|
||||
// The above line calls ByRef() on a const value.
|
||||
EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
|
||||
|
||||
double x = 0;
|
||||
a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.
|
||||
EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
|
||||
}
|
||||
|
||||
// Tests using WithoutArgs with an action that takes no argument.
|
||||
TEST(WithoutArgsTest, NoArg) {
|
||||
Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
|
||||
EXPECT_EQ(1, a.Perform(make_tuple(2)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs and WithArg with an action that takes 1 argument.
|
||||
TEST(WithArgsTest, OneArg) {
|
||||
Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
|
||||
EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
|
||||
|
||||
// Also tests the synonym WithArg.
|
||||
Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
|
||||
EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
|
||||
EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
|
||||
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 2 arguments.
|
||||
TEST(WithArgsTest, TwoArgs) {
|
||||
Action<const char*(const char* s, double x, int n)> a =
|
||||
WithArgs<0, 2>(Invoke(Binary));
|
||||
const char s[] = "Hello";
|
||||
EXPECT_EQ(s + 2, a.Perform(make_tuple(s, 0.5, 2)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 3 arguments.
|
||||
TEST(WithArgsTest, ThreeArgs) {
|
||||
Action<int(int, double, char, short)> a = // NOLINT
|
||||
WithArgs<0, 2, 3>(Invoke(Ternary));
|
||||
EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, 20, 3)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 4 arguments.
|
||||
TEST(WithArgsTest, FourArgs) {
|
||||
Action<string(const char*, const char*, double, const char*, const char*)> a =
|
||||
WithArgs<4, 3, 1, 0>(Invoke(Concat4));
|
||||
EXPECT_EQ("4310", a.Perform(make_tuple("0", "1", 2.5, "3", "4")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 5 arguments.
|
||||
TEST(WithArgsTest, FiveArgs) {
|
||||
Action<string(const char*, const char*, const char*,
|
||||
const char*, const char*)> a =
|
||||
WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5));
|
||||
EXPECT_EQ("43210", a.Perform(make_tuple("0", "1", "2", "3", "4")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 6 arguments.
|
||||
TEST(WithArgsTest, SixArgs) {
|
||||
Action<string(const char*, const char*, const char*)> a =
|
||||
WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6));
|
||||
EXPECT_EQ("012210", a.Perform(make_tuple("0", "1", "2")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 7 arguments.
|
||||
TEST(WithArgsTest, SevenArgs) {
|
||||
Action<string(const char*, const char*, const char*, const char*)> a =
|
||||
WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7));
|
||||
EXPECT_EQ("0123210", a.Perform(make_tuple("0", "1", "2", "3")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 8 arguments.
|
||||
TEST(WithArgsTest, EightArgs) {
|
||||
Action<string(const char*, const char*, const char*, const char*)> a =
|
||||
WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8));
|
||||
EXPECT_EQ("01230123", a.Perform(make_tuple("0", "1", "2", "3")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 9 arguments.
|
||||
TEST(WithArgsTest, NineArgs) {
|
||||
Action<string(const char*, const char*, const char*, const char*)> a =
|
||||
WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9));
|
||||
EXPECT_EQ("012312323", a.Perform(make_tuple("0", "1", "2", "3")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that takes 10 arguments.
|
||||
TEST(WithArgsTest, TenArgs) {
|
||||
Action<string(const char*, const char*, const char*, const char*)> a =
|
||||
WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10));
|
||||
EXPECT_EQ("0123210123", a.Perform(make_tuple("0", "1", "2", "3")));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that is not Invoke().
|
||||
class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT
|
||||
public:
|
||||
virtual int Perform(const tuple<int, int>& args) {
|
||||
return get<0>(args) - get<1>(args);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(WithArgsTest, NonInvokeAction) {
|
||||
Action<int(const string&, int, int)> a = // NOLINT
|
||||
WithArgs<2, 1>(MakeAction(new SubstractAction));
|
||||
EXPECT_EQ(8, a.Perform(make_tuple("hi", 2, 10)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs to pass all original arguments in the original order.
|
||||
TEST(WithArgsTest, Identity) {
|
||||
Action<int(int x, char y, short z)> a = // NOLINT
|
||||
WithArgs<0, 1, 2>(Invoke(Ternary));
|
||||
EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 3)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with repeated arguments.
|
||||
TEST(WithArgsTest, RepeatedArguments) {
|
||||
Action<int(bool, int m, int n)> a = // NOLINT
|
||||
WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
|
||||
EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with reversed argument order.
|
||||
TEST(WithArgsTest, ReversedArgumentOrder) {
|
||||
Action<const char*(short n, const char* input)> a = // NOLINT
|
||||
WithArgs<1, 0>(Invoke(Binary));
|
||||
const char s[] = "Hello";
|
||||
EXPECT_EQ(s + 2, a.Perform(make_tuple(2, s)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with compatible, but not identical, argument types.
|
||||
TEST(WithArgsTest, ArgsOfCompatibleTypes) {
|
||||
Action<long(short x, int y, double z, char c)> a = // NOLINT
|
||||
WithArgs<0, 1, 3>(Invoke(Ternary));
|
||||
EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 5.6, 3)));
|
||||
}
|
||||
|
||||
// Tests using WithArgs with an action that returns void.
|
||||
TEST(WithArgsTest, VoidAction) {
|
||||
Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
|
||||
g_done = false;
|
||||
a.Perform(make_tuple(1.5, 'a', 3));
|
||||
EXPECT_TRUE(g_done);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2).
|
||||
TEST(DoAllTest, TwoActions) {
|
||||
int n = 0;
|
||||
Action<int(int*)> a = DoAll(SetArgumentPointee<0>(1), // NOLINT
|
||||
Return(2));
|
||||
EXPECT_EQ(2, a.Perform(make_tuple(&n)));
|
||||
EXPECT_EQ(1, n);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, a3).
|
||||
TEST(DoAllTest, ThreeActions) {
|
||||
int m = 0, n = 0;
|
||||
Action<int(int*, int*)> a = DoAll(SetArgumentPointee<0>(1), // NOLINT
|
||||
SetArgumentPointee<1>(2),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, a3, a4).
|
||||
TEST(DoAllTest, FourActions) {
|
||||
int m = 0, n = 0;
|
||||
char ch = '\0';
|
||||
Action<int(int*, int*, char*)> a = // NOLINT
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', ch);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, a3, a4, a5).
|
||||
TEST(DoAllTest, FiveActions) {
|
||||
int m = 0, n = 0;
|
||||
char a = '\0', b = '\0';
|
||||
Action<int(int*, int*, char*, char*)> action = // NOLINT
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
SetArgumentPointee<3>('b'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', a);
|
||||
EXPECT_EQ('b', b);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, ..., a6).
|
||||
TEST(DoAllTest, SixActions) {
|
||||
int m = 0, n = 0;
|
||||
char a = '\0', b = '\0', c = '\0';
|
||||
Action<int(int*, int*, char*, char*, char*)> action = // NOLINT
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
SetArgumentPointee<3>('b'),
|
||||
SetArgumentPointee<4>('c'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', a);
|
||||
EXPECT_EQ('b', b);
|
||||
EXPECT_EQ('c', c);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, ..., a7).
|
||||
TEST(DoAllTest, SevenActions) {
|
||||
int m = 0, n = 0;
|
||||
char a = '\0', b = '\0', c = '\0', d = '\0';
|
||||
Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
SetArgumentPointee<3>('b'),
|
||||
SetArgumentPointee<4>('c'),
|
||||
SetArgumentPointee<5>('d'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', a);
|
||||
EXPECT_EQ('b', b);
|
||||
EXPECT_EQ('c', c);
|
||||
EXPECT_EQ('d', d);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, ..., a8).
|
||||
TEST(DoAllTest, EightActions) {
|
||||
int m = 0, n = 0;
|
||||
char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
|
||||
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
|
||||
char*)> action =
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
SetArgumentPointee<3>('b'),
|
||||
SetArgumentPointee<4>('c'),
|
||||
SetArgumentPointee<5>('d'),
|
||||
SetArgumentPointee<6>('e'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', a);
|
||||
EXPECT_EQ('b', b);
|
||||
EXPECT_EQ('c', c);
|
||||
EXPECT_EQ('d', d);
|
||||
EXPECT_EQ('e', e);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, ..., a9).
|
||||
TEST(DoAllTest, NineActions) {
|
||||
int m = 0, n = 0;
|
||||
char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
|
||||
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
|
||||
char*, char*)> action =
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
SetArgumentPointee<3>('b'),
|
||||
SetArgumentPointee<4>('c'),
|
||||
SetArgumentPointee<5>('d'),
|
||||
SetArgumentPointee<6>('e'),
|
||||
SetArgumentPointee<7>('f'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', a);
|
||||
EXPECT_EQ('b', b);
|
||||
EXPECT_EQ('c', c);
|
||||
EXPECT_EQ('d', d);
|
||||
EXPECT_EQ('e', e);
|
||||
EXPECT_EQ('f', f);
|
||||
}
|
||||
|
||||
// Tests DoAll(a1, a2, ..., a10).
|
||||
TEST(DoAllTest, TenActions) {
|
||||
int m = 0, n = 0;
|
||||
char a = '\0', b = '\0', c = '\0', d = '\0';
|
||||
char e = '\0', f = '\0', g = '\0';
|
||||
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
|
||||
char*, char*, char*)> action =
|
||||
DoAll(SetArgumentPointee<0>(1),
|
||||
SetArgumentPointee<1>(2),
|
||||
SetArgumentPointee<2>('a'),
|
||||
SetArgumentPointee<3>('b'),
|
||||
SetArgumentPointee<4>('c'),
|
||||
SetArgumentPointee<5>('d'),
|
||||
SetArgumentPointee<6>('e'),
|
||||
SetArgumentPointee<7>('f'),
|
||||
SetArgumentPointee<8>('g'),
|
||||
Return(3));
|
||||
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
|
||||
EXPECT_EQ(1, m);
|
||||
EXPECT_EQ(2, n);
|
||||
EXPECT_EQ('a', a);
|
||||
EXPECT_EQ('b', b);
|
||||
EXPECT_EQ('c', c);
|
||||
EXPECT_EQ('d', d);
|
||||
EXPECT_EQ('e', e);
|
||||
EXPECT_EQ('f', f);
|
||||
EXPECT_EQ('g', g);
|
||||
}
|
||||
|
||||
} // namespace gmock_generated_actions_test
|
||||
} // namespace testing
|
426
test/gmock-generated-function-mockers_test.cc
Normal file
426
test/gmock-generated-function-mockers_test.cc
Normal file
@ -0,0 +1,426 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the function mocker classes.
|
||||
|
||||
#include <gmock/gmock-generated-function-mockers.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
|
||||
// we are getting compiler errors if we use basetyps.h, hence including
|
||||
// objbase.h for definition of STDMETHOD.
|
||||
#include <objbase.h>
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// There is a bug in MSVC (fixed in VS 2008) that prevents creating a
|
||||
// mock for a function with const arguments, so we don't test such
|
||||
// cases for MSVC versions older than 2008.
|
||||
#if !defined(GTEST_OS_WINDOWS) || (_MSC_VER >= 1500)
|
||||
#define GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
#endif // !defined(GTEST_OS_WINDOWS) || (_MSC_VER >= 1500)
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_generated_function_mockers_test {
|
||||
|
||||
using testing::internal::string;
|
||||
using testing::_;
|
||||
using testing::A;
|
||||
using testing::An;
|
||||
using testing::AnyNumber;
|
||||
using testing::Const;
|
||||
using testing::DoDefault;
|
||||
using testing::Eq;
|
||||
using testing::Lt;
|
||||
using testing::Ref;
|
||||
using testing::Return;
|
||||
using testing::ReturnRef;
|
||||
using testing::TypedEq;
|
||||
|
||||
class FooInterface {
|
||||
public:
|
||||
virtual ~FooInterface() {}
|
||||
|
||||
virtual void VoidReturning(int x) = 0;
|
||||
|
||||
virtual int Nullary() = 0;
|
||||
virtual bool Unary(int x) = 0;
|
||||
virtual long Binary(short x, int y) = 0; // NOLINT
|
||||
virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
|
||||
float g, double h, unsigned i, char* j, const string& k)
|
||||
= 0;
|
||||
|
||||
virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
|
||||
virtual string TakesConstReference(const int& n) = 0;
|
||||
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
virtual bool TakesConst(const int x) = 0;
|
||||
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
|
||||
virtual int OverloadedOnArgumentNumber() = 0;
|
||||
virtual int OverloadedOnArgumentNumber(int n) = 0;
|
||||
|
||||
virtual int OverloadedOnArgumentType(int n) = 0;
|
||||
virtual char OverloadedOnArgumentType(char c) = 0;
|
||||
|
||||
virtual int OverloadedOnConstness() = 0;
|
||||
virtual char OverloadedOnConstness() const = 0;
|
||||
|
||||
virtual int TypeWithHole(int (*func)()) = 0;
|
||||
virtual int TypeWithComma(const std::map<int, string>& a_map) = 0;
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
STDMETHOD_(int, CTNullary)() = 0;
|
||||
STDMETHOD_(bool, CTUnary)(int x) = 0;
|
||||
STDMETHOD_(int, CTDecimal)(bool b, char c, short d, int e, long f, // NOLINT
|
||||
float g, double h, unsigned i, char* j, const string& k) = 0;
|
||||
STDMETHOD_(char, CTConst)(int x) const = 0;
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
};
|
||||
|
||||
class MockFoo : public FooInterface {
|
||||
public:
|
||||
// Makes sure that a mock function parameter can be named.
|
||||
MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(Nullary, int()); // NOLINT
|
||||
|
||||
// Makes sure that a mock function parameter can be unnamed.
|
||||
MOCK_METHOD1(Unary, bool(int)); // NOLINT
|
||||
MOCK_METHOD2(Binary, long(short, int)); // NOLINT
|
||||
MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
|
||||
double, unsigned, char*, const string& str));
|
||||
|
||||
MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
|
||||
MOCK_METHOD1(TakesConstReference, string(const int&));
|
||||
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
|
||||
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
|
||||
MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
|
||||
|
||||
MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
|
||||
MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
|
||||
|
||||
MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
|
||||
MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
|
||||
|
||||
MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
|
||||
MOCK_METHOD1(TypeWithComma, int(const std::map<int, string>&)); // NOLINT
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int));
|
||||
MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, int(bool b, char c,
|
||||
short d, int e, long f, float g, double h, unsigned i, char* j,
|
||||
const string& k));
|
||||
MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int));
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
};
|
||||
|
||||
class FunctionMockerTest : public testing::Test {
|
||||
protected:
|
||||
FunctionMockerTest() : foo_(&mock_foo_) {}
|
||||
|
||||
FooInterface* const foo_;
|
||||
MockFoo mock_foo_;
|
||||
};
|
||||
|
||||
// Tests mocking a void-returning function.
|
||||
TEST_F(FunctionMockerTest, MocksVoidFunction) {
|
||||
EXPECT_CALL(mock_foo_, VoidReturning(Lt(100)));
|
||||
foo_->VoidReturning(0);
|
||||
}
|
||||
|
||||
// Tests mocking a nullary function.
|
||||
TEST_F(FunctionMockerTest, MocksNullaryFunction) {
|
||||
EXPECT_CALL(mock_foo_, Nullary())
|
||||
.WillOnce(DoDefault())
|
||||
.WillOnce(Return(1));
|
||||
|
||||
EXPECT_EQ(0, foo_->Nullary());
|
||||
EXPECT_EQ(1, foo_->Nullary());
|
||||
}
|
||||
|
||||
// Tests mocking a unary function.
|
||||
TEST_F(FunctionMockerTest, MocksUnaryFunction) {
|
||||
EXPECT_CALL(mock_foo_, Unary(Eq(2)))
|
||||
.Times(2)
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(foo_->Unary(2));
|
||||
EXPECT_FALSE(foo_->Unary(2));
|
||||
}
|
||||
|
||||
// Tests mocking a binary function.
|
||||
TEST_F(FunctionMockerTest, MocksBinaryFunction) {
|
||||
EXPECT_CALL(mock_foo_, Binary(2, _))
|
||||
.WillOnce(Return(3));
|
||||
|
||||
EXPECT_EQ(3, foo_->Binary(2, 1));
|
||||
}
|
||||
|
||||
// Tests mocking a decimal function.
|
||||
TEST_F(FunctionMockerTest, MocksDecimalFunction) {
|
||||
EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(),
|
||||
Lt(100), 5U, NULL, "hi"))
|
||||
.WillOnce(Return(5));
|
||||
|
||||
EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a non-const reference.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
|
||||
int a = 0;
|
||||
EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(foo_->TakesNonConstReference(a));
|
||||
}
|
||||
|
||||
// Tests mocking a function that takes a const reference.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
|
||||
int a = 0;
|
||||
EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a)))
|
||||
.WillOnce(Return("Hello"));
|
||||
|
||||
EXPECT_EQ("Hello", foo_->TakesConstReference(a));
|
||||
}
|
||||
|
||||
#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
// Tests mocking a function that takes a const variable.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionWithConstArgument) {
|
||||
EXPECT_CALL(mock_foo_, TakesConst(Lt(10)))
|
||||
.WillOnce(DoDefault());
|
||||
|
||||
EXPECT_FALSE(foo_->TakesConst(5));
|
||||
}
|
||||
#endif // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS
|
||||
|
||||
// Tests mocking functions overloaded on the number of arguments.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber())
|
||||
.WillOnce(Return(1));
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_))
|
||||
.WillOnce(Return(2));
|
||||
|
||||
EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1));
|
||||
EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber());
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the types of argument.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>()))
|
||||
.WillOnce(Return(1));
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
|
||||
.WillOnce(Return('b'));
|
||||
|
||||
EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0));
|
||||
EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a'));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the const-ness of this object.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
|
||||
EXPECT_CALL(mock_foo_, OverloadedOnConstness());
|
||||
EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness())
|
||||
.WillOnce(Return('a'));
|
||||
|
||||
EXPECT_EQ(0, foo_->OverloadedOnConstness());
|
||||
EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness());
|
||||
}
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Tests mocking a nullary function with calltype.
|
||||
TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
|
||||
EXPECT_CALL(mock_foo_, CTNullary())
|
||||
.WillOnce(Return(-1))
|
||||
.WillOnce(Return(0));
|
||||
|
||||
EXPECT_EQ(-1, foo_->CTNullary());
|
||||
EXPECT_EQ(0, foo_->CTNullary());
|
||||
}
|
||||
|
||||
// Tests mocking a unary function with calltype.
|
||||
TEST_F(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
|
||||
EXPECT_CALL(mock_foo_, CTUnary(Eq(2)))
|
||||
.Times(2)
|
||||
.WillOnce(Return(true))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
EXPECT_TRUE(foo_->CTUnary(2));
|
||||
EXPECT_FALSE(foo_->CTUnary(2));
|
||||
}
|
||||
|
||||
// Tests mocking a decimal function with calltype.
|
||||
TEST_F(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
|
||||
EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
|
||||
Lt(100), 5U, NULL, "hi"))
|
||||
.WillOnce(Return(10));
|
||||
|
||||
EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
|
||||
}
|
||||
|
||||
// Tests mocking functions overloaded on the const-ness of this object.
|
||||
TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
|
||||
EXPECT_CALL(Const(mock_foo_), CTConst(_))
|
||||
.WillOnce(Return('a'));
|
||||
|
||||
EXPECT_EQ('a', Const(*foo_).CTConst(0));
|
||||
}
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
class MockB {
|
||||
public:
|
||||
MOCK_METHOD0(DoB, void());
|
||||
};
|
||||
|
||||
// Tests that functions with no EXPECT_CALL() ruls can be called any
|
||||
// number of times.
|
||||
TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
|
||||
{
|
||||
MockB b;
|
||||
}
|
||||
|
||||
{
|
||||
MockB b;
|
||||
b.DoB();
|
||||
}
|
||||
|
||||
{
|
||||
MockB b;
|
||||
b.DoB();
|
||||
b.DoB();
|
||||
}
|
||||
}
|
||||
|
||||
// Tests mocking template interfaces.
|
||||
|
||||
template <typename T>
|
||||
class StackInterface {
|
||||
public:
|
||||
virtual ~StackInterface() {}
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
virtual void Push(const T& value) = 0;
|
||||
virtual void Pop() = 0;
|
||||
virtual int GetSize() const = 0;
|
||||
// Template parameter appears in function return type.
|
||||
virtual const T& GetTop() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MockStack : public StackInterface<T> {
|
||||
public:
|
||||
MOCK_METHOD1_T(Push, void(const T& elem));
|
||||
MOCK_METHOD0_T(Pop, void());
|
||||
MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
|
||||
MOCK_CONST_METHOD0_T(GetTop, const T&());
|
||||
};
|
||||
|
||||
// Tests that template mock works.
|
||||
TEST(TemplateMockTest, Works) {
|
||||
MockStack<int> mock;
|
||||
|
||||
EXPECT_CALL(mock, GetSize())
|
||||
.WillOnce(Return(0))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(mock, Push(_));
|
||||
int n = 5;
|
||||
EXPECT_CALL(mock, GetTop())
|
||||
.WillOnce(ReturnRef(n));
|
||||
EXPECT_CALL(mock, Pop())
|
||||
.Times(AnyNumber());
|
||||
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
mock.Push(5);
|
||||
EXPECT_EQ(1, mock.GetSize());
|
||||
EXPECT_EQ(5, mock.GetTop());
|
||||
mock.Pop();
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
}
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// Tests mocking template interfaces with calltype.
|
||||
|
||||
template <typename T>
|
||||
class StackInterfaceWithCallType {
|
||||
public:
|
||||
virtual ~StackInterfaceWithCallType() {}
|
||||
|
||||
// Template parameter appears in function parameter.
|
||||
STDMETHOD_(void, Push)(const T& value) = 0;
|
||||
STDMETHOD_(void, Pop)() = 0;
|
||||
STDMETHOD_(int, GetSize)() const = 0;
|
||||
// Template parameter appears in function return type.
|
||||
STDMETHOD_(const T&, GetTop)() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MockStackWithCallType : public StackInterfaceWithCallType<T> {
|
||||
public:
|
||||
MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
|
||||
MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
|
||||
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
|
||||
MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
|
||||
};
|
||||
|
||||
// Tests that template mock with calltype works.
|
||||
TEST(TemplateMockTestWithCallType, Works) {
|
||||
MockStackWithCallType<int> mock;
|
||||
|
||||
EXPECT_CALL(mock, GetSize())
|
||||
.WillOnce(Return(0))
|
||||
.WillOnce(Return(1))
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(mock, Push(_));
|
||||
int n = 5;
|
||||
EXPECT_CALL(mock, GetTop())
|
||||
.WillOnce(ReturnRef(n));
|
||||
EXPECT_CALL(mock, Pop())
|
||||
.Times(AnyNumber());
|
||||
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
mock.Push(5);
|
||||
EXPECT_EQ(1, mock.GetSize());
|
||||
EXPECT_EQ(5, mock.GetTop());
|
||||
mock.Pop();
|
||||
EXPECT_EQ(0, mock.GetSize());
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
} // namespace gmock_generated_function_mockers_test
|
||||
} // namespace testing
|
127
test/gmock-generated-internal-utils_test.cc
Normal file
127
test/gmock-generated-internal-utils_test.cc
Normal file
@ -0,0 +1,127 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the internal utilities.
|
||||
|
||||
#include <gmock/internal/gmock-generated-internal-utils.h>
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::tr1::tuple;
|
||||
using ::testing::Matcher;
|
||||
using ::testing::internal::CompileAssertTypesEqual;
|
||||
using ::testing::internal::MatcherTuple;
|
||||
using ::testing::internal::Function;
|
||||
using ::testing::internal::IgnoredValue;
|
||||
|
||||
// Tests the MatcherTuple template struct.
|
||||
|
||||
TEST(MatcherTupleTest, ForSize0) {
|
||||
CompileAssertTypesEqual<tuple<>, MatcherTuple<tuple<> >::type>();
|
||||
}
|
||||
|
||||
TEST(MatcherTupleTest, ForSize1) {
|
||||
CompileAssertTypesEqual<tuple<Matcher<int> >,
|
||||
MatcherTuple<tuple<int> >::type>();
|
||||
}
|
||||
|
||||
TEST(MatcherTupleTest, ForSize2) {
|
||||
CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char> >,
|
||||
MatcherTuple<tuple<int, char> >::type>();
|
||||
}
|
||||
|
||||
TEST(MatcherTupleTest, ForSize5) {
|
||||
CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char>, Matcher<bool>,
|
||||
Matcher<double>, Matcher<char*> >,
|
||||
MatcherTuple<tuple<int, char, bool, double, char*>
|
||||
>::type>();
|
||||
}
|
||||
|
||||
// Tests the Function template struct.
|
||||
|
||||
TEST(FunctionTest, Nullary) {
|
||||
typedef Function<int()> F; // NOLINT
|
||||
CompileAssertTypesEqual<int, F::Result>();
|
||||
CompileAssertTypesEqual<tuple<>, F::ArgumentTuple>();
|
||||
CompileAssertTypesEqual<tuple<>, F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(), F::MakeResultVoid>();
|
||||
CompileAssertTypesEqual<IgnoredValue(), F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
TEST(FunctionTest, Unary) {
|
||||
typedef Function<int(bool)> F; // NOLINT
|
||||
CompileAssertTypesEqual<int, F::Result>();
|
||||
CompileAssertTypesEqual<bool, F::Argument1>();
|
||||
CompileAssertTypesEqual<tuple<bool>, F::ArgumentTuple>();
|
||||
CompileAssertTypesEqual<tuple<Matcher<bool> >, F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(bool), F::MakeResultVoid>(); // NOLINT
|
||||
CompileAssertTypesEqual<IgnoredValue(bool), // NOLINT
|
||||
F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
TEST(FunctionTest, Binary) {
|
||||
typedef Function<int(bool, const long&)> F; // NOLINT
|
||||
CompileAssertTypesEqual<int, F::Result>();
|
||||
CompileAssertTypesEqual<bool, F::Argument1>();
|
||||
CompileAssertTypesEqual<const long&, F::Argument2>(); // NOLINT
|
||||
CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>(); // NOLINT
|
||||
CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<const long&> >, // NOLINT
|
||||
F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>(); // NOLINT
|
||||
CompileAssertTypesEqual<IgnoredValue(bool, const long&), // NOLINT
|
||||
F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
TEST(FunctionTest, LongArgumentList) {
|
||||
typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT
|
||||
CompileAssertTypesEqual<char, F::Result>();
|
||||
CompileAssertTypesEqual<bool, F::Argument1>();
|
||||
CompileAssertTypesEqual<int, F::Argument2>();
|
||||
CompileAssertTypesEqual<char*, F::Argument3>();
|
||||
CompileAssertTypesEqual<int&, F::Argument4>();
|
||||
CompileAssertTypesEqual<const long&, F::Argument5>(); // NOLINT
|
||||
CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>, // NOLINT
|
||||
F::ArgumentTuple>();
|
||||
CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<int>, Matcher<char*>,
|
||||
Matcher<int&>, Matcher<const long&> >, // NOLINT
|
||||
F::ArgumentMatcherTuple>();
|
||||
CompileAssertTypesEqual<void(bool, int, char*, int&, const long&), // NOLINT
|
||||
F::MakeResultVoid>();
|
||||
CompileAssertTypesEqual<
|
||||
IgnoredValue(bool, int, char*, int&, const long&), // NOLINT
|
||||
F::MakeResultIgnoredValue>();
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
373
test/gmock-generated-matchers_test.cc
Normal file
373
test/gmock-generated-matchers_test.cc
Normal file
@ -0,0 +1,373 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the built-in matchers generated by a script.
|
||||
|
||||
#include <gmock/gmock-generated-matchers.h>
|
||||
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using std::list;
|
||||
using std::stringstream;
|
||||
using std::vector;
|
||||
using testing::_;
|
||||
using testing::ElementsAre;
|
||||
using testing::ElementsAreArray;
|
||||
using testing::Eq;
|
||||
using testing::Ge;
|
||||
using testing::Gt;
|
||||
using testing::MakeMatcher;
|
||||
using testing::Matcher;
|
||||
using testing::MatcherInterface;
|
||||
using testing::Ne;
|
||||
using testing::Not;
|
||||
using testing::Pointee;
|
||||
using testing::Ref;
|
||||
using testing::StrEq;
|
||||
using testing::internal::string;
|
||||
|
||||
// Returns the description of the given matcher.
|
||||
template <typename T>
|
||||
string Describe(const Matcher<T>& m) {
|
||||
stringstream ss;
|
||||
m.DescribeTo(&ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Returns the description of the negation of the given matcher.
|
||||
template <typename T>
|
||||
string DescribeNegation(const Matcher<T>& m) {
|
||||
stringstream ss;
|
||||
m.DescribeNegationTo(&ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Returns the reason why x matches, or doesn't match, m.
|
||||
template <typename MatcherType, typename Value>
|
||||
string Explain(const MatcherType& m, const Value& x) {
|
||||
stringstream ss;
|
||||
m.ExplainMatchResultTo(x, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// For testing ExplainMatchResultTo().
|
||||
class GreaterThanMatcher : public MatcherInterface<int> {
|
||||
public:
|
||||
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
|
||||
|
||||
virtual bool Matches(int lhs) const { return lhs > rhs_; }
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "is greater than " << rhs_;
|
||||
}
|
||||
|
||||
virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const {
|
||||
const int diff = lhs - rhs_;
|
||||
if (diff > 0) {
|
||||
*os << "is " << diff << " more than " << rhs_;
|
||||
} else if (diff == 0) {
|
||||
*os << "is the same as " << rhs_;
|
||||
} else {
|
||||
*os << "is " << -diff << " less than " << rhs_;
|
||||
}
|
||||
}
|
||||
private:
|
||||
const int rhs_;
|
||||
};
|
||||
|
||||
Matcher<int> GreaterThan(int n) {
|
||||
return MakeMatcher(new GreaterThanMatcher(n));
|
||||
}
|
||||
|
||||
// Tests for ElementsAre().
|
||||
|
||||
// Evaluates to the number of elements in 'array'.
|
||||
#define GMOCK_ARRAY_SIZE_(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeExpectingNoElement) {
|
||||
Matcher<const vector<int>&> m = ElementsAre();
|
||||
EXPECT_EQ("is empty", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeExpectingOneElement) {
|
||||
Matcher<vector<int> > m = ElementsAre(Gt(5));
|
||||
EXPECT_EQ("has 1 element that is greater than 5", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeExpectingManyElements) {
|
||||
Matcher<list<string> > m = ElementsAre(StrEq("one"), "two");
|
||||
EXPECT_EQ("has 2 elements where\n"
|
||||
"element 0 is equal to \"one\",\n"
|
||||
"element 1 is equal to \"two\"", Describe(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) {
|
||||
Matcher<vector<int> > m = ElementsAre();
|
||||
EXPECT_EQ("is not empty", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) {
|
||||
Matcher<const list<int>& > m = ElementsAre(Gt(5));
|
||||
EXPECT_EQ("does not have 1 element, or\n"
|
||||
"element 0 is not greater than 5", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) {
|
||||
Matcher<const list<string>& > m = ElementsAre("one", "two");
|
||||
EXPECT_EQ("does not have 2 elements, or\n"
|
||||
"element 0 is not equal to \"one\", or\n"
|
||||
"element 1 is not equal to \"two\"", DescribeNegation(m));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotExplainTrivialMatch) {
|
||||
Matcher<const list<int>& > m = ElementsAre(1, Ne(2));
|
||||
|
||||
list<int> test_list;
|
||||
test_list.push_back(1);
|
||||
test_list.push_back(3);
|
||||
EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything.
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, ExplainsNonTrivialMatch) {
|
||||
Matcher<const vector<int>& > m =
|
||||
ElementsAre(GreaterThan(1), 0, GreaterThan(2));
|
||||
|
||||
const int a[] = { 10, 0, 100 };
|
||||
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_EQ("element 0 is 9 more than 1,\n"
|
||||
"element 2 is 98 more than 2", Explain(m, test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanExplainMismatchWrongSize) {
|
||||
Matcher<const list<int>& > m = ElementsAre(1, 3);
|
||||
|
||||
list<int> test_list;
|
||||
// No need to explain when the container is empty.
|
||||
EXPECT_EQ("", Explain(m, test_list));
|
||||
|
||||
test_list.push_back(1);
|
||||
EXPECT_EQ("has 1 element", Explain(m, test_list));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, CanExplainMismatchRightSize) {
|
||||
Matcher<const vector<int>& > m = ElementsAre(1, GreaterThan(5));
|
||||
|
||||
vector<int> v;
|
||||
v.push_back(2);
|
||||
v.push_back(1);
|
||||
EXPECT_EQ("element 0 doesn't match", Explain(m, v));
|
||||
|
||||
v[0] = 1;
|
||||
EXPECT_EQ("element 1 doesn't match (is 4 less than 5)", Explain(m, v));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementVector) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("test string");
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(StrEq("test string")));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementList) {
|
||||
list<string> test_list;
|
||||
test_list.push_back("test string");
|
||||
|
||||
EXPECT_THAT(test_list, ElementsAre("test string"));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesThreeElementVector) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("one");
|
||||
test_vector.push_back("two");
|
||||
test_vector.push_back("three");
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre("one", StrEq("two"), _));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementEqMatcher) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(4);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(Eq(4)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementAnyMatcher) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(4);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(_));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesOneElementValue) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(4);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(4));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesThreeElementsMixedMatchers) {
|
||||
vector<int> test_vector;
|
||||
test_vector.push_back(1);
|
||||
test_vector.push_back(2);
|
||||
test_vector.push_back(3);
|
||||
|
||||
EXPECT_THAT(test_vector, ElementsAre(1, Eq(2), _));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, MatchesTenElementVector) {
|
||||
const int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
|
||||
EXPECT_THAT(test_vector,
|
||||
// The element list can contain values and/or matchers
|
||||
// of different types.
|
||||
ElementsAre(0, Ge(0), _, 3, 4, Ne(2), Eq(6), 7, 8, _));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotMatchWrongSize) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("test string");
|
||||
test_vector.push_back("test string");
|
||||
|
||||
Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
|
||||
EXPECT_FALSE(m.Matches(test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotMatchWrongValue) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("other string");
|
||||
|
||||
Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
|
||||
EXPECT_FALSE(m.Matches(test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, DoesNotMatchWrongOrder) {
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("one");
|
||||
test_vector.push_back("three");
|
||||
test_vector.push_back("two");
|
||||
|
||||
Matcher<vector<string> > m = ElementsAre(
|
||||
StrEq("one"), StrEq("two"), StrEq("three"));
|
||||
EXPECT_FALSE(m.Matches(test_vector));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksForNestedContainer) {
|
||||
const char* strings[] = {
|
||||
"Hi",
|
||||
"world"
|
||||
};
|
||||
|
||||
vector<list<char> > nested;
|
||||
for (int i = 0; i < GMOCK_ARRAY_SIZE_(strings); i++) {
|
||||
nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i])));
|
||||
}
|
||||
|
||||
EXPECT_THAT(nested, ElementsAre(ElementsAre('H', Ne('e')),
|
||||
ElementsAre('w', 'o', _, _, 'd')));
|
||||
EXPECT_THAT(nested, Not(ElementsAre(ElementsAre('H', 'e'),
|
||||
ElementsAre('w', 'o', _, _, 'd'))));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksWithByRefElementMatchers) {
|
||||
int a[] = { 0, 1, 2 };
|
||||
vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
|
||||
EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2])));
|
||||
EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2]))));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
|
||||
int a[] = { 0, 1, 2 };
|
||||
vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
|
||||
EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _)));
|
||||
EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
|
||||
}
|
||||
|
||||
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most
|
||||
// of the implementation with ElementsAre(), we don't test it as
|
||||
// thoroughly here.
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) {
|
||||
const int a[] = { 1, 2, 3 };
|
||||
|
||||
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(a));
|
||||
|
||||
test_vector[2] = 0;
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) {
|
||||
const char* a[] = { "one", "two", "three" };
|
||||
|
||||
vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(a, GMOCK_ARRAY_SIZE_(a)));
|
||||
|
||||
const char** p = a;
|
||||
test_vector[0] = "1";
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GMOCK_ARRAY_SIZE_(a))));
|
||||
}
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) {
|
||||
const char* a[] = { "one", "two", "three" };
|
||||
|
||||
vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(a));
|
||||
|
||||
test_vector[0] = "1";
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
|
||||
const Matcher<string> kMatcherArray[] =
|
||||
{ StrEq("one"), StrEq("two"), StrEq("three") };
|
||||
|
||||
vector<string> test_vector;
|
||||
test_vector.push_back("one");
|
||||
test_vector.push_back("two");
|
||||
test_vector.push_back("three");
|
||||
EXPECT_THAT(test_vector, ElementsAreArray(kMatcherArray));
|
||||
|
||||
test_vector.push_back("three");
|
||||
EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
|
||||
}
|
||||
|
||||
} // namespace
|
521
test/gmock-internal-utils_test.cc
Normal file
521
test/gmock-internal-utils_test.cc
Normal file
@ -0,0 +1,521 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the internal utilities.
|
||||
|
||||
#include <gmock/internal/gmock-internal-utils.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::tr1::tuple;
|
||||
|
||||
// Tests that CompileAssertTypesEqual compiles when the type arguments are
|
||||
// equal.
|
||||
TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) {
|
||||
CompileAssertTypesEqual<void, void>();
|
||||
CompileAssertTypesEqual<int*, int*>();
|
||||
}
|
||||
|
||||
// Tests that RemoveReference does not affect non-reference types.
|
||||
TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) {
|
||||
CompileAssertTypesEqual<int, RemoveReference<int>::type>();
|
||||
CompileAssertTypesEqual<const char, RemoveReference<const char>::type>();
|
||||
}
|
||||
|
||||
// Tests that RemoveReference removes reference from reference types.
|
||||
TEST(RemoveReferenceTest, RemovesReference) {
|
||||
CompileAssertTypesEqual<int, RemoveReference<int&>::type>();
|
||||
CompileAssertTypesEqual<const char, RemoveReference<const char&>::type>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_REMOVE_REFERENCE.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockRemoveReference() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_REMOVE_REFERENCE(T2)>();
|
||||
}
|
||||
|
||||
TEST(RemoveReferenceTest, MacroVersion) {
|
||||
TestGMockRemoveReference<int, int>();
|
||||
TestGMockRemoveReference<const char, const char&>();
|
||||
}
|
||||
|
||||
|
||||
// Tests that RemoveConst does not affect non-const types.
|
||||
TEST(RemoveConstTest, DoesNotAffectNonConstType) {
|
||||
CompileAssertTypesEqual<int, RemoveConst<int>::type>();
|
||||
CompileAssertTypesEqual<char&, RemoveConst<char&>::type>();
|
||||
}
|
||||
|
||||
// Tests that RemoveConst removes const from const types.
|
||||
TEST(RemoveConstTest, RemovesConst) {
|
||||
CompileAssertTypesEqual<int, RemoveConst<const int>::type>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_REMOVE_CONST.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockRemoveConst() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_REMOVE_CONST(T2)>();
|
||||
}
|
||||
|
||||
TEST(RemoveConstTest, MacroVersion) {
|
||||
TestGMockRemoveConst<int, int>();
|
||||
TestGMockRemoveConst<double&, double&>();
|
||||
TestGMockRemoveConst<char, const char>();
|
||||
}
|
||||
|
||||
// Tests that AddReference does not affect reference types.
|
||||
TEST(AddReferenceTest, DoesNotAffectReferenceType) {
|
||||
CompileAssertTypesEqual<int&, AddReference<int&>::type>();
|
||||
CompileAssertTypesEqual<const char&, AddReference<const char&>::type>();
|
||||
}
|
||||
|
||||
// Tests that AddReference adds reference to non-reference types.
|
||||
TEST(AddReferenceTest, AddsReference) {
|
||||
CompileAssertTypesEqual<int&, AddReference<int>::type>();
|
||||
CompileAssertTypesEqual<const char&, AddReference<const char>::type>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_ADD_REFERENCE.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockAddReference() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_ADD_REFERENCE(T2)>();
|
||||
}
|
||||
|
||||
TEST(AddReferenceTest, MacroVersion) {
|
||||
TestGMockAddReference<int&, int>();
|
||||
TestGMockAddReference<const char&, const char&>();
|
||||
}
|
||||
|
||||
// Tests GMOCK_REFERENCE_TO_CONST.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void TestGMockReferenceToConst() {
|
||||
CompileAssertTypesEqual<T1, GMOCK_REFERENCE_TO_CONST(T2)>();
|
||||
}
|
||||
|
||||
TEST(GMockReferenceToConstTest, Works) {
|
||||
TestGMockReferenceToConst<const char&, char>();
|
||||
TestGMockReferenceToConst<const int&, const int>();
|
||||
TestGMockReferenceToConst<const double&, double>();
|
||||
TestGMockReferenceToConst<const string&, const string&>();
|
||||
}
|
||||
|
||||
TEST(PointeeOfTest, WorksForSmartPointers) {
|
||||
CompileAssertTypesEqual<const char,
|
||||
PointeeOf<internal::linked_ptr<const char> >::type>();
|
||||
}
|
||||
|
||||
TEST(PointeeOfTest, WorksForRawPointers) {
|
||||
CompileAssertTypesEqual<int, PointeeOf<int*>::type>();
|
||||
CompileAssertTypesEqual<const char, PointeeOf<const char*>::type>();
|
||||
CompileAssertTypesEqual<void, PointeeOf<void*>::type>();
|
||||
}
|
||||
|
||||
TEST(GetRawPointerTest, WorksForSmartPointers) {
|
||||
const char* const raw_p4 = new const char('a'); // NOLINT
|
||||
const internal::linked_ptr<const char> p4(raw_p4);
|
||||
EXPECT_EQ(raw_p4, GetRawPointer(p4));
|
||||
}
|
||||
|
||||
TEST(GetRawPointerTest, WorksForRawPointers) {
|
||||
int* p = NULL;
|
||||
EXPECT_EQ(NULL, GetRawPointer(p));
|
||||
int n = 1;
|
||||
EXPECT_EQ(&n, GetRawPointer(&n));
|
||||
}
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
|
||||
// Tests that ImplicitlyConvertible<T1, T2>::value is a compile-time constant.
|
||||
TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) {
|
||||
GMOCK_COMPILE_ASSERT((ImplicitlyConvertible<int, int>::value), const_true);
|
||||
GMOCK_COMPILE_ASSERT((!ImplicitlyConvertible<void*, int*>::value), const_false);
|
||||
}
|
||||
|
||||
// Tests that ImplicitlyConvertible<T1, T2>::value is true when T1 can
|
||||
// be implicitly converted to T2.
|
||||
TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) {
|
||||
EXPECT_TRUE((ImplicitlyConvertible<int, double>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<double, int>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<int*, void*>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<int*, const int*>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<Derived&, const Base&>::value));
|
||||
EXPECT_TRUE((ImplicitlyConvertible<const Base, Base>::value));
|
||||
}
|
||||
|
||||
// Tests that ImplicitlyConvertible<T1, T2>::value is false when T1
|
||||
// cannot be implicitly converted to T2.
|
||||
TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) {
|
||||
EXPECT_FALSE((ImplicitlyConvertible<double, int*>::value));
|
||||
EXPECT_FALSE((ImplicitlyConvertible<void*, int*>::value));
|
||||
EXPECT_FALSE((ImplicitlyConvertible<const int*, int*>::value));
|
||||
EXPECT_FALSE((ImplicitlyConvertible<Base&, Derived&>::value));
|
||||
}
|
||||
|
||||
// Tests that IsAProtocolMessage<T>::value is a compile-time constant.
|
||||
TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) {
|
||||
GMOCK_COMPILE_ASSERT(IsAProtocolMessage<ProtocolMessage>::value, const_true);
|
||||
GMOCK_COMPILE_ASSERT(!IsAProtocolMessage<int>::value, const_false);
|
||||
}
|
||||
|
||||
// Tests that IsAProtocolMessage<T>::value is true when T is
|
||||
// ProtocolMessage or a sub-class of it.
|
||||
TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) {
|
||||
EXPECT_TRUE(IsAProtocolMessage<ProtocolMessage>::value);
|
||||
#if GMOCK_HAS_PROTOBUF_
|
||||
EXPECT_TRUE(IsAProtocolMessage<const TestMessage>::value);
|
||||
#endif // GMOCK_HAS_PROTOBUF_
|
||||
}
|
||||
|
||||
// Tests that IsAProtocolMessage<T>::value is false when T is neither
|
||||
// ProtocolMessage nor a sub-class of it.
|
||||
TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) {
|
||||
EXPECT_FALSE(IsAProtocolMessage<int>::value);
|
||||
EXPECT_FALSE(IsAProtocolMessage<const Base>::value);
|
||||
}
|
||||
|
||||
// Tests IsContainerTest.
|
||||
|
||||
class NonContainer {};
|
||||
|
||||
TEST(IsContainerTestTest, WorksForNonContainer) {
|
||||
EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<int>(0)));
|
||||
EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<char[5]>(0)));
|
||||
EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<NonContainer>(0)));
|
||||
}
|
||||
|
||||
TEST(IsContainerTestTest, WorksForContainer) {
|
||||
EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest<std::vector<bool> >(0)));
|
||||
EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest<std::map<int, double> >(0)));
|
||||
}
|
||||
|
||||
// Tests the TupleMatches() template function.
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize0) {
|
||||
tuple<> matchers;
|
||||
tuple<> values;
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize1) {
|
||||
tuple<Matcher<int> > matchers(Eq(1));
|
||||
tuple<int> values1(1),
|
||||
values2(2);
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize2) {
|
||||
tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a'));
|
||||
tuple<int, char> values1(1, 'a'),
|
||||
values2(1, 'b'),
|
||||
values3(2, 'a'),
|
||||
values4(2, 'b');
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values3));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values4));
|
||||
}
|
||||
|
||||
TEST(TupleMatchesTest, WorksForSize5) {
|
||||
tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<long>, // NOLINT
|
||||
Matcher<string> >
|
||||
matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi"));
|
||||
tuple<int, char, bool, long, string> // NOLINT
|
||||
values1(1, 'a', true, 2L, "hi"),
|
||||
values2(1, 'a', true, 2L, "hello"),
|
||||
values3(2, 'a', true, 2L, "hi");
|
||||
|
||||
EXPECT_TRUE(TupleMatches(matchers, values1));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values2));
|
||||
EXPECT_FALSE(TupleMatches(matchers, values3));
|
||||
}
|
||||
|
||||
// Tests that Assert(true, ...) succeeds.
|
||||
TEST(AssertTest, SucceedsOnTrue) {
|
||||
Assert(true, __FILE__, __LINE__, "This should succeed.");
|
||||
Assert(true, __FILE__, __LINE__); // This should succeed too.
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that Assert(false, ...) generates a fatal failure.
|
||||
TEST(AssertTest, FailsFatallyOnFalse) {
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
Assert(false, __FILE__, __LINE__, "This should fail.");
|
||||
}, "");
|
||||
|
||||
EXPECT_DEATH({ // NOLINT
|
||||
Assert(false, __FILE__, __LINE__);
|
||||
}, "");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that Expect(true, ...) succeeds.
|
||||
TEST(ExpectTest, SucceedsOnTrue) {
|
||||
Expect(true, __FILE__, __LINE__, "This should succeed.");
|
||||
Expect(true, __FILE__, __LINE__); // This should succeed too.
|
||||
}
|
||||
|
||||
// Tests that Expect(false, ...) generates a non-fatal failure.
|
||||
TEST(ExpectTest, FailsNonfatallyOnFalse) {
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Expect(false, __FILE__, __LINE__, "This should fail.");
|
||||
}, "This should fail");
|
||||
|
||||
EXPECT_NONFATAL_FAILURE({ // NOLINT
|
||||
Expect(false, __FILE__, __LINE__);
|
||||
}, "Expectation failed");
|
||||
}
|
||||
|
||||
// TODO(wan@google.com): find a way to re-enable these tests.
|
||||
#if 0
|
||||
|
||||
// Tests the Log() function.
|
||||
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
void TestLogWithSeverity(const string& verbosity, LogSeverity severity,
|
||||
bool should_print) {
|
||||
const string old_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureTestStdout();
|
||||
Log(severity, "Test log.\n", 0);
|
||||
if (should_print) {
|
||||
EXPECT_PRED2(RE::FullMatch,
|
||||
GetCapturedTestStdout(),
|
||||
severity == WARNING ?
|
||||
"\nGMOCK WARNING:\nTest log\\.\nStack trace:\n[\\s\\S]*" :
|
||||
"\nTest log\\.\nStack trace:\n[\\s\\S]*");
|
||||
} else {
|
||||
EXPECT_EQ("", GetCapturedTestStdout());
|
||||
}
|
||||
GMOCK_FLAG(verbose) = old_flag;
|
||||
}
|
||||
|
||||
// Tests that when the stack_frames_to_skip parameter is negative,
|
||||
// Log() doesn't include the stack trace in the output.
|
||||
TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
|
||||
GMOCK_FLAG(verbose) = kInfoVerbosity;
|
||||
CaptureTestStdout();
|
||||
Log(INFO, "Test log.\n", -1);
|
||||
EXPECT_EQ("\nTest log.\n", GetCapturedTestStdout());
|
||||
}
|
||||
|
||||
// Tests that in opt mode, a positive stack_frames_to_skip argument is
|
||||
// treated as 0.
|
||||
TEST(LogTest, NoSkippingStackFrameInOptMode) {
|
||||
CaptureTestStdout();
|
||||
Log(WARNING, "Test log.\n", 100);
|
||||
const string log = GetCapturedTestStdout();
|
||||
#ifdef NDEBUG
|
||||
// In opt mode, no stack frame should be skipped.
|
||||
EXPECT_THAT(log, ContainsRegex("\nGMOCK WARNING:\n"
|
||||
"Test log\\.\n"
|
||||
"Stack trace:\n"
|
||||
".+"));
|
||||
#else
|
||||
// In dbg mode, the stack frames should be skipped.
|
||||
EXPECT_EQ("\nGMOCK WARNING:\n"
|
||||
"Test log.\n"
|
||||
"Stack trace:\n", log);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
// Tests that all logs are printed when the value of the
|
||||
// --gmock_verbose flag is "info".
|
||||
TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) {
|
||||
TestLogWithSeverity(kInfoVerbosity, INFO, true);
|
||||
TestLogWithSeverity(kInfoVerbosity, WARNING, true);
|
||||
}
|
||||
|
||||
// Tests that only warnings are printed when the value of the
|
||||
// --gmock_verbose flag is "warning".
|
||||
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) {
|
||||
TestLogWithSeverity(kWarningVerbosity, INFO, false);
|
||||
TestLogWithSeverity(kWarningVerbosity, WARNING, true);
|
||||
}
|
||||
|
||||
// Tests that no logs are printed when the value of the
|
||||
// --gmock_verbose flag is "error".
|
||||
TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) {
|
||||
TestLogWithSeverity(kErrorVerbosity, INFO, false);
|
||||
TestLogWithSeverity(kErrorVerbosity, WARNING, false);
|
||||
}
|
||||
|
||||
// Tests that only warnings are printed when the value of the
|
||||
// --gmock_verbose flag is invalid.
|
||||
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
|
||||
TestLogWithSeverity("invalid", INFO, false);
|
||||
TestLogWithSeverity("invalid", WARNING, true);
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
TEST(TypeTraitsTest, true_type) {
|
||||
EXPECT_TRUE(true_type::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, false_type) {
|
||||
EXPECT_FALSE(false_type::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, is_reference) {
|
||||
EXPECT_FALSE(is_reference<int>::value);
|
||||
EXPECT_FALSE(is_reference<char*>::value);
|
||||
EXPECT_TRUE(is_reference<const int&>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, is_pointer) {
|
||||
EXPECT_FALSE(is_pointer<int>::value);
|
||||
EXPECT_FALSE(is_pointer<char&>::value);
|
||||
EXPECT_TRUE(is_pointer<const int*>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, type_equals) {
|
||||
EXPECT_FALSE((type_equals<int, const int>::value));
|
||||
EXPECT_FALSE((type_equals<int, int&>::value));
|
||||
EXPECT_FALSE((type_equals<int, double>::value));
|
||||
EXPECT_TRUE((type_equals<char, char>::value));
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, remove_reference) {
|
||||
EXPECT_TRUE((type_equals<char, remove_reference<char&>::type>::value));
|
||||
EXPECT_TRUE((type_equals<const int,
|
||||
remove_reference<const int&>::type>::value));
|
||||
EXPECT_TRUE((type_equals<int, remove_reference<int>::type>::value));
|
||||
EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value));
|
||||
}
|
||||
|
||||
// TODO(wan@google.com): find a way to re-enable these tests.
|
||||
#if 0
|
||||
|
||||
// Verifies that Log() behaves correctly for the given verbosity level
|
||||
// and log severity.
|
||||
string GrabOutput(void(*logger)(), const char* verbosity) {
|
||||
const string saved_flag = GMOCK_FLAG(verbose);
|
||||
GMOCK_FLAG(verbose) = verbosity;
|
||||
CaptureTestStdout();
|
||||
logger();
|
||||
GMOCK_FLAG(verbose) = saved_flag;
|
||||
return GetCapturedTestStdout();
|
||||
}
|
||||
|
||||
class DummyMock {
|
||||
public:
|
||||
MOCK_METHOD0(TestMethod, void());
|
||||
MOCK_METHOD1(TestMethodArg, void(int dummy));
|
||||
};
|
||||
|
||||
void ExpectCallLogger() {
|
||||
DummyMock mock;
|
||||
EXPECT_CALL(mock, TestMethod());
|
||||
mock.TestMethod();
|
||||
};
|
||||
|
||||
// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) {
|
||||
EXPECT_THAT(GrabOutput(ExpectCallLogger, kInfoVerbosity),
|
||||
HasSubstr("EXPECT_CALL(mock, TestMethod())"));
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "warning".
|
||||
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) {
|
||||
EXPECT_EQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity));
|
||||
}
|
||||
|
||||
// Verifies that EXPECT_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "error".
|
||||
TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
EXPECT_EQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity));
|
||||
}
|
||||
|
||||
void OnCallLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethod());
|
||||
};
|
||||
|
||||
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
|
||||
TEST(OnCallTest, LogsWhenVerbosityIsInfo) {
|
||||
EXPECT_THAT(GrabOutput(OnCallLogger, kInfoVerbosity),
|
||||
HasSubstr("ON_CALL(mock, TestMethod())"));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL doesn't log
|
||||
// if the --gmock_verbose flag is set to "warning".
|
||||
TEST(OnCallTest, DoesNotLogWhenVerbosityIsWarning) {
|
||||
EXPECT_EQ("", GrabOutput(OnCallLogger, kWarningVerbosity));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL doesn't log if
|
||||
// the --gmock_verbose flag is set to "error".
|
||||
TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) {
|
||||
EXPECT_EQ("", GrabOutput(OnCallLogger, kErrorVerbosity));
|
||||
}
|
||||
|
||||
void OnCallAnyArgumentLogger() {
|
||||
DummyMock mock;
|
||||
ON_CALL(mock, TestMethodArg(_));
|
||||
}
|
||||
|
||||
// Verifies that ON_CALL prints provided _ argument.
|
||||
TEST(OnCallTest, LogsAnythingArgument) {
|
||||
EXPECT_THAT(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity),
|
||||
HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
} // namespace
|
||||
} // namespace internal
|
||||
} // namespace testing
|
2629
test/gmock-matchers_test.cc
Normal file
2629
test/gmock-matchers_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
228
test/gmock-nice-strict_test.cc
Normal file
228
test/gmock-nice-strict_test.cc
Normal file
@ -0,0 +1,228 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <gmock/gmock-generated-nice-strict.h>
|
||||
|
||||
#include <string>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_nice_strict_test {
|
||||
|
||||
using testing::internal::string;
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::HasSubstr;
|
||||
using testing::NiceMock;
|
||||
using testing::StrictMock;
|
||||
|
||||
// Defines some mock classes needed by the tests.
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
|
||||
virtual void DoThis() = 0;
|
||||
virtual int DoThat(bool flag) = 0;
|
||||
};
|
||||
|
||||
class MockFoo : public Foo {
|
||||
public:
|
||||
void Delete() { delete this; }
|
||||
|
||||
MOCK_METHOD0(DoThis, void());
|
||||
MOCK_METHOD1(DoThat, int(bool flag));
|
||||
};
|
||||
|
||||
class MockBar {
|
||||
public:
|
||||
explicit MockBar(const string& s) : str_(s) {}
|
||||
|
||||
MockBar(char a1, char a2, string a3, string a4, int a5, int a6,
|
||||
const string& a7, const string& a8, bool a9, bool a10) {
|
||||
str_ = string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) +
|
||||
static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + (a10 ? 'T' : 'F');
|
||||
}
|
||||
|
||||
virtual ~MockBar() {}
|
||||
|
||||
const string& str() const { return str_; }
|
||||
|
||||
MOCK_METHOD0(This, int());
|
||||
MOCK_METHOD2(That, string(int, bool));
|
||||
|
||||
private:
|
||||
string str_;
|
||||
};
|
||||
|
||||
// TODO(wan@google.com): find a way to re-enable these tests.
|
||||
#if 0
|
||||
|
||||
// Tests that a nice mock generates no warning for uninteresting calls.
|
||||
TEST(NiceMockTest, NoWarningForUninterestingCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
CaptureTestStdout();
|
||||
nice_foo.DoThis();
|
||||
nice_foo.DoThat(true);
|
||||
EXPECT_EQ("", GetCapturedTestStdout());
|
||||
}
|
||||
|
||||
// Tests that a nice mock generates no warning for uninteresting calls
|
||||
// that delete the mock object.
|
||||
TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
|
||||
NiceMock<MockFoo>* const nice_foo = new NiceMock<MockFoo>;
|
||||
|
||||
ON_CALL(*nice_foo, DoThis())
|
||||
.WillByDefault(Invoke(nice_foo, &MockFoo::Delete));
|
||||
|
||||
CaptureTestStdout();
|
||||
nice_foo->DoThis();
|
||||
EXPECT_EQ("", GetCapturedTestStdout());
|
||||
}
|
||||
|
||||
// Tests that a nice mock generates informational logs for
|
||||
// uninteresting calls.
|
||||
TEST(NiceMockTest, InfoForUninterestingCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
GMOCK_FLAG(verbose) = "info";
|
||||
CaptureTestStdout();
|
||||
nice_foo.DoThis();
|
||||
EXPECT_THAT(GetCapturedTestStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
|
||||
CaptureTestStdout();
|
||||
nice_foo.DoThat(true);
|
||||
EXPECT_THAT(GetCapturedTestStdout(),
|
||||
HasSubstr("Uninteresting mock function call"));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
// Tests that a nice mock allows expected calls.
|
||||
TEST(NiceMockTest, AllowsExpectedCall) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
EXPECT_CALL(nice_foo, DoThis());
|
||||
nice_foo.DoThis();
|
||||
}
|
||||
|
||||
// Tests that an unexpected call on a nice mock fails.
|
||||
TEST(NiceMockTest, UnexpectedCallFails) {
|
||||
NiceMock<MockFoo> nice_foo;
|
||||
|
||||
EXPECT_CALL(nice_foo, DoThis()).Times(0);
|
||||
EXPECT_NONFATAL_FAILURE(nice_foo.DoThis(), "called more times than expected");
|
||||
}
|
||||
|
||||
// Tests that NiceMock works with a mock class that has a non-default
|
||||
// constructor.
|
||||
TEST(NiceMockTest, NonDefaultConstructor) {
|
||||
NiceMock<MockBar> nice_bar("hi");
|
||||
EXPECT_EQ("hi", nice_bar.str());
|
||||
|
||||
nice_bar.This();
|
||||
nice_bar.That(5, true);
|
||||
}
|
||||
|
||||
// Tests that NiceMock works with a mock class that has a 10-ary
|
||||
// non-default constructor.
|
||||
TEST(NiceMockTest, NonDefaultConstructor10) {
|
||||
NiceMock<MockBar> nice_bar('a', 'b', "c", "d", 'e', 'f',
|
||||
"g", "h", true, false);
|
||||
EXPECT_EQ("abcdefghTF", nice_bar.str());
|
||||
|
||||
nice_bar.This();
|
||||
nice_bar.That(5, true);
|
||||
}
|
||||
|
||||
// Tests that a strict mock allows expected calls.
|
||||
TEST(StrictMockTest, AllowsExpectedCall) {
|
||||
StrictMock<MockFoo> strict_foo;
|
||||
|
||||
EXPECT_CALL(strict_foo, DoThis());
|
||||
strict_foo.DoThis();
|
||||
}
|
||||
|
||||
// Tests that an unexpected call on a strict mock fails.
|
||||
TEST(StrictMockTest, UnexpectedCallFails) {
|
||||
StrictMock<MockFoo> strict_foo;
|
||||
|
||||
EXPECT_CALL(strict_foo, DoThis()).Times(0);
|
||||
EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
|
||||
"called more times than expected");
|
||||
}
|
||||
|
||||
// Tests that an uninteresting call on a strict mock fails.
|
||||
TEST(StrictMockTest, UninterestingCallFails) {
|
||||
StrictMock<MockFoo> strict_foo;
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
// Tests that an uninteresting call on a strict mock fails, even if
|
||||
// the call deletes the mock object.
|
||||
TEST(StrictMockTest, UninterestingCallFailsAfterDeath) {
|
||||
StrictMock<MockFoo>* const strict_foo = new StrictMock<MockFoo>;
|
||||
|
||||
ON_CALL(*strict_foo, DoThis())
|
||||
.WillByDefault(Invoke(strict_foo, &MockFoo::Delete));
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_foo->DoThis(),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
// Tests that StrictMock works with a mock class that has a
|
||||
// non-default constructor.
|
||||
TEST(StrictMockTest, NonDefaultConstructor) {
|
||||
StrictMock<MockBar> strict_bar("hi");
|
||||
EXPECT_EQ("hi", strict_bar.str());
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
// Tests that StrictMock works with a mock class that has a 10-ary
|
||||
// non-default constructor.
|
||||
TEST(StrictMockTest, NonDefaultConstructor10) {
|
||||
StrictMock<MockBar> strict_bar('a', 'b', "c", "d", 'e', 'f',
|
||||
"g", "h", true, false);
|
||||
EXPECT_EQ("abcdefghTF", strict_bar.str());
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
|
||||
"Uninteresting mock function call");
|
||||
}
|
||||
|
||||
} // namespace gmock_nice_strict_test
|
||||
} // namespace testing
|
95
test/gmock-port_test.cc
Normal file
95
test/gmock-port_test.cc
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vladl@google.com (Vlad Losev)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the internal cross-platform support utilities.
|
||||
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(GmockCheckSyntaxTest, BehavesLikeASingleStatement) {
|
||||
if (false)
|
||||
GMOCK_CHECK_(false) << "This should never be executed; "
|
||||
"It's a compilation test only.";
|
||||
|
||||
if (true)
|
||||
GMOCK_CHECK_(true);
|
||||
else
|
||||
;
|
||||
|
||||
if (false)
|
||||
;
|
||||
else
|
||||
GMOCK_CHECK_(true) << "";
|
||||
}
|
||||
|
||||
TEST(GmockCheckSyntaxTest, WorksWithSwitch) {
|
||||
switch (0) {
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
GMOCK_CHECK_(true);
|
||||
}
|
||||
|
||||
switch(0)
|
||||
case 0:
|
||||
GMOCK_CHECK_(true) << "Check failed in switch case";
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(GmockCheckDeathTest, DiesWithCorrectOutputOnFailure) {
|
||||
const bool a_false_condition = false;
|
||||
EXPECT_DEATH(GMOCK_CHECK_(a_false_condition) << "Extra info",
|
||||
// MSVC and gcc use different formats to print source
|
||||
// file locations. Google Mock's failure messages use
|
||||
// the same format as used by the compiler, in order
|
||||
// for the IDE to recognize them. Therefore we look
|
||||
// for different patterns here depending on the
|
||||
// compiler.
|
||||
#ifdef _MSC_VER
|
||||
"gmock-port_test\\.cc\\([0-9]+\\):"
|
||||
#else
|
||||
"gmock-port_test\\.cc:[0-9]+"
|
||||
#endif // _MSC_VER
|
||||
".*a_false_condition.*Extra info");
|
||||
}
|
||||
|
||||
TEST(GmockCheckDeathTest, LivesSilentlyOnSuccess) {
|
||||
EXPECT_EXIT({
|
||||
GMOCK_CHECK_(true) << "Extra info";
|
||||
::std::cerr << "Success\n";
|
||||
exit(0); },
|
||||
::testing::ExitedWithCode(0), "Success");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
903
test/gmock-printers_test.cc
Normal file
903
test/gmock-printers_test.cc
Normal file
@ -0,0 +1,903 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests the universal value printer.
|
||||
|
||||
#include <gmock/gmock-printers.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gmock/internal/gmock-port.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// hash_map and hash_set are available on Windows.
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
#define GMOCK_HAS_HASH_MAP_ // Indicates that hash_map is available.
|
||||
#include <hash_map> // NOLINT
|
||||
#define GMOCK_HAS_HASH_SET_ // Indicates that hash_set is available.
|
||||
#include <hash_set> // NOLINT
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Some user-defined types for testing the universal value printer.
|
||||
|
||||
// A user-defined unprintable class template in the global namespace.
|
||||
template <typename T>
|
||||
class UnprintableTemplateInGlobal {
|
||||
public:
|
||||
UnprintableTemplateInGlobal() : value_() {}
|
||||
private:
|
||||
T value_;
|
||||
};
|
||||
|
||||
// A user-defined streamable type in the global namespace.
|
||||
class StreamableInGlobal {
|
||||
public:
|
||||
virtual ~StreamableInGlobal() {}
|
||||
};
|
||||
|
||||
inline void operator<<(::std::ostream& os, const StreamableInGlobal& x) {
|
||||
os << "StreamableInGlobal";
|
||||
}
|
||||
|
||||
namespace foo {
|
||||
|
||||
// A user-defined unprintable type in a user namespace.
|
||||
class UnprintableInFoo {
|
||||
public:
|
||||
UnprintableInFoo() : x_(0x12EF), y_(0xAB34), z_(0) {}
|
||||
private:
|
||||
testing::internal::Int32 x_;
|
||||
testing::internal::Int32 y_;
|
||||
double z_;
|
||||
};
|
||||
|
||||
// A user-defined printable type in a user-chosen namespace.
|
||||
struct PrintableViaPrintTo {
|
||||
PrintableViaPrintTo() : value() {}
|
||||
int value;
|
||||
};
|
||||
|
||||
void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) {
|
||||
*os << "PrintableViaPrintTo: " << x.value;
|
||||
}
|
||||
|
||||
// A user-defined printable class template in a user-chosen namespace.
|
||||
template <typename T>
|
||||
class PrintableViaPrintToTemplate {
|
||||
public:
|
||||
explicit PrintableViaPrintToTemplate(const T& value) : value_(value) {}
|
||||
|
||||
const T& value() const { return value_; }
|
||||
private:
|
||||
T value_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void PrintTo(const PrintableViaPrintToTemplate<T>& x, ::std::ostream* os) {
|
||||
*os << "PrintableViaPrintToTemplate: " << x.value();
|
||||
}
|
||||
|
||||
// A user-defined streamable class template in a user namespace.
|
||||
template <typename T>
|
||||
class StreamableTemplateInFoo {
|
||||
public:
|
||||
StreamableTemplateInFoo() : value_() {}
|
||||
|
||||
const T& value() const { return value_; }
|
||||
private:
|
||||
T value_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline ::std::ostream& operator<<(::std::ostream& os,
|
||||
const StreamableTemplateInFoo<T>& x) {
|
||||
return os << "StreamableTemplateInFoo: " << x.value();
|
||||
}
|
||||
|
||||
} // namespace foo
|
||||
|
||||
namespace testing {
|
||||
namespace gmock_printers_test {
|
||||
|
||||
using ::std::deque;
|
||||
using ::std::list;
|
||||
using ::std::make_pair;
|
||||
using ::std::map;
|
||||
using ::std::multimap;
|
||||
using ::std::multiset;
|
||||
using ::std::pair;
|
||||
using ::std::set;
|
||||
using ::std::tr1::make_tuple;
|
||||
using ::std::tr1::tuple;
|
||||
using ::std::vector;
|
||||
using ::testing::StartsWith;
|
||||
using ::testing::internal::UniversalPrinter;
|
||||
using ::testing::internal::string;
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
// MSVC defines the following classes in the ::stdext namespace while
|
||||
// gcc defines them in the :: namespace. Note that they are not part
|
||||
// of the C++ standard.
|
||||
|
||||
using ::stdext::hash_map;
|
||||
using ::stdext::hash_set;
|
||||
using ::stdext::hash_multimap;
|
||||
using ::stdext::hash_multiset;
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Prints a value to a string using the universal value printer. This
|
||||
// is a helper for testing UniversalPrinter<T>::Print() for various types.
|
||||
template <typename T>
|
||||
string Print(const T& value) {
|
||||
::std::stringstream ss;
|
||||
UniversalPrinter<T>::Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Prints a value passed by reference to a string, using the universal
|
||||
// value printer. This is a helper for testing
|
||||
// UniversalPrinter<T&>::Print() for various types.
|
||||
template <typename T>
|
||||
string PrintByRef(const T& value) {
|
||||
::std::stringstream ss;
|
||||
UniversalPrinter<T&>::Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Tests printing various char types.
|
||||
|
||||
// char.
|
||||
TEST(PrintCharTest, PlainChar) {
|
||||
EXPECT_EQ("'\\0'", Print('\0'));
|
||||
EXPECT_EQ("'\\'' (39)", Print('\''));
|
||||
EXPECT_EQ("'\"' (34)", Print('"'));
|
||||
EXPECT_EQ("'\\?' (63)", Print('\?'));
|
||||
EXPECT_EQ("'\\\\' (92)", Print('\\'));
|
||||
EXPECT_EQ("'\\a' (7)", Print('\a'));
|
||||
EXPECT_EQ("'\\b' (8)", Print('\b'));
|
||||
EXPECT_EQ("'\\f' (12)", Print('\f'));
|
||||
EXPECT_EQ("'\\n' (10)", Print('\n'));
|
||||
EXPECT_EQ("'\\r' (13)", Print('\r'));
|
||||
EXPECT_EQ("'\\t' (9)", Print('\t'));
|
||||
EXPECT_EQ("'\\v' (11)", Print('\v'));
|
||||
EXPECT_EQ("'\\x7F' (127)", Print('\x7F'));
|
||||
EXPECT_EQ("'\\xFF' (255)", Print('\xFF'));
|
||||
EXPECT_EQ("' ' (32)", Print(' '));
|
||||
EXPECT_EQ("'a' (97)", Print('a'));
|
||||
}
|
||||
|
||||
// signed char.
|
||||
TEST(PrintCharTest, SignedChar) {
|
||||
EXPECT_EQ("'\\0'", Print(static_cast<signed char>('\0')));
|
||||
EXPECT_EQ("'\\xCE' (-50)",
|
||||
Print(static_cast<signed char>(-50)));
|
||||
}
|
||||
|
||||
// unsigned char.
|
||||
TEST(PrintCharTest, UnsignedChar) {
|
||||
EXPECT_EQ("'\\0'", Print(static_cast<unsigned char>('\0')));
|
||||
EXPECT_EQ("'b' (98)",
|
||||
Print(static_cast<unsigned char>('b')));
|
||||
}
|
||||
|
||||
// Tests printing other simple, built-in types.
|
||||
|
||||
// bool.
|
||||
TEST(PrintBuiltInTypeTest, Bool) {
|
||||
EXPECT_EQ("false", Print(false));
|
||||
EXPECT_EQ("true", Print(true));
|
||||
}
|
||||
|
||||
// wchar_t.
|
||||
TEST(PrintBuiltInTypeTest, Wchar_t) {
|
||||
EXPECT_EQ("L'\\0'", Print(L'\0'));
|
||||
EXPECT_EQ("L'\\'' (39)", Print(L'\''));
|
||||
EXPECT_EQ("L'\"' (34)", Print(L'"'));
|
||||
EXPECT_EQ("L'\\?' (63)", Print(L'\?'));
|
||||
EXPECT_EQ("L'\\\\' (92)", Print(L'\\'));
|
||||
EXPECT_EQ("L'\\a' (7)", Print(L'\a'));
|
||||
EXPECT_EQ("L'\\b' (8)", Print(L'\b'));
|
||||
EXPECT_EQ("L'\\f' (12)", Print(L'\f'));
|
||||
EXPECT_EQ("L'\\n' (10)", Print(L'\n'));
|
||||
EXPECT_EQ("L'\\r' (13)", Print(L'\r'));
|
||||
EXPECT_EQ("L'\\t' (9)", Print(L'\t'));
|
||||
EXPECT_EQ("L'\\v' (11)", Print(L'\v'));
|
||||
EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F'));
|
||||
EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF'));
|
||||
EXPECT_EQ("L' ' (32)", Print(L' '));
|
||||
EXPECT_EQ("L'a' (97)", Print(L'a'));
|
||||
EXPECT_EQ("L'\\x576' (1398)", Print(L'\x576'));
|
||||
EXPECT_EQ("L'\\xC74D' (51021)", Print(L'\xC74D'));
|
||||
}
|
||||
|
||||
// Test that Int64 provides more storage than wchar_t.
|
||||
TEST(PrintTypeSizeTest, Wchar_t) {
|
||||
EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64));
|
||||
}
|
||||
|
||||
// Various integer types.
|
||||
TEST(PrintBuiltInTypeTest, Integer) {
|
||||
EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8
|
||||
EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8
|
||||
EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16
|
||||
EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16
|
||||
EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32
|
||||
EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32
|
||||
EXPECT_EQ("18446744073709551615",
|
||||
Print(static_cast<testing::internal::UInt64>(-1))); // uint64
|
||||
EXPECT_EQ("-9223372036854775808",
|
||||
Print(static_cast<testing::internal::Int64>(1) << 63)); // int64
|
||||
}
|
||||
|
||||
// Size types.
|
||||
TEST(PrintBuiltInTypeTest, Size_t) {
|
||||
EXPECT_EQ("1", Print(sizeof('a'))); // size_t.
|
||||
#ifndef GTEST_OS_WINDOWS
|
||||
// Windows has no ssize_t type.
|
||||
EXPECT_EQ("-2", Print(static_cast<ssize_t>(-2))); // ssize_t.
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
}
|
||||
|
||||
// Floating-points.
|
||||
TEST(PrintBuiltInTypeTest, FloatingPoints) {
|
||||
EXPECT_EQ("1.5", Print(1.5f)); // float
|
||||
EXPECT_EQ("-2.5", Print(-2.5)); // double
|
||||
}
|
||||
|
||||
// Since ::std::stringstream::operator<<(const void *) formats the pointer
|
||||
// output differently with different compilers, we have to create the expected
|
||||
// output first and use it as our expectation.
|
||||
static string PrintPointer(const void *p) {
|
||||
::std::stringstream expected_result_stream;
|
||||
expected_result_stream << p;
|
||||
return expected_result_stream.str();
|
||||
}
|
||||
|
||||
// Tests printing C strings.
|
||||
|
||||
// const char*.
|
||||
TEST(PrintCStringTest, Const) {
|
||||
const char* p = "World";
|
||||
EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p));
|
||||
}
|
||||
|
||||
// char*.
|
||||
TEST(PrintCStringTest, NonConst) {
|
||||
char p[] = "Hi";
|
||||
EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"",
|
||||
Print(static_cast<char*>(p)));
|
||||
}
|
||||
|
||||
// NULL C string.
|
||||
TEST(PrintCStringTest, Null) {
|
||||
const char* p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// Tests that C strings are escaped properly.
|
||||
TEST(PrintCStringTest, EscapesProperly) {
|
||||
const char* p = "'\"\?\\\a\b\f\n\r\t\v\x7F\xFF a";
|
||||
EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"\\?\\\\\\a\\b\\f"
|
||||
"\\n\\r\\t\\v\\x7F\\xFF a\"",
|
||||
Print(p));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// possibly accessing more memory than intended and causing invalid
|
||||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
// wchar_t is implemented as a native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
|
||||
// const wchar_t*.
|
||||
TEST(PrintWideCStringTest, Const) {
|
||||
const wchar_t* p = L"World";
|
||||
EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p));
|
||||
}
|
||||
|
||||
// wchar_t*.
|
||||
TEST(PrintWideCStringTest, NonConst) {
|
||||
wchar_t p[] = L"Hi";
|
||||
EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"",
|
||||
Print(static_cast<wchar_t*>(p)));
|
||||
}
|
||||
|
||||
// NULL wide C string.
|
||||
TEST(PrintWideCStringTest, Null) {
|
||||
const wchar_t* p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// Tests that wide C strings are escaped properly.
|
||||
TEST(PrintWideCStringTest, EscapesProperly) {
|
||||
const wchar_t* p = L"'\"\?\\\a\b\f\n\r\t\v\xD3\x576\x8D3\xC74D a";
|
||||
EXPECT_EQ(PrintPointer(p) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f"
|
||||
"\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"",
|
||||
Print(p));
|
||||
}
|
||||
#endif // native wchar_t
|
||||
|
||||
// Tests printing pointers to other char types.
|
||||
|
||||
// signed char*.
|
||||
TEST(PrintCharPointerTest, SignedChar) {
|
||||
signed char* p = reinterpret_cast<signed char*>(0x1234);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// const signed char*.
|
||||
TEST(PrintCharPointerTest, ConstSignedChar) {
|
||||
signed char* p = reinterpret_cast<signed char*>(0x1234);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// unsigned char*.
|
||||
TEST(PrintCharPointerTest, UnsignedChar) {
|
||||
unsigned char* p = reinterpret_cast<unsigned char*>(0x1234);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// const unsigned char*.
|
||||
TEST(PrintCharPointerTest, ConstUnsignedChar) {
|
||||
const unsigned char* p = reinterpret_cast<const unsigned char*>(0x1234);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// Tests printing pointers to simple, built-in types.
|
||||
|
||||
// bool*.
|
||||
TEST(PrintPointerToBuiltInTypeTest, Bool) {
|
||||
bool* p = reinterpret_cast<bool*>(0xABCD);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// void*.
|
||||
TEST(PrintPointerToBuiltInTypeTest, Void) {
|
||||
void* p = reinterpret_cast<void*>(0xABCD);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// const void*.
|
||||
TEST(PrintPointerToBuiltInTypeTest, ConstVoid) {
|
||||
const void* p = reinterpret_cast<const void*>(0xABCD);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// Tests printing pointers to pointers.
|
||||
TEST(PrintPointerToPointerTest, IntPointerPointer) {
|
||||
int** p = reinterpret_cast<int**>(0xABCD);
|
||||
EXPECT_EQ(PrintPointer(p), Print(p));
|
||||
p = NULL;
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// Tests printing (non-member) function pointers.
|
||||
|
||||
void MyFunction(int n) {}
|
||||
|
||||
TEST(PrintPointerTest, NonMemberFunctionPointer) {
|
||||
EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>(&MyFunction)),
|
||||
Print(&MyFunction));
|
||||
int (*p)(bool) = NULL; // NOLINT
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
}
|
||||
|
||||
// Tests printing member variable pointers. Although they are called
|
||||
// pointers, they don't point to a location in the address space.
|
||||
// Their representation is implementation-defined. Thus they will be
|
||||
// printed as raw bytes.
|
||||
|
||||
struct Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
int MyMethod(char x) { return x + 1; }
|
||||
virtual char MyVirtualMethod(int n) { return 'a'; }
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
TEST(PrintPointerTest, MemberVariablePointer) {
|
||||
EXPECT_THAT(Print(&Foo::value),
|
||||
StartsWith(Print(sizeof(&Foo::value)) + "-byte object "));
|
||||
int (Foo::*p) = NULL; // NOLINT
|
||||
EXPECT_THAT(Print(p),
|
||||
StartsWith(Print(sizeof(p)) + "-byte object "));
|
||||
}
|
||||
|
||||
// Tests printing member function pointers. Although they are called
|
||||
// pointers, they don't point to a location in the address space.
|
||||
// Their representation is implementation-defined. Thus they will be
|
||||
// printed as raw bytes.
|
||||
TEST(PrintPointerTest, MemberFunctionPointer) {
|
||||
EXPECT_THAT(Print(&Foo::MyMethod),
|
||||
StartsWith(Print(sizeof(&Foo::MyMethod)) + "-byte object "));
|
||||
EXPECT_THAT(Print(&Foo::MyVirtualMethod),
|
||||
StartsWith(Print(sizeof((&Foo::MyVirtualMethod)))
|
||||
+ "-byte object "));
|
||||
int (Foo::*p)(char) = NULL; // NOLINT
|
||||
EXPECT_THAT(Print(p),
|
||||
StartsWith(Print(sizeof(p)) + "-byte object "));
|
||||
}
|
||||
|
||||
// Tests printing C arrays.
|
||||
|
||||
// One-dimensional array.
|
||||
|
||||
void ArrayHelper1(int (&a)[5]) { // NOLINT
|
||||
EXPECT_EQ("{ 1, 2, 3, 4, 5 }", Print(a));
|
||||
}
|
||||
|
||||
TEST(PrintArrayTest, OneDimensionalArray) {
|
||||
int a[5] = { 1, 2, 3, 4, 5 };
|
||||
ArrayHelper1(a);
|
||||
}
|
||||
|
||||
// Two-dimensional array.
|
||||
|
||||
void ArrayHelper2(int (&a)[2][5]) { // NOLINT
|
||||
EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", Print(a));
|
||||
}
|
||||
|
||||
TEST(PrintArrayTest, TwoDimensionalArray) {
|
||||
int a[2][5] = {
|
||||
{ 1, 2, 3, 4, 5 },
|
||||
{ 6, 7, 8, 9, 0 }
|
||||
};
|
||||
ArrayHelper2(a);
|
||||
}
|
||||
|
||||
// Array of const elements.
|
||||
|
||||
void ArrayHelper3(const bool (&a)[1]) { // NOLINT
|
||||
EXPECT_EQ("{ false }", Print(a));
|
||||
}
|
||||
|
||||
TEST(PrintArrayTest, ConstArray) {
|
||||
const bool a[1] = { false };
|
||||
ArrayHelper3(a);
|
||||
}
|
||||
|
||||
// Char array.
|
||||
|
||||
void ArrayHelper4(char (&a)[3]) { // NOLINT
|
||||
EXPECT_EQ(PrintPointer(a) + " pointing to \"Hi\"", Print(a));
|
||||
}
|
||||
|
||||
TEST(PrintArrayTest, CharArray) {
|
||||
char a[3] = "Hi";
|
||||
ArrayHelper4(a);
|
||||
}
|
||||
|
||||
// Const char array.
|
||||
|
||||
void ArrayHelper5(const char (&a)[3]) { // NOLINT
|
||||
EXPECT_EQ(Print(a), PrintPointer(a) + " pointing to \"Hi\"");
|
||||
}
|
||||
|
||||
TEST(PrintArrayTest, ConstCharArray) {
|
||||
const char a[3] = "Hi";
|
||||
ArrayHelper5(a);
|
||||
}
|
||||
|
||||
// Array of objects.
|
||||
TEST(PrintArrayTest, ObjectArray) {
|
||||
string a[3] = { "Hi", "Hello", "Ni hao" };
|
||||
EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", Print(a));
|
||||
}
|
||||
|
||||
// Array with many elements.
|
||||
TEST(PrintArrayTest, BigArray) {
|
||||
int a[100] = { 1, 2, 3 };
|
||||
EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }",
|
||||
Print(a));
|
||||
}
|
||||
|
||||
// Tests printing ::string and ::std::string.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
// ::string.
|
||||
TEST(PrintStringTest, StringInGlobalNamespace) {
|
||||
const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
|
||||
const ::string str(s, sizeof(s));
|
||||
EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
|
||||
Print(str));
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
// ::std::string.
|
||||
TEST(PrintStringTest, StringInStdNamespace) {
|
||||
const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
|
||||
const ::std::string str(s, sizeof(s));
|
||||
EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
|
||||
Print(str));
|
||||
}
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
// Tests printing ::wstring and ::std::wstring.
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
// ::wstring.
|
||||
TEST(PrintWideStringTest, StringInGlobalNamespace) {
|
||||
const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a";
|
||||
const ::wstring str(s, sizeof(s)/sizeof(wchar_t));
|
||||
EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v"
|
||||
"\\xD3\\x576\\x8D3\\xC74D a\\0\"",
|
||||
Print(str));
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// ::std::wstring.
|
||||
TEST(PrintWideStringTest, StringInStdNamespace) {
|
||||
const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a";
|
||||
const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t));
|
||||
EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v"
|
||||
"\\xD3\\x576\\x8D3\\xC74D a\\0\"",
|
||||
Print(str));
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Tests printing STL containers.
|
||||
|
||||
TEST(PrintStlContainerTest, EmptyDeque) {
|
||||
deque<char> empty;
|
||||
EXPECT_EQ("{}", Print(empty));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, NonEmptyDeque) {
|
||||
deque<int> non_empty;
|
||||
non_empty.push_back(1);
|
||||
non_empty.push_back(3);
|
||||
EXPECT_EQ("{ 1, 3 }", Print(non_empty));
|
||||
}
|
||||
|
||||
#ifdef GMOCK_HAS_HASH_MAP_
|
||||
|
||||
TEST(PrintStlContainerTest, OneElementHashMap) {
|
||||
hash_map<int, char> map1;
|
||||
map1[1] = 'a';
|
||||
EXPECT_EQ("{ (1, 'a' (97)) }", Print(map1));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, HashMultiMap) {
|
||||
hash_multimap<int, bool> map1;
|
||||
map1.insert(make_pair(5, true));
|
||||
map1.insert(make_pair(5, false));
|
||||
|
||||
// Elements of hash_multimap can be printed in any order.
|
||||
const string result = Print(map1);
|
||||
EXPECT_TRUE(result == "{ (5, true), (5, false) }" ||
|
||||
result == "{ (5, false), (5, true) }")
|
||||
<< " where Print(map1) returns \"" << result << "\".";
|
||||
}
|
||||
|
||||
#endif // GMOCK_HAS_HASH_MAP_
|
||||
|
||||
#ifdef GMOCK_HAS_HASH_SET_
|
||||
|
||||
TEST(PrintStlContainerTest, HashSet) {
|
||||
hash_set<string> set1;
|
||||
set1.insert("hello");
|
||||
EXPECT_EQ("{ \"hello\" }", Print(set1));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, HashMultiSet) {
|
||||
const int kSize = 5;
|
||||
int a[kSize] = { 1, 1, 2, 5, 1 };
|
||||
hash_multiset<int> set1(a, a + kSize);
|
||||
|
||||
// Elements of hash_multiset can be printed in any order.
|
||||
const string result = Print(set1);
|
||||
const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit.
|
||||
|
||||
// Verifies the result matches the expected pattern; also extracts
|
||||
// the numbers in the result.
|
||||
ASSERT_EQ(expected_pattern.length(), result.length());
|
||||
std::vector<int> numbers;
|
||||
for (size_t i = 0; i != result.length(); i++) {
|
||||
if (expected_pattern[i] == 'd') {
|
||||
ASSERT_TRUE(isdigit(result[i]));
|
||||
numbers.push_back(result[i] - '0');
|
||||
} else {
|
||||
EXPECT_EQ(expected_pattern[i], result[i]) << " where result is "
|
||||
<< result;
|
||||
}
|
||||
}
|
||||
|
||||
// Makes sure the result contains the right numbers.
|
||||
std::sort(numbers.begin(), numbers.end());
|
||||
std::sort(a, a + kSize);
|
||||
EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin()));
|
||||
}
|
||||
|
||||
#endif // GMOCK_HAS_HASH_SET_
|
||||
|
||||
TEST(PrintStlContainerTest, List) {
|
||||
const char* a[] = {
|
||||
"hello",
|
||||
"world"
|
||||
};
|
||||
const list<string> strings(a, a + 2);
|
||||
EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, Map) {
|
||||
map<int, bool> map1;
|
||||
map1[1] = true;
|
||||
map1[5] = false;
|
||||
map1[3] = true;
|
||||
EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, MultiMap) {
|
||||
multimap<bool, int> map1;
|
||||
map1.insert(make_pair(true, 0));
|
||||
map1.insert(make_pair(true, 1));
|
||||
map1.insert(make_pair(false, 2));
|
||||
EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, Set) {
|
||||
const unsigned int a[] = { 3, 0, 5 };
|
||||
set<unsigned int> set1(a, a + 3);
|
||||
EXPECT_EQ("{ 0, 3, 5 }", Print(set1));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, MultiSet) {
|
||||
const int a[] = { 1, 1, 2, 5, 1 };
|
||||
multiset<int> set1(a, a + 5);
|
||||
EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, Pair) {
|
||||
pair<const bool, int> p(true, 5);
|
||||
EXPECT_EQ("(true, 5)", Print(p));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, Vector) {
|
||||
vector<int> v;
|
||||
v.push_back(1);
|
||||
v.push_back(2);
|
||||
EXPECT_EQ("{ 1, 2 }", Print(v));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, LongSequence) {
|
||||
const int a[100] = { 1, 2, 3 };
|
||||
const vector<int> v(a, a + 100);
|
||||
EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "
|
||||
"0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v));
|
||||
}
|
||||
|
||||
TEST(PrintStlContainerTest, NestedContainer) {
|
||||
const int a1[] = { 1, 2 };
|
||||
const int a2[] = { 3, 4, 5 };
|
||||
const list<int> l1(a1, a1 + 2);
|
||||
const list<int> l2(a2, a2 + 3);
|
||||
|
||||
vector<list<int> > v;
|
||||
v.push_back(l1);
|
||||
v.push_back(l2);
|
||||
EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v));
|
||||
}
|
||||
|
||||
|
||||
// Tests printing tuples.
|
||||
|
||||
// Tuples of various arities.
|
||||
TEST(PrintTupleTest, VariousSizes) {
|
||||
tuple<> t0;
|
||||
EXPECT_EQ("()", Print(t0));
|
||||
|
||||
tuple<int> t1(5);
|
||||
EXPECT_EQ("(5)", Print(t1));
|
||||
|
||||
tuple<char, bool> t2('a', true);
|
||||
EXPECT_EQ("('a' (97), true)", Print(t2));
|
||||
|
||||
const char* const str = "8";
|
||||
tuple<bool, char, short, testing::internal::Int32, // NOLINT
|
||||
testing::internal::Int64, float, double, const char*, void*, string>
|
||||
t10(false, 'a', 3, 4, 5, 6.5F, 7.5, str, NULL, "10");
|
||||
EXPECT_EQ("(false, 'a' (97), 3, 4, 5, 6.5, 7.5, " + PrintPointer(str) +
|
||||
" pointing to \"8\", NULL, \"10\")",
|
||||
Print(t10));
|
||||
}
|
||||
|
||||
// Nested tuples.
|
||||
TEST(PrintTupleTest, NestedTuple) {
|
||||
tuple<tuple<int, double>, char> nested(make_tuple(5, 9.5), 'a');
|
||||
EXPECT_EQ("((5, 9.5), 'a' (97))", Print(nested));
|
||||
}
|
||||
|
||||
// Tests printing user-defined unprintable types.
|
||||
|
||||
// Unprintable types in the global namespace.
|
||||
TEST(PrintUnprintableTypeTest, InGlobalNamespace) {
|
||||
EXPECT_EQ("1-byte object <00>",
|
||||
Print(UnprintableTemplateInGlobal<bool>()));
|
||||
}
|
||||
|
||||
// Unprintable types in a user namespace.
|
||||
TEST(PrintUnprintableTypeTest, InUserNamespace) {
|
||||
EXPECT_EQ("16-byte object <EF12 0000 34AB 0000 0000 0000 0000 0000>",
|
||||
Print(::foo::UnprintableInFoo()));
|
||||
}
|
||||
|
||||
// Unprintable types are that too big to be printed completely.
|
||||
|
||||
struct Big {
|
||||
Big() { memset(array, 0, sizeof(array)); }
|
||||
char array[257];
|
||||
};
|
||||
|
||||
TEST(PrintUnpritableTypeTest, BigObject) {
|
||||
EXPECT_EQ("257-byte object <0000 0000 0000 0000 0000 0000 "
|
||||
"0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
|
||||
"0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
|
||||
"0000 0000 0000 0000 0000 0000 ... 0000 0000 0000 "
|
||||
"0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
|
||||
"0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "
|
||||
"0000 0000 0000 0000 0000 0000 0000 0000 00>",
|
||||
Print(Big()));
|
||||
}
|
||||
|
||||
// Tests printing user-defined streamable types.
|
||||
|
||||
// Streamable types in the global namespace.
|
||||
TEST(PrintStreamableTypeTest, InGlobalNamespace) {
|
||||
EXPECT_EQ("StreamableInGlobal",
|
||||
Print(StreamableInGlobal()));
|
||||
}
|
||||
|
||||
// Printable template types in a user namespace.
|
||||
TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) {
|
||||
EXPECT_EQ("StreamableTemplateInFoo: 0",
|
||||
Print(::foo::StreamableTemplateInFoo<int>()));
|
||||
}
|
||||
|
||||
// Tests printing user-defined types that have a PrintTo() function.
|
||||
TEST(PrintPrintableTypeTest, InUserNamespace) {
|
||||
EXPECT_EQ("PrintableViaPrintTo: 0",
|
||||
Print(::foo::PrintableViaPrintTo()));
|
||||
}
|
||||
|
||||
// Tests printing user-defined class template that have a PrintTo() function.
|
||||
TEST(PrintPrintableTypeTest, TemplateInUserNamespace) {
|
||||
EXPECT_EQ("PrintableViaPrintToTemplate: 5",
|
||||
Print(::foo::PrintableViaPrintToTemplate<int>(5)));
|
||||
}
|
||||
|
||||
#if GMOCK_HAS_PROTOBUF_
|
||||
|
||||
// Tests printing a protocol message.
|
||||
TEST(PrintProtocolMessageTest, PrintsShortDebugString) {
|
||||
testing::internal::TestMessage msg;
|
||||
msg.set_member("yes");
|
||||
EXPECT_EQ("<member:\"yes\">", Print(msg));
|
||||
}
|
||||
|
||||
// Tests printing a proto2 message.
|
||||
TEST(PrintProto2MessageTest, PrintsShortDebugString) {
|
||||
testing::internal::FooMessage msg;
|
||||
msg.set_int_field(2);
|
||||
EXPECT_PRED2(RE::FullMatch, Print(msg),
|
||||
"<int_field:\\s*2\\s*>");
|
||||
}
|
||||
|
||||
#endif // GMOCK_HAS_PROTOBUF_
|
||||
|
||||
// Tests that the universal printer prints both the address and the
|
||||
// value of a reference.
|
||||
TEST(PrintReferenceTest, PrintsAddressAndValue) {
|
||||
int n = 5;
|
||||
EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n));
|
||||
|
||||
int a[2][3] = {
|
||||
{ 0, 1, 2 },
|
||||
{ 3, 4, 5 }
|
||||
};
|
||||
EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }",
|
||||
PrintByRef(a));
|
||||
|
||||
const ::foo::UnprintableInFoo x;
|
||||
EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object "
|
||||
"<EF12 0000 34AB 0000 0000 0000 0000 0000>",
|
||||
PrintByRef(x));
|
||||
}
|
||||
|
||||
// Tests that the universal printer prints a function pointer passed by
|
||||
// reference.
|
||||
TEST(PrintReferenceTest, HandlesFunctionPointer) {
|
||||
void (*fp)(int n) = &MyFunction;
|
||||
const string fp_pointer_string =
|
||||
PrintPointer(reinterpret_cast<const void*>(&fp));
|
||||
const string fp_string = PrintPointer(reinterpret_cast<const void*>(fp));
|
||||
EXPECT_EQ("@" + fp_pointer_string + " " + fp_string,
|
||||
PrintByRef(fp));
|
||||
}
|
||||
|
||||
// Tests that the universal printer prints a member function pointer
|
||||
// passed by reference.
|
||||
TEST(PrintReferenceTest, HandlesMemberFunctionPointer) {
|
||||
int (Foo::*p)(char ch) = &Foo::MyMethod;
|
||||
EXPECT_THAT(PrintByRef(p),
|
||||
StartsWith("@" + PrintPointer(reinterpret_cast<const void*>(&p))
|
||||
+ " " + Print(sizeof(p)) + "-byte object "));
|
||||
|
||||
char (Foo::*p2)(int n) = &Foo::MyVirtualMethod;
|
||||
EXPECT_THAT(PrintByRef(p2),
|
||||
StartsWith("@" + PrintPointer(reinterpret_cast<const void*>(&p2))
|
||||
+ " " + Print(sizeof(p2)) + "-byte object "));
|
||||
}
|
||||
|
||||
// Tests that the universal printer prints a member variable pointer
|
||||
// passed by reference.
|
||||
TEST(PrintReferenceTest, HandlesMemberVariablePointer) {
|
||||
int (Foo::*p) = &Foo::value; // NOLINT
|
||||
EXPECT_THAT(PrintByRef(p),
|
||||
StartsWith("@" + PrintPointer(&p)
|
||||
+ " " + Print(sizeof(p)) + "-byte object "));
|
||||
}
|
||||
|
||||
} // namespace gmock_printers_test
|
||||
} // namespace testing
|
32
test/gmock-sample.cc
Normal file
32
test/gmock-sample.cc
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "test/gmock-sample.h"
|
49
test/gmock-sample.h
Normal file
49
test/gmock-sample.h
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#ifndef GMOCK_TEST_GMOCK_SAMPLE_H_
|
||||
#define GMOCK_TEST_GMOCK_SAMPLE_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class Sample {
|
||||
public:
|
||||
virtual ~Sample() {}
|
||||
|
||||
virtual bool Foo(int n) = 0;
|
||||
};
|
||||
|
||||
class MockSample : public Sample {
|
||||
public:
|
||||
MOCK_METHOD1(Foo, bool(int n));
|
||||
};
|
||||
|
||||
#endif // GMOCK_TEST_GMOCK_SAMPLE_H_
|
1889
test/gmock-spec-builders_test.cc
Normal file
1889
test/gmock-spec-builders_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
37
test/gmock_link_test.cc
Normal file
37
test/gmock_link_test.cc
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// This file is for verifying that a header file defining a mock class
|
||||
// can be included in multiple translation units without causing a
|
||||
// link error. It doesn't have to actually do anything - we are only
|
||||
// checking that the test links correctly.
|
||||
|
||||
#include "test/gmock-sample.h"
|
200
test/gmock_output_test.py
Executable file
200
test/gmock_output_test.py
Executable file
@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Tests the text output of Google C++ Mocking Framework.
|
||||
|
||||
SYNOPSIS
|
||||
gmock_output_test.py --gmock_build_dir=BUILD/DIR --gengolden
|
||||
# where BUILD/DIR contains the built gmock_output_test_ file.
|
||||
gmock_output_test.py --gengolden
|
||||
gmock_output_test.py
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import gmock_test_utils
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
# The flag for generating the golden file
|
||||
GENGOLDEN_FLAG = '--gengolden'
|
||||
|
||||
IS_WINDOWS = os.name == 'nt'
|
||||
|
||||
if IS_WINDOWS:
|
||||
PROGRAM = r'..\build.dbg\gmock_output_test_.exe'
|
||||
else:
|
||||
PROGRAM = 'gmock_output_test_'
|
||||
|
||||
PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
|
||||
COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0'
|
||||
GOLDEN_NAME = 'gmock_output_test_golden.txt'
|
||||
GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(),
|
||||
GOLDEN_NAME)
|
||||
|
||||
def ToUnixLineEnding(s):
|
||||
"""Changes all Windows/Mac line endings in s to UNIX line endings."""
|
||||
|
||||
return s.replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
|
||||
def RemoveReportHeaderAndFooter(output):
|
||||
"""Removes Google Test result report's header and footer from the output."""
|
||||
|
||||
output = re.sub(r'.*gtest_main.*\n', '', output)
|
||||
output = re.sub(r'\[.*\d+ tests.*\n', '', output)
|
||||
output = re.sub(r'\[.* test environment .*\n', '', output)
|
||||
output = re.sub(r'\[=+\] \d+ tests .* ran.*', '', output)
|
||||
output = re.sub(r'.* FAILED TESTS\n', '', output)
|
||||
return output
|
||||
|
||||
|
||||
def RemoveLocations(output):
|
||||
"""Removes all file location info from a Google Test program's output.
|
||||
|
||||
Args:
|
||||
output: the output of a Google Test program.
|
||||
|
||||
Returns:
|
||||
output with all file location info (in the form of
|
||||
'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or
|
||||
'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by
|
||||
'FILE:#: '.
|
||||
"""
|
||||
|
||||
return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\:', 'FILE:#:', output)
|
||||
|
||||
|
||||
def NormalizeErrorMarker(output):
|
||||
"""Normalizes the error marker, which is different on Windows vs on Linux."""
|
||||
|
||||
return re.sub(r' error: ', ' Failure\n', output)
|
||||
|
||||
|
||||
def RemoveMemoryAddresses(output):
|
||||
"""Removes memory addresses from the test output."""
|
||||
|
||||
return re.sub(r'@\w+', '@0x#', output)
|
||||
|
||||
|
||||
def NormalizeOutput(output):
|
||||
"""Normalizes output (the output of gmock_output_test_.exe)."""
|
||||
|
||||
output = ToUnixLineEnding(output)
|
||||
output = RemoveReportHeaderAndFooter(output)
|
||||
output = NormalizeErrorMarker(output)
|
||||
output = RemoveLocations(output)
|
||||
output = RemoveMemoryAddresses(output)
|
||||
return output
|
||||
|
||||
|
||||
def IterShellCommandOutput(cmd, stdin_string=None):
|
||||
"""Runs a command in a sub-process, and iterates the lines in its STDOUT.
|
||||
|
||||
Args:
|
||||
|
||||
cmd: The shell command.
|
||||
stdin_string: The string to be fed to the STDIN of the sub-process;
|
||||
If None, the sub-process will inherit the STDIN
|
||||
from the parent process.
|
||||
"""
|
||||
|
||||
# Spawns cmd in a sub-process, and gets its standard I/O file objects.
|
||||
stdin_file, stdout_file = os.popen2(cmd, 'b')
|
||||
|
||||
# If the caller didn't specify a string for STDIN, gets it from the
|
||||
# parent process.
|
||||
if stdin_string is None:
|
||||
stdin_string = sys.stdin.read()
|
||||
|
||||
# Feeds the STDIN string to the sub-process.
|
||||
stdin_file.write(stdin_string)
|
||||
stdin_file.close()
|
||||
|
||||
while True:
|
||||
line = stdout_file.readline()
|
||||
if not line: # EOF
|
||||
stdout_file.close()
|
||||
break
|
||||
|
||||
yield line
|
||||
|
||||
|
||||
def GetShellCommandOutput(cmd, stdin_string=None):
|
||||
"""Runs a command in a sub-process, and returns its STDOUT in a string.
|
||||
|
||||
Args:
|
||||
|
||||
cmd: The shell command.
|
||||
stdin_string: The string to be fed to the STDIN of the sub-process;
|
||||
If None, the sub-process will inherit the STDIN
|
||||
from the parent process.
|
||||
"""
|
||||
|
||||
lines = list(IterShellCommandOutput(cmd, stdin_string))
|
||||
return string.join(lines, '')
|
||||
|
||||
|
||||
def GetCommandOutput(cmd):
|
||||
"""Runs a command and returns its output with all file location
|
||||
info stripped off.
|
||||
|
||||
Args:
|
||||
cmd: the shell command.
|
||||
"""
|
||||
|
||||
# Disables exception pop-ups on Windows.
|
||||
os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
|
||||
return NormalizeOutput(GetShellCommandOutput(cmd, ''))
|
||||
|
||||
|
||||
class GMockOutputTest(unittest.TestCase):
|
||||
def testOutput(self):
|
||||
output = GetCommandOutput(COMMAND)
|
||||
golden_file = open(GOLDEN_PATH, 'rb')
|
||||
golden = golden_file.read()
|
||||
golden_file.close()
|
||||
|
||||
self.assertEquals(golden, output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.argv[1:] == [GENGOLDEN_FLAG]:
|
||||
output = GetCommandOutput(COMMAND)
|
||||
golden_file = open(GOLDEN_PATH, 'wb')
|
||||
golden_file.write(output)
|
||||
golden_file.close()
|
||||
else:
|
||||
gmock_test_utils.Main()
|
241
test/gmock_output_test_.cc
Normal file
241
test/gmock_output_test_.cc
Normal file
@ -0,0 +1,241 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Tests Google Mock's output in various scenarios. This ensures that
|
||||
// Google Mock's messages are readable and useful.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using testing::_;
|
||||
using testing::Ge;
|
||||
using testing::InSequence;
|
||||
using testing::Ref;
|
||||
using testing::Return;
|
||||
using testing::Sequence;
|
||||
|
||||
class MockFoo {
|
||||
public:
|
||||
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
|
||||
MOCK_METHOD2(Bar2, bool(int x, int y));
|
||||
MOCK_METHOD2(Bar3, void(int x, int y));
|
||||
};
|
||||
|
||||
class GMockOutputTest : public testing::Test {
|
||||
protected:
|
||||
MockFoo foo_;
|
||||
};
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCall) {
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) {
|
||||
testing::GMOCK_FLAG(verbose) = "info";
|
||||
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
|
||||
testing::GMOCK_FLAG(verbose) = "warning";
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExplicitActionsRunOut) {
|
||||
EXPECT_CALL(foo_, Bar2(_, _))
|
||||
.Times(2)
|
||||
.WillOnce(Return(false));
|
||||
foo_.Bar2(2, 2);
|
||||
foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnexpectedCall) {
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
|
||||
foo_.Bar2(1, 0); // Unexpected call
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnexpectedCallToVoidFunction) {
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
|
||||
foo_.Bar3(1, 0); // Unexpected call
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExcessiveCall) {
|
||||
EXPECT_CALL(foo_, Bar2(0, _));
|
||||
|
||||
foo_.Bar2(0, 0); // Expected call
|
||||
foo_.Bar2(0, 1); // Excessive call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExcessiveCallToVoidFunction) {
|
||||
EXPECT_CALL(foo_, Bar3(0, _));
|
||||
|
||||
foo_.Bar3(0, 0); // Expected call
|
||||
foo_.Bar3(0, 1); // Excessive call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UninterestingCall) {
|
||||
foo_.Bar2(0, 1); // Uninteresting call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UninterestingCallToVoidFunction) {
|
||||
foo_.Bar3(0, 1); // Uninteresting call
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, RetiredExpectation) {
|
||||
EXPECT_CALL(foo_, Bar2(_, _))
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(foo_, Bar2(0, 0));
|
||||
|
||||
foo_.Bar2(1, 1);
|
||||
foo_.Bar2(1, 1); // Matches a retired expectation
|
||||
foo_.Bar2(0, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnsatisfiedPrerequisite) {
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(foo_, Bar(_, 0, _));
|
||||
EXPECT_CALL(foo_, Bar2(0, 0));
|
||||
EXPECT_CALL(foo_, Bar2(1, _));
|
||||
}
|
||||
|
||||
foo_.Bar2(1, 0); // Has one immediate unsatisfied pre-requisite
|
||||
foo_.Bar("Hi", 0, 0);
|
||||
foo_.Bar2(0, 0);
|
||||
foo_.Bar2(1, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnsatisfiedPrerequisites) {
|
||||
Sequence s1, s2;
|
||||
|
||||
EXPECT_CALL(foo_, Bar(_, 0, _))
|
||||
.InSequence(s1);
|
||||
EXPECT_CALL(foo_, Bar2(0, 0))
|
||||
.InSequence(s2);
|
||||
EXPECT_CALL(foo_, Bar2(1, _))
|
||||
.InSequence(s1, s2);
|
||||
|
||||
foo_.Bar2(1, 0); // Has two immediate unsatisfied pre-requisites
|
||||
foo_.Bar("Hi", 0, 0);
|
||||
foo_.Bar2(0, 0);
|
||||
foo_.Bar2(1, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnsatisfiedExpectation) {
|
||||
EXPECT_CALL(foo_, Bar(_, _, _));
|
||||
EXPECT_CALL(foo_, Bar2(0, _))
|
||||
.Times(2);
|
||||
|
||||
foo_.Bar2(0, 1);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, MismatchArguments) {
|
||||
const std::string s = "Hi";
|
||||
EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)));
|
||||
|
||||
foo_.Bar("Ho", 0, -0.1); // Mismatch arguments
|
||||
foo_.Bar(s, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, MismatchWithArguments) {
|
||||
EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
|
||||
.WithArguments(Ge());
|
||||
|
||||
foo_.Bar2(2, 3); // Mismatch WithArguments()
|
||||
foo_.Bar2(2, 1);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, MismatchArgumentsAndWithArguments) {
|
||||
EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))
|
||||
.WithArguments(Ge());
|
||||
|
||||
foo_.Bar2(1, 3); // Mismatch arguments and mismatch WithArguments()
|
||||
foo_.Bar2(2, 1);
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UnexpectedCallWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
ON_CALL(foo_, Bar2(1, _))
|
||||
.WillByDefault(Return(false)); // Default action #2
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(2, 2));
|
||||
foo_.Bar2(1, 0); // Unexpected call, takes default action #2.
|
||||
foo_.Bar2(0, 0); // Unexpected call, takes default action #1.
|
||||
foo_.Bar2(2, 2); // Expected call.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExcessiveCallWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
ON_CALL(foo_, Bar2(1, _))
|
||||
.WillByDefault(Return(false)); // Default action #2
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(2, 2));
|
||||
EXPECT_CALL(foo_, Bar2(1, 1));
|
||||
|
||||
foo_.Bar2(2, 2); // Expected call.
|
||||
foo_.Bar2(2, 2); // Excessive call, takes default action #1.
|
||||
foo_.Bar2(1, 1); // Expected call.
|
||||
foo_.Bar2(1, 1); // Excessive call, takes default action #2.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, UninterestingCallWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
ON_CALL(foo_, Bar2(1, _))
|
||||
.WillByDefault(Return(false)); // Default action #2
|
||||
|
||||
foo_.Bar2(2, 2); // Uninteresting call, takes default action #1.
|
||||
foo_.Bar2(1, 1); // Uninteresting call, takes default action #2.
|
||||
}
|
||||
|
||||
TEST_F(GMockOutputTest, ExplicitActionsRunOutWithDefaultAction) {
|
||||
ON_CALL(foo_, Bar2(_, _))
|
||||
.WillByDefault(Return(true)); // Default action #1
|
||||
|
||||
EXPECT_CALL(foo_, Bar2(_, _))
|
||||
.Times(2)
|
||||
.WillOnce(Return(false));
|
||||
foo_.Bar2(2, 2);
|
||||
foo_.Bar2(1, 1); // Explicit actions in EXPECT_CALL run out.
|
||||
}
|
296
test/gmock_output_test_golden.txt
Normal file
296
test/gmock_output_test_golden.txt
Normal file
@ -0,0 +1,296 @@
|
||||
Running main() from gmock_main.cc
|
||||
[ RUN ] GMockOutputTest.ExpectedCall
|
||||
|
||||
FILE:#: EXPECT_CALL(foo_, Bar2(0, _)) invoked
|
||||
Stack trace:
|
||||
|
||||
FILE:#: Expected mock function call.
|
||||
Function call: Bar2(0, 0)
|
||||
Returns: false
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExpectedCall
|
||||
[ RUN ] GMockOutputTest.ExpectedCallToVoidFunction
|
||||
|
||||
FILE:#: EXPECT_CALL(foo_, Bar3(0, _)) invoked
|
||||
Stack trace:
|
||||
|
||||
FILE:#: Expected mock function call.
|
||||
Function call: Bar3(0, 0)
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExpectedCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOut
|
||||
|
||||
GMOCK WARNING:
|
||||
FILE:#: Too few actions specified.
|
||||
Expected to be called twice, but has only 1 WillOnce().
|
||||
GMOCK WARNING:
|
||||
FILE:#: Actions ran out.
|
||||
Called 2 times, but only 1 WillOnce() is specified - returning default value.
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExplicitActionsRunOut
|
||||
[ RUN ] GMockOutputTest.UnexpectedCall
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning directly.
|
||||
Function call: Bar3(1, 0)
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCall
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - returning default value.
|
||||
Function call: Bar2(0, 1)
|
||||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCall
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.UninterestingCall
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - returning default value.
|
||||
Function call: Bar2(0, 1)
|
||||
Returns: false
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.UninterestingCall
|
||||
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - returning directly.
|
||||
Function call: Bar3(0, 1)
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
|
||||
[ RUN ] GMockOutputTest.RetiredExpectation
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
Google Mock tried the following 2 expectations, but none matched:
|
||||
|
||||
FILE:#: tried expectation #0
|
||||
Expected: the expectation is active
|
||||
Actual: it is retired
|
||||
Expected: to be called once
|
||||
Actual: called once - saturated and retired
|
||||
FILE:#: tried expectation #1
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected arg #1: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.RetiredExpectation
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 2 expectations, but none matched:
|
||||
|
||||
FILE:#: tried expectation #0
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
FILE:#: tried expectation #1
|
||||
Expected: all pre-requisites are satisfied
|
||||
Actual: the following immediate pre-requisites are not satisfied:
|
||||
FILE:#: pre-requisite #0
|
||||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 2 expectations, but none matched:
|
||||
|
||||
FILE:#: tried expectation #0
|
||||
Expected arg #0: is equal to 0
|
||||
Actual: 1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
FILE:#: tried expectation #1
|
||||
Expected: all pre-requisites are satisfied
|
||||
Actual: the following immediate pre-requisites are not satisfied:
|
||||
FILE:#: pre-requisite #0
|
||||
FILE:#: pre-requisite #1
|
||||
(end of pre-requisites)
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
[ RUN ] GMockOutputTest.UnsatisfiedExpectation
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match this expectation.
|
||||
Expected: to be called twice
|
||||
Actual: called once - unsatisfied and active
|
||||
FILE:#: Failure
|
||||
Actual function call count doesn't match this expectation.
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
|
||||
[ RUN ] GMockOutputTest.MismatchArguments
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar(@0x# "Ho", 0, -0.1)
|
||||
Returns: '\0'
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: references the variable @0x# "Hi"
|
||||
Actual: "Ho" (is located @0x#)
|
||||
Expected arg #2: is greater than or equal to 0
|
||||
Actual: -0.1
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.MismatchArguments
|
||||
[ RUN ] GMockOutputTest.MismatchWithArguments
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(2, 3)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected: argument #0 is greater than or equal to argument #1
|
||||
Actual: false
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.MismatchWithArguments
|
||||
[ RUN ] GMockOutputTest.MismatchArgumentsAndWithArguments
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - returning default value.
|
||||
Function call: Bar2(1, 3)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is greater than or equal to 2
|
||||
Actual: 1
|
||||
Expected: argument #0 is greater than or equal to argument #1
|
||||
Actual: false
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
|
||||
[ RUN ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 0)
|
||||
Returns: false
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 2
|
||||
Actual: 1
|
||||
Expected arg #1: is equal to 2
|
||||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
unknown file: Failure
|
||||
|
||||
Unexpected mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(0, 0)
|
||||
Returns: true
|
||||
Google Mock tried the following 1 expectation, but it didn't match:
|
||||
|
||||
FILE:#:
|
||||
Expected arg #0: is equal to 2
|
||||
Actual: 0
|
||||
Expected arg #1: is equal to 2
|
||||
Actual: 0
|
||||
Expected: to be called once
|
||||
Actual: never called - unsatisfied and active
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(2, 2)
|
||||
Returns: true
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
FILE:#: Failure
|
||||
Mock function called more times than expected - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
Expected: to be called once
|
||||
Actual: called twice - over-saturated and active
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(2, 2)
|
||||
Returns: true
|
||||
Stack trace:
|
||||
|
||||
GMOCK WARNING:
|
||||
Uninteresting mock function call - taking default action specified at:
|
||||
FILE:#:
|
||||
Function call: Bar2(1, 1)
|
||||
Returns: false
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
|
||||
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||
|
||||
GMOCK WARNING:
|
||||
FILE:#: Too few actions specified.
|
||||
Expected to be called twice, but has only 1 WillOnce().
|
||||
GMOCK WARNING:
|
||||
FILE:#: Actions ran out.
|
||||
Called 2 times, but only 1 WillOnce() is specified - taking default action specified at:
|
||||
FILE:#:
|
||||
Stack trace:
|
||||
[ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCall
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCall
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction
|
||||
[ FAILED ] GMockOutputTest.RetiredExpectation
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites
|
||||
[ FAILED ] GMockOutputTest.UnsatisfiedExpectation
|
||||
[ FAILED ] GMockOutputTest.MismatchArguments
|
||||
[ FAILED ] GMockOutputTest.MismatchWithArguments
|
||||
[ FAILED ] GMockOutputTest.MismatchArgumentsAndWithArguments
|
||||
[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction
|
||||
[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction
|
||||
|
248
test/gmock_test.cc
Normal file
248
test/gmock_test.cc
Normal file
@ -0,0 +1,248 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file tests code in gmock.cc.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using testing::GMOCK_FLAG(verbose);
|
||||
using testing::InitGoogleMock;
|
||||
using testing::internal::g_init_gtest_count;
|
||||
|
||||
// Verifies that calling InitGoogleMock() on argv results in new_argv,
|
||||
// and the gmock_verbose flag's value is set to expected_gmock_verbose.
|
||||
template <typename Char, int M, int N>
|
||||
void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N],
|
||||
const ::std::string& expected_gmock_verbose) {
|
||||
const ::std::string old_verbose = GMOCK_FLAG(verbose);
|
||||
|
||||
int argc = M;
|
||||
InitGoogleMock(&argc, const_cast<Char**>(argv));
|
||||
ASSERT_EQ(N, argc) << "The new argv has wrong number of elements.";
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
EXPECT_STREQ(new_argv[i], argv[i]);
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str());
|
||||
GMOCK_FLAG(verbose) = old_verbose; // Restores the gmock_verbose flag.
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
const char* argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--gmock_verbose=info",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "info");
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
}
|
||||
|
||||
TEST(InitGoogleMockTest, CallsInitGoogleTest) {
|
||||
const int old_init_gtest_count = g_init_gtest_count;
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* new_argv[] = {
|
||||
"foo.exe",
|
||||
"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
const wchar_t* argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--gmock_verbose=info",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "info");
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose));
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
L"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
}
|
||||
|
||||
TEST(WideInitGoogleMockTest, CallsInitGoogleTest) {
|
||||
const int old_init_gtest_count = g_init_gtest_count;
|
||||
const wchar_t* argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
L"--gmock_verbose=error",
|
||||
NULL
|
||||
};
|
||||
|
||||
const wchar_t* new_argv[] = {
|
||||
L"foo.exe",
|
||||
L"--non_gmock_flag=blah",
|
||||
NULL
|
||||
};
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
|
||||
}
|
126
test/gmock_test_utils.py
Executable file
126
test/gmock_test_utils.py
Executable file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/python2.4
|
||||
#
|
||||
# Copyright 2006, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Unit test utilities for Google C++ Mocking Framework."""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
# Initially maps a flag to its default value. After
|
||||
# _ParseAndStripGMockFlags() is called, maps a flag to its actual
|
||||
# value.
|
||||
_flag_map = {'gmock_source_dir': os.path.dirname(sys.argv[0]),
|
||||
'gmock_build_dir': os.path.dirname(sys.argv[0])}
|
||||
_gmock_flags_are_parsed = False
|
||||
|
||||
|
||||
def _ParseAndStripGMockFlags(argv):
|
||||
"""Parses and strips Google Test flags from argv. This is idempotent."""
|
||||
|
||||
global _gmock_flags_are_parsed
|
||||
if _gmock_flags_are_parsed:
|
||||
return
|
||||
|
||||
_gmock_flags_are_parsed = True
|
||||
for flag in _flag_map:
|
||||
# The environment variable overrides the default value.
|
||||
if flag.upper() in os.environ:
|
||||
_flag_map[flag] = os.environ[flag.upper()]
|
||||
|
||||
# The command line flag overrides the environment variable.
|
||||
i = 1 # Skips the program name.
|
||||
while i < len(argv):
|
||||
prefix = '--' + flag + '='
|
||||
if argv[i].startswith(prefix):
|
||||
_flag_map[flag] = argv[i][len(prefix):]
|
||||
del argv[i]
|
||||
break
|
||||
else:
|
||||
# We don't increment i in case we just found a --gmock_* flag
|
||||
# and removed it from argv.
|
||||
i += 1
|
||||
|
||||
|
||||
def GetFlag(flag):
|
||||
"""Returns the value of the given flag."""
|
||||
|
||||
# In case GetFlag() is called before Main(), we always call
|
||||
# _ParseAndStripGMockFlags() here to make sure the --gmock_* flags
|
||||
# are parsed.
|
||||
_ParseAndStripGMockFlags(sys.argv)
|
||||
|
||||
return _flag_map[flag]
|
||||
|
||||
|
||||
def GetSourceDir():
|
||||
"""Returns the absolute path of the directory where the .py files are."""
|
||||
|
||||
return os.path.abspath(GetFlag('gmock_source_dir'))
|
||||
|
||||
|
||||
def GetBuildDir():
|
||||
"""Returns the absolute path of the directory where the test binaries are."""
|
||||
|
||||
return os.path.abspath(GetFlag('gmock_build_dir'))
|
||||
|
||||
|
||||
def GetExitStatus(exit_code):
|
||||
"""Returns the argument to exit(), or -1 if exit() wasn't called.
|
||||
|
||||
Args:
|
||||
exit_code: the result value of os.system(command).
|
||||
"""
|
||||
|
||||
if os.name == 'nt':
|
||||
# On Windows, os.WEXITSTATUS() doesn't work and os.system() returns
|
||||
# the argument to exit() directly.
|
||||
return exit_code
|
||||
else:
|
||||
# On Unix, os.WEXITSTATUS() must be used to extract the exit status
|
||||
# from the result of os.system().
|
||||
if os.WIFEXITED(exit_code):
|
||||
return os.WEXITSTATUS(exit_code)
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
def Main():
|
||||
"""Runs the unit test."""
|
||||
|
||||
# We must call _ParseAndStripGMockFlags() before calling
|
||||
# unittest.main(). Otherwise the latter will be confused by the
|
||||
# --gmock_* flags.
|
||||
_ParseAndStripGMockFlags(sys.argv)
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user