mirror of
https://github.com/monero-project/monero.git
synced 2024-12-29 13:16:13 -05:00
updated gtest
This commit is contained in:
parent
153fe0cb75
commit
4df6aa5d12
@ -22,6 +22,11 @@ option(gtest_build_samples "Build gtest's sample programs." OFF)
|
|||||||
|
|
||||||
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
|
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
|
||||||
|
|
||||||
|
option(
|
||||||
|
gtest_hide_internal_symbols
|
||||||
|
"Build gtest with internal symbols hidden in shared libraries."
|
||||||
|
OFF)
|
||||||
|
|
||||||
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||||
include(cmake/hermetic_build.cmake OPTIONAL)
|
include(cmake/hermetic_build.cmake OPTIONAL)
|
||||||
|
|
||||||
@ -46,6 +51,11 @@ if (COMMAND set_up_hermetic_build)
|
|||||||
set_up_hermetic_build()
|
set_up_hermetic_build()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (gtest_hide_internal_symbols)
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||||
|
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Define helper functions and macros used by Google Test.
|
# Define helper functions and macros used by Google Test.
|
||||||
include(cmake/internal_utils.cmake)
|
include(cmake/internal_utils.cmake)
|
||||||
|
|
||||||
@ -81,6 +91,22 @@ cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
|
|||||||
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
|
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
|
||||||
target_link_libraries(gtest_main gtest)
|
target_link_libraries(gtest_main gtest)
|
||||||
|
|
||||||
|
# If the CMake version supports it, attach header directory information
|
||||||
|
# to the targets for when we are part of a parent build (ie being pulled
|
||||||
|
# in via add_subdirectory() rather than being a standalone build).
|
||||||
|
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||||
|
target_include_directories(gtest INTERFACE "${gtest_SOURCE_DIR}/include")
|
||||||
|
target_include_directories(gtest_main INTERFACE "${gtest_SOURCE_DIR}/include")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# Install rules
|
||||||
|
install(TARGETS gtest gtest_main
|
||||||
|
DESTINATION lib)
|
||||||
|
install(DIRECTORY ${gtest_SOURCE_DIR}/include/gtest
|
||||||
|
DESTINATION include)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
# Samples on how to link user tests with gtest or gtest_main.
|
# Samples on how to link user tests with gtest or gtest_main.
|
||||||
|
@ -1,435 +0,0 @@
|
|||||||
Google C++ Testing Framework
|
|
||||||
============================
|
|
||||||
|
|
||||||
http://code.google.com/p/googletest/
|
|
||||||
|
|
||||||
Overview
|
|
||||||
--------
|
|
||||||
|
|
||||||
Google's framework for writing C++ tests on a variety of platforms
|
|
||||||
(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the
|
|
||||||
xUnit architecture. Supports automatic test discovery, a rich set of
|
|
||||||
assertions, user-defined assertions, death tests, fatal and non-fatal
|
|
||||||
failures, various options for running the tests, and XML test report
|
|
||||||
generation.
|
|
||||||
|
|
||||||
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!
|
|
||||||
|
|
||||||
Requirements for End Users
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
Google Test is designed to have fairly minimal requirements to build
|
|
||||||
and use with your projects, but there are some. Currently, we support
|
|
||||||
Linux, Windows, Mac OS X, and Cygwin. We will also make our best
|
|
||||||
effort to support other platforms (e.g. Solaris, AIX, and z/OS).
|
|
||||||
However, since core members of the Google Test project have no access
|
|
||||||
to these platforms, Google Test may have outstanding issues there. If
|
|
||||||
you notice any problems on your platform, please notify
|
|
||||||
googletestframework@googlegroups.com. Patches for fixing them are
|
|
||||||
even more welcome!
|
|
||||||
|
|
||||||
### Linux Requirements ###
|
|
||||||
|
|
||||||
These are the base requirements to build and use Google Test from a source
|
|
||||||
package (as described below):
|
|
||||||
* GNU-compatible Make or gmake
|
|
||||||
* POSIX-standard shell
|
|
||||||
* POSIX(-2) Regular Expressions (regex.h)
|
|
||||||
* A C++98-standard-compliant compiler
|
|
||||||
|
|
||||||
### Windows Requirements ###
|
|
||||||
|
|
||||||
* Microsoft Visual C++ 7.1 or newer
|
|
||||||
|
|
||||||
### Cygwin Requirements ###
|
|
||||||
|
|
||||||
* Cygwin 1.5.25-14 or newer
|
|
||||||
|
|
||||||
### Mac OS X Requirements ###
|
|
||||||
|
|
||||||
* Mac OS X 10.4 Tiger or newer
|
|
||||||
* Developer Tools Installed
|
|
||||||
|
|
||||||
Also, you'll need CMake 2.6.4 or higher if you want to build the
|
|
||||||
samples using the provided CMake script, regardless of the platform.
|
|
||||||
|
|
||||||
Requirements for Contributors
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
We welcome patches. If you plan to contribute a patch, you need to
|
|
||||||
build Google Test and its own tests from an SVN checkout (described
|
|
||||||
below), which has further requirements:
|
|
||||||
|
|
||||||
* Python version 2.3 or newer (for running some of the tests and
|
|
||||||
re-generating certain source files from templates)
|
|
||||||
* CMake 2.6.4 or newer
|
|
||||||
|
|
||||||
Getting the Source
|
|
||||||
------------------
|
|
||||||
|
|
||||||
There are two primary ways of getting Google Test'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) repository.
|
|
||||||
The SVN checkout requires a few extra steps and some extra software
|
|
||||||
packages on your system, but lets you track the latest development and
|
|
||||||
make patches much more easily, so we highly encourage it.
|
|
||||||
|
|
||||||
### Source Package ###
|
|
||||||
|
|
||||||
Google Test 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 used to
|
|
||||||
manipulate them, and the size of the resulting file. Download
|
|
||||||
whichever you are most comfortable with.
|
|
||||||
|
|
||||||
[1] http://code.google.com/p/googletest/downloads/list
|
|
||||||
|
|
||||||
Once the package is downloaded, expand it using whichever tools you
|
|
||||||
prefer for that type. This will result in a new directory with the
|
|
||||||
name "gtest-X.Y.Z" which contains all of the source code. Here are
|
|
||||||
some examples on Linux:
|
|
||||||
|
|
||||||
tar -xvzf gtest-X.Y.Z.tar.gz
|
|
||||||
tar -xvjf gtest-X.Y.Z.tar.bz2
|
|
||||||
unzip gtest-X.Y.Z.zip
|
|
||||||
|
|
||||||
### SVN Checkout ###
|
|
||||||
|
|
||||||
To check out the main branch (also known as the "trunk") of Google
|
|
||||||
Test, run the following Subversion command:
|
|
||||||
|
|
||||||
svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
|
|
||||||
|
|
||||||
Setting up the Build
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
To build Google Test 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 ###
|
|
||||||
|
|
||||||
Suppose you put Google Test in directory ${GTEST_DIR}. To build it,
|
|
||||||
create a library build target (or a project as called by Visual Studio
|
|
||||||
and Xcode) to compile
|
|
||||||
|
|
||||||
${GTEST_DIR}/src/gtest-all.cc
|
|
||||||
|
|
||||||
with ${GTEST_DIR}/include in the system header search path and ${GTEST_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} \
|
|
||||||
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
|
|
||||||
ar -rv libgtest.a gtest-all.o
|
|
||||||
|
|
||||||
(We need -pthread as Google Test uses threads.)
|
|
||||||
|
|
||||||
Next, you should compile your test source file with
|
|
||||||
${GTEST_DIR}/include in the system header search path, and link it
|
|
||||||
with gtest and any other necessary libraries:
|
|
||||||
|
|
||||||
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
|
|
||||||
-o your_test
|
|
||||||
|
|
||||||
As an example, the make/ directory contains a Makefile that you can
|
|
||||||
use to build Google Test on systems where GNU make is available
|
|
||||||
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
|
|
||||||
Test's own tests. Instead, it just builds the Google Test 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 ${GTEST_DIR}/make
|
|
||||||
make
|
|
||||||
./sample1_unittest
|
|
||||||
|
|
||||||
If you see errors, try to tweak the contents of make/Makefile to make
|
|
||||||
them go away. There are instructions in make/Makefile on how to do
|
|
||||||
it.
|
|
||||||
|
|
||||||
### Using CMake ###
|
|
||||||
|
|
||||||
Google Test comes with a CMake build script (CMakeLists.txt) that can
|
|
||||||
be used on a wide range of platforms ("C" stands for cross-platform.).
|
|
||||||
If you don't have CMake installed already, you can download it for
|
|
||||||
free from http://www.cmake.org/.
|
|
||||||
|
|
||||||
CMake works by generating native makefiles or build projects that can
|
|
||||||
be used in the compiler environment of your choice. The typical
|
|
||||||
workflow starts with:
|
|
||||||
|
|
||||||
mkdir mybuild # Create a directory to hold the build output.
|
|
||||||
cd mybuild
|
|
||||||
cmake ${GTEST_DIR} # Generate native build scripts.
|
|
||||||
|
|
||||||
If you want to build Google Test's samples, you should replace the
|
|
||||||
last command with
|
|
||||||
|
|
||||||
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
|
|
||||||
|
|
||||||
If you are on a *nix system, you should now see a Makefile in the
|
|
||||||
current directory. Just type 'make' to build gtest.
|
|
||||||
|
|
||||||
If you use Windows and have Visual Studio installed, a gtest.sln file
|
|
||||||
and several .vcproj files will be created. You can then build them
|
|
||||||
using Visual Studio.
|
|
||||||
|
|
||||||
On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
|
|
||||||
|
|
||||||
### Legacy Build Scripts ###
|
|
||||||
|
|
||||||
Before settling on CMake, we have been providing hand-maintained build
|
|
||||||
projects/scripts for Visual Studio, Xcode, and Autotools. While we
|
|
||||||
continue to provide them for convenience, they are not actively
|
|
||||||
maintained any more. We highly recommend that you follow the
|
|
||||||
instructions in the previous two sections to integrate Google Test
|
|
||||||
with your existing build system.
|
|
||||||
|
|
||||||
If you still need to use the legacy build scripts, here's how:
|
|
||||||
|
|
||||||
The msvc\ folder contains two solutions with Visual C++ projects.
|
|
||||||
Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
|
|
||||||
are ready to build Google Test the same way you build any Visual
|
|
||||||
Studio project. Files that have names ending with -md use DLL
|
|
||||||
versions of Microsoft runtime libraries (the /MD or the /MDd compiler
|
|
||||||
option). Files without that suffix use static versions of the runtime
|
|
||||||
libraries (the /MT or the /MTd option). Please note that one must use
|
|
||||||
the same option to compile both gtest and the test code. If you use
|
|
||||||
Visual Studio 2005 or above, we recommend the -md version as /MD is
|
|
||||||
the default for new projects in these versions of Visual Studio.
|
|
||||||
|
|
||||||
On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
|
|
||||||
Xcode. Build the "gtest" target. The universal binary framework will
|
|
||||||
end up in your selected build directory (selected in the Xcode
|
|
||||||
"Preferences..." -> "Building" pane and defaults to xcode/build).
|
|
||||||
Alternatively, at the command line, enter:
|
|
||||||
|
|
||||||
xcodebuild
|
|
||||||
|
|
||||||
This will build the "Release" configuration of gtest.framework in your
|
|
||||||
default build location. See the "xcodebuild" man page for more
|
|
||||||
information about building different configurations and building in
|
|
||||||
different locations.
|
|
||||||
|
|
||||||
If you wish to use the Google Test Xcode project with Xcode 4.x and
|
|
||||||
above, you need to either:
|
|
||||||
* update the SDK configuration options in xcode/Config/General.xconfig.
|
|
||||||
Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If
|
|
||||||
you choose this route you lose the ability to target earlier versions
|
|
||||||
of MacOS X.
|
|
||||||
* Install an SDK for an earlier version. This doesn't appear to be
|
|
||||||
supported by Apple, but has been reported to work
|
|
||||||
(http://stackoverflow.com/questions/5378518).
|
|
||||||
|
|
||||||
Tweaking Google Test
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Google Test 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 Test 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 include/gtest/internal/gtest-port.h.
|
|
||||||
|
|
||||||
### Choosing a TR1 Tuple Library ###
|
|
||||||
|
|
||||||
Some Google Test features require the C++ Technical Report 1 (TR1)
|
|
||||||
tuple library, which is not yet available with all compilers. The
|
|
||||||
good news is that Google Test implements a subset of TR1 tuple that's
|
|
||||||
enough for its own need, and will automatically use this when the
|
|
||||||
compiler doesn't provide TR1 tuple.
|
|
||||||
|
|
||||||
Usually you don't need to care about which tuple library Google Test
|
|
||||||
uses. However, if your project already uses TR1 tuple, you need to
|
|
||||||
tell Google Test 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 and your tests. If
|
|
||||||
you want to force Google Test to use its own tuple library, just add
|
|
||||||
|
|
||||||
-DGTEST_USE_OWN_TR1_TUPLE=1
|
|
||||||
|
|
||||||
to the compiler flags instead.
|
|
||||||
|
|
||||||
If you don't want Google Test to use tuple at all, add
|
|
||||||
|
|
||||||
-DGTEST_HAS_TR1_TUPLE=0
|
|
||||||
|
|
||||||
and all features using tuple will be disabled.
|
|
||||||
|
|
||||||
### Multi-threaded Tests ###
|
|
||||||
|
|
||||||
Google Test is thread-safe where the pthread library is available.
|
|
||||||
After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE
|
|
||||||
macro to see whether this is the case (yes if the macro is #defined to
|
|
||||||
1, no if it's undefined.).
|
|
||||||
|
|
||||||
If Google Test doesn't correctly detect whether pthread is available
|
|
||||||
in your environment, you can force it with
|
|
||||||
|
|
||||||
-DGTEST_HAS_PTHREAD=1
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
-DGTEST_HAS_PTHREAD=0
|
|
||||||
|
|
||||||
When Google Test uses pthread, you may need to add flags to your
|
|
||||||
compiler and/or linker to select the pthread library, or you'll get
|
|
||||||
link errors. If you use the CMake script or the deprecated Autotools
|
|
||||||
script, this is taken care of for you. If you use your own build
|
|
||||||
script, you'll need to read your compiler and linker's manual to
|
|
||||||
figure out what flags to add.
|
|
||||||
|
|
||||||
### As a Shared Library (DLL) ###
|
|
||||||
|
|
||||||
Google Test is compact, so most users can build and link it as a
|
|
||||||
static library for the simplicity. You can choose to use Google Test
|
|
||||||
as a shared library (known as a DLL on Windows) if you prefer.
|
|
||||||
|
|
||||||
To compile *gtest* as a shared library, add
|
|
||||||
|
|
||||||
-DGTEST_CREATE_SHARED_LIBRARY=1
|
|
||||||
|
|
||||||
to the compiler flags. You'll also need to tell the linker to produce
|
|
||||||
a shared library instead - consult your linker's manual for how to do
|
|
||||||
it.
|
|
||||||
|
|
||||||
To compile your *tests* that use the gtest shared library, add
|
|
||||||
|
|
||||||
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
|
||||||
|
|
||||||
to the compiler flags.
|
|
||||||
|
|
||||||
Note: while the above steps aren't technically necessary today when
|
|
||||||
using some compilers (e.g. GCC), they may become necessary in the
|
|
||||||
future, if we decide to improve the speed of loading the library (see
|
|
||||||
http://gcc.gnu.org/wiki/Visibility for details). Therefore you are
|
|
||||||
recommended to always add the above flags when using Google Test as a
|
|
||||||
shared library. Otherwise a future release of Google Test may break
|
|
||||||
your build script.
|
|
||||||
|
|
||||||
### Avoiding Macro Name Clashes ###
|
|
||||||
|
|
||||||
In C++, macros don't obey namespaces. Therefore two libraries that
|
|
||||||
both define a macro of the same name will clash if you #include both
|
|
||||||
definitions. In case a Google Test macro clashes with another
|
|
||||||
library, you can force Google Test to rename its macro to avoid the
|
|
||||||
conflict.
|
|
||||||
|
|
||||||
Specifically, if both Google Test and some other code define macro
|
|
||||||
FOO, you can add
|
|
||||||
|
|
||||||
-DGTEST_DONT_DEFINE_FOO=1
|
|
||||||
|
|
||||||
to the compiler flags to tell Google Test to change the macro's name
|
|
||||||
from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST.
|
|
||||||
For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
|
|
||||||
|
|
||||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
|
||||||
|
|
||||||
instead of
|
|
||||||
|
|
||||||
TEST(SomeTest, DoesThis) { ... }
|
|
||||||
|
|
||||||
in order to define a test.
|
|
||||||
|
|
||||||
Upgrating from an Earlier Version
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
We strive to keep Google Test 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 Test.
|
|
||||||
|
|
||||||
### Upgrading from 1.3.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 ###
|
|
||||||
|
|
||||||
The Autotools build script (configure + make) is no longer officially
|
|
||||||
supportted. You are encouraged to migrate to your own build system or
|
|
||||||
use CMake. If you still need to use Autotools, you can find
|
|
||||||
instructions in the README file from Google Test 1.4.0.
|
|
||||||
|
|
||||||
On platforms where the pthread library is available, Google Test uses
|
|
||||||
it in order to be thread-safe. See the "Multi-threaded Tests" section
|
|
||||||
for what this means to your build script.
|
|
||||||
|
|
||||||
If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
|
|
||||||
Test will no longer compile. This should affect very few people, as a
|
|
||||||
large portion of STL (including <string>) doesn't compile in this mode
|
|
||||||
anyway. We decided to stop supporting it in order to greatly simplify
|
|
||||||
Google Test's implementation.
|
|
||||||
|
|
||||||
Developing Google Test
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
This section discusses how to make your own changes to Google Test.
|
|
||||||
|
|
||||||
### Testing Google Test 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 can use CMake:
|
|
||||||
|
|
||||||
mkdir mybuild
|
|
||||||
cd mybuild
|
|
||||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
|
|
||||||
|
|
||||||
Make sure you have Python installed, as some of Google Test's tests
|
|
||||||
are written in Python. If the cmake command complains about not being
|
|
||||||
able to find Python ("Could NOT find PythonInterp (missing:
|
|
||||||
PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
|
|
||||||
executable can be found:
|
|
||||||
|
|
||||||
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
|
|
||||||
|
|
||||||
Next, you can build Google Test and all of its own tests. On *nix,
|
|
||||||
this is usually done by 'make'. To run the tests, do
|
|
||||||
|
|
||||||
make test
|
|
||||||
|
|
||||||
All tests should pass.
|
|
||||||
|
|
||||||
### Regenerating Source Files ###
|
|
||||||
|
|
||||||
Some of Google Test'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/gtest/internal/gtest-type-util.h.pump is used to generate
|
|
||||||
gtest-type-util.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.py Python script to
|
|
||||||
regenerate them. You can find pump.py in the scripts/ directory.
|
|
||||||
Read the Pump manual [2] for how to use it.
|
|
||||||
|
|
||||||
[2] http://code.google.com/p/googletest/wiki/PumpManual
|
|
||||||
|
|
||||||
### Contributing a Patch ###
|
|
||||||
|
|
||||||
We welcome patches. Please read the Google Test developer's guide [3]
|
|
||||||
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.
|
|
||||||
|
|
||||||
[3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
|
|
||||||
|
|
||||||
Happy testing!
|
|
@ -1387,14 +1387,17 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
|
|||||||
static int AddToRegistry() { \
|
static int AddToRegistry() { \
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
GetTestCasePatternHolder<test_case_name>(\
|
||||||
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
|
#test_case_name, \
|
||||||
|
::testing::internal::CodeLocation(\
|
||||||
|
__FILE__, __LINE__))->AddTestPattern(\
|
||||||
#test_case_name, \
|
#test_case_name, \
|
||||||
#test_name, \
|
#test_name, \
|
||||||
new ::testing::internal::TestMetaFactory< \
|
new ::testing::internal::TestMetaFactory< \
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
|
GTEST_TEST_CLASS_NAME_(\
|
||||||
|
test_case_name, test_name)>()); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static int gtest_registering_dummy_; \
|
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
||||||
}; \
|
}; \
|
||||||
@ -1403,15 +1406,35 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
|
|||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
||||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
||||||
|
|
||||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
|
// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user
|
||||||
|
// to specify a function or functor that generates custom test name suffixes
|
||||||
|
// based on the test parameters. The function should accept one argument of
|
||||||
|
// type testing::TestParamInfo<class ParamType>, and return std::string.
|
||||||
|
//
|
||||||
|
// testing::PrintToStringParamName is a builtin test suffix generator that
|
||||||
|
// returns the value of testing::PrintToString(GetParam()). It does not work
|
||||||
|
// for std::string or C strings.
|
||||||
|
//
|
||||||
|
// Note: test names must be non-empty, unique, and may only contain ASCII
|
||||||
|
// alphanumeric characters or underscore.
|
||||||
|
|
||||||
|
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
||||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||||
int gtest_##prefix##test_case_name##_dummy_ = \
|
::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||||
|
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||||
|
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
||||||
|
(__VA_ARGS__)(info); \
|
||||||
|
} \
|
||||||
|
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
GetTestCasePatternHolder<test_case_name>(\
|
||||||
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
|
#test_case_name, \
|
||||||
|
::testing::internal::CodeLocation(\
|
||||||
|
__FILE__, __LINE__))->AddTestCaseInstantiation(\
|
||||||
#prefix, \
|
#prefix, \
|
||||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
>est_##prefix##test_case_name##_EvalGenerator_, \
|
||||||
|
>est_##prefix##test_case_name##_EvalGenerateName_, \
|
||||||
__FILE__, __LINE__)
|
__FILE__, __LINE__)
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -453,14 +453,17 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
|||||||
static int AddToRegistry() { \
|
static int AddToRegistry() { \
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
GetTestCasePatternHolder<test_case_name>(\
|
||||||
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
|
#test_case_name, \
|
||||||
|
::testing::internal::CodeLocation(\
|
||||||
|
__FILE__, __LINE__))->AddTestPattern(\
|
||||||
#test_case_name, \
|
#test_case_name, \
|
||||||
#test_name, \
|
#test_name, \
|
||||||
new ::testing::internal::TestMetaFactory< \
|
new ::testing::internal::TestMetaFactory< \
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
|
GTEST_TEST_CLASS_NAME_(\
|
||||||
|
test_case_name, test_name)>()); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
static int gtest_registering_dummy_; \
|
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
||||||
}; \
|
}; \
|
||||||
@ -469,15 +472,35 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
|||||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
||||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
||||||
|
|
||||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
|
// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user
|
||||||
|
// to specify a function or functor that generates custom test name suffixes
|
||||||
|
// based on the test parameters. The function should accept one argument of
|
||||||
|
// type testing::TestParamInfo<class ParamType>, and return std::string.
|
||||||
|
//
|
||||||
|
// testing::PrintToStringParamName is a builtin test suffix generator that
|
||||||
|
// returns the value of testing::PrintToString(GetParam()).
|
||||||
|
//
|
||||||
|
// Note: test names must be non-empty, unique, and may only contain ASCII
|
||||||
|
// alphanumeric characters or underscore. Because PrintToString adds quotes
|
||||||
|
// to std::string and C strings, it won't work for these types.
|
||||||
|
|
||||||
|
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
||||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||||
int gtest_##prefix##test_case_name##_dummy_ = \
|
::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||||
|
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||||
|
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
||||||
|
(__VA_ARGS__)(info); \
|
||||||
|
} \
|
||||||
|
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||||
GetTestCasePatternHolder<test_case_name>(\
|
GetTestCasePatternHolder<test_case_name>(\
|
||||||
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
|
#test_case_name, \
|
||||||
|
::testing::internal::CodeLocation(\
|
||||||
|
__FILE__, __LINE__))->AddTestCaseInstantiation(\
|
||||||
#prefix, \
|
#prefix, \
|
||||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
>est_##prefix##test_case_name##_EvalGenerator_, \
|
||||||
|
>est_##prefix##test_case_name##_EvalGenerateName_, \
|
||||||
__FILE__, __LINE__)
|
__FILE__, __LINE__)
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
@ -254,6 +254,103 @@ void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
|
||||||
|
// value of type ToPrint that is an operand of a comparison assertion
|
||||||
|
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
|
||||||
|
// the comparison, and is used to help determine the best way to
|
||||||
|
// format the value. In particular, when the value is a C string
|
||||||
|
// (char pointer) and the other operand is an STL string object, we
|
||||||
|
// want to format the C string as a string, since we know it is
|
||||||
|
// compared by value with the string object. If the value is a char
|
||||||
|
// pointer but the other operand is not an STL string object, we don't
|
||||||
|
// know whether the pointer is supposed to point to a NUL-terminated
|
||||||
|
// string, and thus want to print it as a pointer to be safe.
|
||||||
|
//
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
|
||||||
|
// The default case.
|
||||||
|
template <typename ToPrint, typename OtherOperand>
|
||||||
|
class FormatForComparison {
|
||||||
|
public:
|
||||||
|
static ::std::string Format(const ToPrint& value) {
|
||||||
|
return ::testing::PrintToString(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Array.
|
||||||
|
template <typename ToPrint, size_t N, typename OtherOperand>
|
||||||
|
class FormatForComparison<ToPrint[N], OtherOperand> {
|
||||||
|
public:
|
||||||
|
static ::std::string Format(const ToPrint* value) {
|
||||||
|
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// By default, print C string as pointers to be safe, as we don't know
|
||||||
|
// whether they actually point to a NUL-terminated string.
|
||||||
|
|
||||||
|
#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
|
||||||
|
template <typename OtherOperand> \
|
||||||
|
class FormatForComparison<CharType*, OtherOperand> { \
|
||||||
|
public: \
|
||||||
|
static ::std::string Format(CharType* value) { \
|
||||||
|
return ::testing::PrintToString(static_cast<const void*>(value)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
||||||
|
|
||||||
|
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
|
||||||
|
|
||||||
|
// If a C string is compared with an STL string object, we know it's meant
|
||||||
|
// to point to a NUL-terminated string, and thus can print it as a string.
|
||||||
|
|
||||||
|
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
|
||||||
|
template <> \
|
||||||
|
class FormatForComparison<CharType*, OtherStringType> { \
|
||||||
|
public: \
|
||||||
|
static ::std::string Format(CharType* value) { \
|
||||||
|
return ::testing::PrintToString(value); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
||||||
|
|
||||||
|
#if GTEST_HAS_GLOBAL_STRING
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_HAS_GLOBAL_WSTRING
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_HAS_STD_WSTRING
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
|
||||||
|
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
|
||||||
|
|
||||||
|
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
|
||||||
|
// operand to be used in a failure message. The type (but not value)
|
||||||
|
// of the other operand may affect the format. This allows us to
|
||||||
|
// print a char* as a raw pointer when it is compared against another
|
||||||
|
// char* or void*, and print it as a C string when it is compared
|
||||||
|
// against an std::string object, for example.
|
||||||
|
//
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
std::string FormatForComparisonFailureMessage(
|
||||||
|
const T1& value, const T2& /* other_operand */) {
|
||||||
|
return FormatForComparison<T1, T2>::Format(value);
|
||||||
|
}
|
||||||
|
|
||||||
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
||||||
// value to the given ostream. The caller must ensure that
|
// value to the given ostream. The caller must ensure that
|
||||||
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
||||||
@ -888,4 +985,9 @@ template <typename T>
|
|||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
// Include any custom printer added by the local installation.
|
||||||
|
// We must include this header at the end to make sure it can use the
|
||||||
|
// declarations from this file.
|
||||||
|
#include "gtest/internal/custom/gtest-printers.h"
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||||
|
@ -181,7 +181,8 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
|||||||
::testing::internal::TemplateSel< \
|
::testing::internal::TemplateSel< \
|
||||||
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
|
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
|
||||||
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
|
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
|
||||||
"", #CaseName, #TestName, 0); \
|
"", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||||
|
#CaseName, #TestName, 0); \
|
||||||
template <typename gtest_TypeParam_> \
|
template <typename gtest_TypeParam_> \
|
||||||
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
|
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
|
||||||
|
|
||||||
@ -252,7 +253,10 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
|||||||
::testing::internal::TypeParameterizedTestCase<CaseName, \
|
::testing::internal::TypeParameterizedTestCase<CaseName, \
|
||||||
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
||||||
::testing::internal::TypeList< Types >::type>::Register(\
|
::testing::internal::TypeList< Types >::type>::Register(\
|
||||||
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
|
#Prefix, \
|
||||||
|
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||||
|
>EST_TYPED_TEST_CASE_P_STATE_(CaseName), \
|
||||||
|
#CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
|
||||||
|
|
||||||
#endif // GTEST_HAS_TYPED_TEST_P
|
#endif // GTEST_HAS_TYPED_TEST_P
|
||||||
|
|
||||||
|
@ -452,8 +452,7 @@ class GTEST_API_ Test {
|
|||||||
// internal method to avoid clashing with names used in user TESTs.
|
// internal method to avoid clashing with names used in user TESTs.
|
||||||
void DeleteSelf_() { delete this; }
|
void DeleteSelf_() { delete this; }
|
||||||
|
|
||||||
// Uses a GTestFlagSaver to save and restore all Google Test flags.
|
const internal::scoped_ptr< GTEST_FLAG_SAVER_ > gtest_flag_saver_;
|
||||||
const internal::GTestFlagSaver* const gtest_flag_saver_;
|
|
||||||
|
|
||||||
// Often a user misspells SetUp() as Setup() and spends a long time
|
// Often a user misspells SetUp() as Setup() and spends a long time
|
||||||
// wondering why it is never called by Google Test. The declaration of
|
// wondering why it is never called by Google Test. The declaration of
|
||||||
@ -670,6 +669,12 @@ class GTEST_API_ TestInfo {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the file name where this test is defined.
|
||||||
|
const char* file() const { return location_.file.c_str(); }
|
||||||
|
|
||||||
|
// Returns the line where this test is defined.
|
||||||
|
int line() const { return location_.line; }
|
||||||
|
|
||||||
// Returns true if this test should run, that is if the test is not
|
// Returns true if this test should run, that is if the test is not
|
||||||
// disabled (or it is disabled but the also_run_disabled_tests flag has
|
// disabled (or it is disabled but the also_run_disabled_tests flag has
|
||||||
// been specified) and its full name matches the user-specified filter.
|
// been specified) and its full name matches the user-specified filter.
|
||||||
@ -712,6 +717,7 @@ class GTEST_API_ TestInfo {
|
|||||||
const char* name,
|
const char* name,
|
||||||
const char* type_param,
|
const char* type_param,
|
||||||
const char* value_param,
|
const char* value_param,
|
||||||
|
internal::CodeLocation code_location,
|
||||||
internal::TypeId fixture_class_id,
|
internal::TypeId fixture_class_id,
|
||||||
Test::SetUpTestCaseFunc set_up_tc,
|
Test::SetUpTestCaseFunc set_up_tc,
|
||||||
Test::TearDownTestCaseFunc tear_down_tc,
|
Test::TearDownTestCaseFunc tear_down_tc,
|
||||||
@ -723,6 +729,7 @@ class GTEST_API_ TestInfo {
|
|||||||
const std::string& name,
|
const std::string& name,
|
||||||
const char* a_type_param, // NULL if not a type-parameterized test
|
const char* a_type_param, // NULL if not a type-parameterized test
|
||||||
const char* a_value_param, // NULL if not a value-parameterized test
|
const char* a_value_param, // NULL if not a value-parameterized test
|
||||||
|
internal::CodeLocation a_code_location,
|
||||||
internal::TypeId fixture_class_id,
|
internal::TypeId fixture_class_id,
|
||||||
internal::TestFactoryBase* factory);
|
internal::TestFactoryBase* factory);
|
||||||
|
|
||||||
@ -749,6 +756,7 @@ class GTEST_API_ TestInfo {
|
|||||||
// Text representation of the value parameter, or NULL if this is not a
|
// Text representation of the value parameter, or NULL if this is not a
|
||||||
// value-parameterized test.
|
// value-parameterized test.
|
||||||
const internal::scoped_ptr<const ::std::string> value_param_;
|
const internal::scoped_ptr<const ::std::string> value_param_;
|
||||||
|
internal::CodeLocation location_;
|
||||||
const internal::TypeId fixture_class_id_; // ID of the test fixture class
|
const internal::TypeId fixture_class_id_; // ID of the test fixture class
|
||||||
bool should_run_; // True iff this test should run
|
bool should_run_; // True iff this test should run
|
||||||
bool is_disabled_; // True iff this test is disabled
|
bool is_disabled_; // True iff this test is disabled
|
||||||
@ -1360,103 +1368,6 @@ GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
|
|
||||||
// value of type ToPrint that is an operand of a comparison assertion
|
|
||||||
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
|
|
||||||
// the comparison, and is used to help determine the best way to
|
|
||||||
// format the value. In particular, when the value is a C string
|
|
||||||
// (char pointer) and the other operand is an STL string object, we
|
|
||||||
// want to format the C string as a string, since we know it is
|
|
||||||
// compared by value with the string object. If the value is a char
|
|
||||||
// pointer but the other operand is not an STL string object, we don't
|
|
||||||
// know whether the pointer is supposed to point to a NUL-terminated
|
|
||||||
// string, and thus want to print it as a pointer to be safe.
|
|
||||||
//
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
||||||
|
|
||||||
// The default case.
|
|
||||||
template <typename ToPrint, typename OtherOperand>
|
|
||||||
class FormatForComparison {
|
|
||||||
public:
|
|
||||||
static ::std::string Format(const ToPrint& value) {
|
|
||||||
return ::testing::PrintToString(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Array.
|
|
||||||
template <typename ToPrint, size_t N, typename OtherOperand>
|
|
||||||
class FormatForComparison<ToPrint[N], OtherOperand> {
|
|
||||||
public:
|
|
||||||
static ::std::string Format(const ToPrint* value) {
|
|
||||||
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// By default, print C string as pointers to be safe, as we don't know
|
|
||||||
// whether they actually point to a NUL-terminated string.
|
|
||||||
|
|
||||||
#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
|
|
||||||
template <typename OtherOperand> \
|
|
||||||
class FormatForComparison<CharType*, OtherOperand> { \
|
|
||||||
public: \
|
|
||||||
static ::std::string Format(CharType* value) { \
|
|
||||||
return ::testing::PrintToString(static_cast<const void*>(value)); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
|
||||||
|
|
||||||
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
|
|
||||||
|
|
||||||
// If a C string is compared with an STL string object, we know it's meant
|
|
||||||
// to point to a NUL-terminated string, and thus can print it as a string.
|
|
||||||
|
|
||||||
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
|
|
||||||
template <> \
|
|
||||||
class FormatForComparison<CharType*, OtherStringType> { \
|
|
||||||
public: \
|
|
||||||
static ::std::string Format(CharType* value) { \
|
|
||||||
return ::testing::PrintToString(value); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_STRING
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_WSTRING
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
|
|
||||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
|
|
||||||
|
|
||||||
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
|
|
||||||
// operand to be used in a failure message. The type (but not value)
|
|
||||||
// of the other operand may affect the format. This allows us to
|
|
||||||
// print a char* as a raw pointer when it is compared against another
|
|
||||||
// char* or void*, and print it as a C string when it is compared
|
|
||||||
// against an std::string object, for example.
|
|
||||||
//
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
std::string FormatForComparisonFailureMessage(
|
|
||||||
const T1& value, const T2& /* other_operand */) {
|
|
||||||
return FormatForComparison<T1, T2>::Format(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Separate the error generating code from the code path to reduce the stack
|
// Separate the error generating code from the code path to reduce the stack
|
||||||
// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers
|
// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers
|
||||||
// when calling EXPECT_* in a tight loop.
|
// when calling EXPECT_* in a tight loop.
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -99,9 +100,6 @@ class ScopedTrace; // Implements scoped trace.
|
|||||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
class TestInfoImpl; // Opaque implementation of TestInfo
|
||||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
class UnitTestImpl; // Opaque implementation of UnitTest
|
||||||
|
|
||||||
// How many times InitGoogleTest() has been called.
|
|
||||||
GTEST_API_ extern int g_init_gtest_count;
|
|
||||||
|
|
||||||
// The text used in failure messages to indicate the start of the
|
// The text used in failure messages to indicate the start of the
|
||||||
// stack trace.
|
// stack trace.
|
||||||
GTEST_API_ extern const char kStackTraceMarker[];
|
GTEST_API_ extern const char kStackTraceMarker[];
|
||||||
@ -503,6 +501,13 @@ GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
|
|||||||
typedef void (*SetUpTestCaseFunc)();
|
typedef void (*SetUpTestCaseFunc)();
|
||||||
typedef void (*TearDownTestCaseFunc)();
|
typedef void (*TearDownTestCaseFunc)();
|
||||||
|
|
||||||
|
struct CodeLocation {
|
||||||
|
CodeLocation(const string& a_file, int a_line) : file(a_file), line(a_line) {}
|
||||||
|
|
||||||
|
string file;
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
|
||||||
// Creates a new TestInfo object and registers it with Google Test;
|
// Creates a new TestInfo object and registers it with Google Test;
|
||||||
// returns the created object.
|
// returns the created object.
|
||||||
//
|
//
|
||||||
@ -514,6 +519,7 @@ typedef void (*TearDownTestCaseFunc)();
|
|||||||
// this is not a typed or a type-parameterized test.
|
// this is not a typed or a type-parameterized test.
|
||||||
// value_param text representation of the test's value parameter,
|
// value_param text representation of the test's value parameter,
|
||||||
// or NULL if this is not a type-parameterized test.
|
// or NULL if this is not a type-parameterized test.
|
||||||
|
// code_location: code location where the test is defined
|
||||||
// fixture_class_id: ID of the test fixture class
|
// fixture_class_id: ID of the test fixture class
|
||||||
// set_up_tc: pointer to the function that sets up the test case
|
// set_up_tc: pointer to the function that sets up the test case
|
||||||
// tear_down_tc: pointer to the function that tears down the test case
|
// tear_down_tc: pointer to the function that tears down the test case
|
||||||
@ -525,6 +531,7 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
|||||||
const char* name,
|
const char* name,
|
||||||
const char* type_param,
|
const char* type_param,
|
||||||
const char* value_param,
|
const char* value_param,
|
||||||
|
CodeLocation code_location,
|
||||||
TypeId fixture_class_id,
|
TypeId fixture_class_id,
|
||||||
SetUpTestCaseFunc set_up_tc,
|
SetUpTestCaseFunc set_up_tc,
|
||||||
TearDownTestCaseFunc tear_down_tc,
|
TearDownTestCaseFunc tear_down_tc,
|
||||||
@ -554,10 +561,21 @@ class GTEST_API_ TypedTestCasePState {
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
posix::Abort();
|
posix::Abort();
|
||||||
}
|
}
|
||||||
defined_test_names_.insert(test_name);
|
registered_tests_.insert(
|
||||||
|
::std::make_pair(test_name, CodeLocation(file, line)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TestExists(const std::string& test_name) const {
|
||||||
|
return registered_tests_.count(test_name) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CodeLocation& GetCodeLocation(const std::string& test_name) const {
|
||||||
|
RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);
|
||||||
|
GTEST_CHECK_(it != registered_tests_.end());
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
// Verifies that registered_tests match the test names in
|
// Verifies that registered_tests match the test names in
|
||||||
// defined_test_names_; returns registered_tests if successful, or
|
// defined_test_names_; returns registered_tests if successful, or
|
||||||
// aborts the program otherwise.
|
// aborts the program otherwise.
|
||||||
@ -565,8 +583,10 @@ class GTEST_API_ TypedTestCasePState {
|
|||||||
const char* file, int line, const char* registered_tests);
|
const char* file, int line, const char* registered_tests);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap;
|
||||||
|
|
||||||
bool registered_;
|
bool registered_;
|
||||||
::std::set<const char*> defined_test_names_;
|
RegisteredTestsMap registered_tests_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Skips to the first non-space char after the first comma in 'str';
|
// Skips to the first non-space char after the first comma in 'str';
|
||||||
@ -587,6 +607,11 @@ inline std::string GetPrefixUntilComma(const char* str) {
|
|||||||
return comma == NULL ? str : std::string(str, comma);
|
return comma == NULL ? str : std::string(str, comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Splits a given string on a given delimiter, populating a given
|
||||||
|
// vector with the fields.
|
||||||
|
void SplitString(const ::std::string& str, char delimiter,
|
||||||
|
::std::vector< ::std::string>* dest);
|
||||||
|
|
||||||
// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
|
// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
|
||||||
// registers a list of type-parameterized tests with Google Test. The
|
// registers a list of type-parameterized tests with Google Test. The
|
||||||
// return value is insignificant - we just need to return something
|
// return value is insignificant - we just need to return something
|
||||||
@ -601,8 +626,10 @@ class TypeParameterizedTest {
|
|||||||
// specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
|
// specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
|
||||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||||
// length of Types.
|
// length of Types.
|
||||||
static bool Register(const char* prefix, const char* case_name,
|
static bool Register(const char* prefix,
|
||||||
const char* test_names, int index) {
|
CodeLocation code_location,
|
||||||
|
const char* case_name, const char* test_names,
|
||||||
|
int index) {
|
||||||
typedef typename Types::Head Type;
|
typedef typename Types::Head Type;
|
||||||
typedef Fixture<Type> FixtureClass;
|
typedef Fixture<Type> FixtureClass;
|
||||||
typedef typename GTEST_BIND_(TestSel, Type) TestClass;
|
typedef typename GTEST_BIND_(TestSel, Type) TestClass;
|
||||||
@ -615,6 +642,7 @@ class TypeParameterizedTest {
|
|||||||
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
||||||
GetTypeName<Type>().c_str(),
|
GetTypeName<Type>().c_str(),
|
||||||
NULL, // No value parameter.
|
NULL, // No value parameter.
|
||||||
|
code_location,
|
||||||
GetTypeId<FixtureClass>(),
|
GetTypeId<FixtureClass>(),
|
||||||
TestClass::SetUpTestCase,
|
TestClass::SetUpTestCase,
|
||||||
TestClass::TearDownTestCase,
|
TestClass::TearDownTestCase,
|
||||||
@ -622,7 +650,7 @@ class TypeParameterizedTest {
|
|||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the type list.
|
// Next, recurses (at compile time) with the tail of the type list.
|
||||||
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
|
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
|
||||||
::Register(prefix, case_name, test_names, index + 1);
|
::Register(prefix, code_location, case_name, test_names, index + 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -630,8 +658,9 @@ class TypeParameterizedTest {
|
|||||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||||
class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, const char* /*case_name*/,
|
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||||
const char* /*test_names*/, int /*index*/) {
|
const char* /*case_name*/, const char* /*test_names*/,
|
||||||
|
int /*index*/) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -643,17 +672,31 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> {
|
|||||||
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
||||||
class TypeParameterizedTestCase {
|
class TypeParameterizedTestCase {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* prefix, const char* case_name,
|
static bool Register(const char* prefix, CodeLocation code_location,
|
||||||
const char* test_names) {
|
const TypedTestCasePState* state,
|
||||||
|
const char* case_name, const char* test_names) {
|
||||||
|
std::string test_name = StripTrailingSpaces(
|
||||||
|
GetPrefixUntilComma(test_names));
|
||||||
|
if (!state->TestExists(test_name)) {
|
||||||
|
fprintf(stderr, "Failed to get code location for test %s.%s at %s.",
|
||||||
|
case_name, test_name.c_str(),
|
||||||
|
FormatFileLocation(code_location.file.c_str(),
|
||||||
|
code_location.line).c_str());
|
||||||
|
fflush(stderr);
|
||||||
|
posix::Abort();
|
||||||
|
}
|
||||||
|
const CodeLocation& test_location = state->GetCodeLocation(test_name);
|
||||||
|
|
||||||
typedef typename Tests::Head Head;
|
typedef typename Tests::Head Head;
|
||||||
|
|
||||||
// First, register the first test in 'Test' for each type in 'Types'.
|
// First, register the first test in 'Test' for each type in 'Types'.
|
||||||
TypeParameterizedTest<Fixture, Head, Types>::Register(
|
TypeParameterizedTest<Fixture, Head, Types>::Register(
|
||||||
prefix, case_name, test_names, 0);
|
prefix, test_location, case_name, test_names, 0);
|
||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the test list.
|
// Next, recurses (at compile time) with the tail of the test list.
|
||||||
return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
|
return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
|
||||||
::Register(prefix, case_name, SkipComma(test_names));
|
::Register(prefix, code_location, state,
|
||||||
|
case_name, SkipComma(test_names));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -661,8 +704,9 @@ class TypeParameterizedTestCase {
|
|||||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||||
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, const char* /*case_name*/,
|
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||||
const char* /*test_names*/) {
|
const TypedTestCasePState* /*state*/,
|
||||||
|
const char* /*case_name*/, const char* /*test_names*/) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1182,6 +1226,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
|
|||||||
::test_info_ =\
|
::test_info_ =\
|
||||||
::testing::internal::MakeAndRegisterTestInfo(\
|
::testing::internal::MakeAndRegisterTestInfo(\
|
||||||
#test_case_name, #test_name, NULL, NULL, \
|
#test_case_name, #test_name, NULL, NULL, \
|
||||||
|
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||||
(parent_id), \
|
(parent_id), \
|
||||||
parent_class::SetUpTestCase, \
|
parent_class::SetUpTestCase, \
|
||||||
parent_class::TearDownTestCase, \
|
parent_class::TearDownTestCase, \
|
||||||
|
@ -79,7 +79,10 @@ class ValueArray1 {
|
|||||||
explicit ValueArray1(T1 v1) : v1_(v1) {}
|
explicit ValueArray1(T1 v1) : v1_(v1) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
|
operator ParamGenerator<T>() const {
|
||||||
|
const T array[] = {static_cast<T>(v1_)};
|
||||||
|
return ValuesIn(array);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// No implementation - assignment is unsupported.
|
// No implementation - assignment is unsupported.
|
||||||
|
@ -72,29 +72,14 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Used in the Values() function to provide polymorphic capabilities.
|
// Used in the Values() function to provide polymorphic capabilities.
|
||||||
template <typename T1>
|
$range i 1..n
|
||||||
class ValueArray1 {
|
|
||||||
public:
|
|
||||||
explicit ValueArray1(T1 v1) : v1_(v1) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// No implementation - assignment is unsupported.
|
|
||||||
void operator=(const ValueArray1& other);
|
|
||||||
|
|
||||||
const T1 v1_;
|
|
||||||
};
|
|
||||||
|
|
||||||
$range i 2..n
|
|
||||||
$for i [[
|
$for i [[
|
||||||
$range j 1..i
|
$range j 1..i
|
||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
template <$for j, [[typename T$j]]>
|
||||||
class ValueArray$i {
|
class ValueArray$i {
|
||||||
public:
|
public:
|
||||||
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
|
$if i==1 [[explicit ]]ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const {
|
operator ParamGenerator<T>() const {
|
||||||
|
@ -34,7 +34,10 @@
|
|||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -49,6 +52,27 @@
|
|||||||
#if GTEST_HAS_PARAM_TEST
|
#if GTEST_HAS_PARAM_TEST
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
|
// Input to a parameterized test name generator, describing a test parameter.
|
||||||
|
// Consists of the parameter value and the integer parameter index.
|
||||||
|
template <class ParamType>
|
||||||
|
struct TestParamInfo {
|
||||||
|
TestParamInfo(const ParamType& a_param, size_t an_index) :
|
||||||
|
param(a_param),
|
||||||
|
index(an_index) {}
|
||||||
|
ParamType param;
|
||||||
|
size_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A builtin parameterized test name generator which returns the result of
|
||||||
|
// testing::PrintToString.
|
||||||
|
struct PrintToStringParamName {
|
||||||
|
template <class ParamType>
|
||||||
|
std::string operator()(const TestParamInfo<ParamType>& info) const {
|
||||||
|
return PrintToString(info.param);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
@ -58,7 +82,7 @@ namespace internal {
|
|||||||
// TEST_P macro is used to define two tests with the same name
|
// TEST_P macro is used to define two tests with the same name
|
||||||
// but in different namespaces.
|
// but in different namespaces.
|
||||||
GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
|
GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
|
||||||
const char* file, int line);
|
CodeLocation code_location);
|
||||||
|
|
||||||
template <typename> class ParamGeneratorInterface;
|
template <typename> class ParamGeneratorInterface;
|
||||||
template <typename> class ParamGenerator;
|
template <typename> class ParamGenerator;
|
||||||
@ -206,7 +230,7 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
return base_;
|
return base_;
|
||||||
}
|
}
|
||||||
virtual void Advance() {
|
virtual void Advance() {
|
||||||
value_ = value_ + step_;
|
value_ = static_cast<T>(value_ + step_);
|
||||||
index_++;
|
index_++;
|
||||||
}
|
}
|
||||||
virtual ParamIteratorInterface<T>* Clone() const {
|
virtual ParamIteratorInterface<T>* Clone() const {
|
||||||
@ -243,7 +267,7 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
const T& end,
|
const T& end,
|
||||||
const IncrementT& step) {
|
const IncrementT& step) {
|
||||||
int end_index = 0;
|
int end_index = 0;
|
||||||
for (T i = begin; i < end; i = i + step)
|
for (T i = begin; i < end; i = static_cast<T>(i + step))
|
||||||
end_index++;
|
end_index++;
|
||||||
return end_index;
|
return end_index;
|
||||||
}
|
}
|
||||||
@ -345,6 +369,37 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
const ContainerType container_;
|
const ContainerType container_;
|
||||||
}; // class ValuesInIteratorRangeGenerator
|
}; // class ValuesInIteratorRangeGenerator
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Default parameterized test name generator, returns a string containing the
|
||||||
|
// integer test parameter index.
|
||||||
|
template <class ParamType>
|
||||||
|
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
||||||
|
Message name_stream;
|
||||||
|
name_stream << info.index;
|
||||||
|
return name_stream.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
|
//
|
||||||
|
// Parameterized test name overload helpers, which help the
|
||||||
|
// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized
|
||||||
|
// test name generator and user param name generator.
|
||||||
|
template <class ParamType, class ParamNameGenFunctor>
|
||||||
|
ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParamType>
|
||||||
|
struct ParamNameGenFunc {
|
||||||
|
typedef std::string Type(const TestParamInfo<ParamType>&);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ParamType>
|
||||||
|
typename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() {
|
||||||
|
return DefaultParamName;
|
||||||
|
}
|
||||||
|
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||||
//
|
//
|
||||||
// Stores a parameter value and later creates tests parameterized with that
|
// Stores a parameter value and later creates tests parameterized with that
|
||||||
@ -449,9 +504,11 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
typedef typename TestCase::ParamType ParamType;
|
typedef typename TestCase::ParamType ParamType;
|
||||||
// A function that returns an instance of appropriate generator type.
|
// A function that returns an instance of appropriate generator type.
|
||||||
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||||
|
typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc;
|
||||||
|
|
||||||
explicit ParameterizedTestCaseInfo(const char* name)
|
explicit ParameterizedTestCaseInfo(
|
||||||
: test_case_name_(name) {}
|
const char* name, CodeLocation code_location)
|
||||||
|
: test_case_name_(name), code_location_(code_location) {}
|
||||||
|
|
||||||
// Test case base name for display purposes.
|
// Test case base name for display purposes.
|
||||||
virtual const string& GetTestCaseName() const { return test_case_name_; }
|
virtual const string& GetTestCaseName() const { return test_case_name_; }
|
||||||
@ -474,9 +531,11 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
// about a generator.
|
// about a generator.
|
||||||
int AddTestCaseInstantiation(const string& instantiation_name,
|
int AddTestCaseInstantiation(const string& instantiation_name,
|
||||||
GeneratorCreationFunc* func,
|
GeneratorCreationFunc* func,
|
||||||
const char* /* file */,
|
ParamNameGeneratorFunc* name_func,
|
||||||
int /* line */) {
|
const char* file,
|
||||||
instantiations_.push_back(::std::make_pair(instantiation_name, func));
|
int line) {
|
||||||
|
instantiations_.push_back(
|
||||||
|
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
||||||
return 0; // Return value used only to run this method in namespace scope.
|
return 0; // Return value used only to run this method in namespace scope.
|
||||||
}
|
}
|
||||||
// UnitTest class invokes this method to register tests in this test case
|
// UnitTest class invokes this method to register tests in this test case
|
||||||
@ -491,25 +550,45 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
for (typename InstantiationContainer::iterator gen_it =
|
for (typename InstantiationContainer::iterator gen_it =
|
||||||
instantiations_.begin(); gen_it != instantiations_.end();
|
instantiations_.begin(); gen_it != instantiations_.end();
|
||||||
++gen_it) {
|
++gen_it) {
|
||||||
const string& instantiation_name = gen_it->first;
|
const string& instantiation_name = gen_it->name;
|
||||||
ParamGenerator<ParamType> generator((*gen_it->second)());
|
ParamGenerator<ParamType> generator((*gen_it->generator)());
|
||||||
|
ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
||||||
|
const char* file = gen_it->file;
|
||||||
|
int line = gen_it->line;
|
||||||
|
|
||||||
string test_case_name;
|
string test_case_name;
|
||||||
if ( !instantiation_name.empty() )
|
if ( !instantiation_name.empty() )
|
||||||
test_case_name = instantiation_name + "/";
|
test_case_name = instantiation_name + "/";
|
||||||
test_case_name += test_info->test_case_base_name;
|
test_case_name += test_info->test_case_base_name;
|
||||||
|
|
||||||
int i = 0;
|
size_t i = 0;
|
||||||
|
std::set<std::string> test_param_names;
|
||||||
for (typename ParamGenerator<ParamType>::iterator param_it =
|
for (typename ParamGenerator<ParamType>::iterator param_it =
|
||||||
generator.begin();
|
generator.begin();
|
||||||
param_it != generator.end(); ++param_it, ++i) {
|
param_it != generator.end(); ++param_it, ++i) {
|
||||||
Message test_name_stream;
|
Message test_name_stream;
|
||||||
test_name_stream << test_info->test_base_name << "/" << i;
|
|
||||||
|
std::string param_name = name_func(
|
||||||
|
TestParamInfo<ParamType>(*param_it, i));
|
||||||
|
|
||||||
|
GTEST_CHECK_(IsValidParamName(param_name))
|
||||||
|
<< "Parameterized test name '" << param_name
|
||||||
|
<< "' is invalid, in " << file
|
||||||
|
<< " line " << line << std::endl;
|
||||||
|
|
||||||
|
GTEST_CHECK_(test_param_names.count(param_name) == 0)
|
||||||
|
<< "Duplicate parameterized test name '" << param_name
|
||||||
|
<< "', in " << file << " line " << line << std::endl;
|
||||||
|
|
||||||
|
test_param_names.insert(param_name);
|
||||||
|
|
||||||
|
test_name_stream << test_info->test_base_name << "/" << param_name;
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
test_case_name.c_str(),
|
test_case_name.c_str(),
|
||||||
test_name_stream.GetString().c_str(),
|
test_name_stream.GetString().c_str(),
|
||||||
NULL, // No type parameter.
|
NULL, // No type parameter.
|
||||||
PrintToString(*param_it).c_str(),
|
PrintToString(*param_it).c_str(),
|
||||||
|
code_location_,
|
||||||
GetTestCaseTypeId(),
|
GetTestCaseTypeId(),
|
||||||
TestCase::SetUpTestCase,
|
TestCase::SetUpTestCase,
|
||||||
TestCase::TearDownTestCase,
|
TestCase::TearDownTestCase,
|
||||||
@ -535,12 +614,45 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
|||||||
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
|
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
|
||||||
};
|
};
|
||||||
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
|
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
|
||||||
// Keeps pairs of <Instantiation name, Sequence generator creation function>
|
// Records data received from INSTANTIATE_TEST_CASE_P macros:
|
||||||
// received from INSTANTIATE_TEST_CASE_P macros.
|
// <Instantiation name, Sequence generator creation function,
|
||||||
typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> >
|
// Name generator function, Source file, Source line>
|
||||||
InstantiationContainer;
|
struct InstantiationInfo {
|
||||||
|
InstantiationInfo(const std::string &name_in,
|
||||||
|
GeneratorCreationFunc* generator_in,
|
||||||
|
ParamNameGeneratorFunc* name_func_in,
|
||||||
|
const char* file_in,
|
||||||
|
int line_in)
|
||||||
|
: name(name_in),
|
||||||
|
generator(generator_in),
|
||||||
|
name_func(name_func_in),
|
||||||
|
file(file_in),
|
||||||
|
line(line_in) {}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
GeneratorCreationFunc* generator;
|
||||||
|
ParamNameGeneratorFunc* name_func;
|
||||||
|
const char* file;
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
typedef ::std::vector<InstantiationInfo> InstantiationContainer;
|
||||||
|
|
||||||
|
static bool IsValidParamName(const std::string& name) {
|
||||||
|
// Check for empty string
|
||||||
|
if (name.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for invalid characters
|
||||||
|
for (std::string::size_type index = 0; index < name.size(); ++index) {
|
||||||
|
if (!isalnum(name[index]) && name[index] != '_')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const string test_case_name_;
|
const string test_case_name_;
|
||||||
|
CodeLocation code_location_;
|
||||||
TestInfoContainer tests_;
|
TestInfoContainer tests_;
|
||||||
InstantiationContainer instantiations_;
|
InstantiationContainer instantiations_;
|
||||||
|
|
||||||
@ -568,8 +680,7 @@ class ParameterizedTestCaseRegistry {
|
|||||||
template <class TestCase>
|
template <class TestCase>
|
||||||
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||||
const char* test_case_name,
|
const char* test_case_name,
|
||||||
const char* file,
|
CodeLocation code_location) {
|
||||||
int line) {
|
|
||||||
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
|
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
|
||||||
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
|
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
|
||||||
it != test_case_infos_.end(); ++it) {
|
it != test_case_infos_.end(); ++it) {
|
||||||
@ -578,7 +689,7 @@ class ParameterizedTestCaseRegistry {
|
|||||||
// Complain about incorrect usage of Google Test facilities
|
// Complain about incorrect usage of Google Test facilities
|
||||||
// and terminate the program since we cannot guaranty correct
|
// and terminate the program since we cannot guaranty correct
|
||||||
// test case setup and tear-down in this case.
|
// test case setup and tear-down in this case.
|
||||||
ReportInvalidTestCaseType(test_case_name, file, line);
|
ReportInvalidTestCaseType(test_case_name, code_location);
|
||||||
posix::Abort();
|
posix::Abort();
|
||||||
} else {
|
} else {
|
||||||
// At this point we are sure that the object we found is of the same
|
// At this point we are sure that the object we found is of the same
|
||||||
@ -591,7 +702,8 @@ class ParameterizedTestCaseRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typed_test_info == NULL) {
|
if (typed_test_info == NULL) {
|
||||||
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
|
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
|
||||||
|
test_case_name, code_location);
|
||||||
test_case_infos_.push_back(typed_test_info);
|
test_case_infos_.push_back(typed_test_info);
|
||||||
}
|
}
|
||||||
return typed_test_info;
|
return typed_test_info;
|
||||||
|
@ -276,13 +276,23 @@
|
|||||||
#include <sstream> // NOLINT
|
#include <sstream> // NOLINT
|
||||||
#include <string> // NOLINT
|
#include <string> // NOLINT
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector> // NOLINT
|
||||||
|
|
||||||
|
#include "gtest/internal/gtest-port-arch.h"
|
||||||
|
#include "gtest/internal/custom/gtest-port.h"
|
||||||
|
|
||||||
|
#if !defined(GTEST_DEV_EMAIL_)
|
||||||
# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
|
# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
|
||||||
# define GTEST_FLAG_PREFIX_ "gtest_"
|
# define GTEST_FLAG_PREFIX_ "gtest_"
|
||||||
# define GTEST_FLAG_PREFIX_DASH_ "gtest-"
|
# define GTEST_FLAG_PREFIX_DASH_ "gtest-"
|
||||||
# define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
|
# define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
|
||||||
# define GTEST_NAME_ "Google Test"
|
# define GTEST_NAME_ "Google Test"
|
||||||
#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
|
# define GTEST_PROJECT_URL_ "https://github.com/google/googletest/"
|
||||||
|
#endif // !defined(GTEST_DEV_EMAIL_)
|
||||||
|
|
||||||
|
#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_)
|
||||||
|
# define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest"
|
||||||
|
#endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_)
|
||||||
|
|
||||||
// Determines the version of gcc that is used to compile this.
|
// Determines the version of gcc that is used to compile this.
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -291,61 +301,6 @@
|
|||||||
(__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
|
(__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
|
||||||
#endif // __GNUC__
|
#endif // __GNUC__
|
||||||
|
|
||||||
// Determines the platform on which Google Test is compiled.
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
# define GTEST_OS_CYGWIN 1
|
|
||||||
#elif defined __SYMBIAN32__
|
|
||||||
# define GTEST_OS_SYMBIAN 1
|
|
||||||
#elif defined _WIN32
|
|
||||||
# define GTEST_OS_WINDOWS 1
|
|
||||||
# ifdef _WIN32_WCE
|
|
||||||
# define GTEST_OS_WINDOWS_MOBILE 1
|
|
||||||
# elif defined(__MINGW__) || defined(__MINGW32__)
|
|
||||||
# define GTEST_OS_WINDOWS_MINGW 1
|
|
||||||
# elif defined(WINAPI_FAMILY)
|
|
||||||
# include <winapifamily.h>
|
|
||||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
|
||||||
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
|
||||||
# define GTEST_OS_WINDOWS_PHONE 1
|
|
||||||
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
|
||||||
# define GTEST_OS_WINDOWS_RT 1
|
|
||||||
# else
|
|
||||||
// WINAPI_FAMILY defined but no known partition matched.
|
|
||||||
// Default to desktop.
|
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
|
||||||
# endif // _WIN32_WCE
|
|
||||||
#elif defined __APPLE__
|
|
||||||
# define GTEST_OS_MAC 1
|
|
||||||
# if TARGET_OS_IPHONE
|
|
||||||
# define GTEST_OS_IOS 1
|
|
||||||
# endif
|
|
||||||
#elif defined __FreeBSD__
|
|
||||||
# define GTEST_OS_FREEBSD 1
|
|
||||||
#elif defined __linux__
|
|
||||||
# define GTEST_OS_LINUX 1
|
|
||||||
# if defined __ANDROID__
|
|
||||||
# define GTEST_OS_LINUX_ANDROID 1
|
|
||||||
# endif
|
|
||||||
#elif defined __MVS__
|
|
||||||
# define GTEST_OS_ZOS 1
|
|
||||||
#elif defined(__sun) && defined(__SVR4)
|
|
||||||
# define GTEST_OS_SOLARIS 1
|
|
||||||
#elif defined(_AIX)
|
|
||||||
# define GTEST_OS_AIX 1
|
|
||||||
#elif defined(__hpux)
|
|
||||||
# define GTEST_OS_HPUX 1
|
|
||||||
#elif defined __native_client__
|
|
||||||
# define GTEST_OS_NACL 1
|
|
||||||
#elif defined __OpenBSD__
|
|
||||||
# define GTEST_OS_OPENBSD 1
|
|
||||||
#elif defined __QNX__
|
|
||||||
# define GTEST_OS_QNX 1
|
|
||||||
#endif // __CYGWIN__
|
|
||||||
|
|
||||||
// Macros for disabling Microsoft Visual C++ warnings.
|
// Macros for disabling Microsoft Visual C++ warnings.
|
||||||
//
|
//
|
||||||
// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
|
// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
|
||||||
@ -403,6 +358,8 @@
|
|||||||
# define GTEST_HAS_STD_FUNCTION_ 1
|
# define GTEST_HAS_STD_FUNCTION_ 1
|
||||||
# define GTEST_HAS_STD_INITIALIZER_LIST_ 1
|
# define GTEST_HAS_STD_INITIALIZER_LIST_ 1
|
||||||
# define GTEST_HAS_STD_MOVE_ 1
|
# define GTEST_HAS_STD_MOVE_ 1
|
||||||
|
# define GTEST_HAS_STD_SHARED_PTR_ 1
|
||||||
|
# define GTEST_HAS_STD_TYPE_TRAITS_ 1
|
||||||
# define GTEST_HAS_STD_UNIQUE_PTR_ 1
|
# define GTEST_HAS_STD_UNIQUE_PTR_ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -466,7 +423,10 @@ struct _RTL_CRITICAL_SECTION;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GTEST_HAS_POSIX_RE
|
#if GTEST_USES_PCRE
|
||||||
|
// The appropriate headers have already been included.
|
||||||
|
|
||||||
|
#elif GTEST_HAS_POSIX_RE
|
||||||
|
|
||||||
// On some platforms, <regex.h> needs someone to define size_t, and
|
// On some platforms, <regex.h> needs someone to define size_t, and
|
||||||
// won't compile otherwise. We can #include it here as we already
|
// won't compile otherwise. We can #include it here as we already
|
||||||
@ -488,7 +448,7 @@ struct _RTL_CRITICAL_SECTION;
|
|||||||
// simple regex implementation instead.
|
// simple regex implementation instead.
|
||||||
# define GTEST_USES_SIMPLE_RE 1
|
# define GTEST_USES_SIMPLE_RE 1
|
||||||
|
|
||||||
#endif // GTEST_HAS_POSIX_RE
|
#endif // GTEST_USES_PCRE
|
||||||
|
|
||||||
#ifndef GTEST_HAS_EXCEPTIONS
|
#ifndef GTEST_HAS_EXCEPTIONS
|
||||||
// The user didn't tell us whether exceptions are enabled, so we need
|
// The user didn't tell us whether exceptions are enabled, so we need
|
||||||
@ -653,6 +613,15 @@ struct _RTL_CRITICAL_SECTION;
|
|||||||
# include <time.h> // NOLINT
|
# include <time.h> // NOLINT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Determines if hash_map/hash_set are available.
|
||||||
|
// Only used for testing against those containers.
|
||||||
|
#if !defined(GTEST_HAS_HASH_MAP_)
|
||||||
|
# if _MSC_VER
|
||||||
|
# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available.
|
||||||
|
# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available.
|
||||||
|
# endif // _MSC_VER
|
||||||
|
#endif // !defined(GTEST_HAS_HASH_MAP_)
|
||||||
|
|
||||||
// Determines whether Google Test can use tr1/tuple. You can define
|
// Determines whether Google Test can use tr1/tuple. You can define
|
||||||
// this macro to 0 to prevent Google Test from using tuple (any
|
// this macro to 0 to prevent Google Test from using tuple (any
|
||||||
// feature depending on tuple with be disabled in this mode).
|
// feature depending on tuple with be disabled in this mode).
|
||||||
@ -823,7 +792,6 @@ using ::std::tuple_size;
|
|||||||
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
|
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
|
||||||
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD)
|
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD)
|
||||||
# define GTEST_HAS_DEATH_TEST 1
|
# define GTEST_HAS_DEATH_TEST 1
|
||||||
# include <vector> // NOLINT
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We don't support MSVC 7.1 with exceptions disabled now. Therefore
|
// We don't support MSVC 7.1 with exceptions disabled now. Therefore
|
||||||
@ -946,20 +914,20 @@ using ::std::tuple_size;
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
#define GTEST_IS_THREADSAFE \
|
#define GTEST_IS_THREADSAFE \
|
||||||
(0 \
|
(GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ \
|
||||||
|| (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \
|
|| (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \
|
||||||
|| GTEST_HAS_PTHREAD)
|
|| GTEST_HAS_PTHREAD)
|
||||||
|
|
||||||
#endif // GTEST_HAS_SEH
|
#endif // GTEST_HAS_SEH
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
# if GTEST_LINKED_AS_SHARED_LIBRARY
|
# if GTEST_LINKED_AS_SHARED_LIBRARY
|
||||||
# define GTEST_API_ __declspec(dllimport)
|
# define GTEST_API_ __declspec(dllimport)
|
||||||
# elif GTEST_CREATE_SHARED_LIBRARY
|
# elif GTEST_CREATE_SHARED_LIBRARY
|
||||||
# define GTEST_API_ __declspec(dllexport)
|
# define GTEST_API_ __declspec(dllexport)
|
||||||
# endif
|
# endif
|
||||||
|
#elif __GNUC__ >= 4 || defined(__clang__)
|
||||||
|
# define GTEST_API_ __attribute__((visibility ("default")))
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#ifndef GTEST_API_
|
#ifndef GTEST_API_
|
||||||
@ -1298,6 +1266,8 @@ class GTEST_API_ GTestLog {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(GTEST_LOG_)
|
||||||
|
|
||||||
# define GTEST_LOG_(severity) \
|
# define GTEST_LOG_(severity) \
|
||||||
::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
|
::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
|
||||||
__FILE__, __LINE__).GetStream()
|
__FILE__, __LINE__).GetStream()
|
||||||
@ -1305,6 +1275,9 @@ class GTEST_API_ GTestLog {
|
|||||||
inline void LogToStderr() {}
|
inline void LogToStderr() {}
|
||||||
inline void FlushInfoLog() { fflush(NULL); }
|
inline void FlushInfoLog() { fflush(NULL); }
|
||||||
|
|
||||||
|
#endif // !defined(GTEST_LOG_)
|
||||||
|
|
||||||
|
#if !defined(GTEST_CHECK_)
|
||||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||||
//
|
//
|
||||||
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
||||||
@ -1325,6 +1298,7 @@ inline void FlushInfoLog() { fflush(NULL); }
|
|||||||
; \
|
; \
|
||||||
else \
|
else \
|
||||||
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
|
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
|
||||||
|
#endif // !defined(GTEST_CHECK_)
|
||||||
|
|
||||||
// An all-mode assert to verify that the given POSIX-style function
|
// An all-mode assert to verify that the given POSIX-style function
|
||||||
// call returns 0 (indicating success). Known limitation: this
|
// call returns 0 (indicating success). Known limitation: this
|
||||||
@ -1366,7 +1340,7 @@ const T& move(const T& t) {
|
|||||||
// similar functions users may have (e.g., implicit_cast). The internal
|
// similar functions users may have (e.g., implicit_cast). The internal
|
||||||
// namespace alone is not enough because the function can be found by ADL.
|
// namespace alone is not enough because the function can be found by ADL.
|
||||||
template<typename To>
|
template<typename To>
|
||||||
inline To ImplicitCast_(To x) { return ::testing::internal::move(x); }
|
inline To ImplicitCast_(To x) { return x; }
|
||||||
|
|
||||||
// When you upcast (that is, cast a pointer from type Foo to type
|
// When you upcast (that is, cast a pointer from type Foo to type
|
||||||
// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts
|
// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts
|
||||||
@ -1418,6 +1392,11 @@ template <class Derived, class Base>
|
|||||||
Derived* CheckedDowncastToActualType(Base* base) {
|
Derived* CheckedDowncastToActualType(Base* base) {
|
||||||
#if GTEST_HAS_RTTI
|
#if GTEST_HAS_RTTI
|
||||||
GTEST_CHECK_(typeid(*base) == typeid(Derived));
|
GTEST_CHECK_(typeid(*base) == typeid(Derived));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GTEST_HAS_DOWNCAST_
|
||||||
|
return ::down_cast<Derived*>(base);
|
||||||
|
#elif GTEST_HAS_RTTI
|
||||||
return dynamic_cast<Derived*>(base); // NOLINT
|
return dynamic_cast<Derived*>(base); // NOLINT
|
||||||
#else
|
#else
|
||||||
return static_cast<Derived*>(base); // Poor man's downcast.
|
return static_cast<Derived*>(base); // Poor man's downcast.
|
||||||
@ -1439,6 +1418,17 @@ GTEST_API_ std::string GetCapturedStderr();
|
|||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
|
|
||||||
|
// Returns a path to temporary directory.
|
||||||
|
GTEST_API_ std::string TempDir();
|
||||||
|
|
||||||
|
// Returns the size (in bytes) of a file.
|
||||||
|
GTEST_API_ size_t GetFileSize(FILE* file);
|
||||||
|
|
||||||
|
// Reads the entire content of a file as a string.
|
||||||
|
GTEST_API_ std::string ReadEntireFile(FILE* file);
|
||||||
|
|
||||||
|
// All command line arguments.
|
||||||
|
GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs();
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
@ -1446,8 +1436,6 @@ const ::std::vector<testing::internal::string>& GetInjectableArgvs();
|
|||||||
void SetInjectableArgvs(const ::std::vector<testing::internal::string>*
|
void SetInjectableArgvs(const ::std::vector<testing::internal::string>*
|
||||||
new_argvs);
|
new_argvs);
|
||||||
|
|
||||||
// A copy of all command line arguments. Set by InitGoogleTest().
|
|
||||||
extern ::std::vector<testing::internal::string> g_argvs;
|
|
||||||
|
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
@ -1466,7 +1454,10 @@ inline void SleepMilliseconds(int n) {
|
|||||||
}
|
}
|
||||||
# endif // GTEST_HAS_PTHREAD
|
# endif // GTEST_HAS_PTHREAD
|
||||||
|
|
||||||
# if 0 // OS detection
|
# if GTEST_HAS_NOTIFICATION_
|
||||||
|
// Notification has already been imported into the namespace.
|
||||||
|
// Nothing to do here.
|
||||||
|
|
||||||
# elif GTEST_HAS_PTHREAD
|
# elif GTEST_HAS_PTHREAD
|
||||||
// Allows a controller thread to pause execution of newly created
|
// Allows a controller thread to pause execution of newly created
|
||||||
// threads until notified. Instances of this class must be created
|
// threads until notified. Instances of this class must be created
|
||||||
@ -1560,7 +1551,7 @@ class GTEST_API_ Notification {
|
|||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
||||||
};
|
};
|
||||||
# endif // OS detection
|
# endif // GTEST_HAS_NOTIFICATION_
|
||||||
|
|
||||||
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
|
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
|
||||||
// defined, but we don't want to use MinGW's pthreads implementation, which
|
// defined, but we don't want to use MinGW's pthreads implementation, which
|
||||||
@ -1643,9 +1634,13 @@ class ThreadWithParam : public ThreadWithParamBase {
|
|||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
|
||||||
};
|
};
|
||||||
# endif // GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW
|
# endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD ||
|
||||||
|
// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
|
||||||
|
|
||||||
|
# if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
|
||||||
|
// Mutex and ThreadLocal have already been imported into the namespace.
|
||||||
|
// Nothing to do here.
|
||||||
|
|
||||||
# if 0 // OS detection
|
|
||||||
# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
||||||
|
|
||||||
// Mutex implements mutex on Windows platforms. It is used in conjunction
|
// Mutex implements mutex on Windows platforms. It is used in conjunction
|
||||||
@ -1850,8 +1845,9 @@ class ThreadWithParam : public ThreadWithParamBase {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadLocal : public ThreadLocalBase {
|
class ThreadLocal : public ThreadLocalBase {
|
||||||
public:
|
public:
|
||||||
ThreadLocal() : default_() {}
|
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
|
||||||
explicit ThreadLocal(const T& value) : default_(value) {}
|
explicit ThreadLocal(const T& value)
|
||||||
|
: default_factory_(new InstanceValueHolderFactory(value)) {}
|
||||||
|
|
||||||
~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }
|
~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }
|
||||||
|
|
||||||
@ -1865,6 +1861,7 @@ class ThreadLocal : public ThreadLocalBase {
|
|||||||
// knowing the type of T.
|
// knowing the type of T.
|
||||||
class ValueHolder : public ThreadLocalValueHolderBase {
|
class ValueHolder : public ThreadLocalValueHolderBase {
|
||||||
public:
|
public:
|
||||||
|
ValueHolder() : value_() {}
|
||||||
explicit ValueHolder(const T& value) : value_(value) {}
|
explicit ValueHolder(const T& value) : value_(value) {}
|
||||||
|
|
||||||
T* pointer() { return &value_; }
|
T* pointer() { return &value_; }
|
||||||
@ -1881,10 +1878,42 @@ class ThreadLocal : public ThreadLocalBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const {
|
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const {
|
||||||
return new ValueHolder(default_);
|
return default_factory_->MakeNewHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
const T default_; // The default value for each thread.
|
class ValueHolderFactory {
|
||||||
|
public:
|
||||||
|
ValueHolderFactory() {}
|
||||||
|
virtual ~ValueHolderFactory() {}
|
||||||
|
virtual ValueHolder* MakeNewHolder() const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DefaultValueHolderFactory : public ValueHolderFactory {
|
||||||
|
public:
|
||||||
|
DefaultValueHolderFactory() {}
|
||||||
|
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
class InstanceValueHolderFactory : public ValueHolderFactory {
|
||||||
|
public:
|
||||||
|
explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
|
||||||
|
virtual ValueHolder* MakeNewHolder() const {
|
||||||
|
return new ValueHolder(value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T value_; // The value for each thread.
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
scoped_ptr<ValueHolderFactory> default_factory_;
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
||||||
};
|
};
|
||||||
@ -1940,13 +1969,8 @@ class MutexBase {
|
|||||||
extern ::testing::internal::MutexBase mutex
|
extern ::testing::internal::MutexBase mutex
|
||||||
|
|
||||||
// Defines and statically (i.e. at link time) initializes a static mutex.
|
// Defines and statically (i.e. at link time) initializes a static mutex.
|
||||||
// The initialization list here does not explicitly initialize each field,
|
|
||||||
// instead relying on default initialization for the unspecified fields. In
|
|
||||||
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
|
|
||||||
// This allows initialization to work whether pthread_t is a scalar or struct.
|
|
||||||
// The flag -Wmissing-field-initializers must not be specified for this to work.
|
|
||||||
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
||||||
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
|
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false, pthread_t() }
|
||||||
|
|
||||||
// The Mutex class can only be used for mutexes created at runtime. It
|
// The Mutex class can only be used for mutexes created at runtime. It
|
||||||
// shares its API with MutexBase otherwise.
|
// shares its API with MutexBase otherwise.
|
||||||
@ -2005,10 +2029,11 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadLocal {
|
class ThreadLocal {
|
||||||
public:
|
public:
|
||||||
ThreadLocal() : key_(CreateKey()),
|
ThreadLocal()
|
||||||
default_() {}
|
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
|
||||||
explicit ThreadLocal(const T& value) : key_(CreateKey()),
|
explicit ThreadLocal(const T& value)
|
||||||
default_(value) {}
|
: key_(CreateKey()),
|
||||||
|
default_factory_(new InstanceValueHolderFactory(value)) {}
|
||||||
|
|
||||||
~ThreadLocal() {
|
~ThreadLocal() {
|
||||||
// Destroys the managed object for the current thread, if any.
|
// Destroys the managed object for the current thread, if any.
|
||||||
@ -2028,6 +2053,7 @@ class ThreadLocal {
|
|||||||
// Holds a value of type T.
|
// Holds a value of type T.
|
||||||
class ValueHolder : public ThreadLocalValueHolderBase {
|
class ValueHolder : public ThreadLocalValueHolderBase {
|
||||||
public:
|
public:
|
||||||
|
ValueHolder() : value_() {}
|
||||||
explicit ValueHolder(const T& value) : value_(value) {}
|
explicit ValueHolder(const T& value) : value_(value) {}
|
||||||
|
|
||||||
T* pointer() { return &value_; }
|
T* pointer() { return &value_; }
|
||||||
@ -2053,20 +2079,52 @@ class ThreadLocal {
|
|||||||
return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
|
return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueHolder* const new_holder = new ValueHolder(default_);
|
ValueHolder* const new_holder = default_factory_->MakeNewHolder();
|
||||||
ThreadLocalValueHolderBase* const holder_base = new_holder;
|
ThreadLocalValueHolderBase* const holder_base = new_holder;
|
||||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
|
GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
|
||||||
return new_holder->pointer();
|
return new_holder->pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ValueHolderFactory {
|
||||||
|
public:
|
||||||
|
ValueHolderFactory() {}
|
||||||
|
virtual ~ValueHolderFactory() {}
|
||||||
|
virtual ValueHolder* MakeNewHolder() const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DefaultValueHolderFactory : public ValueHolderFactory {
|
||||||
|
public:
|
||||||
|
DefaultValueHolderFactory() {}
|
||||||
|
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
|
||||||
|
};
|
||||||
|
|
||||||
|
class InstanceValueHolderFactory : public ValueHolderFactory {
|
||||||
|
public:
|
||||||
|
explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
|
||||||
|
virtual ValueHolder* MakeNewHolder() const {
|
||||||
|
return new ValueHolder(value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T value_; // The value for each thread.
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory);
|
||||||
|
};
|
||||||
|
|
||||||
// A key pthreads uses for looking up per-thread values.
|
// A key pthreads uses for looking up per-thread values.
|
||||||
const pthread_key_t key_;
|
const pthread_key_t key_;
|
||||||
const T default_; // The default value for each thread.
|
scoped_ptr<ValueHolderFactory> default_factory_;
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
||||||
};
|
};
|
||||||
|
|
||||||
# endif // OS detection
|
# endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
|
||||||
|
|
||||||
#else // GTEST_IS_THREADSAFE
|
#else // GTEST_IS_THREADSAFE
|
||||||
|
|
||||||
@ -2442,7 +2500,16 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
|
|||||||
// Utilities for command line flags and environment variables.
|
// Utilities for command line flags and environment variables.
|
||||||
|
|
||||||
// Macro for referencing flags.
|
// Macro for referencing flags.
|
||||||
|
#if !defined(GTEST_FLAG)
|
||||||
# define GTEST_FLAG(name) FLAGS_gtest_##name
|
# define GTEST_FLAG(name) FLAGS_gtest_##name
|
||||||
|
#endif // !defined(GTEST_FLAG)
|
||||||
|
|
||||||
|
#if !defined(GTEST_USE_OWN_FLAGFILE_FLAG_)
|
||||||
|
# define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
|
||||||
|
#endif // !defined(GTEST_USE_OWN_FLAGFILE_FLAG_)
|
||||||
|
|
||||||
|
#if !defined(GTEST_DECLARE_bool_)
|
||||||
|
# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
|
||||||
|
|
||||||
// Macros for declaring flags.
|
// Macros for declaring flags.
|
||||||
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
|
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
|
||||||
@ -2459,9 +2526,13 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
|
|||||||
#define GTEST_DEFINE_string_(name, default_val, doc) \
|
#define GTEST_DEFINE_string_(name, default_val, doc) \
|
||||||
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
|
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
|
||||||
|
|
||||||
|
#endif // !defined(GTEST_DECLARE_bool_)
|
||||||
|
|
||||||
// Thread annotations
|
// Thread annotations
|
||||||
|
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
||||||
# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
||||||
# define GTEST_LOCK_EXCLUDED_(locks)
|
# define GTEST_LOCK_EXCLUDED_(locks)
|
||||||
|
#endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
||||||
|
|
||||||
// Parses 'str' for a 32-bit signed integer. If successful, writes the result
|
// Parses 'str' for a 32-bit signed integer. If successful, writes the result
|
||||||
// to *value and returns true; otherwise leaves *value unchanged and returns
|
// to *value and returns true; otherwise leaves *value unchanged and returns
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "gtest/gtest-death-test.h"
|
#include "gtest/gtest-death-test.h"
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
#include "gtest/internal/custom/gtest.h"
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
@ -120,7 +121,9 @@ namespace internal {
|
|||||||
|
|
||||||
// Valid only for fast death tests. Indicates the code is running in the
|
// Valid only for fast death tests. Indicates the code is running in the
|
||||||
// child process of a fast style death test.
|
// child process of a fast style death test.
|
||||||
|
# if !GTEST_OS_WINDOWS
|
||||||
static bool g_in_fast_death_test_child = false;
|
static bool g_in_fast_death_test_child = false;
|
||||||
|
# endif
|
||||||
|
|
||||||
// Returns a Boolean value indicating whether the caller is currently
|
// Returns a Boolean value indicating whether the caller is currently
|
||||||
// executing in the context of the death test child process. Tools such as
|
// executing in the context of the death test child process. Tools such as
|
||||||
@ -169,6 +172,14 @@ KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
|
|||||||
|
|
||||||
// KilledBySignal function-call operator.
|
// KilledBySignal function-call operator.
|
||||||
bool KilledBySignal::operator()(int exit_status) const {
|
bool KilledBySignal::operator()(int exit_status) const {
|
||||||
|
# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
|
||||||
return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
|
return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
|
||||||
}
|
}
|
||||||
# endif // !GTEST_OS_WINDOWS
|
# endif // !GTEST_OS_WINDOWS
|
||||||
@ -875,6 +886,11 @@ class ExecDeathTest : public ForkingDeathTest {
|
|||||||
static ::std::vector<testing::internal::string>
|
static ::std::vector<testing::internal::string>
|
||||||
GetArgvsForDeathTestChildProcess() {
|
GetArgvsForDeathTestChildProcess() {
|
||||||
::std::vector<testing::internal::string> args = GetInjectableArgvs();
|
::std::vector<testing::internal::string> args = GetInjectableArgvs();
|
||||||
|
# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
|
||||||
|
::std::vector<testing::internal::string> extra_args =
|
||||||
|
GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();
|
||||||
|
args.insert(args.end(), extra_args.begin(), extra_args.end());
|
||||||
|
# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
// The name of the file in which the death test is located.
|
// The name of the file in which the death test is located.
|
||||||
@ -1204,26 +1220,6 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splits a given string on a given delimiter, populating a given
|
|
||||||
// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have
|
|
||||||
// ::std::string, so we can use it here.
|
|
||||||
static void SplitString(const ::std::string& str, char delimiter,
|
|
||||||
::std::vector< ::std::string>* dest) {
|
|
||||||
::std::vector< ::std::string> parsed;
|
|
||||||
::std::string::size_type pos = 0;
|
|
||||||
while (::testing::internal::AlwaysTrue()) {
|
|
||||||
const ::std::string::size_type colon = str.find(delimiter, pos);
|
|
||||||
if (colon == ::std::string::npos) {
|
|
||||||
parsed.push_back(str.substr(pos));
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
parsed.push_back(str.substr(pos, colon - pos));
|
|
||||||
pos = colon + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dest->swap(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
# if GTEST_OS_WINDOWS
|
# if GTEST_OS_WINDOWS
|
||||||
// Recreates the pipe and event handles from the provided parameters,
|
// Recreates the pipe and event handles from the provided parameters,
|
||||||
// signals the event, and returns a file descriptor wrapped around the pipe
|
// signals the event, and returns a file descriptor wrapped around the pipe
|
||||||
|
@ -100,6 +100,7 @@ const char kShuffleFlag[] = "shuffle";
|
|||||||
const char kStackTraceDepthFlag[] = "stack_trace_depth";
|
const char kStackTraceDepthFlag[] = "stack_trace_depth";
|
||||||
const char kStreamResultToFlag[] = "stream_result_to";
|
const char kStreamResultToFlag[] = "stream_result_to";
|
||||||
const char kThrowOnFailureFlag[] = "throw_on_failure";
|
const char kThrowOnFailureFlag[] = "throw_on_failure";
|
||||||
|
const char kFlagfileFlag[] = "flagfile";
|
||||||
|
|
||||||
// A valid random seed must be in [1, kMaxRandomSeed].
|
// A valid random seed must be in [1, kMaxRandomSeed].
|
||||||
const int kMaxRandomSeed = 99999;
|
const int kMaxRandomSeed = 99999;
|
||||||
@ -432,6 +433,10 @@ class OsStackTraceGetterInterface {
|
|||||||
// CurrentStackTrace() will use to find and hide Google Test stack frames.
|
// CurrentStackTrace() will use to find and hide Google Test stack frames.
|
||||||
virtual void UponLeavingGTest() = 0;
|
virtual void UponLeavingGTest() = 0;
|
||||||
|
|
||||||
|
// This string is inserted in place of stack frames that are part of
|
||||||
|
// Google Test's implementation.
|
||||||
|
static const char* const kElidedFramesMarker;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
|
||||||
};
|
};
|
||||||
@ -439,26 +444,12 @@ class OsStackTraceGetterInterface {
|
|||||||
// A working implementation of the OsStackTraceGetterInterface interface.
|
// A working implementation of the OsStackTraceGetterInterface interface.
|
||||||
class OsStackTraceGetter : public OsStackTraceGetterInterface {
|
class OsStackTraceGetter : public OsStackTraceGetterInterface {
|
||||||
public:
|
public:
|
||||||
OsStackTraceGetter() : caller_frame_(NULL) {}
|
OsStackTraceGetter() {}
|
||||||
|
|
||||||
virtual string CurrentStackTrace(int max_depth, int skip_count)
|
virtual string CurrentStackTrace(int max_depth, int skip_count);
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_);
|
virtual void UponLeavingGTest();
|
||||||
|
|
||||||
virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);
|
|
||||||
|
|
||||||
// This string is inserted in place of stack frames that are part of
|
|
||||||
// Google Test's implementation.
|
|
||||||
static const char* const kElidedFramesMarker;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex mutex_; // protects all internal state
|
|
||||||
|
|
||||||
// We save the stack frame below the frame that calls user code.
|
|
||||||
// We do this because the address of the frame immediately below
|
|
||||||
// the user code changes between the call to UponLeavingGTest()
|
|
||||||
// and any calls to CurrentStackTrace() from within the user code.
|
|
||||||
void* caller_frame_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1041,7 +1032,7 @@ class TestResultAccessor {
|
|||||||
#if GTEST_CAN_STREAM_RESULTS_
|
#if GTEST_CAN_STREAM_RESULTS_
|
||||||
|
|
||||||
// Streams test results to the given port on the given host machine.
|
// Streams test results to the given port on the given host machine.
|
||||||
class StreamingListener : public EmptyTestEventListener {
|
class GTEST_API_ StreamingListener : public EmptyTestEventListener {
|
||||||
public:
|
public:
|
||||||
// Abstract base class for writing strings to a socket.
|
// Abstract base class for writing strings to a socket.
|
||||||
class AbstractSocketWriter {
|
class AbstractSocketWriter {
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
@ -57,6 +58,11 @@
|
|||||||
# include <sys/procfs.h>
|
# include <sys/procfs.h>
|
||||||
#endif // GTEST_OS_QNX
|
#endif // GTEST_OS_QNX
|
||||||
|
|
||||||
|
#if GTEST_OS_AIX
|
||||||
|
# include <procinfo.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
#endif // GTEST_OS_AIX
|
||||||
|
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
#include "gtest/gtest-message.h"
|
#include "gtest/gtest-message.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
@ -83,10 +89,31 @@ const int kStdOutFileno = STDOUT_FILENO;
|
|||||||
const int kStdErrFileno = STDERR_FILENO;
|
const int kStdErrFileno = STDERR_FILENO;
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if GTEST_OS_MAC
|
#if GTEST_OS_LINUX
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename T>
|
||||||
|
T ReadProcFileField(const string& filename, int field) {
|
||||||
|
std::string dummy;
|
||||||
|
std::ifstream file(filename.c_str());
|
||||||
|
while (field-- > 0) {
|
||||||
|
file >> dummy;
|
||||||
|
}
|
||||||
|
T output = 0;
|
||||||
|
file >> output;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Returns the number of active threads, or 0 when there is an error.
|
||||||
|
size_t GetThreadCount() {
|
||||||
|
const string filename =
|
||||||
|
(Message() << "/proc/" << getpid() << "/stat").GetString();
|
||||||
|
return ReadProcFileField<int>(filename, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif GTEST_OS_MAC
|
||||||
|
|
||||||
// Returns the number of threads running in the process, or 0 to indicate that
|
|
||||||
// we cannot detect it.
|
|
||||||
size_t GetThreadCount() {
|
size_t GetThreadCount() {
|
||||||
const task_t task = mach_task_self();
|
const task_t task = mach_task_self();
|
||||||
mach_msg_type_number_t thread_count;
|
mach_msg_type_number_t thread_count;
|
||||||
@ -124,6 +151,19 @@ size_t GetThreadCount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif GTEST_OS_AIX
|
||||||
|
|
||||||
|
size_t GetThreadCount() {
|
||||||
|
struct procentry64 entry;
|
||||||
|
pid_t pid = getpid();
|
||||||
|
int status = getprocs64(&entry, sizeof(entry), NULL, 0, &pid, 1);
|
||||||
|
if (status == 1) {
|
||||||
|
return entry.pi_thcount;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
size_t GetThreadCount() {
|
size_t GetThreadCount() {
|
||||||
@ -132,7 +172,7 @@ size_t GetThreadCount() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_OS_MAC
|
#endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
||||||
|
|
||||||
@ -196,8 +236,8 @@ void Notification::WaitForNotification() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Mutex()
|
Mutex::Mutex()
|
||||||
: type_(kDynamic),
|
: owner_thread_id_(0),
|
||||||
owner_thread_id_(0),
|
type_(kDynamic),
|
||||||
critical_section_init_phase_(0),
|
critical_section_init_phase_(0),
|
||||||
critical_section_(new CRITICAL_SECTION) {
|
critical_section_(new CRITICAL_SECTION) {
|
||||||
::InitializeCriticalSection(critical_section_);
|
::InitializeCriticalSection(critical_section_);
|
||||||
@ -865,7 +905,6 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
|
|||||||
return file_name + ":" + StreamableToString(line);
|
return file_name + ":" + StreamableToString(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
|
GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
|
||||||
: severity_(severity) {
|
: severity_(severity) {
|
||||||
const char* const marker =
|
const char* const marker =
|
||||||
@ -962,12 +1001,6 @@ class CapturedStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Reads the entire content of a file as an std::string.
|
|
||||||
static std::string ReadEntireFile(FILE* file);
|
|
||||||
|
|
||||||
// Returns the size (in bytes) of a file.
|
|
||||||
static size_t GetFileSize(FILE* file);
|
|
||||||
|
|
||||||
const int fd_; // A stream to capture.
|
const int fd_; // A stream to capture.
|
||||||
int uncaptured_fd_;
|
int uncaptured_fd_;
|
||||||
// Name of the temporary file holding the stderr output.
|
// Name of the temporary file holding the stderr output.
|
||||||
@ -976,35 +1009,6 @@ class CapturedStream {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns the size (in bytes) of a file.
|
|
||||||
size_t CapturedStream::GetFileSize(FILE* file) {
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
return static_cast<size_t>(ftell(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads the entire content of a file as a string.
|
|
||||||
std::string CapturedStream::ReadEntireFile(FILE* file) {
|
|
||||||
const size_t file_size = GetFileSize(file);
|
|
||||||
char* const buffer = new char[file_size];
|
|
||||||
|
|
||||||
size_t bytes_last_read = 0; // # of bytes read in the last fread()
|
|
||||||
size_t bytes_read = 0; // # of bytes read so far
|
|
||||||
|
|
||||||
fseek(file, 0, SEEK_SET);
|
|
||||||
|
|
||||||
// Keeps reading the file until we cannot read further or the
|
|
||||||
// pre-determined file size is reached.
|
|
||||||
do {
|
|
||||||
bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
|
|
||||||
bytes_read += bytes_last_read;
|
|
||||||
} while (bytes_last_read > 0 && bytes_read < file_size);
|
|
||||||
|
|
||||||
const std::string content(buffer, bytes_read);
|
|
||||||
delete[] buffer;
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||||
|
|
||||||
static CapturedStream* g_captured_stderr = NULL;
|
static CapturedStream* g_captured_stderr = NULL;
|
||||||
@ -1051,10 +1055,52 @@ std::string GetCapturedStderr() {
|
|||||||
|
|
||||||
#endif // GTEST_HAS_STREAM_REDIRECTION
|
#endif // GTEST_HAS_STREAM_REDIRECTION
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
std::string TempDir() {
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
return "\\temp\\";
|
||||||
|
#elif GTEST_OS_WINDOWS
|
||||||
|
const char* temp_dir = posix::GetEnv("TEMP");
|
||||||
|
if (temp_dir == NULL || temp_dir[0] == '\0')
|
||||||
|
return "\\temp\\";
|
||||||
|
else if (temp_dir[strlen(temp_dir) - 1] == '\\')
|
||||||
|
return temp_dir;
|
||||||
|
else
|
||||||
|
return std::string(temp_dir) + "\\";
|
||||||
|
#elif GTEST_OS_LINUX_ANDROID
|
||||||
|
return "/sdcard/";
|
||||||
|
#else
|
||||||
|
return "/tmp/";
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
}
|
||||||
|
|
||||||
// A copy of all command line arguments. Set by InitGoogleTest().
|
size_t GetFileSize(FILE* file) {
|
||||||
::std::vector<testing::internal::string> g_argvs;
|
fseek(file, 0, SEEK_END);
|
||||||
|
return static_cast<size_t>(ftell(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ReadEntireFile(FILE* file) {
|
||||||
|
const size_t file_size = GetFileSize(file);
|
||||||
|
char* const buffer = new char[file_size];
|
||||||
|
|
||||||
|
size_t bytes_last_read = 0; // # of bytes read in the last fread()
|
||||||
|
size_t bytes_read = 0; // # of bytes read so far
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// Keeps reading the file until we cannot read further or the
|
||||||
|
// pre-determined file size is reached.
|
||||||
|
do {
|
||||||
|
bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
|
||||||
|
bytes_read += bytes_last_read;
|
||||||
|
} while (bytes_last_read > 0 && bytes_read < file_size);
|
||||||
|
|
||||||
|
const std::string content(buffer, bytes_read);
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
|
static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
|
||||||
NULL; // Owned.
|
NULL; // Owned.
|
||||||
@ -1069,7 +1115,7 @@ const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
|
|||||||
if (g_injected_test_argvs != NULL) {
|
if (g_injected_test_argvs != NULL) {
|
||||||
return *g_injected_test_argvs;
|
return *g_injected_test_argvs;
|
||||||
}
|
}
|
||||||
return g_argvs;
|
return GetArgvs();
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
@ -1143,6 +1189,9 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
|
|||||||
//
|
//
|
||||||
// The value is considered true iff it's not "0".
|
// The value is considered true iff it's not "0".
|
||||||
bool BoolFromGTestEnv(const char* flag, bool default_value) {
|
bool BoolFromGTestEnv(const char* flag, bool default_value) {
|
||||||
|
#if defined(GTEST_GET_BOOL_FROM_ENV_)
|
||||||
|
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
|
||||||
|
#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
|
||||||
const std::string env_var = FlagToEnvVar(flag);
|
const std::string env_var = FlagToEnvVar(flag);
|
||||||
const char* const string_value = posix::GetEnv(env_var.c_str());
|
const char* const string_value = posix::GetEnv(env_var.c_str());
|
||||||
return string_value == NULL ?
|
return string_value == NULL ?
|
||||||
@ -1153,6 +1202,9 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
|
|||||||
// variable corresponding to the given flag; if it isn't set or
|
// variable corresponding to the given flag; if it isn't set or
|
||||||
// doesn't represent a valid 32-bit integer, returns default_value.
|
// doesn't represent a valid 32-bit integer, returns default_value.
|
||||||
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
|
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
|
||||||
|
#if defined(GTEST_GET_INT32_FROM_ENV_)
|
||||||
|
return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
|
||||||
|
#endif // defined(GTEST_GET_INT32_FROM_ENV_)
|
||||||
const std::string env_var = FlagToEnvVar(flag);
|
const std::string env_var = FlagToEnvVar(flag);
|
||||||
const char* const string_value = posix::GetEnv(env_var.c_str());
|
const char* const string_value = posix::GetEnv(env_var.c_str());
|
||||||
if (string_value == NULL) {
|
if (string_value == NULL) {
|
||||||
@ -1175,6 +1227,9 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
|
|||||||
// Reads and returns the string environment variable corresponding to
|
// Reads and returns the string environment variable corresponding to
|
||||||
// the given flag; if it's not set, returns default_value.
|
// the given flag; if it's not set, returns default_value.
|
||||||
const char* StringFromGTestEnv(const char* flag, const char* default_value) {
|
const char* StringFromGTestEnv(const char* flag, const char* default_value) {
|
||||||
|
#if defined(GTEST_GET_STRING_FROM_ENV_)
|
||||||
|
return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
|
||||||
|
#endif // defined(GTEST_GET_STRING_FROM_ENV_)
|
||||||
const std::string env_var = FlagToEnvVar(flag);
|
const std::string env_var = FlagToEnvVar(flag);
|
||||||
const char* const value = posix::GetEnv(env_var.c_str());
|
const char* const value = posix::GetEnv(env_var.c_str());
|
||||||
return value == NULL ? default_value : value;
|
return value == NULL ? default_value : value;
|
||||||
|
@ -55,11 +55,11 @@ static std::vector<std::string> SplitIntoTestNames(const char* src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that registered_tests match the test names in
|
// Verifies that registered_tests match the test names in
|
||||||
// defined_test_names_; returns registered_tests if successful, or
|
// registered_tests_; returns registered_tests if successful, or
|
||||||
// aborts the program otherwise.
|
// aborts the program otherwise.
|
||||||
const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
||||||
const char* file, int line, const char* registered_tests) {
|
const char* file, int line, const char* registered_tests) {
|
||||||
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
|
typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
|
||||||
registered_ = true;
|
registered_ = true;
|
||||||
|
|
||||||
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
|
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
|
||||||
@ -76,10 +76,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (DefinedTestIter it = defined_test_names_.begin();
|
for (RegisteredTestIter it = registered_tests_.begin();
|
||||||
it != defined_test_names_.end();
|
it != registered_tests_.end();
|
||||||
++it) {
|
++it) {
|
||||||
if (name == *it) {
|
if (name == it->first) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -93,11 +93,11 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DefinedTestIter it = defined_test_names_.begin();
|
for (RegisteredTestIter it = registered_tests_.begin();
|
||||||
it != defined_test_names_.end();
|
it != registered_tests_.end();
|
||||||
++it) {
|
++it) {
|
||||||
if (tests.count(*it) == 0) {
|
if (tests.count(it->first) == 0) {
|
||||||
errors << "You forgot to list test " << *it << ".\n";
|
errors << "You forgot to list test " << it->first << ".\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
// The Google C++ Testing Framework (Google Test)
|
// The Google C++ Testing Framework (Google Test)
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "gtest/internal/custom/gtest.h"
|
||||||
#include "gtest/gtest-spi.h"
|
#include "gtest/gtest-spi.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -189,6 +190,12 @@ bool g_help_flag = false;
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
static const char* GetDefaultFilter() {
|
static const char* GetDefaultFilter() {
|
||||||
|
#ifdef GTEST_TEST_FILTER_ENV_VAR_
|
||||||
|
const char* const testbridge_test_only = getenv(GTEST_TEST_FILTER_ENV_VAR_);
|
||||||
|
if (testbridge_test_only != NULL) {
|
||||||
|
return testbridge_test_only;
|
||||||
|
}
|
||||||
|
#endif // GTEST_TEST_FILTER_ENV_VAR_
|
||||||
return kUniversalFilter;
|
return kUniversalFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +296,13 @@ GTEST_DEFINE_bool_(
|
|||||||
"if exceptions are enabled or exit the program with a non-zero code "
|
"if exceptions are enabled or exit the program with a non-zero code "
|
||||||
"otherwise.");
|
"otherwise.");
|
||||||
|
|
||||||
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
GTEST_DEFINE_string_(
|
||||||
|
flagfile,
|
||||||
|
internal::StringFromGTestEnv("flagfile", ""),
|
||||||
|
"This flag specifies the flagfile to read command-line flags from.");
|
||||||
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Generates a random number from [0, range), using a Linear
|
// Generates a random number from [0, range), using a Linear
|
||||||
@ -313,13 +327,7 @@ UInt32 Random::Generate(UInt32 range) {
|
|||||||
// GTestIsInitialized() returns true iff the user has initialized
|
// GTestIsInitialized() returns true iff the user has initialized
|
||||||
// Google Test. Useful for catching the user mistake of not initializing
|
// Google Test. Useful for catching the user mistake of not initializing
|
||||||
// Google Test before calling RUN_ALL_TESTS().
|
// Google Test before calling RUN_ALL_TESTS().
|
||||||
//
|
static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
|
||||||
// A user must call testing::InitGoogleTest() to initialize Google
|
|
||||||
// Test. g_init_gtest_count is set to the number of times
|
|
||||||
// InitGoogleTest() has been called. We don't protect this variable
|
|
||||||
// under a mutex as it is only accessed in the main thread.
|
|
||||||
GTEST_API_ int g_init_gtest_count = 0;
|
|
||||||
static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
|
|
||||||
|
|
||||||
// Iterates over a vector of TestCases, keeping a running sum of the
|
// Iterates over a vector of TestCases, keeping a running sum of the
|
||||||
// results of calling a given int-returning method on each.
|
// results of calling a given int-returning method on each.
|
||||||
@ -375,8 +383,16 @@ void AssertHelper::operator=(const Message& message) const {
|
|||||||
// Mutex for linked pointers.
|
// Mutex for linked pointers.
|
||||||
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
||||||
|
|
||||||
// Application pathname gotten in InitGoogleTest.
|
// A copy of all command line arguments. Set by InitGoogleTest().
|
||||||
std::string g_executable_path;
|
::std::vector<testing::internal::string> g_argvs;
|
||||||
|
|
||||||
|
const ::std::vector<testing::internal::string>& GetArgvs() {
|
||||||
|
#if defined(GTEST_CUSTOM_GET_ARGVS_)
|
||||||
|
return GTEST_CUSTOM_GET_ARGVS_();
|
||||||
|
#else // defined(GTEST_CUSTOM_GET_ARGVS_)
|
||||||
|
return g_argvs;
|
||||||
|
#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the current application's name, removing directory path if that
|
// Returns the current application's name, removing directory path if that
|
||||||
// is present.
|
// is present.
|
||||||
@ -384,9 +400,9 @@ FilePath GetCurrentExecutableName() {
|
|||||||
FilePath result;
|
FilePath result;
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
|
result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe"));
|
||||||
#else
|
#else
|
||||||
result.Set(FilePath(g_executable_path));
|
result.Set(FilePath(GetArgvs()[0]));
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
return result.RemoveDirectoryName();
|
return result.RemoveDirectoryName();
|
||||||
@ -778,8 +794,12 @@ int UnitTestImpl::test_to_run_count() const {
|
|||||||
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
|
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
|
||||||
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
||||||
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
||||||
(void)skip_count;
|
return os_stack_trace_getter()->CurrentStackTrace(
|
||||||
return "";
|
static_cast<int>(GTEST_FLAG(stack_trace_depth)),
|
||||||
|
skip_count + 1
|
||||||
|
// Skips the user-specified number of frames plus this function
|
||||||
|
// itself.
|
||||||
|
); // NOLINT
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the current time in milliseconds.
|
// Returns the current time in milliseconds.
|
||||||
@ -899,6 +919,23 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
|
|||||||
|
|
||||||
#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
|
||||||
|
|
||||||
|
void SplitString(const ::std::string& str, char delimiter,
|
||||||
|
::std::vector< ::std::string>* dest) {
|
||||||
|
::std::vector< ::std::string> parsed;
|
||||||
|
::std::string::size_type pos = 0;
|
||||||
|
while (::testing::internal::AlwaysTrue()) {
|
||||||
|
const ::std::string::size_type colon = str.find(delimiter, pos);
|
||||||
|
if (colon == ::std::string::npos) {
|
||||||
|
parsed.push_back(str.substr(pos));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
parsed.push_back(str.substr(pos, colon - pos));
|
||||||
|
pos = colon + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest->swap(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// Constructs an empty Message.
|
// Constructs an empty Message.
|
||||||
@ -2173,14 +2210,15 @@ int TestResult::test_property_count() const {
|
|||||||
|
|
||||||
// Creates a Test object.
|
// Creates a Test object.
|
||||||
|
|
||||||
// The c'tor saves the values of all Google Test flags.
|
// The c'tor saves the states of all flags.
|
||||||
Test::Test()
|
Test::Test()
|
||||||
: gtest_flag_saver_(new internal::GTestFlagSaver) {
|
: gtest_flag_saver_(new GTEST_FLAG_SAVER_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The d'tor restores the values of all Google Test flags.
|
// The d'tor restores the states of all flags. The actual work is
|
||||||
|
// done by the d'tor of the gtest_flag_saver_ field, and thus not
|
||||||
|
// visible here.
|
||||||
Test::~Test() {
|
Test::~Test() {
|
||||||
delete gtest_flag_saver_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up the test fixture.
|
// Sets up the test fixture.
|
||||||
@ -2464,12 +2502,14 @@ TestInfo::TestInfo(const std::string& a_test_case_name,
|
|||||||
const std::string& a_name,
|
const std::string& a_name,
|
||||||
const char* a_type_param,
|
const char* a_type_param,
|
||||||
const char* a_value_param,
|
const char* a_value_param,
|
||||||
|
internal::CodeLocation a_code_location,
|
||||||
internal::TypeId fixture_class_id,
|
internal::TypeId fixture_class_id,
|
||||||
internal::TestFactoryBase* factory)
|
internal::TestFactoryBase* factory)
|
||||||
: test_case_name_(a_test_case_name),
|
: test_case_name_(a_test_case_name),
|
||||||
name_(a_name),
|
name_(a_name),
|
||||||
type_param_(a_type_param ? new std::string(a_type_param) : NULL),
|
type_param_(a_type_param ? new std::string(a_type_param) : NULL),
|
||||||
value_param_(a_value_param ? new std::string(a_value_param) : NULL),
|
value_param_(a_value_param ? new std::string(a_value_param) : NULL),
|
||||||
|
location_(a_code_location),
|
||||||
fixture_class_id_(fixture_class_id),
|
fixture_class_id_(fixture_class_id),
|
||||||
should_run_(false),
|
should_run_(false),
|
||||||
is_disabled_(false),
|
is_disabled_(false),
|
||||||
@ -2493,6 +2533,7 @@ namespace internal {
|
|||||||
// this is not a typed or a type-parameterized test.
|
// this is not a typed or a type-parameterized test.
|
||||||
// value_param: text representation of the test's value parameter,
|
// value_param: text representation of the test's value parameter,
|
||||||
// or NULL if this is not a value-parameterized test.
|
// or NULL if this is not a value-parameterized test.
|
||||||
|
// code_location: code location where the test is defined
|
||||||
// fixture_class_id: ID of the test fixture class
|
// fixture_class_id: ID of the test fixture class
|
||||||
// set_up_tc: pointer to the function that sets up the test case
|
// set_up_tc: pointer to the function that sets up the test case
|
||||||
// tear_down_tc: pointer to the function that tears down the test case
|
// tear_down_tc: pointer to the function that tears down the test case
|
||||||
@ -2504,20 +2545,21 @@ TestInfo* MakeAndRegisterTestInfo(
|
|||||||
const char* name,
|
const char* name,
|
||||||
const char* type_param,
|
const char* type_param,
|
||||||
const char* value_param,
|
const char* value_param,
|
||||||
|
CodeLocation code_location,
|
||||||
TypeId fixture_class_id,
|
TypeId fixture_class_id,
|
||||||
SetUpTestCaseFunc set_up_tc,
|
SetUpTestCaseFunc set_up_tc,
|
||||||
TearDownTestCaseFunc tear_down_tc,
|
TearDownTestCaseFunc tear_down_tc,
|
||||||
TestFactoryBase* factory) {
|
TestFactoryBase* factory) {
|
||||||
TestInfo* const test_info =
|
TestInfo* const test_info =
|
||||||
new TestInfo(test_case_name, name, type_param, value_param,
|
new TestInfo(test_case_name, name, type_param, value_param,
|
||||||
fixture_class_id, factory);
|
code_location, fixture_class_id, factory);
|
||||||
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
|
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
|
||||||
return test_info;
|
return test_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_PARAM_TEST
|
#if GTEST_HAS_PARAM_TEST
|
||||||
void ReportInvalidTestCaseType(const char* test_case_name,
|
void ReportInvalidTestCaseType(const char* test_case_name,
|
||||||
const char* file, int line) {
|
CodeLocation code_location) {
|
||||||
Message errors;
|
Message errors;
|
||||||
errors
|
errors
|
||||||
<< "Attempted redefinition of test case " << test_case_name << ".\n"
|
<< "Attempted redefinition of test case " << test_case_name << ".\n"
|
||||||
@ -2529,7 +2571,9 @@ void ReportInvalidTestCaseType(const char* test_case_name,
|
|||||||
<< "probably rename one of the classes to put the tests into different\n"
|
<< "probably rename one of the classes to put the tests into different\n"
|
||||||
<< "test cases.";
|
<< "test cases.";
|
||||||
|
|
||||||
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
|
fprintf(stderr, "%s %s",
|
||||||
|
FormatFileLocation(code_location.file.c_str(),
|
||||||
|
code_location.line).c_str(),
|
||||||
errors.GetString().c_str());
|
errors.GetString().c_str());
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_PARAM_TEST
|
#endif // GTEST_HAS_PARAM_TEST
|
||||||
@ -2886,6 +2930,8 @@ bool ShouldUseColor(bool stdout_is_tty) {
|
|||||||
String::CStringEquals(term, "xterm-256color") ||
|
String::CStringEquals(term, "xterm-256color") ||
|
||||||
String::CStringEquals(term, "screen") ||
|
String::CStringEquals(term, "screen") ||
|
||||||
String::CStringEquals(term, "screen-256color") ||
|
String::CStringEquals(term, "screen-256color") ||
|
||||||
|
String::CStringEquals(term, "rxvt-unicode") ||
|
||||||
|
String::CStringEquals(term, "rxvt-unicode-256color") ||
|
||||||
String::CStringEquals(term, "linux") ||
|
String::CStringEquals(term, "linux") ||
|
||||||
String::CStringEquals(term, "cygwin");
|
String::CStringEquals(term, "cygwin");
|
||||||
return stdout_is_tty && term_supports_color;
|
return stdout_is_tty && term_supports_color;
|
||||||
@ -3501,7 +3547,7 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
|
|||||||
// Formats the given time in milliseconds as seconds.
|
// Formats the given time in milliseconds as seconds.
|
||||||
std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
|
std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
|
||||||
::std::stringstream ss;
|
::std::stringstream ss;
|
||||||
ss << ms/1000.0;
|
ss << (static_cast<double>(ms) * 1e-3);
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3796,26 +3842,15 @@ ScopedTrace::~ScopedTrace()
|
|||||||
|
|
||||||
// class OsStackTraceGetter
|
// class OsStackTraceGetter
|
||||||
|
|
||||||
// Returns the current OS stack trace as an std::string. Parameters:
|
const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
|
||||||
//
|
"... " GTEST_NAME_ " internal frames ...";
|
||||||
// max_depth - the maximum number of stack frames to be included
|
|
||||||
// in the trace.
|
|
||||||
// skip_count - the number of top frames to be skipped; doesn't count
|
|
||||||
// against max_depth.
|
|
||||||
//
|
|
||||||
string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/,
|
string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/,
|
||||||
int /* skip_count */)
|
int /*skip_count*/) {
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsStackTraceGetter::UponLeavingGTest()
|
void OsStackTraceGetter::UponLeavingGTest() {}
|
||||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* const
|
|
||||||
OsStackTraceGetter::kElidedFramesMarker =
|
|
||||||
"... " GTEST_NAME_ " internal frames ...";
|
|
||||||
|
|
||||||
// A helper class that creates the premature-exit file in its
|
// A helper class that creates the premature-exit file in its
|
||||||
// constructor and deletes the file in its destructor.
|
// constructor and deletes the file in its destructor.
|
||||||
@ -4401,6 +4436,11 @@ void UnitTestImpl::PostFlagParsingInit() {
|
|||||||
if (!post_flag_parse_init_performed_) {
|
if (!post_flag_parse_init_performed_) {
|
||||||
post_flag_parse_init_performed_ = true;
|
post_flag_parse_init_performed_ = true;
|
||||||
|
|
||||||
|
#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)
|
||||||
|
// Register to send notifications about key process state changes.
|
||||||
|
listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_());
|
||||||
|
#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
InitDeathTestSubprocessControlInfo();
|
InitDeathTestSubprocessControlInfo();
|
||||||
SuppressTestEventsIfInSubprocess();
|
SuppressTestEventsIfInSubprocess();
|
||||||
@ -4534,6 +4574,11 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
|
in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
|
||||||
|
# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
|
||||||
|
if (in_subprocess_for_death_test) {
|
||||||
|
GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();
|
||||||
|
}
|
||||||
|
# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
|
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
|
||||||
@ -4870,7 +4915,11 @@ void UnitTestImpl::set_os_stack_trace_getter(
|
|||||||
// getter, and returns it.
|
// getter, and returns it.
|
||||||
OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
|
OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
|
||||||
if (os_stack_trace_getter_ == NULL) {
|
if (os_stack_trace_getter_ == NULL) {
|
||||||
|
#ifdef GTEST_OS_STACK_TRACE_GETTER_
|
||||||
|
os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_;
|
||||||
|
#else
|
||||||
os_stack_trace_getter_ = new OsStackTraceGetter;
|
os_stack_trace_getter_ = new OsStackTraceGetter;
|
||||||
|
#endif // GTEST_OS_STACK_TRACE_GETTER_
|
||||||
}
|
}
|
||||||
|
|
||||||
return os_stack_trace_getter_;
|
return os_stack_trace_getter_;
|
||||||
@ -5169,21 +5218,8 @@ static const char kColorEncodedHelpMessage[] =
|
|||||||
"(not one in your own code or tests), please report it to\n"
|
"(not one in your own code or tests), please report it to\n"
|
||||||
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
||||||
|
|
||||||
// Parses the command line for Google Test flags, without initializing
|
bool ParseGoogleTestFlag(const char* const arg) {
|
||||||
// other parts of Google Test. The type parameter CharType can be
|
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
||||||
// instantiated to either char or wchar_t.
|
|
||||||
template <typename CharType>
|
|
||||||
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
|
||||||
for (int i = 1; i < *argc; i++) {
|
|
||||||
const std::string arg_string = StreamableToString(argv[i]);
|
|
||||||
const char* const arg = arg_string.c_str();
|
|
||||||
|
|
||||||
using internal::ParseBoolFlag;
|
|
||||||
using internal::ParseInt32Flag;
|
|
||||||
using internal::ParseStringFlag;
|
|
||||||
|
|
||||||
// Do we see a Google Test flag?
|
|
||||||
if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
|
|
||||||
>EST_FLAG(also_run_disabled_tests)) ||
|
>EST_FLAG(also_run_disabled_tests)) ||
|
||||||
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
ParseBoolFlag(arg, kBreakOnFailureFlag,
|
||||||
>EST_FLAG(break_on_failure)) ||
|
>EST_FLAG(break_on_failure)) ||
|
||||||
@ -5208,9 +5244,63 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
|||||||
ParseStringFlag(arg, kStreamResultToFlag,
|
ParseStringFlag(arg, kStreamResultToFlag,
|
||||||
>EST_FLAG(stream_result_to)) ||
|
>EST_FLAG(stream_result_to)) ||
|
||||||
ParseBoolFlag(arg, kThrowOnFailureFlag,
|
ParseBoolFlag(arg, kThrowOnFailureFlag,
|
||||||
>EST_FLAG(throw_on_failure))
|
>EST_FLAG(throw_on_failure));
|
||||||
) {
|
}
|
||||||
// Yes. Shift the remainder of the argv list left by one. Note
|
|
||||||
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
void LoadFlagsFromFile(const std::string& path) {
|
||||||
|
FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
||||||
|
if (!flagfile) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unable to open file \"%s\"\n",
|
||||||
|
GTEST_FLAG(flagfile).c_str());
|
||||||
|
fflush(stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
std::string contents(ReadEntireFile(flagfile));
|
||||||
|
posix::FClose(flagfile);
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
SplitString(contents, '\n', &lines);
|
||||||
|
for (size_t i = 0; i < lines.size(); ++i) {
|
||||||
|
if (lines[i].empty())
|
||||||
|
continue;
|
||||||
|
if (!ParseGoogleTestFlag(lines[i].c_str()))
|
||||||
|
g_help_flag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
|
||||||
|
// Parses the command line for Google Test flags, without initializing
|
||||||
|
// other parts of Google Test. The type parameter CharType can be
|
||||||
|
// instantiated to either char or wchar_t.
|
||||||
|
template <typename CharType>
|
||||||
|
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
||||||
|
for (int i = 1; i < *argc; i++) {
|
||||||
|
const std::string arg_string = StreamableToString(argv[i]);
|
||||||
|
const char* const arg = arg_string.c_str();
|
||||||
|
|
||||||
|
using internal::ParseBoolFlag;
|
||||||
|
using internal::ParseInt32Flag;
|
||||||
|
using internal::ParseStringFlag;
|
||||||
|
|
||||||
|
bool remove_flag = false;
|
||||||
|
if (ParseGoogleTestFlag(arg)) {
|
||||||
|
remove_flag = true;
|
||||||
|
#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
} else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) {
|
||||||
|
LoadFlagsFromFile(GTEST_FLAG(flagfile));
|
||||||
|
remove_flag = true;
|
||||||
|
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
||||||
|
} else if (arg_string == "--help" || arg_string == "-h" ||
|
||||||
|
arg_string == "-?" || arg_string == "/?" ||
|
||||||
|
HasGoogleTestFlagPrefix(arg)) {
|
||||||
|
// Both help flag and unrecognized Google Test flags (excluding
|
||||||
|
// internal ones) trigger help display.
|
||||||
|
g_help_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_flag) {
|
||||||
|
// Shift the remainder of the argv list left by one. Note
|
||||||
// that argv has (*argc + 1) elements, the last one always being
|
// that argv has (*argc + 1) elements, the last one always being
|
||||||
// NULL. The following loop moves the trailing NULL element as
|
// NULL. The following loop moves the trailing NULL element as
|
||||||
// well.
|
// well.
|
||||||
@ -5224,12 +5314,6 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
|||||||
// We also need to decrement the iterator as we just removed
|
// We also need to decrement the iterator as we just removed
|
||||||
// an element.
|
// an element.
|
||||||
i--;
|
i--;
|
||||||
} else if (arg_string == "--help" || arg_string == "-h" ||
|
|
||||||
arg_string == "-?" || arg_string == "/?" ||
|
|
||||||
HasGoogleTestFlagPrefix(arg)) {
|
|
||||||
// Both help flag and unrecognized Google Test flags (excluding
|
|
||||||
// internal ones) trigger help display.
|
|
||||||
g_help_flag = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5256,24 +5340,16 @@ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
|
|||||||
// wchar_t.
|
// wchar_t.
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
void InitGoogleTestImpl(int* argc, CharType** argv) {
|
void InitGoogleTestImpl(int* argc, CharType** argv) {
|
||||||
g_init_gtest_count++;
|
|
||||||
|
|
||||||
// We don't want to run the initialization code twice.
|
// We don't want to run the initialization code twice.
|
||||||
if (g_init_gtest_count != 1) return;
|
if (GTestIsInitialized()) return;
|
||||||
|
|
||||||
if (*argc <= 0) return;
|
if (*argc <= 0) return;
|
||||||
|
|
||||||
internal::g_executable_path = internal::StreamableToString(argv[0]);
|
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
|
||||||
|
|
||||||
g_argvs.clear();
|
g_argvs.clear();
|
||||||
for (int i = 0; i != *argc; i++) {
|
for (int i = 0; i != *argc; i++) {
|
||||||
g_argvs.push_back(StreamableToString(argv[i]));
|
g_argvs.push_back(StreamableToString(argv[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
|
||||||
|
|
||||||
ParseGoogleTestFlagsOnly(argc, argv);
|
ParseGoogleTestFlagsOnly(argc, argv);
|
||||||
GetUnitTestImpl()->PostFlagParsingInit();
|
GetUnitTestImpl()->PostFlagParsingInit();
|
||||||
}
|
}
|
||||||
@ -5290,13 +5366,21 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
|
|||||||
//
|
//
|
||||||
// Calling the function for the second time has no user-visible effect.
|
// Calling the function for the second time has no user-visible effect.
|
||||||
void InitGoogleTest(int* argc, char** argv) {
|
void InitGoogleTest(int* argc, char** argv) {
|
||||||
|
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
|
GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);
|
||||||
|
#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
internal::InitGoogleTestImpl(argc, argv);
|
internal::InitGoogleTestImpl(argc, argv);
|
||||||
|
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This overloaded version can be used in Windows programs compiled in
|
// This overloaded version can be used in Windows programs compiled in
|
||||||
// UNICODE mode.
|
// UNICODE mode.
|
||||||
void InitGoogleTest(int* argc, wchar_t** argv) {
|
void InitGoogleTest(int* argc, wchar_t** argv) {
|
||||||
|
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
|
GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);
|
||||||
|
#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
internal::InitGoogleTestImpl(argc, argv);
|
internal::InitGoogleTestImpl(argc, argv);
|
||||||
|
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
Loading…
Reference in New Issue
Block a user