updated gtest

This commit is contained in:
Riccardo Spagni 2016-01-25 20:10:10 +02:00
parent 153fe0cb75
commit 4df6aa5d12
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
17 changed files with 884 additions and 888 deletions

View File

@ -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.

View File

@ -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!

View File

@ -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, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \ &gtest_##prefix##test_case_name##_EvalGenerator_, \
&gtest_##prefix##test_case_name##_EvalGenerateName_, \
__FILE__, __LINE__) __FILE__, __LINE__)
} // namespace testing } // namespace testing

View File

@ -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, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \ &gtest_##prefix##test_case_name##_EvalGenerator_, \
&gtest_##prefix##test_case_name##_EvalGenerateName_, \
__FILE__, __LINE__) __FILE__, __LINE__)
} // namespace testing } // namespace testing

View File

@ -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_

View File

@ -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__), \
&GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), \
#CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_TYPED_TEST_P

View File

@ -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.

View File

@ -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, \

View File

@ -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.

View File

@ -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 {

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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";
} }
} }

View File

@ -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,
&GTEST_FLAG(also_run_disabled_tests)) || &GTEST_FLAG(also_run_disabled_tests)) ||
ParseBoolFlag(arg, kBreakOnFailureFlag, ParseBoolFlag(arg, kBreakOnFailureFlag,
&GTEST_FLAG(break_on_failure)) || &GTEST_FLAG(break_on_failure)) ||
@ -5208,9 +5244,63 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
ParseStringFlag(arg, kStreamResultToFlag, ParseStringFlag(arg, kStreamResultToFlag,
&GTEST_FLAG(stream_result_to)) || &GTEST_FLAG(stream_result_to)) ||
ParseBoolFlag(arg, kThrowOnFailureFlag, ParseBoolFlag(arg, kThrowOnFailureFlag,
&GTEST_FLAG(throw_on_failure)) &GTEST_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, &GTEST_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