Merge "Move Widevine Unit Tests to Standard gMock" into nyc-dev
This commit is contained in:
@@ -13,10 +13,6 @@ cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine
|
||||
pwd
|
||||
mm || mma
|
||||
|
||||
cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine/test/gmock
|
||||
pwd
|
||||
mm || mma
|
||||
|
||||
cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine/test/unit
|
||||
pwd
|
||||
mm || mma
|
||||
|
||||
@@ -18,6 +18,7 @@ LOCAL_SRC_FILES := \
|
||||
../core/test/url_request.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
external/gmock/include \
|
||||
external/gtest/include \
|
||||
external/openssl/include \
|
||||
vendor/widevine/libwvdrmengine/android/cdm/test \
|
||||
@@ -27,7 +28,6 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/profiler/test \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
vendor/widevine/libwvdrmengine/test/gmock/include
|
||||
|
||||
LOCAL_C_INCLUDES += external/protobuf/src
|
||||
|
||||
@@ -37,9 +37,9 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm_utils \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libgmock \
|
||||
libgtest \
|
||||
libgtest_main \
|
||||
libwvgmock \
|
||||
libwvlevel3 \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
|
||||
@@ -5,6 +5,7 @@ LOCAL_SRC_FILES := \
|
||||
WVCryptoPlugin_test.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
external/gmock/include \
|
||||
external/gtest/include \
|
||||
frameworks/av/include \
|
||||
frameworks/native/include \
|
||||
@@ -12,7 +13,6 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
vendor/widevine/libwvdrmengine/test/gmock/include \
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
@@ -20,8 +20,8 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm_utils \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libwvgmock \
|
||||
libwvgmock_main \
|
||||
libgmock \
|
||||
libgmock_main \
|
||||
libgtest \
|
||||
libwvlevel3 \
|
||||
libwvdrmcryptoplugin \
|
||||
|
||||
@@ -5,6 +5,7 @@ LOCAL_SRC_FILES := \
|
||||
WVDrmPlugin_test.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
external/gmock/include \
|
||||
external/gtest/include \
|
||||
frameworks/av/include \
|
||||
frameworks/native/include \
|
||||
@@ -14,7 +15,6 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediadrm/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
vendor/widevine/libwvdrmengine/test/gmock/include \
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
@@ -22,9 +22,9 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm_utils \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libgmock \
|
||||
libgmock_main \
|
||||
libgtest \
|
||||
libwvgmock \
|
||||
libwvgmock_main \
|
||||
libwvlevel3 \
|
||||
libwvdrmdrmplugin \
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
include $(call all-subdir-makefiles)
|
||||
@@ -1,126 +0,0 @@
|
||||
Changes for 1.7.0:
|
||||
|
||||
* All new improvements in Google Test 1.7.0.
|
||||
* New feature: matchers DoubleNear(), FloatNear(),
|
||||
NanSensitiveDoubleNear(), NanSensitiveFloatNear(),
|
||||
UnorderedElementsAre(), UnorderedElementsAreArray(), WhenSorted(),
|
||||
WhenSortedBy(), IsEmpty(), and SizeIs().
|
||||
* Improvement: Google Mock can now be built as a DLL.
|
||||
* Improvement: when compiled by a C++11 compiler, matchers AllOf()
|
||||
and AnyOf() can accept an arbitrary number of matchers.
|
||||
* Improvement: when compiled by a C++11 compiler, matchers
|
||||
ElementsAreArray() can accept an initializer list.
|
||||
* Improvement: when exceptions are enabled, a mock method with no
|
||||
default action now throws instead crashing the test.
|
||||
* Improvement: added class testing::StringMatchResultListener to aid
|
||||
definition of composite matchers.
|
||||
* Improvement: function return types used in MOCK_METHOD*() macros can
|
||||
now contain unprotected commas.
|
||||
* Improvement (potentially breaking): EXPECT_THAT() and ASSERT_THAT()
|
||||
are now more strict in ensuring that the value type and the matcher
|
||||
type are compatible, catching potential bugs in tests.
|
||||
* Improvement: Pointee() now works on an optional<T>.
|
||||
* Improvement: the ElementsAreArray() matcher can now take a vector or
|
||||
iterator range as input, and makes a copy of its input elements
|
||||
before the conversion to a Matcher.
|
||||
* Improvement: the Google Mock Generator can now generate mocks for
|
||||
some class templates.
|
||||
* Bug fix: mock object destruction triggerred by another mock object's
|
||||
destruction no longer hangs.
|
||||
* Improvement: Google Mock Doctor works better with newer Clang and
|
||||
GCC now.
|
||||
* Compatibility fixes.
|
||||
* Bug/warning fixes.
|
||||
|
||||
Changes for 1.6.0:
|
||||
|
||||
* Compilation is much faster and uses much less memory, especially
|
||||
when the constructor and destructor of a mock class are moved out of
|
||||
the class body.
|
||||
* New matchers: Pointwise(), Each().
|
||||
* New actions: ReturnPointee() and ReturnRefOfCopy().
|
||||
* CMake support.
|
||||
* Project files for Visual Studio 2010.
|
||||
* AllOf() and AnyOf() can handle up-to 10 arguments now.
|
||||
* Google Mock doctor understands Clang error messages now.
|
||||
* SetArgPointee<> now accepts string literals.
|
||||
* gmock_gen.py handles storage specifier macros and template return
|
||||
types now.
|
||||
* Compatibility fixes.
|
||||
* Bug fixes and implementation clean-ups.
|
||||
* Potentially incompatible changes: disables the harmful 'make install'
|
||||
command in autotools.
|
||||
|
||||
Potentially breaking changes:
|
||||
|
||||
* The description string for MATCHER*() changes from Python-style
|
||||
interpolation to an ordinary C++ string expression.
|
||||
* SetArgumentPointee is deprecated in favor of SetArgPointee.
|
||||
* Some non-essential project files for Visual Studio 2005 are removed.
|
||||
|
||||
Changes for 1.5.0:
|
||||
|
||||
* New feature: Google Mock can be safely used in multi-threaded tests
|
||||
on platforms having pthreads.
|
||||
* New feature: function for printing a value of arbitrary type.
|
||||
* New feature: function ExplainMatchResult() for easy definition of
|
||||
composite matchers.
|
||||
* The new matcher API lets user-defined matchers generate custom
|
||||
explanations more directly and efficiently.
|
||||
* Better failure messages all around.
|
||||
* NotNull() and IsNull() now work with smart pointers.
|
||||
* Field() and Property() now work when the matcher argument is a pointer
|
||||
passed by reference.
|
||||
* Regular expression matchers on all platforms.
|
||||
* Added GCC 4.0 support for Google Mock Doctor.
|
||||
* Added gmock_all_test.cc for compiling most Google Mock tests
|
||||
in a single file.
|
||||
* Significantly cleaned up compiler warnings.
|
||||
* Bug fixes, better test coverage, and implementation clean-ups.
|
||||
|
||||
Potentially breaking changes:
|
||||
|
||||
* Custom matchers defined using MatcherInterface or MakePolymorphicMatcher()
|
||||
need to be updated after upgrading to Google Mock 1.5.0; matchers defined
|
||||
using MATCHER or MATCHER_P* aren't affected.
|
||||
* Dropped support for 'make install'.
|
||||
|
||||
Changes for 1.4.0 (we skipped 1.2.* and 1.3.* to match the version of
|
||||
Google Test):
|
||||
|
||||
* Works in more environments: Symbian and minGW, Visual C++ 7.1.
|
||||
* Lighter weight: comes with our own implementation of TR1 tuple (no
|
||||
more dependency on Boost!).
|
||||
* New feature: --gmock_catch_leaked_mocks for detecting leaked mocks.
|
||||
* New feature: ACTION_TEMPLATE for defining templatized actions.
|
||||
* New feature: the .After() clause for specifying expectation order.
|
||||
* New feature: the .With() clause for for specifying inter-argument
|
||||
constraints.
|
||||
* New feature: actions ReturnArg<k>(), ReturnNew<T>(...), and
|
||||
DeleteArg<k>().
|
||||
* New feature: matchers Key(), Pair(), Args<...>(), AllArgs(), IsNull(),
|
||||
and Contains().
|
||||
* New feature: utility class MockFunction<F>, useful for checkpoints, etc.
|
||||
* New feature: functions Value(x, m) and SafeMatcherCast<T>(m).
|
||||
* New feature: copying a mock object is rejected at compile time.
|
||||
* New feature: a script for fusing all Google Mock and Google Test
|
||||
source files for easy deployment.
|
||||
* Improved the Google Mock doctor to diagnose more diseases.
|
||||
* Improved the Google Mock generator script.
|
||||
* Compatibility fixes for Mac OS X and gcc.
|
||||
* Bug fixes and implementation clean-ups.
|
||||
|
||||
Changes for 1.1.0:
|
||||
|
||||
* New feature: ability to use Google Mock with any testing framework.
|
||||
* New feature: macros for easily defining new matchers
|
||||
* New feature: macros for easily defining new actions.
|
||||
* New feature: more container matchers.
|
||||
* New feature: actions for accessing function arguments and throwing
|
||||
exceptions.
|
||||
* Improved the Google Mock doctor script for diagnosing compiler errors.
|
||||
* Bug fixes and implementation clean-ups.
|
||||
|
||||
Changes for 1.0.0:
|
||||
|
||||
* Initial Open Source release of Google Mock
|
||||
@@ -1,40 +0,0 @@
|
||||
# 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
|
||||
Manuel Klimek <klimek@google.com>
|
||||
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>
|
||||
Nermin Ozkiranartli <nermin@google.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>
|
||||
Sverre Sundsdal <sundsdal@gmail.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>
|
||||
@@ -1,28 +0,0 @@
|
||||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,369 +0,0 @@
|
||||
Google C++ Mocking Framework
|
||||
============================
|
||||
|
||||
http://code.google.com/p/googlemock/
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Google's framework for writing and using C++ mock classes on a variety
|
||||
of platforms (Linux, Mac OS X, Windows, Windows CE, Symbian, etc).
|
||||
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 the
|
||||
mailing list 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, which is different from Google Mock's license.
|
||||
|
||||
Requirements for End Users
|
||||
--------------------------
|
||||
|
||||
Google Mock is implemented on top of the Google Test C++ testing
|
||||
framework (http://code.google.com/p/googletest/), and includes the
|
||||
latter as part of the SVN repositary and distribution package. You
|
||||
must use the bundled version of Google Test when using Google Mock, or
|
||||
you may get compiler/linker errors.
|
||||
|
||||
You can also easily configure Google Mock to work with another testing
|
||||
framework of your choice; although it will still need Google Test as
|
||||
an internal dependency. Please read
|
||||
http://code.google.com/p/googlemock/wiki/ForDummies#Using_Google_Mock_with_Any_Testing_Framework
|
||||
for how to do it.
|
||||
|
||||
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)
|
||||
* C++98-standard-compliant compiler (e.g. GCC 3.4 or newer)
|
||||
|
||||
### Windows Requirements ###
|
||||
|
||||
* Microsoft Visual C++ 8.0 SP1 or newer
|
||||
|
||||
### Mac OS X Requirements ###
|
||||
|
||||
* Mac OS X 10.4 Tiger or newer
|
||||
* Developer Tools Installed
|
||||
|
||||
Requirements for Contributors
|
||||
-----------------------------
|
||||
|
||||
We welcome patches. If you plan to contribute a patch, you need to
|
||||
build Google Mock and its own tests from an SVN checkout (described
|
||||
below), which has further requirements:
|
||||
|
||||
* Automake version 1.9 or newer
|
||||
* Autoconf version 2.59 or newer
|
||||
* Libtool / Libtoolize
|
||||
* Python version 2.3 or newer (for running some of the tests and
|
||||
re-generating certain source files from templates)
|
||||
|
||||
Getting the Source
|
||||
------------------
|
||||
|
||||
There are two primary ways of getting Google Mock's source code: you
|
||||
can download a stable source release in your preferred archive format,
|
||||
or directly check out the source from our Subversion (SVN) repositary.
|
||||
The SVN checkout requires a few extra steps and some extra software
|
||||
packages on your system, but lets you track development and make
|
||||
patches much more easily, so we highly encourage it.
|
||||
|
||||
### Source Package ###
|
||||
|
||||
Google Mock is released in versioned source packages which can be
|
||||
downloaded from the download page [1]. Several different archive
|
||||
formats are provided, but the only difference is the tools needed to
|
||||
extract their contents, and the size of the resulting file. Download
|
||||
whichever you are most comfortable with.
|
||||
|
||||
[1] 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 on Linux:
|
||||
|
||||
tar -xvzf gmock-X.Y.Z.tar.gz
|
||||
tar -xvjf gmock-X.Y.Z.tar.bz2
|
||||
unzip gmock-X.Y.Z.zip
|
||||
|
||||
### SVN Checkout ###
|
||||
|
||||
To check out the main branch (also known as the "trunk") of Google
|
||||
Mock, run the following Subversion command:
|
||||
|
||||
svn checkout http://googlemock.googlecode.com/svn/trunk/ gmock-svn
|
||||
|
||||
If you are using a *nix system and plan to use the GNU Autotools build
|
||||
system to build Google Mock (described below), you'll need to
|
||||
configure it now. Otherwise you are done with getting the source
|
||||
files.
|
||||
|
||||
To prepare the Autotools build system, enter the target directory of
|
||||
the checkout command you used ('gmock-svn') and proceed with the
|
||||
following command:
|
||||
|
||||
autoreconf -fvi
|
||||
|
||||
Once you have completed this step, you are ready to build the library.
|
||||
Note that you should only need to complete this step once. The
|
||||
subsequent 'make' invocations will automatically re-generate the bits
|
||||
of the build system that need to be changed.
|
||||
|
||||
If your system uses older versions of the autotools, the above command
|
||||
will fail. You may need to explicitly specify a version to use. For
|
||||
instance, if you have both GNU Automake 1.4 and 1.9 installed and
|
||||
'automake' would invoke the 1.4, use instead:
|
||||
|
||||
AUTOMAKE=automake-1.9 ACLOCAL=aclocal-1.9 autoreconf -fvi
|
||||
|
||||
Make sure you're using the same version of automake and aclocal.
|
||||
|
||||
Setting up the Build
|
||||
--------------------
|
||||
|
||||
To build Google Mock and your tests that use it, you need to tell your
|
||||
build system where to find its headers and source files. The exact
|
||||
way to do it depends on which build system you use, and is usually
|
||||
straightforward.
|
||||
|
||||
### Generic Build Instructions ###
|
||||
|
||||
This section shows how you can integrate Google Mock into your
|
||||
existing build system.
|
||||
|
||||
Suppose you put Google Mock in directory ${GMOCK_DIR} and Google Test
|
||||
in ${GTEST_DIR} (the latter is ${GMOCK_DIR}/gtest by default). To
|
||||
build Google Mock, create a library build target (or a project as
|
||||
called by Visual Studio and Xcode) to compile
|
||||
|
||||
${GTEST_DIR}/src/gtest-all.cc and ${GMOCK_DIR}/src/gmock-all.cc
|
||||
|
||||
with
|
||||
|
||||
${GTEST_DIR}/include and ${GMOCK_DIR}/include
|
||||
|
||||
in the system header search path, and
|
||||
|
||||
${GTEST_DIR} and ${GMOCK_DIR}
|
||||
|
||||
in the normal header search path. Assuming a Linux-like system and gcc,
|
||||
something like the following will do:
|
||||
|
||||
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
|
||||
-isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \
|
||||
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
|
||||
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
|
||||
-isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \
|
||||
-pthread -c ${GMOCK_DIR}/src/gmock-all.cc
|
||||
ar -rv libgmock.a gtest-all.o gmock-all.o
|
||||
|
||||
(We need -pthread as Google Test and Google Mock use threads.)
|
||||
|
||||
Next, you should compile your test source file with
|
||||
${GTEST_DIR}/include and ${GMOCK_DIR}/include in the header search
|
||||
path, and link it with gmock and any other necessary libraries:
|
||||
|
||||
g++ -isystem ${GTEST_DIR}/include -isystem ${GMOCK_DIR}/include \
|
||||
-pthread path/to/your_test.cc libgmock.a -o your_test
|
||||
|
||||
As an example, the make/ directory contains a Makefile that you can
|
||||
use to build Google Mock on systems where GNU make is available
|
||||
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
|
||||
Mock's own tests. Instead, it just builds the Google Mock library and
|
||||
a sample test. You can use it as a starting point for your own build
|
||||
script.
|
||||
|
||||
If the default settings are correct for your environment, the
|
||||
following commands should succeed:
|
||||
|
||||
cd ${GMOCK_DIR}/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.
|
||||
|
||||
### Windows ###
|
||||
|
||||
The msvc/2005 directory contains VC++ 2005 projects and the msvc/2010
|
||||
directory contains VC++ 2010 projects for building Google Mock and
|
||||
selected tests.
|
||||
|
||||
Change to the appropriate directory and run "msbuild gmock.sln" to
|
||||
build the library and tests (or open the gmock.sln in the MSVC IDE).
|
||||
If you want to create your own project to use with Google Mock, you'll
|
||||
have to configure it to use the gmock_config propety sheet. For that:
|
||||
|
||||
* Open the Property Manager window (View | Other Windows | Property Manager)
|
||||
* Right-click on your project and select "Add Existing Property Sheet..."
|
||||
* Navigate to gmock_config.vsprops or gmock_config.props and select it.
|
||||
* In Project Properties | Configuration Properties | General | Additional
|
||||
Include Directories, type <path to Google Mock>/include.
|
||||
|
||||
Tweaking Google Mock
|
||||
--------------------
|
||||
|
||||
Google Mock can be used in diverse environments. The default
|
||||
configuration may not work (or may not work well) out of the box in
|
||||
some environments. However, you can easily tweak Google Mock by
|
||||
defining control macros on the compiler command line. Generally,
|
||||
these macros are named like GTEST_XYZ and you define them to either 1
|
||||
or 0 to enable or disable a certain feature.
|
||||
|
||||
We list the most frequently used macros below. For a complete list,
|
||||
see file ${GTEST_DIR}/include/gtest/internal/gtest-port.h.
|
||||
|
||||
### Choosing a TR1 Tuple Library ###
|
||||
|
||||
Google Mock uses the C++ Technical Report 1 (TR1) tuple library
|
||||
heavily. Unfortunately TR1 tuple is not yet widely available with all
|
||||
compilers. The good news is that Google Test 1.4.0+ implements a
|
||||
subset of TR1 tuple that's enough for Google Mock's need. Google Mock
|
||||
will automatically use that implementation when the compiler doesn't
|
||||
provide TR1 tuple.
|
||||
|
||||
Usually you don't need to care about which tuple library Google Test
|
||||
and Google Mock use. However, if your project already uses TR1 tuple,
|
||||
you need to tell Google Test and Google Mock to use the same TR1 tuple
|
||||
library the rest of your project uses, or the two tuple
|
||||
implementations will clash. To do that, add
|
||||
|
||||
-DGTEST_USE_OWN_TR1_TUPLE=0
|
||||
|
||||
to the compiler flags while compiling Google Test, Google Mock, and
|
||||
your tests. If you want to force Google Test and Google Mock to use
|
||||
their own tuple library, just add
|
||||
|
||||
-DGTEST_USE_OWN_TR1_TUPLE=1
|
||||
|
||||
to the compiler flags instead.
|
||||
|
||||
If you want to use Boost's TR1 tuple library with Google Mock, please
|
||||
refer to the Boost website (http://www.boost.org/) for how to obtain
|
||||
it and set it up.
|
||||
|
||||
### As a Shared Library (DLL) ###
|
||||
|
||||
Google Mock is compact, so most users can build and link it as a static
|
||||
library for the simplicity. Google Mock can be used as a DLL, but the
|
||||
same DLL must contain Google Test as well. See Google Test's README
|
||||
file for instructions on how to set up necessary compiler settings.
|
||||
|
||||
### Tweaking Google Mock ###
|
||||
|
||||
Most of Google Test's control macros apply to Google Mock as well.
|
||||
Please see file ${GTEST_DIR}/README for how to tweak them.
|
||||
|
||||
Upgrading from an Earlier Version
|
||||
---------------------------------
|
||||
|
||||
We strive to keep Google Mock releases backward compatible.
|
||||
Sometimes, though, we have to make some breaking changes for the
|
||||
users' long-term benefits. This section describes what you'll need to
|
||||
do if you are upgrading from an earlier version of Google Mock.
|
||||
|
||||
### Upgrading from 1.1.0 or Earlier ###
|
||||
|
||||
You may need to explicitly enable or disable Google Test's own TR1
|
||||
tuple library. See the instructions in section "Choosing a TR1 Tuple
|
||||
Library".
|
||||
|
||||
### Upgrading from 1.4.0 or Earlier ###
|
||||
|
||||
On platforms where the pthread library is available, Google Test and
|
||||
Google Mock use it in order to be thread-safe. For this to work, you
|
||||
may need to tweak your compiler and/or linker flags. Please see the
|
||||
"Multi-threaded Tests" section in file ${GTEST_DIR}/README for what
|
||||
you may need to do.
|
||||
|
||||
If you have custom matchers defined using MatcherInterface or
|
||||
MakePolymorphicMatcher(), you'll need to update their definitions to
|
||||
use the new matcher API [2]. Matchers defined using MATCHER() or
|
||||
MATCHER_P*() aren't affected.
|
||||
|
||||
[2] http://code.google.com/p/googlemock/wiki/CookBook#Writing_New_Monomorphic_Matchers,
|
||||
http://code.google.com/p/googlemock/wiki/CookBook#Writing_New_Polymorphic_Matchers
|
||||
|
||||
Developing Google Mock
|
||||
----------------------
|
||||
|
||||
This section discusses how to make your own changes to Google Mock.
|
||||
|
||||
### Testing Google Mock Itself ###
|
||||
|
||||
To make sure your changes work as intended and don't break existing
|
||||
functionality, you'll want to compile and run Google Test's own tests.
|
||||
For that you'll need Autotools. First, make sure you have followed
|
||||
the instructions in section "SVN Checkout" to configure Google Mock.
|
||||
Then, create a build output directory and enter it. Next,
|
||||
|
||||
${GMOCK_DIR}/configure # Standard GNU configure script, --help for more info
|
||||
|
||||
Once you have successfully configured Google Mock, the build steps are
|
||||
standard for GNU-style OSS packages.
|
||||
|
||||
make # Standard makefile following GNU conventions
|
||||
make check # Builds and runs all tests - all should pass.
|
||||
|
||||
Note that when building your project against Google Mock, you are building
|
||||
against Google Test as well. There is no need to configure Google Test
|
||||
separately.
|
||||
|
||||
### 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. 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. You can find
|
||||
pump.py in the ${GTEST_DIR}/scripts/ directory. Read the Pump manual
|
||||
[3] for how to use it.
|
||||
|
||||
[3] http://code.google.com/p/googletest/wiki/PumpManual.
|
||||
|
||||
### Contributing a Patch ###
|
||||
|
||||
We welcome patches. Please read the Google Mock developer's guide [4]
|
||||
for how you can contribute. In particular, make sure you have signed
|
||||
the Contributor License Agreement, or we won't be able to accept the
|
||||
patch.
|
||||
|
||||
[4] http://code.google.com/p/googlemock/wiki/DevGuide
|
||||
|
||||
Happy testing!
|
||||
@@ -1,74 +0,0 @@
|
||||
URL: https://code.google.com/p/googlemock/downloads/list
|
||||
Version: 1.7.0
|
||||
License: New BSD License
|
||||
|
||||
Description:
|
||||
Google's framework for writing and using C++ mock classes on a variety of
|
||||
platforms (Linux, Mac OS X, Windows, Windows CE, Symbian, etc). 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.
|
||||
|
||||
While gMock supports building with the Android NDK out-of-the-box, it needs some
|
||||
small modifications to build as part of the Android OS build. Specifically, it
|
||||
needs a different format of build script, and it needs to build against the OS'
|
||||
modified version of gTest, rather than the packaged version.
|
||||
|
||||
Local Modifications:
|
||||
--Thu Apr 3, 2015 (juce)--
|
||||
|
||||
Modified the Pump files to increase the maximum arity to 11, and ran Pump on
|
||||
them to regenerate the headers.
|
||||
|
||||
--Tue Jun 3, 2014 (joeyparrish)--
|
||||
|
||||
Removed DOS newlines for the sake of the git-to-piper bridge. Piper converts
|
||||
newlines automatically to unix style. If this change is not made in git, the
|
||||
bridge detects differences and attempts to sync to piper, even when nothing
|
||||
has changed in git.
|
||||
|
||||
--Mon Feb 4, 2014 (juce)--
|
||||
|
||||
Upgraded to gMock 1.7.0. This is required for compatibility with the upgrade
|
||||
of gTest on Android Master to 1.7.0. Note that after this change, this code
|
||||
will no longer work on Android KLP branches. Our gMock must match the version
|
||||
of gTest in the Android tree.
|
||||
|
||||
Updated src/Android.mk to turn on the gTest replacement for std::tr1::tuple.
|
||||
On Android, gTest builds without using the platform's std::tr1::tuple (which
|
||||
does not exist on Android) and without gTest's implementation of a subset of
|
||||
std::tr1::tuple. This works on Android because it omits the few features that
|
||||
rely on std::tr1::tuple. But gMock was written assuming std::tuple or the
|
||||
gTest-defined subset would be available, and it cannot be used without one or
|
||||
the other.
|
||||
|
||||
Updated src/Android.mk to account for the new compilers on Android Master.
|
||||
|
||||
Removed the unused Host build from src/Android.mk.
|
||||
|
||||
Updated the android-rsync-excludes file to reflect the new source and sorted it
|
||||
alphabetically.
|
||||
|
||||
Updated Dr. gMock (which was again omitted from the release) to version 1.7.0.
|
||||
|
||||
--Wed Mar 20, 2013 (juce)--
|
||||
|
||||
Added the Dr. gMock script, which was missing from the 1.6.0 distribution.
|
||||
|
||||
--Mon Mar 4, 2013 (juce)--
|
||||
|
||||
Added this documentation
|
||||
|
||||
Added Android.mk and src/Android.mk files
|
||||
|
||||
Excluded the following files from being copied to Android repo:
|
||||
Makefile.in
|
||||
Makefile.am
|
||||
aclocal.m4
|
||||
CMakeLists.txt
|
||||
configure
|
||||
configure.ac
|
||||
build-aux/
|
||||
make/
|
||||
msvc/
|
||||
fused-src/
|
||||
gtest/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,147 +0,0 @@
|
||||
// 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 GTEST_API_ 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.
|
||||
GTEST_API_ Cardinality AtLeast(int n);
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n);
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber();
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max);
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ 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_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,821 +0,0 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-actions.h.
|
||||
$$
|
||||
$var n = 11 $$ The maximum arity we support.
|
||||
$$}} This meta comment fixes auto-indentation in editors.
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// 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
|
||||
|
||||
// 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& [[]]
|
||||
$if i == 1 [[/* args */]] $else [[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 { return MakeAction(new Impl<F>(action_)); }
|
||||
|
||||
private:
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(const InnerAction& action) : action_(action) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename SelectArgs<Result, ArgumentTuple,
|
||||
$ks>::type InnerFunctionType;
|
||||
|
||||
Action<InnerFunctionType> action_;
|
||||
};
|
||||
|
||||
const InnerAction action_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
|
||||
};
|
||||
|
||||
// A macro from the ACTION* family (defined later in this file)
|
||||
// defines an action that can be used in a mock function. Typically,
|
||||
// these actions only care about a subset of the arguments of the mock
|
||||
// function. For example, if such an action only uses the second
|
||||
// argument, it can be used in any mock function that takes >= 2
|
||||
// arguments where the type of the second argument is compatible.
|
||||
//
|
||||
// Therefore, the action implementation must be prepared to take more
|
||||
// arguments than it needs. The ExcessiveArg type is used to
|
||||
// represent those excessive arguments. In order to keep the compiler
|
||||
// error messages tractable, we define it in the testing namespace
|
||||
// instead of testing::internal. However, this is an INTERNAL TYPE
|
||||
// and subject to change without notice, so a user MUST NOT USE THIS
|
||||
// TYPE DIRECTLY.
|
||||
struct ExcessiveArg {};
|
||||
|
||||
// A helper class needed for implementing the ACTION* macros.
|
||||
template <typename Result, class Impl>
|
||||
class ActionHelper {
|
||||
public:
|
||||
$range i 0..n
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var template = [[$if i==0 [[]] $else [[
|
||||
$range j 0..i-1
|
||||
template <$for j, [[typename A$j]]>
|
||||
]]]]
|
||||
$range j 0..i-1
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var as = [[$for j, [[get<$j>(args)]]]]
|
||||
$range k 1..n-i
|
||||
$var eas = [[$for k, [[ExcessiveArg()]]]]
|
||||
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
|
||||
$template
|
||||
static Result Perform(Impl* impl, const ::std::tr1::tuple<$As>& args) {
|
||||
using ::std::tr1::get;
|
||||
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
|
||||
}
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// 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
|
||||
|
||||
// The ACTION* family of macros can be used in a namespace scope to
|
||||
// define custom actions easily. The syntax:
|
||||
//
|
||||
// ACTION(name) { statements; }
|
||||
//
|
||||
// will define an action with the given name that executes the
|
||||
// statements. The value returned by the statements will be used as
|
||||
// the return value of the action. Inside the statements, you can
|
||||
// refer to the K-th (0-based) argument of the mock function by
|
||||
// 'argK', and refer to its type by 'argK_type'. For example:
|
||||
//
|
||||
// ACTION(IncrementArg1) {
|
||||
// arg1_type temp = arg1;
|
||||
// return ++(*temp);
|
||||
// }
|
||||
//
|
||||
// allows you to write
|
||||
//
|
||||
// ...WillOnce(IncrementArg1());
|
||||
//
|
||||
// You can also refer to the entire argument tuple and its type by
|
||||
// 'args' and 'args_type', and refer to the mock function type and its
|
||||
// return type by 'function_type' and 'return_type'.
|
||||
//
|
||||
// Note that you don't need to specify the types of the mock function
|
||||
// arguments. However rest assured that your code is still type-safe:
|
||||
// you'll get a compiler error if *arg1 doesn't support the ++
|
||||
// operator, or if the type of ++(*arg1) isn't compatible with the
|
||||
// mock function's return type, for example.
|
||||
//
|
||||
// Sometimes you'll want to parameterize the action. For that you can use
|
||||
// another macro:
|
||||
//
|
||||
// ACTION_P(name, param_name) { statements; }
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// ACTION_P(Add, n) { return arg0 + n; }
|
||||
//
|
||||
// will allow you to write:
|
||||
//
|
||||
// ...WillOnce(Add(5));
|
||||
//
|
||||
// Note that you don't need to provide the type of the parameter
|
||||
// either. If you need to reference the type of a parameter named
|
||||
// 'foo', you can write 'foo_type'. For example, in the body of
|
||||
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
|
||||
// of 'n'.
|
||||
//
|
||||
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
|
||||
// multi-parameter actions.
|
||||
//
|
||||
// For the purpose of typing, you can view
|
||||
//
|
||||
// ACTION_Pk(Foo, p1, ..., pk) { ... }
|
||||
//
|
||||
// as shorthand for
|
||||
//
|
||||
// template <typename p1_type, ..., typename pk_type>
|
||||
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||
//
|
||||
// In particular, you can provide the template type arguments
|
||||
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
|
||||
// although usually you can rely on the compiler to infer the types
|
||||
// for you automatically. You can assign the result of expression
|
||||
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
|
||||
// pk_type>. This can be useful when composing actions.
|
||||
//
|
||||
// You can also overload actions with different numbers of parameters:
|
||||
//
|
||||
// ACTION_P(Plus, a) { ... }
|
||||
// ACTION_P2(Plus, a, b) { ... }
|
||||
//
|
||||
// While it's tempting to always use the ACTION* macros when defining
|
||||
// a new action, you should also consider implementing ActionInterface
|
||||
// or using MakePolymorphicAction() instead, especially if you need to
|
||||
// use the action a lot. While these approaches require more work,
|
||||
// they give you more control on the types of the mock function
|
||||
// arguments and the action parameters, which in general leads to
|
||||
// better compiler error messages that pay off in the long run. They
|
||||
// also allow overloading actions based on parameter types (as opposed
|
||||
// to just based on the number of parameters).
|
||||
//
|
||||
// CAVEAT:
|
||||
//
|
||||
// ACTION*() can only be used in a namespace scope. The reason is
|
||||
// that C++ doesn't yet allow function-local types to be used to
|
||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||
// Once that's done, we'll consider supporting using ACTION*() inside
|
||||
// a function.
|
||||
//
|
||||
// MORE INFORMATION:
|
||||
//
|
||||
// To learn more about using these macros, please search for 'ACTION'
|
||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||
|
||||
$range i 0..n
|
||||
$range k 0..n-1
|
||||
|
||||
// An internal macro needed for implementing ACTION*().
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
|
||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_
|
||||
$for k [[, \
|
||||
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
|
||||
|
||||
|
||||
// Sometimes you want to give an action explicit template parameters
|
||||
// that cannot be inferred from its value parameters. ACTION() and
|
||||
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||
//
|
||||
// The syntax:
|
||||
//
|
||||
// ACTION_TEMPLATE(ActionName,
|
||||
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||
//
|
||||
// defines an action template that takes m explicit template
|
||||
// parameters and n value parameters. name_i is the name of the i-th
|
||||
// template parameter, and kind_i specifies whether it's a typename,
|
||||
// an integral constant, or a template. p_i is the name of the i-th
|
||||
// value parameter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||
// // function to type T and copies it to *output.
|
||||
// ACTION_TEMPLATE(DuplicateArg,
|
||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||
// AND_1_VALUE_PARAMS(output)) {
|
||||
// *output = T(std::tr1::get<k>(args));
|
||||
// }
|
||||
// ...
|
||||
// int n;
|
||||
// EXPECT_CALL(mock, Foo(_, _))
|
||||
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||
//
|
||||
// To create an instance of an action template, write:
|
||||
//
|
||||
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||
//
|
||||
// where the ts are the template arguments and the vs are the value
|
||||
// arguments. The value argument types are inferred by the compiler.
|
||||
// If you want to explicitly specify the value argument types, you can
|
||||
// provide additional template arguments:
|
||||
//
|
||||
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||
//
|
||||
// where u_i is the desired type of v_i.
|
||||
//
|
||||
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||
// number of value parameters, but not on the number of template
|
||||
// parameters. Without the restriction, the meaning of the following
|
||||
// is unclear:
|
||||
//
|
||||
// OverloadedAction<int, bool>(x);
|
||||
//
|
||||
// Are we using a single-template-parameter action where 'bool' refers
|
||||
// to the type of x, or are we using a two-template-parameter action
|
||||
// where the compiler is asked to infer the type of x?
|
||||
//
|
||||
// Implementation notes:
|
||||
//
|
||||
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||
// new macro invocations when expanding a macro. For example, we have
|
||||
//
|
||||
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||
//
|
||||
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||
// to expand to
|
||||
//
|
||||
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||
//
|
||||
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||
// preprocessor will continue to expand it to
|
||||
//
|
||||
// ... typename T ...
|
||||
//
|
||||
// This technique conforms to the C++ standard and is portable. It
|
||||
// allows us to implement action templates using O(N) code, where N is
|
||||
// the maximum number of template/value parameters supported. Without
|
||||
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||
// combinations of m and n.
|
||||
|
||||
// Declares the template parameters.
|
||||
|
||||
$range j 1..n
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
|
||||
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the template parameters.
|
||||
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
|
||||
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the types of value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Initializes the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
|
||||
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the fields for storing the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_LIST_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the value parameter types.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||
$for j, [[p$j##_type p$j]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// The suffix of the class template implementing the action template.
|
||||
$for i [[
|
||||
|
||||
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||
$if i==1 [[P]] $elif i>=2 [[P$i]]
|
||||
]]
|
||||
|
||||
|
||||
// The name of the class template implementing the action template.
|
||||
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||
|
||||
$range k 0..n-1
|
||||
|
||||
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||
public:\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
public:\
|
||||
typedef F function_type;\
|
||||
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
||||
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
||||
args_type;\
|
||||
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
virtual return_type Perform(const args_type& args) {\
|
||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||
Perform(this, args);\
|
||||
}\
|
||||
template <$for k, [[typename arg$k[[]]_type]]>\
|
||||
return_type gmock_PerformImpl(const args_type& args[[]]
|
||||
$for k [[, arg$k[[]]_type arg$k]]) const;\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||
};\
|
||||
template <typename F> operator ::testing::Action<F>() const {\
|
||||
return ::testing::Action<F>(\
|
||||
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
||||
}\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
|
||||
};\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
||||
GMOCK_INTERNAL_DECL_##value_params) {\
|
||||
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
||||
GMOCK_INTERNAL_LIST_##value_params);\
|
||||
}\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
template <typename F>\
|
||||
template <typename arg0_type, typename arg1_type, typename arg2_type, \
|
||||
typename arg3_type, typename arg4_type, typename arg5_type, \
|
||||
typename arg6_type, typename arg7_type, typename arg8_type, \
|
||||
typename arg9_type, typename arg10_type>\
|
||||
typename ::testing::internal::Function<F>::Result\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
||||
gmock_PerformImpl(\
|
||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var template = [[$if i==0 [[]] $else [[
|
||||
$range j 0..i-1
|
||||
|
||||
template <$for j, [[typename p$j##_type]]>\
|
||||
]]]]
|
||||
$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
|
||||
$else [[P$i]]]]]]
|
||||
$range j 0..i-1
|
||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||
$var param_field_decls = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var param_field_decls2 = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var params = [[$for j, [[p$j]]]]
|
||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
|
||||
$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
|
||||
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
|
||||
$else [[ACTION_P$i]]]]
|
||||
|
||||
#define $macro_name(name$for j [[, p$j]])\$template
|
||||
class $class_name {\
|
||||
public:\
|
||||
$class_name($ctor_param_list)$inits {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
public:\
|
||||
typedef F function_type;\
|
||||
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
||||
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
||||
args_type;\
|
||||
[[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
|
||||
virtual return_type Perform(const args_type& args) {\
|
||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||
Perform(this, args);\
|
||||
}\
|
||||
template <$typename_arg_types>\
|
||||
return_type gmock_PerformImpl(const args_type& args, [[]]
|
||||
$arg_types_and_names) const;\$param_field_decls
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||
};\
|
||||
template <typename F> operator ::testing::Action<F>() const {\
|
||||
return ::testing::Action<F>(new gmock_Impl<F>($params));\
|
||||
}\$param_field_decls2
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||
};\$template
|
||||
inline $class_name$param_types name($param_types_and_names) {\
|
||||
return $class_name$param_types($params);\
|
||||
}\$template
|
||||
template <typename F>\
|
||||
template <$typename_arg_types>\
|
||||
typename ::testing::internal::Function<F>::Result\
|
||||
$class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\
|
||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||
]]
|
||||
$$ } // This meta comment fixes auto-indentation in Emacs. It won't
|
||||
$$ // show up in the generated code.
|
||||
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
|
||||
ACTION_TEMPLATE(InvokeArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
|
||||
return internal::CallableHelper<return_type>::Call(
|
||||
::std::tr1::get<k>(args)$for j [[, p$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// Various overloads for ReturnNew<T>().
|
||||
//
|
||||
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
|
||||
// instance of type T, constructed on the heap with constructor arguments
|
||||
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
$var ps = [[$for j, [[p$j]]]]
|
||||
|
||||
ACTION_TEMPLATE(ReturnNew,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
AND_$i[[]]_VALUE_PARAMS($ps)) {
|
||||
return new T($ps);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,265 +0,0 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 11 $$ 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 {
|
||||
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) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->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;
|
||||
|
||||
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
|
||||
// We define this as a variadic macro in case F contains unprotected
|
||||
// commas (the same reason that we use variadic macros in other places
|
||||
// in this file).
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT_(tn, ...) \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::Result
|
||||
|
||||
// The type of argument N of the given function type.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG_(tn, N, ...) \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
|
||||
|
||||
// The matcher type for argument N of the given function type.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER_(tn, N, ...) \
|
||||
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
|
||||
|
||||
// The variable for mocking the given method.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var arg_as = [[$for j, \
|
||||
[[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||
$var as = [[$for j, [[gmock_a$j]]]]
|
||||
$var matcher_as = [[$for j, \
|
||||
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
$arg_as) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
|
||||
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
|
||||
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method($matcher_as) constness { \
|
||||
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_($i, constness, Method).With($as); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
|
||||
|
||||
|
||||
]]
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
// A MockFunction<F> class has one mock method whose type is F. It is
|
||||
// useful when you just want your test code to emit some messages and
|
||||
// have Google Mock verify the right messages are sent (and perhaps at
|
||||
// the right times). For example, if you are exercising code:
|
||||
//
|
||||
// Foo(1);
|
||||
// Foo(2);
|
||||
// Foo(3);
|
||||
//
|
||||
// and want to verify that Foo(1) and Foo(3) both invoke
|
||||
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
||||
//
|
||||
// TEST(FooTest, InvokesBarCorrectly) {
|
||||
// MyMock mock;
|
||||
// MockFunction<void(string check_point_name)> check;
|
||||
// {
|
||||
// InSequence s;
|
||||
//
|
||||
// EXPECT_CALL(mock, Bar("a"));
|
||||
// EXPECT_CALL(check, Call("1"));
|
||||
// EXPECT_CALL(check, Call("2"));
|
||||
// EXPECT_CALL(mock, Bar("a"));
|
||||
// }
|
||||
// Foo(1);
|
||||
// check.Call("1");
|
||||
// Foo(2);
|
||||
// check.Call("2");
|
||||
// Foo(3);
|
||||
// }
|
||||
//
|
||||
// The expectation spec says that the first Bar("a") must happen
|
||||
// before check point "1", the second Bar("a") must happen after check
|
||||
// point "2", and nothing should happen between the two check
|
||||
// points. The explicit check points make it easy to tell which
|
||||
// Bar("a") is called by which call to Foo().
|
||||
template <typename F>
|
||||
class MockFunction;
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
template <typename R$for j [[, typename A$j]]>
|
||||
class MockFunction<R($for j, [[A$j]])> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,674 +0,0 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-actions.h.
|
||||
$$
|
||||
$var n = 11 $$ The maximum arity we support.
|
||||
$$ }} This line fixes auto-indentation of the following code in Emacs.
|
||||
// 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 <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "gmock/gmock-matchers.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
$range i 0..n-1
|
||||
|
||||
// The type of the i-th (0-based) field of Tuple.
|
||||
#define GMOCK_FIELD_TYPE_(Tuple, i) \
|
||||
typename ::std::tr1::tuple_element<i, Tuple>::type
|
||||
|
||||
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
|
||||
// tuple of type Tuple. It has two members:
|
||||
//
|
||||
// type: a tuple type whose i-th field is the ki-th field of Tuple.
|
||||
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
|
||||
//
|
||||
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
|
||||
//
|
||||
// type is tuple<int, bool>, and
|
||||
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
|
||||
|
||||
template <class Tuple$for i [[, int k$i = -1]]>
|
||||
class TupleFields;
|
||||
|
||||
// This generic version is used when there are $n selectors.
|
||||
template <class Tuple$for i [[, int k$i]]>
|
||||
class TupleFields {
|
||||
public:
|
||||
typedef ::std::tr1::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
|
||||
static type GetSelectedFields(const Tuple& t) {
|
||||
using ::std::tr1::get;
|
||||
return type($for i, [[get<k$i>(t)]]);
|
||||
}
|
||||
};
|
||||
|
||||
// The following specialization is used for 0 ~ $(n-1) selectors.
|
||||
|
||||
$for i [[
|
||||
$$ }}}
|
||||
$range j 0..i-1
|
||||
$range k 0..n-1
|
||||
|
||||
template <class Tuple$for j [[, int k$j]]>
|
||||
class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
|
||||
public:
|
||||
typedef ::std::tr1::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
|
||||
static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) {
|
||||
using ::std::tr1::get;
|
||||
return type($for j, [[get<k$j>(t)]]);
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
#undef GMOCK_FIELD_TYPE_
|
||||
|
||||
// Implements the Args() matcher.
|
||||
|
||||
$var ks = [[$for i, [[k$i]]]]
|
||||
template <class ArgsTuple$for i [[, int k$i = -1]]>
|
||||
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
||||
public:
|
||||
// ArgsTuple may have top-level const or reference modifiers.
|
||||
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
|
||||
typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
|
||||
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
|
||||
|
||||
template <typename InnerMatcher>
|
||||
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
||||
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
||||
|
||||
virtual bool MatchAndExplain(ArgsTuple args,
|
||||
MatchResultListener* listener) const {
|
||||
const SelectedArgs& selected_args = GetSelectedArgs(args);
|
||||
if (!listener->IsInterested())
|
||||
return inner_matcher_.Matches(selected_args);
|
||||
|
||||
PrintIndices(listener->stream());
|
||||
*listener << "are " << PrintToString(selected_args);
|
||||
|
||||
StringMatchResultListener inner_listener;
|
||||
const bool match = inner_matcher_.MatchAndExplain(selected_args,
|
||||
&inner_listener);
|
||||
PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
||||
return match;
|
||||
}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "are a tuple ";
|
||||
PrintIndices(os);
|
||||
inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "are a tuple ";
|
||||
PrintIndices(os);
|
||||
inner_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
||||
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
|
||||
}
|
||||
|
||||
// Prints the indices of the selected fields.
|
||||
static void PrintIndices(::std::ostream* os) {
|
||||
*os << "whose fields (";
|
||||
const int indices[$n] = { $ks };
|
||||
for (int i = 0; i < $n; i++) {
|
||||
if (indices[i] < 0)
|
||||
break;
|
||||
|
||||
if (i >= 1)
|
||||
*os << ", ";
|
||||
|
||||
*os << "#" << indices[i];
|
||||
}
|
||||
*os << ") ";
|
||||
}
|
||||
|
||||
const MonomorphicInnerMatcher inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
|
||||
};
|
||||
|
||||
template <class InnerMatcher$for i [[, int k$i = -1]]>
|
||||
class ArgsMatcher {
|
||||
public:
|
||||
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
|
||||
: inner_matcher_(inner_matcher) {}
|
||||
|
||||
template <typename ArgsTuple>
|
||||
operator Matcher<ArgsTuple>() const {
|
||||
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
const InnerMatcher inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
|
||||
};
|
||||
|
||||
// A set of metafunctions for computing the result type of AllOf.
|
||||
// AllOf(m1, ..., mN) returns
|
||||
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
||||
|
||||
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
|
||||
// to simplify the implementation.
|
||||
template <typename M1>
|
||||
struct AllOfResult1 {
|
||||
typedef M1 type;
|
||||
};
|
||||
|
||||
$range i 1..n
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <typename M1$for j [[, typename M$j]]>
|
||||
struct AllOfResult$i {
|
||||
typedef BothOfMatcher<
|
||||
typename AllOfResult$m<$for k, [[M$k]]>::type,
|
||||
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// A set of metafunctions for computing the result type of AnyOf.
|
||||
// AnyOf(m1, ..., mN) returns
|
||||
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
||||
|
||||
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
|
||||
// to simplify the implementation.
|
||||
template <typename M1>
|
||||
struct AnyOfResult1 {
|
||||
typedef M1 type;
|
||||
};
|
||||
|
||||
$range i 1..n
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <typename M1$for j [[, typename M$j]]>
|
||||
struct AnyOfResult$i {
|
||||
typedef EitherOfMatcher<
|
||||
typename AnyOfResult$m<$for k, [[M$k]]>::type,
|
||||
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
|
||||
// fields of it matches a_matcher. C++ doesn't support default
|
||||
// arguments for function templates, so we have to overload it.
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j [[int k$j, ]]typename InnerMatcher>
|
||||
inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
|
||||
Args(const InnerMatcher& matcher) {
|
||||
return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
|
||||
// n 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.
|
||||
//
|
||||
// The use of DecayArray in the implementation allows ElementsAre()
|
||||
// to accept string literals, whose type is const char[N], but we
|
||||
// want to treat them as const char*.
|
||||
//
|
||||
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
||||
// must not be used with containers whose elements's order is
|
||||
// undefined (e.g. hash_map).
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
|
||||
$range j 1..i
|
||||
|
||||
$if i>0 [[
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
]]
|
||||
|
||||
inline internal::ElementsAreMatcher<
|
||||
std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> >
|
||||
ElementsAre($for j, [[const T$j& e$j]]) {
|
||||
typedef std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
||||
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
|
||||
// that matches n elements in any order. We support up to n=$n arguments.
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
|
||||
$range j 1..i
|
||||
|
||||
$if i>0 [[
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
]]
|
||||
|
||||
inline internal::UnorderedElementsAreMatcher<
|
||||
std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> >
|
||||
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
|
||||
typedef std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
||||
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
|
||||
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <$for j, [[typename M$j]]>
|
||||
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
|
||||
AllOf($for j, [[M$j m$j]]) {
|
||||
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
|
||||
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
|
||||
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
|
||||
// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <$for j, [[typename M$j]]>
|
||||
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
|
||||
AnyOf($for j, [[M$j m$j]]) {
|
||||
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
|
||||
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
|
||||
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
|
||||
$$ // show up in the generated code.
|
||||
|
||||
|
||||
// The MATCHER* family of macros can be used in a namespace scope to
|
||||
// define custom matchers easily.
|
||||
//
|
||||
// Basic Usage
|
||||
// ===========
|
||||
//
|
||||
// The syntax
|
||||
//
|
||||
// MATCHER(name, description_string) { statements; }
|
||||
//
|
||||
// defines a matcher with the given name that executes the statements,
|
||||
// which must return a bool to indicate if the match succeeds. Inside
|
||||
// the statements, you can refer to the value being matched by 'arg',
|
||||
// and refer to its type by 'arg_type'.
|
||||
//
|
||||
// The description string documents what the matcher does, and is used
|
||||
// to generate the failure message when the match fails. Since a
|
||||
// MATCHER() is usually defined in a header file shared by multiple
|
||||
// C++ source files, we require the description to be a C-string
|
||||
// literal to avoid possible side effects. It can be empty, in which
|
||||
// case we'll use the sequence of words in the matcher name as the
|
||||
// description.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
|
||||
//
|
||||
// allows you to write
|
||||
//
|
||||
// // Expects mock_foo.Bar(n) to be called where n is even.
|
||||
// EXPECT_CALL(mock_foo, Bar(IsEven()));
|
||||
//
|
||||
// or,
|
||||
//
|
||||
// // Verifies that the value of some_expression is even.
|
||||
// EXPECT_THAT(some_expression, IsEven());
|
||||
//
|
||||
// If the above assertion fails, it will print something like:
|
||||
//
|
||||
// Value of: some_expression
|
||||
// Expected: is even
|
||||
// Actual: 7
|
||||
//
|
||||
// where the description "is even" is automatically calculated from the
|
||||
// matcher name IsEven.
|
||||
//
|
||||
// Argument Type
|
||||
// =============
|
||||
//
|
||||
// Note that the type of the value being matched (arg_type) is
|
||||
// determined by the context in which you use the matcher and is
|
||||
// supplied to you by the compiler, so you don't need to worry about
|
||||
// declaring it (nor can you). This allows the matcher to be
|
||||
// polymorphic. For example, IsEven() can be used to match any type
|
||||
// where the value of "(arg % 2) == 0" can be implicitly converted to
|
||||
// a bool. In the "Bar(IsEven())" example above, if method Bar()
|
||||
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
||||
// 'arg_type' will be unsigned long; and so on.
|
||||
//
|
||||
// Parameterizing Matchers
|
||||
// =======================
|
||||
//
|
||||
// Sometimes you'll want to parameterize the matcher. For that you
|
||||
// can use another macro:
|
||||
//
|
||||
// MATCHER_P(name, param_name, description_string) { statements; }
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
|
||||
//
|
||||
// will allow you to write:
|
||||
//
|
||||
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
|
||||
//
|
||||
// which may lead to this message (assuming n is 10):
|
||||
//
|
||||
// Value of: Blah("a")
|
||||
// Expected: has absolute value 10
|
||||
// Actual: -9
|
||||
//
|
||||
// Note that both the matcher description and its parameter are
|
||||
// printed, making the message human-friendly.
|
||||
//
|
||||
// In the matcher definition body, you can write 'foo_type' to
|
||||
// reference the type of a parameter named 'foo'. For example, in the
|
||||
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
|
||||
// 'value_type' to refer to the type of 'value'.
|
||||
//
|
||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
|
||||
// support multi-parameter matchers.
|
||||
//
|
||||
// Describing Parameterized Matchers
|
||||
// =================================
|
||||
//
|
||||
// The last argument to MATCHER*() is a string-typed expression. The
|
||||
// expression can reference all of the matcher's parameters and a
|
||||
// special bool-typed variable named 'negation'. When 'negation' is
|
||||
// false, the expression should evaluate to the matcher's description;
|
||||
// otherwise it should evaluate to the description of the negation of
|
||||
// the matcher. For example,
|
||||
//
|
||||
// using testing::PrintToString;
|
||||
//
|
||||
// MATCHER_P2(InClosedRange, low, hi,
|
||||
// string(negation ? "is not" : "is") + " in range [" +
|
||||
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
|
||||
// return low <= arg && arg <= hi;
|
||||
// }
|
||||
// ...
|
||||
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
|
||||
//
|
||||
// would generate two failures that contain the text:
|
||||
//
|
||||
// Expected: is in range [4, 6]
|
||||
// ...
|
||||
// Expected: is not in range [2, 4]
|
||||
//
|
||||
// If you specify "" as the description, the failure message will
|
||||
// contain the sequence of words in the matcher name followed by the
|
||||
// parameter values printed as a tuple. For example,
|
||||
//
|
||||
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
|
||||
// ...
|
||||
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
|
||||
//
|
||||
// would generate two failures that contain the text:
|
||||
//
|
||||
// Expected: in closed range (4, 6)
|
||||
// ...
|
||||
// Expected: not (in closed range (2, 4))
|
||||
//
|
||||
// Types of Matcher Parameters
|
||||
// ===========================
|
||||
//
|
||||
// For the purpose of typing, you can view
|
||||
//
|
||||
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
||||
//
|
||||
// as shorthand for
|
||||
//
|
||||
// template <typename p1_type, ..., typename pk_type>
|
||||
// FooMatcherPk<p1_type, ..., pk_type>
|
||||
// Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||
//
|
||||
// When you write Foo(v1, ..., vk), the compiler infers the types of
|
||||
// the parameters v1, ..., and vk for you. If you are not happy with
|
||||
// the result of the type inference, you can specify the types by
|
||||
// explicitly instantiating the template, as in Foo<long, bool>(5,
|
||||
// false). As said earlier, you don't get to (or need to) specify
|
||||
// 'arg_type' as that's determined by the context in which the matcher
|
||||
// is used. You can assign the result of expression Foo(p1, ..., pk)
|
||||
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
|
||||
// can be useful when composing matchers.
|
||||
//
|
||||
// While you can instantiate a matcher template with reference types,
|
||||
// passing the parameters by pointer usually makes your code more
|
||||
// readable. If, however, you still want to pass a parameter by
|
||||
// reference, be aware that in the failure message generated by the
|
||||
// matcher you will see the value of the referenced object but not its
|
||||
// address.
|
||||
//
|
||||
// Explaining Match Results
|
||||
// ========================
|
||||
//
|
||||
// Sometimes the matcher description alone isn't enough to explain why
|
||||
// the match has failed or succeeded. For example, when expecting a
|
||||
// long string, it can be very helpful to also print the diff between
|
||||
// the expected string and the actual one. To achieve that, you can
|
||||
// optionally stream additional information to a special variable
|
||||
// named result_listener, whose type is a pointer to class
|
||||
// MatchResultListener:
|
||||
//
|
||||
// MATCHER_P(EqualsLongString, str, "") {
|
||||
// if (arg == str) return true;
|
||||
//
|
||||
// *result_listener << "the difference: "
|
||||
/// << DiffStrings(str, arg);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// Overloading Matchers
|
||||
// ====================
|
||||
//
|
||||
// You can overload matchers with different numbers of parameters:
|
||||
//
|
||||
// MATCHER_P(Blah, a, description_string1) { ... }
|
||||
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
||||
//
|
||||
// Caveats
|
||||
// =======
|
||||
//
|
||||
// When defining a new matcher, you should also consider implementing
|
||||
// MatcherInterface or using MakePolymorphicMatcher(). These
|
||||
// approaches require more work than the MATCHER* macros, but also
|
||||
// give you more control on the types of the value being matched and
|
||||
// the matcher parameters, which may leads to better compiler error
|
||||
// messages when the matcher is used wrong. They also allow
|
||||
// overloading matchers based on parameter types (as opposed to just
|
||||
// based on the number of parameters).
|
||||
//
|
||||
// MATCHER*() can only be used in a namespace scope. The reason is
|
||||
// that C++ doesn't yet allow function-local types to be used to
|
||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||
// Once that's done, we'll consider supporting using MATCHER*() inside
|
||||
// a function.
|
||||
//
|
||||
// More Information
|
||||
// ================
|
||||
//
|
||||
// To learn more about using these macros, please search for 'MATCHER'
|
||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||
|
||||
$range i 0..n
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
|
||||
$else [[MATCHER_P$i]]]]
|
||||
$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
|
||||
$else [[P$i]]]]]]
|
||||
$range j 0..i-1
|
||||
$var template = [[$if i==0 [[]] $else [[
|
||||
|
||||
template <$for j, [[typename p$j##_type]]>\
|
||||
]]]]
|
||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||
$var params = [[$for j, [[p$j]]]]
|
||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||
$var param_field_decls = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var param_field_decls2 = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
|
||||
#define $macro_name(name$for j [[, p$j]], description)\$template
|
||||
class $class_name {\
|
||||
public:\
|
||||
template <typename arg_type>\
|
||||
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
|
||||
public:\
|
||||
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
|
||||
$impl_inits {}\
|
||||
virtual bool MatchAndExplain(\
|
||||
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||
*gmock_os << FormatDescription(false);\
|
||||
}\
|
||||
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
|
||||
*gmock_os << FormatDescription(true);\
|
||||
}\$param_field_decls
|
||||
private:\
|
||||
::testing::internal::string FormatDescription(bool negation) const {\
|
||||
const ::testing::internal::string gmock_description = (description);\
|
||||
if (!gmock_description.empty())\
|
||||
return gmock_description;\
|
||||
return ::testing::internal::FormatMatcherDescription(\
|
||||
negation, #name, \
|
||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
|
||||
}\
|
||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||
};\
|
||||
template <typename arg_type>\
|
||||
operator ::testing::Matcher<arg_type>() const {\
|
||||
return ::testing::Matcher<arg_type>(\
|
||||
new gmock_Impl<arg_type>($params));\
|
||||
}\
|
||||
$class_name($ctor_param_list)$inits {\
|
||||
}\$param_field_decls2
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||
};\$template
|
||||
inline $class_name$param_types name($param_types_and_names) {\
|
||||
return $class_name$param_types($params);\
|
||||
}\$template
|
||||
template <typename arg_type>\
|
||||
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||
arg_type arg, \
|
||||
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||
const
|
||||
]]
|
||||
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
@@ -1,430 +0,0 @@
|
||||
// This file was GENERATED by command:
|
||||
// pump.py gmock-generated-nice-strict.h.pump
|
||||
// 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, NaggyMock, 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), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||
// that prints a warning when an uninteresting call occurs, and
|
||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||
// uninteresting calls as errors.
|
||||
//
|
||||
// Currently a mock is naggy by default, so MockFoo and
|
||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||
// switch the default behavior of mocks to be nice, as that in general
|
||||
// leads to more maintainable tests. When that happens, MockFoo will
|
||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||
// NiceMock<MockFoo>.
|
||||
//
|
||||
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||
// their respective base class, with up-to 11 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>, NaggyMock<MockFoo>,
|
||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||
// or "strict" modifier may not affect it, depending on the compiler.
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// 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() {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
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) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10,
|
||||
typename A11>
|
||||
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, const A11& a11) : MockClass(a1, a2, a3, a4, a5, a6, a7,
|
||||
a8, a9, a10, a11) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~NiceMock() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class NaggyMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NaggyMock() {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NaggyMock(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3,
|
||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10,
|
||||
typename A11>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10, const A11& a11) : MockClass(a1, a2, a3, a4, a5, a6, a7,
|
||||
a8, a9, a10, a11) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~NaggyMock() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class StrictMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
StrictMock() {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
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) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10,
|
||||
typename A11>
|
||||
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, const A11& a11) : MockClass(a1, a2, a3, a4, a5, a6, a7,
|
||||
a8, a9, a10, a11) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~StrictMock() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
||||
};
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock,
|
||||
// NaggyMock, and StrictMock cannot be nested.
|
||||
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
@@ -1,161 +0,0 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-nice-strict.h.
|
||||
$$
|
||||
$var n = 11 $$ 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, NaggyMock, 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), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||
// that prints a warning when an uninteresting call occurs, and
|
||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||
// uninteresting calls as errors.
|
||||
//
|
||||
// Currently a mock is naggy by default, so MockFoo and
|
||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||
// switch the default behavior of mocks to be nice, as that in general
|
||||
// leads to more maintainable tests. When that happens, MockFoo will
|
||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||
// NiceMock<MockFoo>.
|
||||
//
|
||||
// NiceMock, NaggyMock, and StrictMock "inherit" 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>, NaggyMock<MockFoo>,
|
||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||
// or "strict" modifier may not affect it, depending on the compiler.
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// 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 {
|
||||
|
||||
$range kind 0..2
|
||||
$for kind [[
|
||||
|
||||
$var clazz=[[$if kind==0 [[NiceMock]]
|
||||
$elif kind==1 [[NaggyMock]]
|
||||
$else [[StrictMock]]]]
|
||||
|
||||
$var method=[[$if kind==0 [[AllowUninterestingCalls]]
|
||||
$elif kind==1 [[WarnUninterestingCalls]]
|
||||
$else [[FailUninterestingCalls]]]]
|
||||
|
||||
template <class MockClass>
|
||||
class $clazz : 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.
|
||||
$clazz() {
|
||||
::testing::Mock::$method(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit $clazz(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::$method(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename A$j]]>
|
||||
$clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||
::testing::Mock::$method(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
virtual ~$clazz() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// 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,
|
||||
// NaggyMock, and StrictMock cannot be nested.
|
||||
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +0,0 @@
|
||||
// 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 actions that depend on gmock-generated-actions.h.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "gmock/gmock-generated-actions.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// 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_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(InvokeAction);
|
||||
};
|
||||
|
||||
// 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_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
|
||||
};
|
||||
|
||||
} // 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));
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
// Action ReturnArg<k>() returns the k-th argument of the mock function.
|
||||
ACTION_TEMPLATE(ReturnArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
return std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||
// mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArgPointee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = *::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||
// referenced by the k-th (0-based) argument of the mock function.
|
||||
ACTION_TEMPLATE(SetArgReferee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(value)) {
|
||||
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
|
||||
// Ensures that argument #k is a reference. If you get a compiler
|
||||
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||
// a mock function whose k-th (0-based) argument is not a reference.
|
||||
GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
||||
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||
::std::tr1::get<k>(args) = value;
|
||||
}
|
||||
|
||||
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||
// source range [first, last) to the array pointed to by the k-th
|
||||
// (0-based) argument, which can be either a pointer or an
|
||||
// iterator. The action does not take ownership of the elements in the
|
||||
// source range.
|
||||
ACTION_TEMPLATE(SetArrayArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_2_VALUE_PARAMS(first, last)) {
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push) // Saves the current warning state.
|
||||
# pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif
|
||||
::std::copy(first, last, ::std::tr1::get<k>(args));
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop) // Restores the warning state.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
|
||||
// function.
|
||||
ACTION_TEMPLATE(DeleteArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
delete ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// This action returns the value pointed to by 'pointer'.
|
||||
ACTION_P(ReturnPointee, pointer) { return *pointer; }
|
||||
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Suppresses the 'unreachable code' warning that VC generates in opt modes.
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(push) // Saves the current warning state.
|
||||
# pragma warning(disable:4702) // Temporarily disables warning 4702.
|
||||
# endif
|
||||
ACTION_P(Throw, exception) { throw exception; }
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(pop) // Restores the warning state.
|
||||
# endif
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright 2013, 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: marcus.boerger@google.com (Marcus Boerger)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some matchers that depend on gmock-generated-matchers.h.
|
||||
//
|
||||
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||
// gmock-more-matchers-test.cc.
|
||||
|
||||
#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
#define GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Defines a matcher that matches an empty container. The container must
|
||||
// support both size() and empty(), which all STL-like containers provide.
|
||||
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
|
||||
if (arg.empty()) {
|
||||
return true;
|
||||
}
|
||||
*result_listener << "whose size is " << arg.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,94 +0,0 @@
|
||||
// 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(...))
|
||||
// .With(...) ?
|
||||
// .WillByDefault(...);
|
||||
//
|
||||
// where With() is optional and WillByDefault() must appear exactly
|
||||
// once.
|
||||
//
|
||||
// EXPECT_CALL(mock_object.Method(...))
|
||||
// .With(...) ?
|
||||
// .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-nice-strict.h"
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||
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.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv);
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
@@ -1,303 +0,0 @@
|
||||
// This file was GENERATED by command:
|
||||
// pump.py gmock-generated-internal-utils.h.pump
|
||||
// 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& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||
};
|
||||
|
||||
// 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 <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10,
|
||||
typename A11>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
|
||||
A11> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
||||
Matcher<A10>, Matcher<A11> > 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);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10, typename A11>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
|
||||
typedef A11 Argument11;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
|
||||
A11> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9, A10, A11);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
@@ -1,136 +0,0 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 11 $$ 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& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||
};
|
||||
|
||||
// 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_
|
||||
@@ -1,498 +0,0 @@
|
||||
// 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"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// 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 const 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();
|
||||
}
|
||||
};
|
||||
|
||||
// Symbian compilation can be done with wchar_t being either a native
|
||||
// type or a typedef. Using Google Mock with OpenC without wchar_t
|
||||
// should require the definition of _STLP_NO_WCHAR_T.
|
||||
//
|
||||
// MSVC 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. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||
// is a native type.
|
||||
#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
|
||||
(defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
|
||||
// wchar_t is a typedef.
|
||||
#else
|
||||
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#ifdef __GNUC__
|
||||
// signed/unsigned wchar_t are valid types.
|
||||
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
|
||||
#endif
|
||||
|
||||
// In what follows, we use the term "kind" to indicate whether a type
|
||||
// is bool, an integer type (excluding bool), a floating-point type,
|
||||
// or none of them. This categorization is useful for determining
|
||||
// when a matcher argument type can be safely converted to another
|
||||
// type in the implementation of SafeMatcherCast.
|
||||
enum TypeKind {
|
||||
kBool, kInteger, kFloatingPoint, kOther
|
||||
};
|
||||
|
||||
// KindOf<T>::value is the kind of type T.
|
||||
template <typename T> struct KindOf {
|
||||
enum { value = kOther }; // The default kind.
|
||||
};
|
||||
|
||||
// This macro declares that the kind of 'type' is 'kind'.
|
||||
#define GMOCK_DECLARE_KIND_(type, kind) \
|
||||
template <> struct KindOf<type> { enum { value = kind }; }
|
||||
|
||||
GMOCK_DECLARE_KIND_(bool, kBool);
|
||||
|
||||
// All standard integer types.
|
||||
GMOCK_DECLARE_KIND_(char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(signed char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
|
||||
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||
#endif
|
||||
|
||||
// Non-standard integer types.
|
||||
GMOCK_DECLARE_KIND_(Int64, kInteger);
|
||||
GMOCK_DECLARE_KIND_(UInt64, kInteger);
|
||||
|
||||
// All standard floating-point types.
|
||||
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
||||
|
||||
#undef GMOCK_DECLARE_KIND_
|
||||
|
||||
// Evaluates to the kind of 'type'.
|
||||
#define GMOCK_KIND_OF_(type) \
|
||||
static_cast< ::testing::internal::TypeKind>( \
|
||||
::testing::internal::KindOf<type>::value)
|
||||
|
||||
// Evaluates to true iff integer type T is signed.
|
||||
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
|
||||
|
||||
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||
// is true iff arithmetic type From can be losslessly converted to
|
||||
// arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types, kFromKind is the kind of
|
||||
// From, and kToKind is the kind of To; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl : public false_type {};
|
||||
|
||||
// Converting bool to bool is lossless.
|
||||
template <>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting bool to any integer type is lossless.
|
||||
template <typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting bool to any floating-point type is lossless.
|
||||
template <typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting an integer to bool is lossy.
|
||||
template <typename From>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting an integer to another non-bool integer is lossless iff
|
||||
// the target type's range encloses the source type's range.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
||||
: public bool_constant<
|
||||
// When converting from a smaller size to a larger size, we are
|
||||
// fine as long as we are not converting from signed to unsigned.
|
||||
((sizeof(From) < sizeof(To)) &&
|
||||
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
|
||||
// When converting between the same size, the signedness must match.
|
||||
((sizeof(From) == sizeof(To)) &&
|
||||
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
|
||||
|
||||
#undef GMOCK_IS_SIGNED_
|
||||
|
||||
// Converting an integer to a floating-point type may be lossy, since
|
||||
// the format of a floating-point number is implementation-defined.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to bool is lossy.
|
||||
template <typename From>
|
||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to an integer is lossy.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to another floating-point is lossless
|
||||
// iff the target type is at least as big as the source type.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<
|
||||
kFloatingPoint, From, kFloatingPoint, To>
|
||||
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
|
||||
|
||||
// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
|
||||
// type From can be losslessly converted to arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertible
|
||||
: public LosslessArithmeticConvertibleImpl<
|
||||
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
|
||||
|
||||
// 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 {
|
||||
kNonfatal, kFatal
|
||||
};
|
||||
|
||||
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.
|
||||
GTEST_API_ 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::kFatal,
|
||||
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::kNonfatal,
|
||||
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 {
|
||||
kInfo = 0,
|
||||
kWarning = 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";
|
||||
|
||||
// Returns true iff a log with the given severity is visible according
|
||||
// to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// 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.
|
||||
GTEST_API_ void Log(LogSeverity severity,
|
||||
const string& message,
|
||||
int stack_frames_to_skip);
|
||||
|
||||
// TODO(wan@google.com): group all type utilities together.
|
||||
|
||||
// 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; }; // NOLINT
|
||||
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
|
||||
|
||||
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
|
||||
// other types. Useful for saving a copy of a function argument.
|
||||
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
|
||||
template <typename T, size_t N> struct DecayArray<T[N]> {
|
||||
typedef const T* type;
|
||||
};
|
||||
// Sometimes people use arrays whose size is not available at the use site
|
||||
// (e.g. extern const char kNamePrefix[]). This specialization covers that
|
||||
// case.
|
||||
template <typename T> struct DecayArray<T[]> {
|
||||
typedef const T* type;
|
||||
};
|
||||
|
||||
// Invalid<T>() returns an invalid value of type T. This is useful
|
||||
// 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 const_cast<typename remove_reference<T>::type&>(
|
||||
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
|
||||
}
|
||||
template <>
|
||||
inline void Invalid<void>() {}
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
// following members:
|
||||
//
|
||||
// - type is a type that provides an STL-style container view to
|
||||
// (i.e. implements the STL container concept for) RawContainer;
|
||||
// - const_reference is a type that provides a reference to a const
|
||||
// RawContainer;
|
||||
// - ConstReference(raw_container) returns a const reference to an STL-style
|
||||
// container view to raw_container, which is a RawContainer.
|
||||
// - Copy(raw_container) returns an STL-style container view of a
|
||||
// copy of raw_container, which is a RawContainer.
|
||||
//
|
||||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
|
||||
static const_reference ConstReference(const RawContainer& container) {
|
||||
// Ensures that RawContainer is not a const type.
|
||||
testing::StaticAssertTypeEq<RawContainer,
|
||||
GTEST_REMOVE_CONST_(RawContainer)>();
|
||||
return container;
|
||||
}
|
||||
static type Copy(const RawContainer& container) { return container; }
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef GTEST_REMOVE_CONST_(Element) RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
// NativeArray<T> can represent a native array either by value or by
|
||||
// reference (selected by a constructor argument), so 'const type'
|
||||
// can be used to reference a const native array. We cannot
|
||||
// 'typedef const type& const_reference' here, as that would mean
|
||||
// ConstReference() has to return a reference to a local variable.
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(const Element (&array)[N]) {
|
||||
// Ensures that Element is not a const type.
|
||||
testing::StaticAssertTypeEq<Element, RawElement>();
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// The Nokia Symbian compiler confuses itself in template instantiation
|
||||
// for this call without the cast to Element*:
|
||||
// function call '[testing::internal::NativeArray<char *>].NativeArray(
|
||||
// {lval} const char *[4], long, testing::internal::RelationToSource)'
|
||||
// does not match
|
||||
// 'testing::internal::NativeArray<char *>::NativeArray(
|
||||
// char *const *, unsigned int, testing::internal::RelationToSource)'
|
||||
// (instantiating: 'testing::internal::ContainsMatcherImpl
|
||||
// <const char * (&)[4]>::Matches(const char * (&)[4]) const')
|
||||
// (instantiating: 'testing::internal::StlContainerView<char *[4]>::
|
||||
// ConstReference(const char * (&)[4])')
|
||||
// (and though the N parameter type is mismatched in the above explicit
|
||||
// conversion of it doesn't help - only the conversion of the array).
|
||||
return type(const_cast<Element*>(&array[0]), N, kReference);
|
||||
#else
|
||||
return type(array, N, kReference);
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
}
|
||||
static type Copy(const Element (&array)[N]) {
|
||||
#if GTEST_OS_SYMBIAN
|
||||
return type(const_cast<Element*>(&array[0]), N, kCopy);
|
||||
#else
|
||||
return type(array, N, kCopy);
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
}
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array
|
||||
// represented as a (pointer, size) tuple.
|
||||
template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef GTEST_REMOVE_CONST_(
|
||||
typename internal::PointeeOf<ElementPointer>::type) RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(
|
||||
const ::std::tr1::tuple<ElementPointer, Size>& array) {
|
||||
using ::std::tr1::get;
|
||||
return type(get<0>(array), get<1>(array), kReference);
|
||||
}
|
||||
static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) {
|
||||
using ::std::tr1::get;
|
||||
return type(get<0>(array), get<1>(array), kCopy);
|
||||
}
|
||||
};
|
||||
|
||||
// The following specialization prevents the user from instantiating
|
||||
// StlContainer with a reference type.
|
||||
template <typename T> class StlContainerView<T&>;
|
||||
|
||||
// A type transform to remove constness from the first part of a pair.
|
||||
// Pairs like that are used as the value_type of associative containers,
|
||||
// and this transform produces a similar but assignable pair.
|
||||
template <typename T>
|
||||
struct RemoveConstFromKey {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// Partially specialized to remove constness from std::pair<const K, V>.
|
||||
template <typename K, typename V>
|
||||
struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
typedef std::pair<K, V> type;
|
||||
};
|
||||
|
||||
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
|
||||
// std::integral_constant<bool, kValue>.
|
||||
template <bool kValue>
|
||||
struct BooleanConstant {};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
@@ -1,78 +0,0 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vadimb@google.com (Vadim Berman)
|
||||
//
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. They are subject to change without notice. DO NOT USE
|
||||
// THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
// Most of the types needed for porting Google Mock are also required
|
||||
// for Google Test and are defined in gtest-port.h.
|
||||
#include "gtest/internal/gtest-linked_ptr.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gmock-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
|
||||
// guaranteed to pull in the tuple header.
|
||||
|
||||
// For MS Visual C++, check the compiler version. At least VS 2003 is
|
||||
// required to compile Google Mock.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1310
|
||||
# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
|
||||
#endif
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
// use this syntax to reference Google Mock flags.
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
@@ -1,240 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009, 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.
|
||||
|
||||
"""fuse_gmock_files.py v0.1.0
|
||||
Fuses Google Mock and Google Test source code into two .h files and a .cc file.
|
||||
|
||||
SYNOPSIS
|
||||
fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR
|
||||
|
||||
Scans GMOCK_ROOT_DIR for Google Mock and Google Test source
|
||||
code, assuming Google Test is in the GMOCK_ROOT_DIR/gtest
|
||||
sub-directory, and generates three files:
|
||||
OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and
|
||||
OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests
|
||||
by adding OUTPUT_DIR to the include search path and linking
|
||||
with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain
|
||||
everything you need to use Google Mock. Hence you can
|
||||
"install" Google Mock by copying them to wherever you want.
|
||||
|
||||
GMOCK_ROOT_DIR can be omitted and defaults to the parent
|
||||
directory of the directory holding this script.
|
||||
|
||||
EXAMPLES
|
||||
./fuse_gmock_files.py fused_gmock
|
||||
./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock
|
||||
|
||||
This tool is experimental. In particular, it assumes that there is no
|
||||
conditional inclusion of Google Mock or Google Test headers. Please
|
||||
report any problems to googlemock@googlegroups.com. You can read
|
||||
http://code.google.com/p/googlemock/wiki/CookBook for more
|
||||
information.
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import os
|
||||
import re
|
||||
import sets
|
||||
import sys
|
||||
|
||||
# We assume that this file is in the scripts/ directory in the Google
|
||||
# Mock root directory.
|
||||
DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
|
||||
|
||||
# We need to call into gtest/scripts/fuse_gtest_files.py.
|
||||
sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, 'gtest/scripts'))
|
||||
import fuse_gtest_files
|
||||
gtest = fuse_gtest_files
|
||||
|
||||
# Regex for matching '#include "gmock/..."'.
|
||||
INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"')
|
||||
|
||||
# Where to find the source seed files.
|
||||
GMOCK_H_SEED = 'include/gmock/gmock.h'
|
||||
GMOCK_ALL_CC_SEED = 'src/gmock-all.cc'
|
||||
|
||||
# Where to put the generated files.
|
||||
GTEST_H_OUTPUT = 'gtest/gtest.h'
|
||||
GMOCK_H_OUTPUT = 'gmock/gmock.h'
|
||||
GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc'
|
||||
|
||||
|
||||
def GetGTestRootDir(gmock_root):
|
||||
"""Returns the root directory of Google Test."""
|
||||
|
||||
return os.path.join(gmock_root, 'gtest')
|
||||
|
||||
|
||||
def ValidateGMockRootDir(gmock_root):
|
||||
"""Makes sure gmock_root points to a valid gmock root directory.
|
||||
|
||||
The function aborts the program on failure.
|
||||
"""
|
||||
|
||||
gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root))
|
||||
gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED)
|
||||
gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED)
|
||||
|
||||
|
||||
def ValidateOutputDir(output_dir):
|
||||
"""Makes sure output_dir points to a valid output directory.
|
||||
|
||||
The function aborts the program on failure.
|
||||
"""
|
||||
|
||||
gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT)
|
||||
gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT)
|
||||
gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT)
|
||||
|
||||
|
||||
def FuseGMockH(gmock_root, output_dir):
|
||||
"""Scans folder gmock_root to generate gmock/gmock.h in output_dir."""
|
||||
|
||||
output_file = file(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w')
|
||||
processed_files = sets.Set() # Holds all gmock headers we've processed.
|
||||
|
||||
def ProcessFile(gmock_header_path):
|
||||
"""Processes the given gmock header file."""
|
||||
|
||||
# We don't process the same header twice.
|
||||
if gmock_header_path in processed_files:
|
||||
return
|
||||
|
||||
processed_files.add(gmock_header_path)
|
||||
|
||||
# Reads each line in the given gmock header.
|
||||
for line in file(os.path.join(gmock_root, gmock_header_path), 'r'):
|
||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "gmock/..."' - let's process it recursively.
|
||||
ProcessFile('include/' + m.group(1))
|
||||
else:
|
||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "gtest/foo.h"'. We translate it to
|
||||
# "gtest/gtest.h", regardless of what foo is, since all
|
||||
# gtest headers are fused into gtest/gtest.h.
|
||||
|
||||
# There is no need to #include gtest.h twice.
|
||||
if not gtest.GTEST_H_SEED in processed_files:
|
||||
processed_files.add(gtest.GTEST_H_SEED)
|
||||
output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,))
|
||||
else:
|
||||
# Otherwise we copy the line unchanged to the output file.
|
||||
output_file.write(line)
|
||||
|
||||
ProcessFile(GMOCK_H_SEED)
|
||||
output_file.close()
|
||||
|
||||
|
||||
def FuseGMockAllCcToFile(gmock_root, output_file):
|
||||
"""Scans folder gmock_root to fuse gmock-all.cc into output_file."""
|
||||
|
||||
processed_files = sets.Set()
|
||||
|
||||
def ProcessFile(gmock_source_file):
|
||||
"""Processes the given gmock source file."""
|
||||
|
||||
# We don't process the same #included file twice.
|
||||
if gmock_source_file in processed_files:
|
||||
return
|
||||
|
||||
processed_files.add(gmock_source_file)
|
||||
|
||||
# Reads each line in the given gmock source file.
|
||||
for line in file(os.path.join(gmock_root, gmock_source_file), 'r'):
|
||||
m = INCLUDE_GMOCK_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "gmock/foo.h"'. We treat it as '#include
|
||||
# "gmock/gmock.h"', as all other gmock headers are being fused
|
||||
# into gmock.h and cannot be #included directly.
|
||||
|
||||
# There is no need to #include "gmock/gmock.h" more than once.
|
||||
if not GMOCK_H_SEED in processed_files:
|
||||
processed_files.add(GMOCK_H_SEED)
|
||||
output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,))
|
||||
else:
|
||||
m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "gtest/..."'.
|
||||
# There is no need to #include gtest.h as it has been
|
||||
# #included by gtest-all.cc.
|
||||
pass
|
||||
else:
|
||||
m = gtest.INCLUDE_SRC_FILE_REGEX.match(line)
|
||||
if m:
|
||||
# It's '#include "src/foo"' - let's process it recursively.
|
||||
ProcessFile(m.group(1))
|
||||
else:
|
||||
# Otherwise we copy the line unchanged to the output file.
|
||||
output_file.write(line)
|
||||
|
||||
ProcessFile(GMOCK_ALL_CC_SEED)
|
||||
|
||||
|
||||
def FuseGMockGTestAllCc(gmock_root, output_dir):
|
||||
"""Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir."""
|
||||
|
||||
output_file = file(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), 'w')
|
||||
# First, fuse gtest-all.cc into gmock-gtest-all.cc.
|
||||
gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file)
|
||||
# Next, append fused gmock-all.cc to gmock-gtest-all.cc.
|
||||
FuseGMockAllCcToFile(gmock_root, output_file)
|
||||
output_file.close()
|
||||
|
||||
|
||||
def FuseGMock(gmock_root, output_dir):
|
||||
"""Fuses gtest.h, gmock.h, and gmock-gtest-all.h."""
|
||||
|
||||
ValidateGMockRootDir(gmock_root)
|
||||
ValidateOutputDir(output_dir)
|
||||
|
||||
gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir)
|
||||
FuseGMockH(gmock_root, output_dir)
|
||||
FuseGMockGTestAllCc(gmock_root, output_dir)
|
||||
|
||||
|
||||
def main():
|
||||
argc = len(sys.argv)
|
||||
if argc == 2:
|
||||
# fuse_gmock_files.py OUTPUT_DIR
|
||||
FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1])
|
||||
elif argc == 3:
|
||||
# fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR
|
||||
FuseGMock(sys.argv[1], sys.argv[2])
|
||||
else:
|
||||
print __doc__
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,203 +0,0 @@
|
||||
|
||||
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.
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
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.3.5 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]...
|
||||
|
||||
If no ClassNames are specified, all classes in the file are emitted.
|
||||
|
||||
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 281 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.
|
||||
@@ -1,115 +0,0 @@
|
||||
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)
|
||||
@@ -1 +0,0 @@
|
||||
# dummy
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,226 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Generate Google Mock classes from base classes.
|
||||
|
||||
This program will read in a C++ source file and output the Google Mock
|
||||
classes for the specified classes. If no class is specified, all
|
||||
classes in the source file are emitted.
|
||||
|
||||
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
|
||||
|
||||
# Preserve compatibility with Python 2.3.
|
||||
try:
|
||||
_dummy = set
|
||||
except NameError:
|
||||
import sets
|
||||
set = sets.Set
|
||||
|
||||
_VERSION = (1, 0, 1) # The version of this script.
|
||||
# How many spaces to indent. Can set me with the 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
|
||||
indent = ' ' * _INDENT
|
||||
|
||||
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:
|
||||
# Add modifiers like 'const'.
|
||||
modifiers = ''
|
||||
if node.return_type.modifiers:
|
||||
modifiers = ' '.join(node.return_type.modifiers) + ' '
|
||||
return_type = modifiers + node.return_type.name
|
||||
template_args = [arg.name for arg in node.return_type.templated_types]
|
||||
if template_args:
|
||||
return_type += '<' + ', '.join(template_args) + '>'
|
||||
if len(template_args) > 1:
|
||||
for line in [
|
||||
'// The following line won\'t really compile, as the return',
|
||||
'// type has multiple template arguments. To fix it, use a',
|
||||
'// typedef for the return type.']:
|
||||
output_lines.append(indent + line)
|
||||
if node.return_type.pointer:
|
||||
return_type += '*'
|
||||
if node.return_type.reference:
|
||||
return_type += '&'
|
||||
num_parameters = len(node.parameters)
|
||||
if len(node.parameters) == 1:
|
||||
first_param = node.parameters[0]
|
||||
if source[first_param.start:first_param.end].strip() == 'void':
|
||||
# We must treat T(void) as a function with no parameters.
|
||||
num_parameters = 0
|
||||
tmpl = ''
|
||||
if class_node.templated_types:
|
||||
tmpl = '_T'
|
||||
mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl)
|
||||
|
||||
args = ''
|
||||
if node.parameters:
|
||||
# Due to the parser limitations, it is impossible to keep comments
|
||||
# while stripping the default parameters. When defaults are
|
||||
# present, we choose to strip them and comments (and produce
|
||||
# compilable code).
|
||||
# TODO(nnorwitz@google.com): Investigate whether it is possible to
|
||||
# preserve parameter name when reconstructing parameter text from
|
||||
# the AST.
|
||||
if len([param for param in node.parameters if param.default]) > 0:
|
||||
args = ', '.join(param.type.name for param in node.parameters)
|
||||
else:
|
||||
# Get the full text of the parameters from the start
|
||||
# of the first parameter to the end of the last parameter.
|
||||
start = node.parameters[0].start
|
||||
end = node.parameters[-1].end
|
||||
# Remove // comments.
|
||||
args_strings = re.sub(r'//.*', '', source[start:end])
|
||||
# Condense multiple spaces and eliminate newlines putting the
|
||||
# parameters together on a single line. Ensure there is a
|
||||
# space in an argument which is split by a newline without
|
||||
# intervening whitespace, e.g.: int\nBar
|
||||
args = re.sub(' +', ' ', args_strings.replace('\n', ' '))
|
||||
|
||||
# Create the mock method definition.
|
||||
output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name),
|
||||
'%s%s(%s));' % (indent*3, return_type, args)])
|
||||
|
||||
|
||||
def _GenerateMocks(filename, source, ast_list, desired_class_names):
|
||||
processed_class_names = set()
|
||||
lines = []
|
||||
for node in ast_list:
|
||||
if (isinstance(node, ast.Class) and node.body and
|
||||
# desired_class_names being None means that all classes are selected.
|
||||
(not desired_class_names or node.name in desired_class_names)):
|
||||
class_name = node.name
|
||||
parent_name = class_name
|
||||
processed_class_names.add(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 template args for templated classes.
|
||||
if class_node.templated_types:
|
||||
# TODO(paulchang): The AST doesn't preserve template argument order,
|
||||
# so we have to make up names here.
|
||||
# TODO(paulchang): Handle non-type template arguments (e.g.
|
||||
# template<typename T, int N>).
|
||||
template_arg_count = len(class_node.templated_types.keys())
|
||||
template_args = ['T%d' % n for n in range(template_arg_count)]
|
||||
template_decls = ['typename ' + arg for arg in template_args]
|
||||
lines.append('template <' + ', '.join(template_decls) + '>')
|
||||
parent_name += '<' + ', '.join(template_args) + '>'
|
||||
|
||||
# Add the class prolog.
|
||||
lines.append('class Mock%s : public %s {' # }
|
||||
% (class_name, parent_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 desired_class_names:
|
||||
missing_class_name_list = list(desired_class_names - processed_class_names)
|
||||
if missing_class_name_list:
|
||||
missing_class_name_list.sort()
|
||||
sys.stderr.write('Class(es) not found in %s: %s\n' %
|
||||
(filename, ', '.join(missing_class_name_list)))
|
||||
elif not processed_class_names:
|
||||
sys.stderr.write('No class found in %s\n' % filename)
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
if len(argv) < 2:
|
||||
sys.stderr.write('Google Mock Class Generator v%s\n\n' %
|
||||
'.'.join(map(str, _VERSION)))
|
||||
sys.stderr.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 = argv[1]
|
||||
desired_class_names = None # None means all classes in the source file.
|
||||
if len(argv) >= 3:
|
||||
desired_class_names = set(argv[2:])
|
||||
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:
|
||||
lines = _GenerateMocks(filename, source, entire_ast, desired_class_names)
|
||||
sys.stdout.write('\n'.join(lines))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/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.
|
||||
|
||||
"""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
|
||||
@@ -1,287 +0,0 @@
|
||||
#!/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)
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# 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()
|
||||
@@ -1,303 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# These variables are automatically filled in by the configure script.
|
||||
name="@PACKAGE_TARNAME@"
|
||||
version="@PACKAGE_VERSION@"
|
||||
|
||||
show_usage()
|
||||
{
|
||||
echo "Usage: gmock-config [OPTIONS...]"
|
||||
}
|
||||
|
||||
show_help()
|
||||
{
|
||||
show_usage
|
||||
cat <<\EOF
|
||||
|
||||
The `gmock-config' script provides access to the necessary compile and linking
|
||||
flags to connect with Google C++ Mocking Framework, both in a build prior to
|
||||
installation, and on the system proper after installation. The installation
|
||||
overrides may be issued in combination with any other queries, but will only
|
||||
affect installation queries if called on a built but not installed gmock. The
|
||||
installation queries may not be issued with any other types of queries, and
|
||||
only one installation query may be made at a time. The version queries and
|
||||
compiler flag queries may be combined as desired but not mixed. Different
|
||||
version queries are always combined with logical "and" semantics, and only the
|
||||
last of any particular query is used while all previous ones ignored. All
|
||||
versions must be specified as a sequence of numbers separated by periods.
|
||||
Compiler flag queries output the union of the sets of flags when combined.
|
||||
|
||||
Examples:
|
||||
gmock-config --min-version=1.0 || echo "Insufficient Google Mock version."
|
||||
|
||||
g++ $(gmock-config --cppflags --cxxflags) -o foo.o -c foo.cpp
|
||||
g++ $(gmock-config --ldflags --libs) -o foo foo.o
|
||||
|
||||
# When using a built but not installed Google Mock:
|
||||
g++ $(../../my_gmock_build/scripts/gmock-config ...) ...
|
||||
|
||||
# When using an installed Google Mock, but with installation overrides:
|
||||
export GMOCK_PREFIX="/opt"
|
||||
g++ $(gmock-config --libdir="/opt/lib64" ...) ...
|
||||
|
||||
Help:
|
||||
--usage brief usage information
|
||||
--help display this help message
|
||||
|
||||
Installation Overrides:
|
||||
--prefix=<dir> overrides the installation prefix
|
||||
--exec-prefix=<dir> overrides the executable installation prefix
|
||||
--libdir=<dir> overrides the library installation prefix
|
||||
--includedir=<dir> overrides the header file installation prefix
|
||||
|
||||
Installation Queries:
|
||||
--prefix installation prefix
|
||||
--exec-prefix executable installation prefix
|
||||
--libdir library installation directory
|
||||
--includedir header file installation directory
|
||||
--version the version of the Google Mock installation
|
||||
|
||||
Version Queries:
|
||||
--min-version=VERSION return 0 if the version is at least VERSION
|
||||
--exact-version=VERSION return 0 if the version is exactly VERSION
|
||||
--max-version=VERSION return 0 if the version is at most VERSION
|
||||
|
||||
Compilation Flag Queries:
|
||||
--cppflags compile flags specific to the C-like preprocessors
|
||||
--cxxflags compile flags appropriate for C++ programs
|
||||
--ldflags linker flags
|
||||
--libs libraries for linking
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# This function bounds our version with a min and a max. It uses some clever
|
||||
# POSIX-compliant variable expansion to portably do all the work in the shell
|
||||
# and avoid any dependency on a particular "sed" or "awk" implementation.
|
||||
# Notable is that it will only ever compare the first 3 components of versions.
|
||||
# Further components will be cleanly stripped off. All versions must be
|
||||
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
|
||||
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
|
||||
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
|
||||
# continuing to maintain our own shell version.
|
||||
check_versions()
|
||||
{
|
||||
major_version=${version%%.*}
|
||||
minor_version="0"
|
||||
point_version="0"
|
||||
if test "${version#*.}" != "${version}"; then
|
||||
minor_version=${version#*.}
|
||||
minor_version=${minor_version%%.*}
|
||||
fi
|
||||
if test "${version#*.*.}" != "${version}"; then
|
||||
point_version=${version#*.*.}
|
||||
point_version=${point_version%%.*}
|
||||
fi
|
||||
|
||||
min_version="$1"
|
||||
min_major_version=${min_version%%.*}
|
||||
min_minor_version="0"
|
||||
min_point_version="0"
|
||||
if test "${min_version#*.}" != "${min_version}"; then
|
||||
min_minor_version=${min_version#*.}
|
||||
min_minor_version=${min_minor_version%%.*}
|
||||
fi
|
||||
if test "${min_version#*.*.}" != "${min_version}"; then
|
||||
min_point_version=${min_version#*.*.}
|
||||
min_point_version=${min_point_version%%.*}
|
||||
fi
|
||||
|
||||
max_version="$2"
|
||||
max_major_version=${max_version%%.*}
|
||||
max_minor_version="0"
|
||||
max_point_version="0"
|
||||
if test "${max_version#*.}" != "${max_version}"; then
|
||||
max_minor_version=${max_version#*.}
|
||||
max_minor_version=${max_minor_version%%.*}
|
||||
fi
|
||||
if test "${max_version#*.*.}" != "${max_version}"; then
|
||||
max_point_version=${max_version#*.*.}
|
||||
max_point_version=${max_point_version%%.*}
|
||||
fi
|
||||
|
||||
test $(($major_version)) -lt $(($min_major_version)) && exit 1
|
||||
if test $(($major_version)) -eq $(($min_major_version)); then
|
||||
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
|
||||
if test $(($minor_version)) -eq $(($min_minor_version)); then
|
||||
test $(($point_version)) -lt $(($min_point_version)) && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
test $(($major_version)) -gt $(($max_major_version)) && exit 1
|
||||
if test $(($major_version)) -eq $(($max_major_version)); then
|
||||
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
|
||||
if test $(($minor_version)) -eq $(($max_minor_version)); then
|
||||
test $(($point_version)) -gt $(($max_point_version)) && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Show the usage line when no arguments are specified.
|
||||
if test $# -eq 0; then
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--usage) show_usage; exit 0;;
|
||||
--help) show_help; exit 0;;
|
||||
|
||||
# Installation overrides
|
||||
--prefix=*) GMOCK_PREFIX=${1#--prefix=};;
|
||||
--exec-prefix=*) GMOCK_EXEC_PREFIX=${1#--exec-prefix=};;
|
||||
--libdir=*) GMOCK_LIBDIR=${1#--libdir=};;
|
||||
--includedir=*) GMOCK_INCLUDEDIR=${1#--includedir=};;
|
||||
|
||||
# Installation queries
|
||||
--prefix|--exec-prefix|--libdir|--includedir|--version)
|
||||
if test -n "${do_query}"; then
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
do_query=${1#--}
|
||||
;;
|
||||
|
||||
# Version checking
|
||||
--min-version=*)
|
||||
do_check_versions=yes
|
||||
min_version=${1#--min-version=}
|
||||
;;
|
||||
--max-version=*)
|
||||
do_check_versions=yes
|
||||
max_version=${1#--max-version=}
|
||||
;;
|
||||
--exact-version=*)
|
||||
do_check_versions=yes
|
||||
exact_version=${1#--exact-version=}
|
||||
;;
|
||||
|
||||
# Compiler flag output
|
||||
--cppflags) echo_cppflags=yes;;
|
||||
--cxxflags) echo_cxxflags=yes;;
|
||||
--ldflags) echo_ldflags=yes;;
|
||||
--libs) echo_libs=yes;;
|
||||
|
||||
# Everything else is an error
|
||||
*) show_usage; exit 1;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# These have defaults filled in by the configure script but can also be
|
||||
# overridden by environment variables or command line parameters.
|
||||
prefix="${GMOCK_PREFIX:-@prefix@}"
|
||||
exec_prefix="${GMOCK_EXEC_PREFIX:-@exec_prefix@}"
|
||||
libdir="${GMOCK_LIBDIR:-@libdir@}"
|
||||
includedir="${GMOCK_INCLUDEDIR:-@includedir@}"
|
||||
|
||||
# We try and detect if our binary is not located at its installed location. If
|
||||
# it's not, we provide variables pointing to the source and build tree rather
|
||||
# than to the install tree. We also locate Google Test using the configured
|
||||
# gtest-config script rather than searching the PATH and our bindir for one.
|
||||
# This allows building against a just-built gmock rather than an installed
|
||||
# gmock.
|
||||
bindir="@bindir@"
|
||||
this_relative_bindir=`dirname $0`
|
||||
this_bindir=`cd ${this_relative_bindir}; pwd -P`
|
||||
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
|
||||
# The path to the script doesn't end in the bindir sequence from Autoconf,
|
||||
# assume that we are in a build tree.
|
||||
build_dir=`dirname ${this_bindir}`
|
||||
src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P`
|
||||
|
||||
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
|
||||
# should work to remove it, and/or remove libtool altogether, replacing it
|
||||
# with direct references to the library and a link path.
|
||||
gmock_libs="${build_dir}/lib/libgmock.la"
|
||||
gmock_ldflags=""
|
||||
|
||||
# We provide hooks to include from either the source or build dir, where the
|
||||
# build dir is always preferred. This will potentially allow us to write
|
||||
# build rules for generated headers and have them automatically be preferred
|
||||
# over provided versions.
|
||||
gmock_cppflags="-I${build_dir}/include -I${src_dir}/include"
|
||||
gmock_cxxflags=""
|
||||
|
||||
# Directly invoke the gtest-config script used during the build process.
|
||||
gtest_config="@GTEST_CONFIG@"
|
||||
else
|
||||
# We're using an installed gmock, although it may be staged under some
|
||||
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
|
||||
# and are present in the dynamic link paths.
|
||||
gmock_ldflags="-L${libdir}"
|
||||
gmock_libs="-l${name}"
|
||||
gmock_cppflags="-I${includedir}"
|
||||
gmock_cxxflags=""
|
||||
|
||||
# We also prefer any gtest-config script installed in our prefix. Lacking
|
||||
# one, we look in the PATH for one.
|
||||
gtest_config="${bindir}/gtest-config"
|
||||
if test ! -x "${gtest_config}"; then
|
||||
gtest_config=`which gtest-config`
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure that we have located a Google Test to link against.
|
||||
if ! test -x "${gtest_config}"; then
|
||||
echo "Unable to locate Google Test, check your Google Mock configuration" \
|
||||
"and installation" >&2
|
||||
exit 1
|
||||
elif ! "${gtest_config}" "--exact-version=@GTEST_VERSION@"; then
|
||||
echo "The Google Test found is not the same version as Google Mock was " \
|
||||
"built against" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add the necessary Google Test bits into the various flag variables
|
||||
gmock_cppflags="${gmock_cppflags} `${gtest_config} --cppflags`"
|
||||
gmock_cxxflags="${gmock_cxxflags} `${gtest_config} --cxxflags`"
|
||||
gmock_ldflags="${gmock_ldflags} `${gtest_config} --ldflags`"
|
||||
gmock_libs="${gmock_libs} `${gtest_config} --libs`"
|
||||
|
||||
# Do an installation query if requested.
|
||||
if test -n "$do_query"; then
|
||||
case $do_query in
|
||||
prefix) echo $prefix; exit 0;;
|
||||
exec-prefix) echo $exec_prefix; exit 0;;
|
||||
libdir) echo $libdir; exit 0;;
|
||||
includedir) echo $includedir; exit 0;;
|
||||
version) echo $version; exit 0;;
|
||||
*) show_usage; exit 1;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Do a version check if requested.
|
||||
if test "$do_check_versions" = "yes"; then
|
||||
# Make sure we didn't receive a bad combination of parameters.
|
||||
test "$echo_cppflags" = "yes" && show_usage && exit 1
|
||||
test "$echo_cxxflags" = "yes" && show_usage && exit 1
|
||||
test "$echo_ldflags" = "yes" && show_usage && exit 1
|
||||
test "$echo_libs" = "yes" && show_usage && exit 1
|
||||
|
||||
if test "$exact_version" != ""; then
|
||||
check_versions $exact_version $exact_version
|
||||
# unreachable
|
||||
else
|
||||
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
|
||||
# unreachable
|
||||
fi
|
||||
fi
|
||||
|
||||
# Do the output in the correct order so that these can be used in-line of
|
||||
# a compiler invocation.
|
||||
output=""
|
||||
test "$echo_cppflags" = "yes" && output="$output $gmock_cppflags"
|
||||
test "$echo_cxxflags" = "yes" && output="$output $gmock_cxxflags"
|
||||
test "$echo_ldflags" = "yes" && output="$output $gmock_ldflags"
|
||||
test "$echo_libs" = "yes" && output="$output $gmock_libs"
|
||||
echo $output
|
||||
|
||||
exit 0
|
||||
@@ -1,631 +0,0 @@
|
||||
#!/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.
|
||||
|
||||
"""Converts compiler's errors in code using Google Mock to plain English."""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
_VERSION = '1.0.3'
|
||||
|
||||
_EMAIL = 'googlemock@googlegroups.com'
|
||||
|
||||
_COMMON_GMOCK_SYMBOLS = [
|
||||
# Matchers
|
||||
'_',
|
||||
'A',
|
||||
'AddressSatisfies',
|
||||
'AllOf',
|
||||
'An',
|
||||
'AnyOf',
|
||||
'ContainerEq',
|
||||
'Contains',
|
||||
'ContainsRegex',
|
||||
'DoubleEq',
|
||||
'ElementsAre',
|
||||
'ElementsAreArray',
|
||||
'EndsWith',
|
||||
'Eq',
|
||||
'Field',
|
||||
'FloatEq',
|
||||
'Ge',
|
||||
'Gt',
|
||||
'HasSubstr',
|
||||
'IsInitializedProto',
|
||||
'Le',
|
||||
'Lt',
|
||||
'MatcherCast',
|
||||
'Matches',
|
||||
'MatchesRegex',
|
||||
'NanSensitiveDoubleEq',
|
||||
'NanSensitiveFloatEq',
|
||||
'Ne',
|
||||
'Not',
|
||||
'NotNull',
|
||||
'Pointee',
|
||||
'Property',
|
||||
'Ref',
|
||||
'ResultOf',
|
||||
'SafeMatcherCast',
|
||||
'StartsWith',
|
||||
'StrCaseEq',
|
||||
'StrCaseNe',
|
||||
'StrEq',
|
||||
'StrNe',
|
||||
'Truly',
|
||||
'TypedEq',
|
||||
'Value',
|
||||
|
||||
# Actions
|
||||
'Assign',
|
||||
'ByRef',
|
||||
'DeleteArg',
|
||||
'DoAll',
|
||||
'DoDefault',
|
||||
'IgnoreResult',
|
||||
'Invoke',
|
||||
'InvokeArgument',
|
||||
'InvokeWithoutArgs',
|
||||
'Return',
|
||||
'ReturnNew',
|
||||
'ReturnNull',
|
||||
'ReturnRef',
|
||||
'SaveArg',
|
||||
'SetArgReferee',
|
||||
'SetArgPointee',
|
||||
'SetArgumentPointee',
|
||||
'SetArrayArgument',
|
||||
'SetErrnoAndReturn',
|
||||
'Throw',
|
||||
'WithArg',
|
||||
'WithArgs',
|
||||
'WithoutArgs',
|
||||
|
||||
# Cardinalities
|
||||
'AnyNumber',
|
||||
'AtLeast',
|
||||
'AtMost',
|
||||
'Between',
|
||||
'Exactly',
|
||||
|
||||
# Sequences
|
||||
'InSequence',
|
||||
'Sequence',
|
||||
|
||||
# Misc
|
||||
'DefaultValue',
|
||||
'Mock',
|
||||
]
|
||||
|
||||
# Regex for matching source file path and line number in the compiler's errors.
|
||||
_GCC_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(\d+:)?\s+'
|
||||
_CLANG_FILE_LINE_RE = r'(?P<file>.*):(?P<line>\d+):(?P<column>\d+):\s+'
|
||||
_CLANG_NON_GMOCK_FILE_LINE_RE = (
|
||||
r'(?P<file>.*[/\\^](?!gmock-)[^/\\]+):(?P<line>\d+):(?P<column>\d+):\s+')
|
||||
|
||||
|
||||
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, diagnoses, msg):
|
||||
"""Diagnoses the given disease by pattern matching.
|
||||
|
||||
Can provide different diagnoses for different patterns.
|
||||
|
||||
Args:
|
||||
short_name: Short name of the disease.
|
||||
long_name: Long name of the disease.
|
||||
diagnoses: A list of pairs (regex, pattern for formatting the diagnosis
|
||||
for matching regex).
|
||||
msg: Compiler's error messages.
|
||||
Yields:
|
||||
Tuples of the form
|
||||
(short name of disease, long name of disease, diagnosis).
|
||||
"""
|
||||
for regex, diagnosis in diagnoses:
|
||||
if re.search(regex, msg):
|
||||
diagnosis = '%(file)s:%(line)s:' + 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 the compiler."""
|
||||
|
||||
gcc_regex = (r'In member function \'testing::internal::ReturnAction<R>.*\n'
|
||||
+ _GCC_FILE_LINE_RE + r'instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: creating array with negative size')
|
||||
clang_regex = (r'error:.*array.*negative.*\r?\n'
|
||||
r'(.*\n)*?' +
|
||||
_CLANG_NON_GMOCK_FILE_LINE_RE +
|
||||
r'note: in instantiation of function template specialization '
|
||||
r'\'testing::internal::ReturnAction<(?P<type>.*)>'
|
||||
r'::operator Action<.*>\' requested here')
|
||||
diagnosis = """
|
||||
You are using a Return() action in a function that returns a reference to
|
||||
%(type)s. Please use ReturnRef() instead."""
|
||||
return _GenericDiagnoser('NRR', 'Need to Return Reference',
|
||||
[(clang_regex, diagnosis),
|
||||
(gcc_regex, diagnosis % {'type': 'a type'})],
|
||||
msg)
|
||||
|
||||
|
||||
def _NeedToReturnSomethingDiagnoser(msg):
|
||||
"""Diagnoses the NRS disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'(instantiated from here\n.'
|
||||
r'*gmock.*actions\.h.*error: void value not ignored)'
|
||||
r'|(error: control reaches end of non-void function)')
|
||||
clang_regex1 = (_CLANG_FILE_LINE_RE +
|
||||
r'error: cannot initialize return object '
|
||||
r'of type \'Result\' \(aka \'(?P<return_type>.*)\'\) '
|
||||
r'with an rvalue of type \'void\'')
|
||||
clang_regex2 = (_CLANG_FILE_LINE_RE +
|
||||
r'error: cannot initialize return object '
|
||||
r'of type \'(?P<return_type>.*)\' '
|
||||
r'with an rvalue of type \'void\'')
|
||||
diagnosis = """
|
||||
You are using an action that returns void, but it needs to return
|
||||
%(return_type)s. Please tell it *what* to return. Perhaps you can use
|
||||
the pattern DoAll(some_action, Return(some_value))?"""
|
||||
return _GenericDiagnoser(
|
||||
'NRS',
|
||||
'Need to Return Something',
|
||||
[(gcc_regex, diagnosis % {'return_type': '*something*'}),
|
||||
(clang_regex1, diagnosis),
|
||||
(clang_regex2, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _NeedToReturnNothingDiagnoser(msg):
|
||||
"""Diagnoses the NRN disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
|
||||
r'.*gmock-actions\.h.*error: instantiation of '
|
||||
r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' '
|
||||
r'as type \'void\'')
|
||||
clang_regex1 = (r'error: field has incomplete type '
|
||||
r'\'Result\' \(aka \'void\'\)(\r)?\n'
|
||||
r'(.*\n)*?' +
|
||||
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
|
||||
r'of function template specialization '
|
||||
r'\'testing::internal::ReturnAction<(?P<return_type>.*)>'
|
||||
r'::operator Action<void \(.*\)>\' requested here')
|
||||
clang_regex2 = (r'error: field has incomplete type '
|
||||
r'\'Result\' \(aka \'void\'\)(\r)?\n'
|
||||
r'(.*\n)*?' +
|
||||
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
|
||||
r'of function template specialization '
|
||||
r'\'testing::internal::DoBothAction<.*>'
|
||||
r'::operator Action<(?P<return_type>.*) \(.*\)>\' '
|
||||
r'requested here')
|
||||
diagnosis = """
|
||||
You are using an action that returns %(return_type)s, 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',
|
||||
[(gcc_regex, diagnosis % {'return_type': '*something*'}),
|
||||
(clang_regex1, diagnosis),
|
||||
(clang_regex2, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _IncompleteByReferenceArgumentDiagnoser(msg):
|
||||
"""Diagnoses the IBRA disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'instantiated from here\n'
|
||||
r'.*gtest-printers\.h.*error: invalid application of '
|
||||
r'\'sizeof\' to incomplete type \'(?P<type>.*)\'')
|
||||
|
||||
clang_regex = (r'.*gtest-printers\.h.*error: invalid application of '
|
||||
r'\'sizeof\' to an incomplete type '
|
||||
r'\'(?P<type>.*)( const)?\'\r?\n'
|
||||
r'(.*\n)*?' +
|
||||
_CLANG_NON_GMOCK_FILE_LINE_RE +
|
||||
r'note: in instantiation of member function '
|
||||
r'\'testing::internal2::TypeWithoutFormatter<.*>::'
|
||||
r'PrintValue\' requested here')
|
||||
diagnosis = """
|
||||
In order to mock this function, Google Mock needs to see the definition
|
||||
of type "%(type)s" - declaration alone is not enough. Either #include
|
||||
the header that defines it, or change the argument to be passed
|
||||
by pointer."""
|
||||
|
||||
return _GenericDiagnoser('IBRA', 'Incomplete By-Reference Argument Type',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _OverloadedFunctionMatcherDiagnoser(msg):
|
||||
"""Diagnoses the OFM disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
|
||||
r'call to \'Truly\(<unresolved overloaded function type>\)')
|
||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function for '
|
||||
r'call to \'Truly')
|
||||
diagnosis = """
|
||||
The argument you gave to Truly() is an overloaded function. Please tell
|
||||
your compiler 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',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _OverloadedFunctionActionDiagnoser(msg):
|
||||
"""Diagnoses the OFA disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for call to '
|
||||
r'\'Invoke\(<unresolved overloaded function type>')
|
||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching '
|
||||
r'function for call to \'Invoke\'\r?\n'
|
||||
r'(.*\n)*?'
|
||||
r'.*\bgmock-\w+-actions\.h:\d+:\d+:\s+'
|
||||
r'note: candidate template ignored:\s+'
|
||||
r'couldn\'t infer template argument \'FunctionImpl\'')
|
||||
diagnosis = """
|
||||
Function you are passing to Invoke is overloaded. Please tell your compiler
|
||||
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',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _OverloadedMethodActionDiagnoser(msg):
|
||||
"""Diagnoses the OMA disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: no matching function for '
|
||||
r'call to \'Invoke\(.+, <unresolved overloaded function '
|
||||
r'type>\)')
|
||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: no matching function '
|
||||
r'for call to \'Invoke\'\r?\n'
|
||||
r'(.*\n)*?'
|
||||
r'.*\bgmock-\w+-actions\.h:\d+:\d+: '
|
||||
r'note: candidate function template not viable: '
|
||||
r'requires .*, but 2 (arguments )?were provided')
|
||||
diagnosis = """
|
||||
The second argument you gave to Invoke() is an overloaded method. Please
|
||||
tell your compiler 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',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _MockObjectPointerDiagnoser(msg):
|
||||
"""Diagnoses the MOP disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: request for member '
|
||||
r'\'gmock_(?P<method>.+)\' in \'(?P<mock_object>.+)\', '
|
||||
r'which is of non-class type \'(.*::)*(?P<class_name>.+)\*\'')
|
||||
clang_regex = (_CLANG_FILE_LINE_RE + r'error: member reference type '
|
||||
r'\'(?P<class_name>.*?) *\' is a pointer; '
|
||||
r'maybe you meant to use \'->\'\?')
|
||||
diagnosis = """
|
||||
The first argument to ON_CALL() and EXPECT_CALL() must be a mock *object*,
|
||||
not a *pointer* to it. Please write '*(%(mock_object)s)' instead of
|
||||
'%(mock_object)s' as your first argument.
|
||||
|
||||
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',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis % {'mock_object': 'mock_object',
|
||||
'method': 'method',
|
||||
'class_name': '%(class_name)s'})],
|
||||
msg)
|
||||
|
||||
|
||||
def _NeedToUseSymbolDiagnoser(msg):
|
||||
"""Diagnoses the NUS disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE + r'error: \'(?P<symbol>.+)\' '
|
||||
r'(was not declared in this scope|has not been declared)')
|
||||
clang_regex = (_CLANG_FILE_LINE_RE +
|
||||
r'error: (use of undeclared identifier|unknown type name|'
|
||||
r'no template named) \'(?P<symbol>[^\']+)\'')
|
||||
diagnosis = """
|
||||
'%(symbol)s' is defined by Google Mock in the testing namespace.
|
||||
Did you forget to write
|
||||
using testing::%(symbol)s;
|
||||
?"""
|
||||
for m in (list(_FindAllMatches(gcc_regex, msg)) +
|
||||
list(_FindAllMatches(clang_regex, msg))):
|
||||
symbol = m.groupdict()['symbol']
|
||||
if symbol in _COMMON_GMOCK_SYMBOLS:
|
||||
yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict())
|
||||
|
||||
|
||||
def _NeedToUseReturnNullDiagnoser(msg):
|
||||
"""Diagnoses the NRNULL disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = ('instantiated from \'testing::internal::ReturnAction<R>'
|
||||
'::operator testing::Action<Func>\(\) const.*\n' +
|
||||
_GCC_FILE_LINE_RE + r'instantiated from here\n'
|
||||
r'.*error: no matching function for call to \'ImplicitCast_\('
|
||||
r'(:?long )?int&\)')
|
||||
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
|
||||
r'call to \'ImplicitCast_\'\r?\n'
|
||||
r'(.*\n)*?' +
|
||||
_CLANG_NON_GMOCK_FILE_LINE_RE + r'note: in instantiation '
|
||||
r'of function template specialization '
|
||||
r'\'testing::internal::ReturnAction<(int|long)>::operator '
|
||||
r'Action<(?P<type>.*)\(\)>\' requested here')
|
||||
diagnosis = """
|
||||
You are probably calling Return(NULL) and the compiler isn't sure how to turn
|
||||
NULL into %(type)s. Use ReturnNull() instead.
|
||||
Note: the line number may be off; please fix all instances of Return(NULL)."""
|
||||
return _GenericDiagnoser(
|
||||
'NRNULL', 'Need to use ReturnNull',
|
||||
[(clang_regex, diagnosis),
|
||||
(gcc_regex, diagnosis % {'type': 'the right type'})],
|
||||
msg)
|
||||
|
||||
|
||||
def _TypeInTemplatedBaseDiagnoser(msg):
|
||||
"""Diagnoses the TTB disease, given the error messages by the compiler."""
|
||||
|
||||
# This version works when the type is used as the mock function's return
|
||||
# type.
|
||||
gcc_4_3_1_regex_type_in_retval = (
|
||||
r'In member function \'int .*\n' + _GCC_FILE_LINE_RE +
|
||||
r'error: a function call cannot appear in a constant-expression')
|
||||
gcc_4_4_0_regex_type_in_retval = (
|
||||
r'error: a function call cannot appear in a constant-expression'
|
||||
+ _GCC_FILE_LINE_RE + r'error: template argument 1 is invalid\n')
|
||||
# This version works when the type is used as the mock function's sole
|
||||
# parameter type.
|
||||
gcc_regex_type_of_sole_param = (
|
||||
_GCC_FILE_LINE_RE +
|
||||
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
|
||||
r'.*error: template argument 1 is invalid\n')
|
||||
# This version works when the type is used as a parameter of a mock
|
||||
# function that has multiple parameters.
|
||||
gcc_regex_type_of_a_param = (
|
||||
r'error: expected `;\' before \'::\' token\n'
|
||||
+ _GCC_FILE_LINE_RE +
|
||||
r'error: \'(?P<type>.+)\' was not declared in this scope\n'
|
||||
r'.*error: template argument 1 is invalid\n'
|
||||
r'.*error: \'.+\' was not declared in this scope')
|
||||
clang_regex_type_of_retval_or_sole_param = (
|
||||
_CLANG_FILE_LINE_RE +
|
||||
r'error: use of undeclared identifier \'(?P<type>.*)\'\n'
|
||||
r'(.*\n)*?'
|
||||
r'(?P=file):(?P=line):\d+: error: '
|
||||
r'non-friend class member \'Result\' cannot have a qualified name'
|
||||
)
|
||||
clang_regex_type_of_a_param = (
|
||||
_CLANG_FILE_LINE_RE +
|
||||
r'error: C\+\+ requires a type specifier for all declarations\n'
|
||||
r'(.*\n)*?'
|
||||
r'(?P=file):(?P=line):(?P=column): error: '
|
||||
r'C\+\+ requires a type specifier for all declarations'
|
||||
)
|
||||
clang_regex_unknown_type = (
|
||||
_CLANG_FILE_LINE_RE +
|
||||
r'error: unknown type name \'(?P<type>[^\']+)\''
|
||||
)
|
||||
|
||||
diagnosis = """
|
||||
In a mock class template, types or typedefs defined in the base class
|
||||
template are *not* automatically visible. This is how C++ works. Before
|
||||
you can use a type or typedef named %(type)s defined in base class Base<T>, you
|
||||
need to make it visible. One way to do it is:
|
||||
|
||||
typedef typename Base<T>::%(type)s %(type)s;"""
|
||||
|
||||
for diag in _GenericDiagnoser(
|
||||
'TTB', 'Type in Template Base',
|
||||
[(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
|
||||
(gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
|
||||
(gcc_regex_type_of_sole_param, diagnosis),
|
||||
(gcc_regex_type_of_a_param, diagnosis),
|
||||
(clang_regex_type_of_retval_or_sole_param, diagnosis),
|
||||
(clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
|
||||
msg):
|
||||
yield diag
|
||||
# Avoid overlap with the NUS pattern.
|
||||
for m in _FindAllMatches(clang_regex_unknown_type, msg):
|
||||
type_ = m.groupdict()['type']
|
||||
if type_ not in _COMMON_GMOCK_SYMBOLS:
|
||||
yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict())
|
||||
|
||||
|
||||
def _WrongMockMethodMacroDiagnoser(msg):
|
||||
"""Diagnoses the WMM disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE +
|
||||
r'.*this_method_does_not_take_(?P<wrong_args>\d+)_argument.*\n'
|
||||
r'.*\n'
|
||||
r'.*candidates are.*FunctionMocker<[^>]+A(?P<args>\d+)\)>')
|
||||
clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
|
||||
r'error:.*array.*negative.*r?\n'
|
||||
r'(.*\n)*?'
|
||||
r'(?P=file):(?P=line):(?P=column): error: too few arguments '
|
||||
r'to function call, expected (?P<args>\d+), '
|
||||
r'have (?P<wrong_args>\d+)')
|
||||
diagnosis = """
|
||||
You are using MOCK_METHOD%(wrong_args)s to define a mock method that has
|
||||
%(args)s arguments. Use MOCK_METHOD%(args)s (or MOCK_CONST_METHOD%(args)s,
|
||||
MOCK_METHOD%(args)s_T, MOCK_CONST_METHOD%(args)s_T as appropriate) instead."""
|
||||
return _GenericDiagnoser('WMM', 'Wrong MOCK_METHODn Macro',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
def _WrongParenPositionDiagnoser(msg):
|
||||
"""Diagnoses the WPP disease, given the error messages by the compiler."""
|
||||
|
||||
gcc_regex = (_GCC_FILE_LINE_RE +
|
||||
r'error:.*testing::internal::MockSpec<.* has no member named \''
|
||||
r'(?P<method>\w+)\'')
|
||||
clang_regex = (_CLANG_NON_GMOCK_FILE_LINE_RE +
|
||||
r'error: no member named \'(?P<method>\w+)\' in '
|
||||
r'\'testing::internal::MockSpec<.*>\'')
|
||||
diagnosis = """
|
||||
The closing parenthesis of ON_CALL or EXPECT_CALL should be *before*
|
||||
".%(method)s". For example, you should write:
|
||||
EXPECT_CALL(my_mock, Foo(_)).%(method)s(...);
|
||||
instead of:
|
||||
EXPECT_CALL(my_mock, Foo(_).%(method)s(...));"""
|
||||
return _GenericDiagnoser('WPP', 'Wrong Parenthesis Position',
|
||||
[(gcc_regex, diagnosis),
|
||||
(clang_regex, diagnosis)],
|
||||
msg)
|
||||
|
||||
|
||||
_DIAGNOSERS = [
|
||||
_IncompleteByReferenceArgumentDiagnoser,
|
||||
_MockObjectPointerDiagnoser,
|
||||
_NeedToReturnNothingDiagnoser,
|
||||
_NeedToReturnReferenceDiagnoser,
|
||||
_NeedToReturnSomethingDiagnoser,
|
||||
_NeedToUseReturnNullDiagnoser,
|
||||
_NeedToUseSymbolDiagnoser,
|
||||
_OverloadedFunctionActionDiagnoser,
|
||||
_OverloadedFunctionMatcherDiagnoser,
|
||||
_OverloadedMethodActionDiagnoser,
|
||||
_TypeInTemplatedBaseDiagnoser,
|
||||
_WrongMockMethodMacroDiagnoser,
|
||||
_WrongParenPositionDiagnoser,
|
||||
]
|
||||
|
||||
|
||||
def Diagnose(msg):
|
||||
"""Generates all possible diagnoses given the compiler error message."""
|
||||
|
||||
msg = re.sub(r'\x1b\[[^m]*m', '', msg) # Strips all color formatting.
|
||||
# Assuming the string is using the UTF-8 encoding, replaces the left and
|
||||
# the right single quote characters with apostrophes.
|
||||
msg = re.sub(r'(\xe2\x80\x98|\xe2\x80\x99)', "'", msg)
|
||||
|
||||
diagnoses = []
|
||||
for diagnoser in _DIAGNOSERS:
|
||||
for diag in diagnoser(msg):
|
||||
diagnosis = '[%s - %s]\n%s' % diag
|
||||
if not diagnosis in diagnoses:
|
||||
diagnoses.append(diagnosis)
|
||||
return diagnoses
|
||||
|
||||
|
||||
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 = Diagnose(msg)
|
||||
count = len(diagnoses)
|
||||
if not count:
|
||||
print ("""
|
||||
Your compiler complained:
|
||||
8<------------------------------------------------------------
|
||||
%s
|
||||
------------------------------------------------------------>8
|
||||
|
||||
Uh-oh, I'm not smart enough to figure out what the problem is. :-(
|
||||
However...
|
||||
If you send your source code and the compiler's error messages to
|
||||
%s, you can be helped and I can get smarter --
|
||||
win-win for us!""" % (msg, _EMAIL))
|
||||
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 the compiler's error messages to %s.
|
||||
Then you can be helped and I can get smarter -- I promise I won't be upset!""" %
|
||||
_EMAIL)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,50 +0,0 @@
|
||||
# Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
# gMock builds 2 libraries: libgmock and libgmock_main. libgmock contains most
|
||||
# of the code and libgmock_main just provides a common main to run the test.
|
||||
# (i.e. If you link against libgmock_main you shouldn't provide a main() entry
|
||||
# point. If you link against libgmock_main, do not also link against
|
||||
# libgtest_main, as libgmock_main is a superset of libgtest_main, and they will
|
||||
# conflict in subtle ways.)
|
||||
#
|
||||
# We build these 2 libraries for the target device only.
|
||||
#
|
||||
# Renamed to libwvgmock and libwvgmock_main to avoid conflicts with
|
||||
# external/gmock.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
libgmock_target_includes := \
|
||||
$(LOCAL_PATH)/.. \
|
||||
$(LOCAL_PATH)/../include \
|
||||
$(TOP)/external/gtest/include \
|
||||
|
||||
libgmock_host_includes := \
|
||||
$(LOCAL_PATH)/.. \
|
||||
$(LOCAL_PATH)/../include \
|
||||
$(TOP)/external/gtest/include \
|
||||
|
||||
libgmock_cflags := \
|
||||
-Wno-missing-field-initializers \
|
||||
|
||||
#######################################################################
|
||||
# gmock lib target
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_CPP_EXTENSION := .cc
|
||||
LOCAL_SRC_FILES := gmock-all.cc
|
||||
LOCAL_C_INCLUDES := $(libgmock_target_includes)
|
||||
LOCAL_CFLAGS += $(libgmock_cflags)
|
||||
LOCAL_MODULE := libwvgmock
|
||||
LOCAL_MODULE_TARGET_ARCH := arm x86 mips
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
#######################################################################
|
||||
# gmock_main lib target
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_CPP_EXTENSION := .cc
|
||||
LOCAL_SRC_FILES := gmock_main.cc
|
||||
LOCAL_C_INCLUDES := $(libgmock_target_includes)
|
||||
LOCAL_CFLAGS += $(libgmock_cflags)
|
||||
LOCAL_MODULE := libwvgmock_main
|
||||
LOCAL_MODULE_TARGET_ARCH := arm x86 mips
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: 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.
|
||||
|
||||
// This line ensures that gmock.h can be compiled on its own, even
|
||||
// when it's fused.
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
// The following lines pull in the real gmock *.cc files.
|
||||
#include "src/gmock-cardinalities.cc"
|
||||
#include "src/gmock-internal-utils.cc"
|
||||
#include "src/gmock-matchers.cc"
|
||||
#include "src/gmock-spec-builders.cc"
|
||||
#include "src/gmock.cc"
|
||||
@@ -1,156 +0,0 @@
|
||||
// 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.
|
||||
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max) {
|
||||
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
|
||||
|
||||
} // namespace testing
|
||||
@@ -1,174 +0,0 @@
|
||||
// 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 <ctype.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
|
||||
string result;
|
||||
char prev_char = '\0';
|
||||
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
|
||||
// We don't care about the current locale as the input is
|
||||
// guaranteed to be a valid C++ identifier name.
|
||||
const bool starts_new_word = IsUpper(*p) ||
|
||||
(!IsAlpha(prev_char) && IsLower(*p)) ||
|
||||
(!IsDigit(prev_char) && IsDigit(*p));
|
||||
|
||||
if (IsAlNum(*p)) {
|
||||
if (starts_new_word && result != "")
|
||||
result += ' ';
|
||||
result += ToLower(*p);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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 == kFatal ?
|
||||
TestPartResult::kFatalFailure :
|
||||
TestPartResult::kNonFatalFailure,
|
||||
file,
|
||||
line,
|
||||
message.c_str()) = Message();
|
||||
if (type == kFatal) {
|
||||
posix::Abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the global failure reporter. Will create a
|
||||
// GoogleTestFailureReporter and return it the first time called.
|
||||
GTEST_API_ 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 GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
||||
|
||||
// Returns true iff a log with the given severity is visible according
|
||||
// to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
||||
// Always show the log if --gmock_verbose=info.
|
||||
return true;
|
||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
// Always hide it if --gmock_verbose=error.
|
||||
return false;
|
||||
} else {
|
||||
// If --gmock_verbose is neither "info" nor "error", we treat it
|
||||
// as "warning" (its default value).
|
||||
return severity == kWarning;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
GTEST_API_ void Log(LogSeverity severity,
|
||||
const string& message,
|
||||
int stack_frames_to_skip) {
|
||||
if (!LogIsVisible(severity))
|
||||
return;
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
|
||||
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
|
||||
// macro.
|
||||
|
||||
if (severity == kWarning) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
std::cout << "\nGMOCK WARNING:";
|
||||
}
|
||||
// Pre-pends a new-line to message if it doesn't start with one.
|
||||
if (message.empty() || message[0] != '\n') {
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::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') {
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << "Stack trace:\n"
|
||||
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||
::testing::UnitTest::GetInstance(), actual_to_skip);
|
||||
}
|
||||
std::cout << ::std::flush;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
@@ -1,498 +0,0 @@
|
||||
// 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 Matcher<const string&>, Matcher<string>, and
|
||||
// utilities for defining matchers.
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STRING_PIECE_
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(StringPiece s) {
|
||||
*this = Eq(s.ToString());
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(StringPiece s) {
|
||||
*this = Eq(s.ToString());
|
||||
}
|
||||
#endif // GTEST_HAS_STRING_PIECE_
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ string JoinAsTuple(const Strings& fields) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return fields[0];
|
||||
default:
|
||||
string result = "(" + fields[0];
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
result += ", ";
|
||||
result += fields[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the description for a matcher defined using the MATCHER*()
|
||||
// macro where the user-supplied description string is "", if
|
||||
// 'negation' is false; otherwise returns the description of the
|
||||
// negation of the matcher. 'param_values' contains a list of strings
|
||||
// that are the print-out of the matcher's parameters.
|
||||
GTEST_API_ string FormatMatcherDescription(bool negation,
|
||||
const char* matcher_name,
|
||||
const Strings& param_values) {
|
||||
string result = ConvertIdentifierNameToWords(matcher_name);
|
||||
if (param_values.size() >= 1)
|
||||
result += " " + JoinAsTuple(param_values);
|
||||
return negation ? "not (" + result + ")" : result;
|
||||
}
|
||||
|
||||
// FindMaxBipartiteMatching and its helper class.
|
||||
//
|
||||
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
|
||||
// bipartite matching. Flow is considered to be from left to right.
|
||||
// There is an implicit source node that is connected to all of the left
|
||||
// nodes, and an implicit sink node that is connected to all of the
|
||||
// right nodes. All edges have unit capacity.
|
||||
//
|
||||
// Neither the flow graph nor the residual flow graph are represented
|
||||
// explicitly. Instead, they are implied by the information in 'graph' and
|
||||
// a vector<int> called 'left_' whose elements are initialized to the
|
||||
// value kUnused. This represents the initial state of the algorithm,
|
||||
// where the flow graph is empty, and the residual flow graph has the
|
||||
// following edges:
|
||||
// - An edge from source to each left_ node
|
||||
// - An edge from each right_ node to sink
|
||||
// - An edge from each left_ node to each right_ node, if the
|
||||
// corresponding edge exists in 'graph'.
|
||||
//
|
||||
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
|
||||
// nodes l and r. This induces the following changes:
|
||||
// - The edges (source, l), (l, r), and (r, sink) are added to the
|
||||
// flow graph.
|
||||
// - The same three edges are removed from the residual flow graph.
|
||||
// - The reverse edges (l, source), (r, l), and (sink, r) are added
|
||||
// to the residual flow graph, which is a directional graph
|
||||
// representing unused flow capacity.
|
||||
//
|
||||
// When the method augments a flow (moving left_[l] from some r1 to some
|
||||
// other r2), this can be thought of as "undoing" the above steps with
|
||||
// respect to r1 and "redoing" them with respect to r2.
|
||||
//
|
||||
// It bears repeating that the flow graph and residual flow graph are
|
||||
// never represented explicitly, but can be derived by looking at the
|
||||
// information in 'graph' and in left_.
|
||||
//
|
||||
// As an optimization, there is a second vector<int> called right_ which
|
||||
// does not provide any new information. Instead, it enables more
|
||||
// efficient queries about edges entering or leaving the right-side nodes
|
||||
// of the flow or residual flow graphs. The following invariants are
|
||||
// maintained:
|
||||
//
|
||||
// left[l] == kUnused or right[left[l]] == l
|
||||
// right[r] == kUnused or left[right[r]] == r
|
||||
//
|
||||
// . [ source ] .
|
||||
// . ||| .
|
||||
// . ||| .
|
||||
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
|
||||
// . || | | .
|
||||
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
|
||||
// . | || .
|
||||
// . \----> left[2]=2 ------> right[2]=2 --\|| .
|
||||
// . ||| .
|
||||
// . elements matchers vvv .
|
||||
// . [ sink ] .
|
||||
//
|
||||
// See Also:
|
||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford–Fulkerson method".
|
||||
// "Introduction to Algorithms (Second ed.)", pp. 651–664.
|
||||
// [2] "Ford–Fulkerson algorithm", Wikipedia,
|
||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
class MaxBipartiteMatchState {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
: graph_(&graph),
|
||||
left_(graph_->LhsSize(), kUnused),
|
||||
right_(graph_->RhsSize(), kUnused) {
|
||||
}
|
||||
|
||||
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||
ElementMatcherPairs Compute() {
|
||||
// 'seen' is used for path finding { 0: unseen, 1: seen }.
|
||||
::std::vector<char> seen;
|
||||
// Searches the residual flow graph for a path from each left node to
|
||||
// the sink in the residual flow graph, and if one is found, add flow
|
||||
// to the graph. It's okay to search through the left nodes once. The
|
||||
// edge from the implicit source node to each previously-visited left
|
||||
// node will have flow if that left node has any path to the sink
|
||||
// whatsoever. Subsequent augmentations can only add flow to the
|
||||
// network, and cannot take away that previous flow unit from the source.
|
||||
// Since the source-to-left edge can only carry one flow unit (or,
|
||||
// each element can be matched to only one matcher), there is no need
|
||||
// to visit the left nodes more than once looking for augmented paths.
|
||||
// The flow is known to be possible or impossible by looking at the
|
||||
// node once.
|
||||
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
|
||||
// Reset the path-marking vector and try to find a path from
|
||||
// source to sink starting at the left_[ilhs] node.
|
||||
GTEST_CHECK_(left_[ilhs] == kUnused)
|
||||
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
|
||||
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
|
||||
seen.assign(graph_->RhsSize(), 0);
|
||||
TryAugment(ilhs, &seen);
|
||||
}
|
||||
ElementMatcherPairs result;
|
||||
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
|
||||
size_t irhs = left_[ilhs];
|
||||
if (irhs == kUnused) continue;
|
||||
result.push_back(ElementMatcherPair(ilhs, irhs));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t kUnused = static_cast<size_t>(-1);
|
||||
|
||||
// Perform a depth-first search from left node ilhs to the sink. If a
|
||||
// path is found, flow is added to the network by linking the left and
|
||||
// right vector elements corresponding each segment of the path.
|
||||
// Returns true if a path to sink was found, which means that a unit of
|
||||
// flow was added to the network. The 'seen' vector elements correspond
|
||||
// to right nodes and are marked to eliminate cycles from the search.
|
||||
//
|
||||
// Left nodes will only be explored at most once because they
|
||||
// are accessible from at most one right node in the residual flow
|
||||
// graph.
|
||||
//
|
||||
// Note that left_[ilhs] is the only element of left_ that TryAugment will
|
||||
// potentially transition from kUnused to another value. Any other
|
||||
// left_ element holding kUnused before TryAugment will be holding it
|
||||
// when TryAugment returns.
|
||||
//
|
||||
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||
if ((*seen)[irhs])
|
||||
continue;
|
||||
if (!graph_->HasEdge(ilhs, irhs))
|
||||
continue;
|
||||
// There's an available edge from ilhs to irhs.
|
||||
(*seen)[irhs] = 1;
|
||||
// Next a search is performed to determine whether
|
||||
// this edge is a dead end or leads to the sink.
|
||||
//
|
||||
// right_[irhs] == kUnused means that there is residual flow from
|
||||
// right node irhs to the sink, so we can use that to finish this
|
||||
// flow path and return success.
|
||||
//
|
||||
// Otherwise there is residual flow to some ilhs. We push flow
|
||||
// along that path and call ourselves recursively to see if this
|
||||
// ultimately leads to sink.
|
||||
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
|
||||
// Add flow from left_[ilhs] to right_[irhs].
|
||||
left_[ilhs] = irhs;
|
||||
right_[irhs] = ilhs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const MatchMatrix* graph_; // not owned
|
||||
// Each element of the left_ vector represents a left hand side node
|
||||
// (i.e. an element) and each element of right_ is a right hand side
|
||||
// node (i.e. a matcher). The values in the left_ vector indicate
|
||||
// outflow from that node to a node on the the right_ side. The values
|
||||
// in the right_ indicate inflow, and specify which left_ node is
|
||||
// feeding that right_ node, if any. For example, left_[3] == 1 means
|
||||
// there's a flow from element #3 to matcher #1. Such a flow would also
|
||||
// be redundantly represented in the right_ vector as right_[1] == 3.
|
||||
// Elements of left_ and right_ are either kUnused or mutually
|
||||
// referent. Mutually referent means that left_[right_[i]] = i and
|
||||
// right_[left_[i]] = i.
|
||||
::std::vector<size_t> left_;
|
||||
::std::vector<size_t> right_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
|
||||
};
|
||||
|
||||
const size_t MaxBipartiteMatchState::kUnused;
|
||||
|
||||
GTEST_API_ ElementMatcherPairs
|
||||
FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||
return MaxBipartiteMatchState(g).Compute();
|
||||
}
|
||||
|
||||
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
::std::ostream* stream) {
|
||||
typedef ElementMatcherPairs::const_iterator Iter;
|
||||
::std::ostream& os = *stream;
|
||||
os << "{";
|
||||
const char *sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
<< "matcher #" << it->second << ")";
|
||||
sep = ",";
|
||||
}
|
||||
os << "\n}";
|
||||
}
|
||||
|
||||
// Tries to find a pairing, and explains the result.
|
||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) {
|
||||
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||
|
||||
size_t max_flow = matches.size();
|
||||
bool result = (max_flow == matrix.RhsSize());
|
||||
|
||||
if (!result) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener << "where no permutation of the elements can "
|
||||
"satisfy all matchers, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
if (listener->IsInterested()) {
|
||||
const char *sep = "where:\n";
|
||||
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||
*listener << sep << " - element #" << matches[mi].first
|
||||
<< " is matched by matcher #" << matches[mi].second;
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MatchMatrix::NextGraph() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
if (!b) {
|
||||
b = 1;
|
||||
return true;
|
||||
}
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MatchMatrix::Randomize() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
b = static_cast<char>(rand() & 1); // NOLINT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string MatchMatrix::DebugString() const {
|
||||
::std::stringstream ss;
|
||||
const char *sep = "";
|
||||
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||
ss << sep;
|
||||
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||
ss << HasEdge(i, j);
|
||||
}
|
||||
sep = ";";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "is empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "has " << Elements(1) << " and that element ";
|
||||
matcher_describers_[0]->DescribeTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "has " << Elements(matcher_describers_.size())
|
||||
<< " and there exists some permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
}
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "isn't empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "doesn't have " << Elements(1)
|
||||
<< ", or has " << Elements(1) << " that ";
|
||||
matcher_describers_[0]->DescribeNegationTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||
<< ", or there exists no permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Checks that all matchers match at least one element, and that all
|
||||
// elements match at least one matcher. This enables faster matching
|
||||
// and better error reporting.
|
||||
// Returns false, writing an explanation to 'listener', if and only
|
||||
// if the success criteria are not met.
|
||||
bool UnorderedElementsAreMatcherImplBase::
|
||||
VerifyAllElementsAndMatchersAreMatched(
|
||||
const ::std::vector<string>& element_printouts,
|
||||
const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) const {
|
||||
bool result = true;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
||||
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
|
||||
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
|
||||
char matched = matrix.HasEdge(ilhs, irhs);
|
||||
element_matched[ilhs] |= matched;
|
||||
matcher_matched[irhs] |= matched;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const char* sep =
|
||||
"where the following matchers don't match any elements:\n";
|
||||
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||
if (matcher_matched[mi])
|
||||
continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << sep << "matcher #" << mi << ": ";
|
||||
matcher_describers_[mi]->DescribeTo(listener->stream());
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const char* sep =
|
||||
"where the following elements don't match any matchers:\n";
|
||||
const char* outer_sep = "";
|
||||
if (!result) {
|
||||
outer_sep = "\nand ";
|
||||
}
|
||||
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||
if (element_matched[ei])
|
||||
continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||
<< element_printouts[ei];
|
||||
sep = ",\n";
|
||||
outer_sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
@@ -1,813 +0,0 @@
|
||||
// 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 <stdlib.h>
|
||||
#include <iostream> // NOLINT
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
# include <unistd.h> // NOLINT
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
|
||||
|
||||
// Logs a message including file and line number information.
|
||||
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
|
||||
const char* file, int line,
|
||||
const string& message) {
|
||||
::std::ostringstream s;
|
||||
s << file << ":" << line << ": " << message << ::std::endl;
|
||||
Log(severity, s.str(), 0);
|
||||
}
|
||||
|
||||
// Constructs an ExpectationBase object.
|
||||
ExpectationBase::ExpectationBase(const char* a_file,
|
||||
int a_line,
|
||||
const string& a_source_text)
|
||||
: file_(a_file),
|
||||
line_(a_line),
|
||||
source_text_(a_source_text),
|
||||
cardinality_specified_(false),
|
||||
cardinality_(Exactly(1)),
|
||||
call_count_(0),
|
||||
retired_(false),
|
||||
extra_matcher_specified_(false),
|
||||
repeated_action_specified_(false),
|
||||
retires_on_saturation_(false),
|
||||
last_clause_(kNone),
|
||||
action_count_checked_(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& a_cardinality) {
|
||||
cardinality_specified_ = true;
|
||||
cardinality_ = a_cardinality;
|
||||
}
|
||||
|
||||
// Retires all pre-requisites of this expectation.
|
||||
void ExpectationBase::RetireAllPreRequisites()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
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 (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
ExpectationBase* const prerequisite = it->expectation_base().get();
|
||||
if (!prerequisite->is_retired()) {
|
||||
prerequisite->RetireAllPreRequisites();
|
||||
prerequisite->Retire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff all pre-requisites of this expectation have been
|
||||
// satisfied.
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if (!(it->expectation_base()->IsSatisfied()) ||
|
||||
!(it->expectation_base()->AllPrerequisitesAreSatisfied()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if (it->expectation_base()->IsSatisfied()) {
|
||||
// If *it is satisfied and has a call count of 0, some of its
|
||||
// pre-requisites may not be satisfied yet.
|
||||
if (it->expectation_base()->call_count_ == 0) {
|
||||
it->expectation_base()->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 += *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Describes how many times a function call matching this
|
||||
// expectation has occurred.
|
||||
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
|
||||
// Describes how many times the function is expected to be called.
|
||||
*os << " Expected: to be ";
|
||||
cardinality().DescribeTo(os);
|
||||
*os << "\n Actual: ";
|
||||
Cardinality::DescribeActualCallCountTo(call_count(), os);
|
||||
|
||||
// Describes the state of the expectation (e.g. is it satisfied?
|
||||
// is it active?).
|
||||
*os << " - " << (IsOverSaturated() ? "over-saturated" :
|
||||
IsSaturated() ? "saturated" :
|
||||
IsSatisfied() ? "satisfied" : "unsatisfied")
|
||||
<< " and "
|
||||
<< (is_retired() ? "retired" : "active");
|
||||
}
|
||||
|
||||
// Checks the action count (i.e. the number of WillOnce() and
|
||||
// WillRepeatedly() clauses) against the cardinality if this hasn't
|
||||
// been done before. Prints a warning if there are too many or too
|
||||
// few actions.
|
||||
void ExpectationBase::CheckActionCountIfNotDone() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
if (!action_count_checked_) {
|
||||
action_count_checked_ = true;
|
||||
should_check = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_check) {
|
||||
if (!cardinality_specified_) {
|
||||
// The cardinality was inferred - no need to check the action
|
||||
// count against it.
|
||||
return;
|
||||
}
|
||||
|
||||
// The cardinality was explicitly specified.
|
||||
const int action_count = static_cast<int>(untyped_actions_.size());
|
||||
const int upper_bound = cardinality().ConservativeUpperBound();
|
||||
const int lower_bound = cardinality().ConservativeLowerBound();
|
||||
bool too_many; // True if there are too many actions, or false
|
||||
// if there are too few.
|
||||
if (action_count > upper_bound ||
|
||||
(action_count == upper_bound && repeated_action_specified_)) {
|
||||
too_many = true;
|
||||
} else if (0 < action_count && action_count < lower_bound &&
|
||||
!repeated_action_specified_) {
|
||||
too_many = false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
::std::stringstream ss;
|
||||
DescribeLocationTo(&ss);
|
||||
ss << "Too " << (too_many ? "many" : "few")
|
||||
<< " actions specified in " << source_text() << "...\n"
|
||||
<< "Expected to be ";
|
||||
cardinality().DescribeTo(&ss);
|
||||
ss << ", but has " << (too_many ? "" : "only ")
|
||||
<< action_count << " WillOnce()"
|
||||
<< (action_count == 1 ? "" : "s");
|
||||
if (repeated_action_specified_) {
|
||||
ss << " and a WillRepeatedly()";
|
||||
}
|
||||
ss << ".";
|
||||
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the .Times() clause.
|
||||
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
||||
if (last_clause_ == kTimes) {
|
||||
ExpectSpecProperty(false,
|
||||
".Times() cannot appear "
|
||||
"more than once in an EXPECT_CALL().");
|
||||
} else {
|
||||
ExpectSpecProperty(last_clause_ < kTimes,
|
||||
".Times() cannot appear after "
|
||||
".InSequence(), .WillOnce(), .WillRepeatedly(), "
|
||||
"or .RetiresOnSaturation().");
|
||||
}
|
||||
last_clause_ = kTimes;
|
||||
|
||||
SpecifyCardinality(a_cardinality);
|
||||
}
|
||||
|
||||
// Points to the implicit sequence introduced by a living InSequence
|
||||
// object (if any) in the current thread or NULL.
|
||||
GTEST_API_ 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 kAllow:
|
||||
Log(kInfo, msg, 3);
|
||||
break;
|
||||
case kWarn:
|
||||
Log(kWarning, msg, 3);
|
||||
break;
|
||||
default: // FAIL
|
||||
Expect(false, NULL, -1, msg);
|
||||
}
|
||||
}
|
||||
|
||||
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
|
||||
: mock_obj_(NULL), name_("") {}
|
||||
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||
|
||||
// Sets the mock object this mock method belongs to, and registers
|
||||
// this information in the global mock registry. Will be called
|
||||
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
||||
// method.
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
}
|
||||
Mock::Register(mock_obj, this);
|
||||
}
|
||||
|
||||
// Sets the mock object this mock method belongs to, and sets the name
|
||||
// of the mock function. Will be called upon each invocation of this
|
||||
// mock function.
|
||||
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||
const char* name)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// We protect name_ under g_gmock_mutex in case this mock function
|
||||
// is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
// Returns the name of the function being mocked. Must be called
|
||||
// after RegisterOwner() or SetOwnerAndName() has been called.
|
||||
const void* UntypedFunctionMockerBase::MockObject() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const void* mock_obj;
|
||||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
Assert(mock_obj_ != NULL, __FILE__, __LINE__,
|
||||
"MockObject() must not be called before RegisterOwner() or "
|
||||
"SetOwnerAndName() has been called.");
|
||||
mock_obj = mock_obj_;
|
||||
}
|
||||
return mock_obj;
|
||||
}
|
||||
|
||||
// Returns the name of this mock method. Must be called after
|
||||
// SetOwnerAndName() has been called.
|
||||
const char* UntypedFunctionMockerBase::Name() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const char* name;
|
||||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
Assert(name_ != NULL, __FILE__, __LINE__,
|
||||
"Name() must not be called before SetOwnerAndName() has "
|
||||
"been called.");
|
||||
name = name_;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// Calculates the result of invoking this mock function with the given
|
||||
// arguments, prints it, and returns it. The caller is responsible
|
||||
// for deleting the result.
|
||||
const UntypedActionResultHolderBase*
|
||||
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
if (untyped_expectations_.size() == 0) {
|
||||
// No expectation is set on this mock method - we have an
|
||||
// uninteresting call.
|
||||
|
||||
// We must get Google Mock's reaction on uninteresting calls
|
||||
// made on this mock object BEFORE performing the action,
|
||||
// because the action may DELETE the mock object and make the
|
||||
// following expression meaningless.
|
||||
const CallReaction reaction =
|
||||
Mock::GetReactionOnUninterestingCalls(MockObject());
|
||||
|
||||
// True iff we need to print this call's arguments and return
|
||||
// value. This definition must be kept in sync with
|
||||
// the behavior of ReportUninterestingCall().
|
||||
const bool need_to_report_uninteresting_call =
|
||||
// If the user allows this uninteresting call, we print it
|
||||
// only when he wants informational messages.
|
||||
reaction == kAllow ? LogIsVisible(kInfo) :
|
||||
// If the user wants this to be a warning, we print it only
|
||||
// when he wants to see warnings.
|
||||
reaction == kWarn ? LogIsVisible(kWarning) :
|
||||
// Otherwise, the user wants this to be an error, and we
|
||||
// should always print detailed information in the error.
|
||||
true;
|
||||
|
||||
if (!need_to_report_uninteresting_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return this->UntypedPerformDefaultAction(untyped_args, "");
|
||||
}
|
||||
|
||||
// Warns about the uninteresting call.
|
||||
::std::stringstream ss;
|
||||
this->UntypedDescribeUninterestingCall(untyped_args, &ss);
|
||||
|
||||
// Calculates the function result.
|
||||
const UntypedActionResultHolderBase* const result =
|
||||
this->UntypedPerformDefaultAction(untyped_args, ss.str());
|
||||
|
||||
// Prints the function result.
|
||||
if (result != NULL)
|
||||
result->PrintAsActionResult(&ss);
|
||||
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_excessive = false;
|
||||
::std::stringstream ss;
|
||||
::std::stringstream why;
|
||||
::std::stringstream loc;
|
||||
const void* untyped_action = NULL;
|
||||
|
||||
// The UntypedFindMatchingExpectation() function acquires and
|
||||
// releases g_gmock_mutex.
|
||||
const ExpectationBase* const untyped_expectation =
|
||||
this->UntypedFindMatchingExpectation(
|
||||
untyped_args, &untyped_action, &is_excessive,
|
||||
&ss, &why);
|
||||
const bool found = untyped_expectation != NULL;
|
||||
|
||||
// True iff we need to print the call's arguments and return value.
|
||||
// This definition must be kept in sync with the uses of Expect()
|
||||
// and Log() in this function.
|
||||
const bool need_to_report_call =
|
||||
!found || is_excessive || LogIsVisible(kInfo);
|
||||
if (!need_to_report_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return
|
||||
untyped_action == NULL ?
|
||||
this->UntypedPerformDefaultAction(untyped_args, "") :
|
||||
this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
}
|
||||
|
||||
ss << " Function call: " << Name();
|
||||
this->UntypedPrintArgs(untyped_args, &ss);
|
||||
|
||||
// In case the action deletes a piece of the expectation, we
|
||||
// generate the message beforehand.
|
||||
if (found && !is_excessive) {
|
||||
untyped_expectation->DescribeLocationTo(&loc);
|
||||
}
|
||||
|
||||
const UntypedActionResultHolderBase* const result =
|
||||
untyped_action == NULL ?
|
||||
this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
|
||||
this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
if (result != NULL)
|
||||
result->PrintAsActionResult(&ss);
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, NULL, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(),
|
||||
untyped_expectation->line(), ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns an Expectation object that references and co-owns exp,
|
||||
// which must be an expectation on this mock function.
|
||||
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
untyped_expectations_.begin();
|
||||
it != untyped_expectations_.end(); ++it) {
|
||||
if (it->get() == exp) {
|
||||
return Expectation(*it);
|
||||
}
|
||||
}
|
||||
|
||||
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
|
||||
return Expectation();
|
||||
// The above statement is just to make the code compile, and will
|
||||
// never be executed.
|
||||
}
|
||||
|
||||
// Verifies that all expectations on this mock function have been
|
||||
// satisfied. Reports one or more Google Test non-fatal failures
|
||||
// and returns false if not.
|
||||
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
bool expectations_met = true;
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
untyped_expectations_.begin();
|
||||
it != untyped_expectations_.end(); ++it) {
|
||||
ExpectationBase* const untyped_expectation = it->get();
|
||||
if (untyped_expectation->IsOverSaturated()) {
|
||||
// There was an upper-bound violation. Since the error was
|
||||
// already reported when it occurred, there is no need to do
|
||||
// anything here.
|
||||
expectations_met = false;
|
||||
} else if (!untyped_expectation->IsSatisfied()) {
|
||||
expectations_met = false;
|
||||
::std::stringstream ss;
|
||||
ss << "Actual function call count doesn't match "
|
||||
<< untyped_expectation->source_text() << "...\n";
|
||||
// No need to show the source file location of the expectation
|
||||
// in the description, as the Expect() call that follows already
|
||||
// takes care of it.
|
||||
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
|
||||
untyped_expectation->DescribeCallCountTo(&ss);
|
||||
Expect(false, untyped_expectation->file(),
|
||||
untyped_expectation->line(), ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Deleting our expectations may trigger other mock objects to be deleted, for
|
||||
// example if an action contains a reference counted smart pointer to that
|
||||
// mock object, and that is the last reference. So if we delete our
|
||||
// expectations within the context of the global mutex we may deadlock when
|
||||
// this method is called again. Instead, make a copy of the set of
|
||||
// expectations to delete, clear our set within the mutex, and then clear the
|
||||
// copied set outside of it.
|
||||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Class Mock.
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
|
||||
|
||||
// The current state of a mock object. Such information is needed for
|
||||
// detecting leaked mock objects and explicitly verifying a mock's
|
||||
// expectations.
|
||||
struct MockObjectState {
|
||||
MockObjectState()
|
||||
: first_used_file(NULL), first_used_line(-1), leakable(false) {}
|
||||
|
||||
// Where in the source file an ON_CALL or EXPECT_CALL is first
|
||||
// invoked on this mock object.
|
||||
const char* first_used_file;
|
||||
int first_used_line;
|
||||
::std::string first_used_test_case;
|
||||
::std::string first_used_test;
|
||||
bool leakable; // true iff it's OK to leak the object.
|
||||
FunctionMockers function_mockers; // All registered methods of the object.
|
||||
};
|
||||
|
||||
// A global registry holding the state of all mock objects that are
|
||||
// alive. A mock object is added to this registry the first time
|
||||
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
|
||||
// is removed from the registry in the mock object's destructor.
|
||||
class MockObjectRegistry {
|
||||
public:
|
||||
// Maps a mock object (identified by its address) to its state.
|
||||
typedef std::map<const void*, MockObjectState> StateMap;
|
||||
|
||||
// This destructor will be called when a program exits, after all
|
||||
// tests in it have been run. By then, there should be no mock
|
||||
// object alive. Therefore we report any living object as test
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
|
||||
// a macro.
|
||||
|
||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||
return;
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
++it) {
|
||||
if (it->second.leakable) // The user said it's fine to leak this object.
|
||||
continue;
|
||||
|
||||
// TODO(wan@google.com): Print the type of the leaked object.
|
||||
// This can help the user identify the leaked object.
|
||||
std::cout << "\n";
|
||||
const MockObjectState& state = it->second;
|
||||
std::cout << internal::FormatFileLocation(state.first_used_file,
|
||||
state.first_used_line);
|
||||
std::cout << " ERROR: this mock object";
|
||||
if (state.first_used_test != "") {
|
||||
std::cout << " (used in test " << state.first_used_test_case << "."
|
||||
<< state.first_used_test << ")";
|
||||
}
|
||||
std::cout << " should be deleted but never is. Its address is @"
|
||||
<< it->first << ".";
|
||||
leaked_count++;
|
||||
}
|
||||
if (leaked_count > 0) {
|
||||
std::cout << "\nERROR: " << leaked_count
|
||||
<< " leaked mock " << (leaked_count == 1 ? "object" : "objects")
|
||||
<< " found at program exit.\n";
|
||||
std::cout.flush();
|
||||
::std::cerr.flush();
|
||||
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||
// called. Therefore we cannot use the normal Google Test
|
||||
// failure reporting mechanism.
|
||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||
// may already have been called.
|
||||
}
|
||||
}
|
||||
|
||||
StateMap& states() { return states_; }
|
||||
|
||||
private:
|
||||
StateMap states_;
|
||||
};
|
||||
|
||||
// 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.
|
||||
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
internal::CallReaction reaction)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
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.
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
|
||||
}
|
||||
|
||||
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||
// given mock object.
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
|
||||
}
|
||||
|
||||
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||
// object.
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
|
||||
}
|
||||
|
||||
// Tells Google Mock the given mock object is being destroyed and its
|
||||
// entry in the call-reaction table should be removed.
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
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.
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::kDefault : g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
// objects.
|
||||
void Mock::AllowLeak(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
|
||||
// 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.
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
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.
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
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.
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
if (g_mock_object_registry.states().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.states()[mock_obj].function_mockers;
|
||||
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.
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
|
||||
// Tells Google Mock where in the source code mock_obj is used in an
|
||||
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
|
||||
// information helps the user identify which object it is.
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||
const char* file, int line)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||
if (state.first_used_file == NULL) {
|
||||
state.first_used_file = file;
|
||||
state.first_used_line = line;
|
||||
const TestInfo* const test_info =
|
||||
UnitTest::GetInstance()->current_test_info();
|
||||
if (test_info != NULL) {
|
||||
// TODO(wan@google.com): record the test case name when the
|
||||
// ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
|
||||
// TearDownTestCase().
|
||||
state.first_used_test_case = test_info->test_case_name();
|
||||
state.first_used_test = test_info->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
for (MockObjectRegistry::StateMap::iterator it =
|
||||
g_mock_object_registry.states().begin();
|
||||
it != g_mock_object_registry.states().end(); ++it) {
|
||||
FunctionMockers& mockers = it->second.function_mockers;
|
||||
if (mockers.erase(mocker) > 0) {
|
||||
// mocker was in mockers and has been just removed.
|
||||
if (mockers.empty()) {
|
||||
g_mock_object_registry.states().erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clears all ON_CALL()s set on the given mock object.
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
|
||||
if (g_mock_object_registry.states().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.states()[mock_obj].function_mockers;
|
||||
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().
|
||||
}
|
||||
|
||||
Expectation::Expectation() {}
|
||||
|
||||
Expectation::Expectation(
|
||||
const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
|
||||
: expectation_base_(an_expectation_base) {}
|
||||
|
||||
Expectation::~Expectation() {}
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(const Expectation& expectation) const {
|
||||
if (*last_expectation_ != expectation) {
|
||||
if (last_expectation_->expectation_base() != NULL) {
|
||||
expectation.expectation_base()->immediate_prerequisites_
|
||||
+= *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
|
||||
@@ -1,182 +0,0 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// TODO(wan@google.com): support using environment variables to
|
||||
// control the flag values, like what Google Test does.
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
"true iff Google Mock should report leaked mock objects "
|
||||
"as failures.");
|
||||
|
||||
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 std::string flag_str = std::string("--gmock_") + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
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 bool 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 ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == NULL) return false;
|
||||
|
||||
// Converts the string value to a bool.
|
||||
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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,
|
||||
std::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 std::string arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||
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.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <iostream>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
|
||||
// causes a link error when _tmain is defined in a static library and UNICODE
|
||||
// is enabled. For this reason instead of _tmain, main function is used on
|
||||
// Windows. See the following link to track the current status of this bug:
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <tchar.h> // NOLINT
|
||||
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
#else
|
||||
GTEST_API_ int main(int argc, char** argv) {
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
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();
|
||||
}
|
||||
@@ -39,7 +39,6 @@ endif
|
||||
|
||||
# Call the makefiles for all our tests used in TradeFederation
|
||||
MODULAR_DRM_PATH := vendor/widevine/libwvdrmengine
|
||||
include $(MODULAR_DRM_PATH)/test/gmock/Android.mk
|
||||
include $(MODULAR_DRM_PATH)/cdm/test/Android.mk
|
||||
include $(MODULAR_DRM_PATH)/mediacrypto/test/Android.mk
|
||||
include $(MODULAR_DRM_PATH)/mediadrm/test/Android.mk
|
||||
|
||||
Reference in New Issue
Block a user