Update gtest

pull/4537/head
Kim Kulling 2022-05-21 11:09:46 +02:00
parent e5a2b00719
commit e0696486b2
144 changed files with 9027 additions and 38081 deletions

View File

@ -1,14 +1,13 @@
######################################################################## ########################################################################
# Note: CMake support is community-based. The maintainers do not use CMake
# internally.
#
# CMake build script for Google Test. # CMake build script for Google Test.
# #
# To run the tests for Google Test itself on Linux, use 'make test' or # To run the tests for Google Test itself on Linux, use 'make test' or
# ctest. You can select which tests to run using 'ctest -R regex'. # ctest. You can select which tests to run using 'ctest -R regex'.
# For more options, run 'ctest --help'. # For more options, run 'ctest --help'.
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
# make it prominent in the GUI.
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
# When other libraries are using a shared version of runtime libraries, # When other libraries are using a shared version of runtime libraries,
# Google Test also has to use one. # Google Test also has to use one.
option( option(
@ -44,13 +43,45 @@ endif()
# as ${gtest_SOURCE_DIR} and to the root binary directory as # as ${gtest_SOURCE_DIR} and to the root binary directory as
# ${gtest_BINARY_DIR}. # ${gtest_BINARY_DIR}.
# Language "C" is required for find_package(Threads). # Language "C" is required for find_package(Threads).
project(gtest CXX C)
cmake_minimum_required(VERSION 3.10) # Project version:
if (CMAKE_VERSION VERSION_LESS 3.0)
project(gtest CXX C)
set(PROJECT_VERSION ${GOOGLETEST_VERSION})
else()
cmake_policy(SET CMP0048 NEW)
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
endif()
cmake_minimum_required(VERSION 2.8.12)
if (POLICY CMP0063) # Visibility
cmake_policy(SET CMP0063 NEW)
endif (POLICY CMP0063)
if (COMMAND set_up_hermetic_build) if (COMMAND set_up_hermetic_build)
set_up_hermetic_build() set_up_hermetic_build()
endif() endif()
# These commands only run if this is the main project
if(CMAKE_PROJECT_NAME STREQUAL "gtest" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution")
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
# make it prominent in the GUI.
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
else()
mark_as_advanced(
gtest_force_shared_crt
gtest_build_tests
gtest_build_samples
gtest_disable_pthreads
gtest_hide_internal_symbols)
endif()
if (gtest_hide_internal_symbols) if (gtest_hide_internal_symbols)
set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
@ -61,24 +92,34 @@ include(cmake/internal_utils.cmake)
config_compiler_and_linker() # Defined in internal_utils.cmake. config_compiler_and_linker() # Defined in internal_utils.cmake.
# Where Google Test's .h files can be found. # Needed to set the namespace for both the export targets and the
include_directories( # alias libraries
${gtest_SOURCE_DIR}/include set(cmake_package_name GTest CACHE INTERNAL "")
${gtest_SOURCE_DIR})
# Where Google Test's libraries can be found. # Create the CMake package file descriptors.
link_directories(${gtest_BINARY_DIR}/src) if (INSTALL_GTEST)
include(CMakePackageConfigHelpers)
# Summary of tuple support for Microsoft Visual Studio: set(targets_export_name ${cmake_package_name}Targets CACHE INTERNAL "")
# Compiler version(MS) version(cmake) Support set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated" CACHE INTERNAL "")
# ---------- ----------- -------------- ----------------------------- set(cmake_files_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${cmake_package_name}")
# <= VS 2010 <= 10 <= 1600 Use Google Tests's own tuple. set(version_file "${generated_dir}/${cmake_package_name}ConfigVersion.cmake")
# VS 2012 11 1700 std::tr1::tuple + _VARIADIC_MAX=10 write_basic_package_version_file(${version_file} VERSION ${GOOGLETEST_VERSION} COMPATIBILITY AnyNewerVersion)
# VS 2013 12 1800 std::tr1::tuple install(EXPORT ${targets_export_name}
if (MSVC AND MSVC_VERSION EQUAL 1700) NAMESPACE ${cmake_package_name}::
add_definitions(/D _VARIADIC_MAX=10) DESTINATION ${cmake_files_install_dir})
set(config_file "${generated_dir}/${cmake_package_name}Config.cmake")
configure_package_config_file("${gtest_SOURCE_DIR}/cmake/Config.cmake.in"
"${config_file}" INSTALL_DESTINATION ${cmake_files_install_dir})
install(FILES ${version_file} ${config_file}
DESTINATION ${cmake_files_install_dir})
endif() endif()
# Where Google Test's .h files can be found.
set(gtest_build_include_dirs
"${gtest_SOURCE_DIR}/include"
"${gtest_SOURCE_DIR}")
include_directories(${gtest_build_include_dirs})
######################################################################## ########################################################################
# #
# Defines the gtest & gtest_main libraries. User tests should link # Defines the gtest & gtest_main libraries. User tests should link
@ -88,24 +129,26 @@ endif()
# are used for other targets, to ensure that gtest can be compiled by a user # are used for other targets, to ensure that gtest can be compiled by a user
# aggressive about warnings. # aggressive about warnings.
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})
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) set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
# If the CMake version supports it, attach header directory information # 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 # 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). # in via add_subdirectory() rather than being a standalone build).
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") 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 SYSTEM INTERFACE
target_include_directories(gtest_main INTERFACE "${gtest_SOURCE_DIR}/include") "$<BUILD_INTERFACE:${gtest_build_include_dirs}>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
target_include_directories(gtest_main SYSTEM INTERFACE
"$<BUILD_INTERFACE:${gtest_build_include_dirs}>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
endif() endif()
target_link_libraries(gtest_main PUBLIC gtest)
######################################################################## ########################################################################
# #
# Install rules # Install rules
install(TARGETS gtest gtest_main install_project(gtest gtest_main)
DESTINATION lib)
install(DIRECTORY ${gtest_SOURCE_DIR}/include/gtest
DESTINATION include)
######################################################################## ########################################################################
# #
@ -147,33 +190,34 @@ if (gtest_build_tests)
############################################################ ############################################################
# C++ tests built with standard compiler flags. # C++ tests built with standard compiler flags.
cxx_test(gtest-death-test_test gtest_main) cxx_test(googletest-death-test-test gtest_main)
cxx_test(gtest_environment_test gtest) cxx_test(gtest_environment_test gtest)
cxx_test(gtest-filepath_test gtest_main) cxx_test(googletest-filepath-test gtest_main)
cxx_test(gtest-linked_ptr_test gtest_main) cxx_test(googletest-listener-test gtest_main)
cxx_test(gtest-listener_test gtest_main)
cxx_test(gtest_main_unittest gtest_main) cxx_test(gtest_main_unittest gtest_main)
cxx_test(gtest-message_test gtest_main) cxx_test(googletest-message-test gtest_main)
cxx_test(gtest_no_test_unittest gtest) cxx_test(gtest_no_test_unittest gtest)
cxx_test(gtest-options_test gtest_main) cxx_test(googletest-options-test gtest_main)
cxx_test(gtest-param-test_test gtest cxx_test(googletest-param-test-test gtest
test/gtest-param-test2_test.cc) test/googletest-param-test2-test.cc)
cxx_test(gtest-port_test gtest_main) cxx_test(googletest-port-test gtest_main)
cxx_test(gtest_pred_impl_unittest gtest_main) cxx_test(gtest_pred_impl_unittest gtest_main)
cxx_test(gtest_premature_exit_test gtest cxx_test(gtest_premature_exit_test gtest
test/gtest_premature_exit_test.cc) test/gtest_premature_exit_test.cc)
cxx_test(gtest-printers_test gtest_main) cxx_test(googletest-printers-test gtest_main)
cxx_test(gtest_prod_test gtest_main cxx_test(gtest_prod_test gtest_main
test/production.cc) test/production.cc)
cxx_test(gtest_repeat_test gtest) cxx_test(gtest_repeat_test gtest)
cxx_test(gtest_sole_header_test gtest_main) cxx_test(gtest_sole_header_test gtest_main)
cxx_test(gtest_stress_test gtest) cxx_test(gtest_stress_test gtest)
cxx_test(gtest-test-part_test gtest_main) cxx_test(googletest-test-part-test gtest_main)
cxx_test(gtest_throw_on_failure_ex_test gtest) cxx_test(gtest_throw_on_failure_ex_test gtest)
cxx_test(gtest-typed-test_test gtest_main cxx_test(gtest-typed-test_test gtest_main
test/gtest-typed-test2_test.cc) test/gtest-typed-test2_test.cc)
cxx_test(gtest_unittest gtest_main) cxx_test(gtest_unittest gtest_main)
cxx_test(gtest-unittest-api_test gtest) cxx_test(gtest-unittest-api_test gtest)
cxx_test(gtest_skip_in_environment_setup_test gtest_main)
cxx_test(gtest_skip_test gtest_main)
############################################################ ############################################################
# C++ tests built with non-standard compiler flags. # C++ tests built with non-standard compiler flags.
@ -190,10 +234,10 @@ if (gtest_build_tests)
cxx_test_with_flags(gtest-death-test_ex_nocatch_test cxx_test_with_flags(gtest-death-test_ex_nocatch_test
"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0"
gtest test/gtest-death-test_ex_test.cc) gtest test/googletest-death-test_ex_test.cc)
cxx_test_with_flags(gtest-death-test_ex_catch_test cxx_test_with_flags(gtest-death-test_ex_catch_test
"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1"
gtest test/gtest-death-test_ex_test.cc) gtest test/googletest-death-test_ex_test.cc)
cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
gtest_main_no_rtti test/gtest_unittest.cc) gtest_main_no_rtti test/gtest_unittest.cc)
@ -207,80 +251,73 @@ if (gtest_build_tests)
PROPERTIES PROPERTIES
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010.
# Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that
# conflict with our own definitions. Therefore using our own tuple does not
# work on those compilers.
cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}"
src/gtest-all.cc src/gtest_main.cc)
cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}"
gtest_main_use_own_tuple test/gtest-tuple_test.cc)
cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}"
gtest_main_use_own_tuple
test/gtest-param-test_test.cc test/gtest-param-test2_test.cc)
endif()
############################################################ ############################################################
# Python tests. # Python tests.
cxx_executable(gtest_break_on_failure_unittest_ test gtest) cxx_executable(googletest-break-on-failure-unittest_ test gtest)
py_test(gtest_break_on_failure_unittest) py_test(googletest-break-on-failure-unittest)
py_test(gtest_skip_check_output_test)
py_test(gtest_skip_environment_check_output_test)
# Visual Studio .NET 2003 does not support STL with exceptions disabled. # Visual Studio .NET 2003 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003 if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003
cxx_executable_with_flags( cxx_executable_with_flags(
gtest_catch_exceptions_no_ex_test_ googletest-catch-exceptions-no-ex-test_
"${cxx_no_exception}" "${cxx_no_exception}"
gtest_main_no_exception gtest_main_no_exception
test/gtest_catch_exceptions_test_.cc) test/googletest-catch-exceptions-test_.cc)
endif() endif()
cxx_executable_with_flags( cxx_executable_with_flags(
gtest_catch_exceptions_ex_test_ googletest-catch-exceptions-ex-test_
"${cxx_exception}" "${cxx_exception}"
gtest_main gtest_main
test/gtest_catch_exceptions_test_.cc) test/googletest-catch-exceptions-test_.cc)
py_test(gtest_catch_exceptions_test) py_test(googletest-catch-exceptions-test)
cxx_executable(gtest_color_test_ test gtest) cxx_executable(googletest-color-test_ test gtest)
py_test(gtest_color_test) py_test(googletest-color-test)
cxx_executable(gtest_env_var_test_ test gtest) cxx_executable(googletest-env-var-test_ test gtest)
py_test(gtest_env_var_test) py_test(googletest-env-var-test)
cxx_executable(gtest_filter_unittest_ test gtest) cxx_executable(googletest-filter-unittest_ test gtest)
py_test(gtest_filter_unittest) py_test(googletest-filter-unittest)
cxx_executable(gtest_help_test_ test gtest_main) cxx_executable(gtest_help_test_ test gtest_main)
py_test(gtest_help_test) py_test(gtest_help_test)
cxx_executable(gtest_list_tests_unittest_ test gtest) cxx_executable(googletest-list-tests-unittest_ test gtest)
py_test(gtest_list_tests_unittest) py_test(googletest-list-tests-unittest)
cxx_executable(gtest_output_test_ test gtest) cxx_executable(googletest-output-test_ test gtest)
py_test(gtest_output_test) py_test(googletest-output-test --no_stacktrace_support)
cxx_executable(gtest_shuffle_test_ test gtest) cxx_executable(googletest-shuffle-test_ test gtest)
py_test(gtest_shuffle_test) py_test(googletest-shuffle-test)
# MSVC 7.1 does not support STL with exceptions disabled. # MSVC 7.1 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310) if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception) cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception)
set_target_properties(gtest_throw_on_failure_test_ set_target_properties(googletest-throw-on-failure-test_
PROPERTIES PROPERTIES
COMPILE_FLAGS "${cxx_no_exception}") COMPILE_FLAGS "${cxx_no_exception}")
py_test(gtest_throw_on_failure_test) py_test(googletest-throw-on-failure-test)
endif() endif()
cxx_executable(gtest_uninitialized_test_ test gtest) cxx_executable(googletest-uninitialized-test_ test gtest)
py_test(gtest_uninitialized_test) py_test(googletest-uninitialized-test)
cxx_executable(gtest_list_output_unittest_ test gtest)
py_test(gtest_list_output_unittest)
cxx_executable(gtest_xml_outfile1_test_ test gtest_main) cxx_executable(gtest_xml_outfile1_test_ test gtest_main)
cxx_executable(gtest_xml_outfile2_test_ test gtest_main) cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
py_test(gtest_xml_outfiles_test) py_test(gtest_xml_outfiles_test)
py_test(googletest-json-outfiles-test)
cxx_executable(gtest_xml_output_unittest_ test gtest) cxx_executable(gtest_xml_output_unittest_ test gtest)
py_test(gtest_xml_output_unittest) py_test(gtest_xml_output_unittest --no_stacktrace_support)
py_test(googletest-json-output-unittest --no_stacktrace_support)
endif() endif()

View File

@ -1,181 +1,156 @@
### Generic Build Instructions
### Generic Build Instructions ### #### Setup
#### Setup #### To build GoogleTest 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.
To build Google Test and your tests that use it, you need to tell your ### Build with CMake
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.
#### Build #### GoogleTest comes with a CMake build script
([CMakeLists.txt](https://github.com/google/googletest/blob/master/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/>.
Suppose you put Google Test in directory `${GTEST_DIR}`. To build it, CMake works by generating native makefiles or build projects that can be used in
create a library build target (or a project as called by Visual Studio the compiler environment of your choice. You can either build GoogleTest as a
and Xcode) to compile standalone project or it can be incorporated into an existing CMake build for
another project.
${GTEST_DIR}/src/gtest-all.cc #### Standalone CMake Project
with `${GTEST_DIR}/include` in the system header search path and `${GTEST_DIR}` When building GoogleTest as a standalone project, the typical workflow starts
in the normal header search path. Assuming a Linux-like system and gcc, with
something like the following will do:
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ ```
-pthread -c ${GTEST_DIR}/src/gtest-all.cc git clone https://github.com/google/googletest.git -b release-1.10.0
ar -rv libgtest.a gtest-all.o cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output.
cd build
cmake .. # Generate native build scripts for GoogleTest.
```
(We need `-pthread` as Google Test uses threads.) The above command also includes GoogleMock by default. And so, if you want to
build only GoogleTest, you should replace the last command with
Next, you should compile your test source file with ```
`${GTEST_DIR}/include` in the system header search path, and link it cmake .. -DBUILD_GMOCK=OFF
with gtest and any other necessary libraries: ```
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ If you are on a \*nix system, you should now see a Makefile in the current
-o your_test directory. Just type `make` to build GoogleTest. And then you can simply install
GoogleTest if you are a system administrator.
As an example, the make/ directory contains a Makefile that you can ```
use to build Google Test on systems where GNU make is available make
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google sudo make install # Install in /usr/local/ by default
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 If you use Windows and have Visual Studio installed, a `gtest.sln` file and
following commands should succeed: several `.vcproj` files will be created. You can then build them using Visual
Studio.
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](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. On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated.
### Legacy Build Scripts ### #### Incorporating Into An Existing CMake Project
Before settling on CMake, we have been providing hand-maintained build If you want to use GoogleTest in a project which already uses CMake, the easiest
projects/scripts for Visual Studio, Xcode, and Autotools. While we way is to get installed libraries and headers.
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: * Import GoogleTest by using `find_package` (or `pkg_check_modules`). For
example, if `find_package(GTest CONFIG REQUIRED)` succeeds, you can use the
libraries as `GTest::gtest`, `GTest::gmock`.
The msvc\ folder contains two solutions with Visual C++ projects. And a more robust and flexible approach is to build GoogleTest as part of that
Open the `gtest.sln` or `gtest-md.sln` file using Visual Studio, and you project directly. This is done by making the GoogleTest source code available to
are ready to build Google Test the same way you build any Visual the main build and adding it using CMake's `add_subdirectory()` command. This
Studio project. Files that have names ending with -md use DLL has the significant advantage that the same compiler and linker settings are
versions of Microsoft runtime libraries (the /MD or the /MDd compiler used between GoogleTest and the rest of your project, so issues associated with
option). Files without that suffix use static versions of the runtime using incompatible libraries (eg debug/release), etc. are avoided. This is
libraries (the /MT or the /MTd option). Please note that one must use particularly useful on Windows. Making GoogleTest's source code available to the
the same option to compile both gtest and the test code. If you use main build can be done a few different ways:
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 * Download the GoogleTest source code manually and place it at a known
Xcode. Build the "gtest" target. The universal binary framework will location. This is the least flexible approach and can make it more difficult
end up in your selected build directory (selected in the Xcode to use with continuous integration systems, etc.
"Preferences..." -> "Building" pane and defaults to xcode/build). * Embed the GoogleTest source code as a direct copy in the main project's
Alternatively, at the command line, enter: source tree. This is often the simplest approach, but is also the hardest to
keep up to date. Some organizations may not permit this method.
* Add GoogleTest as a git submodule or equivalent. This may not always be
possible or appropriate. Git submodules, for example, have their own set of
advantages and drawbacks.
* Use CMake to download GoogleTest as part of the build's configure step. This
approach doesn't have the limitations of the other methods.
xcodebuild The last of the above methods is implemented with a small piece of CMake code
that downloads and pulls the GoogleTest code into the main build.
This will build the "Release" configuration of gtest.framework in your Just add to your `CMakeLists.txt`:
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 ```cmake
above, you need to either: include(FetchContent)
FetchContent_Declare(
googletest
# Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
* update the SDK configuration options in xcode/Config/General.xconfig. # Now simply link against gtest or gtest_main as needed. Eg
Comment options `SDKROOT`, `MACOS_DEPLOYMENT_TARGET`, and `GCC_VERSION`. If add_executable(example example.cpp)
you choose this route you lose the ability to target earlier versions target_link_libraries(example gtest_main)
of MacOS X. add_test(NAME example_test COMMAND example)
* 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 ### Note that this approach requires CMake 3.14 or later due to its use of the
`FetchContent_MakeAvailable()` command.
Google Test can be used in diverse environments. The default ##### Visual Studio Dynamic vs Static Runtimes
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, By default, new Visual Studio projects link the C runtimes dynamically but
see file [include/gtest/internal/gtest-port.h](include/gtest/internal/gtest-port.h). GoogleTest links them statically. This will generate an error that looks
something like the following: gtest.lib(gtest-all.obj) : error LNK2038: mismatch
detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value
'MDd_DynamicDebug' in main.obj
### Choosing a TR1 Tuple Library ### GoogleTest already has a CMake option for this: `gtest_force_shared_crt`
Some Google Test features require the C++ Technical Report 1 (TR1) Enabling this option will make gtest link the runtimes dynamically too, and
tuple library, which is not yet available with all compilers. The match the project in which it is included.
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 #### C++ Standard Version
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 An environment that supports C++11 is required in order to successfully build
GoogleTest. One way to ensure this is to specify the standard in the top-level
project, for example by using the `set(CMAKE_CXX_STANDARD 11)` command. If this
is not feasible, for example in a C project using GoogleTest for validation,
then it can be specified by adding it to the options for cmake via the
`DCMAKE_CXX_FLAGS` option.
to the compiler flags while compiling Google Test and your tests. If ### Tweaking GoogleTest
you want to force Google Test to use its own tuple library, just add
-DGTEST_USE_OWN_TR1_TUPLE=1 GoogleTest 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 GoogleTest 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.
to the compiler flags instead. We list the most frequently used macros below. For a complete list, see file
[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/master/googletest/include/gtest/internal/gtest-port.h).
If you don't want Google Test to use tuple at all, add ### Multi-threaded Tests
-DGTEST_HAS_TR1_TUPLE=0 GoogleTest 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.).
and all features using tuple will be disabled. If GoogleTest doesn't correctly detect whether pthread is available in your
environment, you can force it with
### 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 -DGTEST_HAS_PTHREAD=1
@ -183,26 +158,24 @@ or
-DGTEST_HAS_PTHREAD=0 -DGTEST_HAS_PTHREAD=0
When Google Test uses pthread, you may need to add flags to your When GoogleTest uses pthread, you may need to add flags to your compiler and/or
compiler and/or linker to select the pthread library, or you'll get linker to select the pthread library, or you'll get link errors. If you use the
link errors. If you use the CMake script or the deprecated Autotools CMake script, this is taken care of for you. If you use your own build script,
script, this is taken care of for you. If you use your own build you'll need to read your compiler and linker's manual to figure out what flags
script, you'll need to read your compiler and linker's manual to to add.
figure out what flags to add.
### As a Shared Library (DLL) ### ### As a Shared Library (DLL)
Google Test is compact, so most users can build and link it as a GoogleTest is compact, so most users can build and link it as a static library
static library for the simplicity. You can choose to use Google Test for the simplicity. You can choose to use GoogleTest as a shared library (known
as a shared library (known as a DLL on Windows) if you prefer. as a DLL on Windows) if you prefer.
To compile *gtest* as a shared library, add To compile *gtest* as a shared library, add
-DGTEST_CREATE_SHARED_LIBRARY=1 -DGTEST_CREATE_SHARED_LIBRARY=1
to the compiler flags. You'll also need to tell the linker to produce to the compiler flags. You'll also need to tell the linker to produce a shared
a shared library instead - consult your linker's manual for how to do library instead - consult your linker's manual for how to do it.
it.
To compile your *tests* that use the gtest shared library, add To compile your *tests* that use the gtest shared library, add
@ -210,31 +183,28 @@ To compile your *tests* that use the gtest shared library, add
to the compiler flags. to the compiler flags.
Note: while the above steps aren't technically necessary today when Note: while the above steps aren't technically necessary today when using some
using some compilers (e.g. GCC), they may become necessary in the compilers (e.g. GCC), they may become necessary in the future, if we decide to
future, if we decide to improve the speed of loading the library (see improve the speed of loading the library (see
<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are <http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are recommended
recommended to always add the above flags when using Google Test as a to always add the above flags when using GoogleTest as a shared library.
shared library. Otherwise a future release of Google Test may break Otherwise a future release of GoogleTest may break your build script.
your build script.
### Avoiding Macro Name Clashes ### ### Avoiding Macro Name Clashes
In C++, macros don't obey namespaces. Therefore two libraries that In C++, macros don't obey namespaces. Therefore two libraries that both define a
both define a macro of the same name will clash if you `#include` both macro of the same name will clash if you `#include` both definitions. In case a
definitions. In case a Google Test macro clashes with another GoogleTest macro clashes with another library, you can force GoogleTest to
library, you can force Google Test to rename its macro to avoid the rename its macro to avoid the conflict.
conflict.
Specifically, if both Google Test and some other code define macro Specifically, if both GoogleTest and some other code define macro FOO, you can
FOO, you can add add
-DGTEST_DONT_DEFINE_FOO=1 -DGTEST_DONT_DEFINE_FOO=1
to the compiler flags to tell Google Test to change the macro's name to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
from `FOO` to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, or `TEST`. For
or `TEST`. For example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
need to write
GTEST_TEST(SomeTest, DoesThis) { ... } GTEST_TEST(SomeTest, DoesThis) { ... }
@ -243,38 +213,3 @@ instead of
TEST(SomeTest, DoesThis) { ... } TEST(SomeTest, DoesThis) { ... }
in order to define a test. in order to define a test.
## 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.
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/](scripts/) directory.
Read the [Pump manual](docs/PumpManual.md) for how to use it.

View File

@ -0,0 +1,9 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
if (@GTEST_HAS_PTHREAD@)
set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@)
find_dependency(Threads)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
check_required_components("@project_name@")

View File

@ -0,0 +1,9 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: gtest
Description: GoogleTest (without main() function)
Version: @PROJECT_VERSION@
URL: https://github.com/google/googletest
Libs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@

View File

@ -0,0 +1,10 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: gtest_main
Description: GoogleTest (with main() function)
Version: @PROJECT_VERSION@
URL: https://github.com/google/googletest
Requires: gtest = @PROJECT_VERSION@
Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@

View File

@ -12,6 +12,10 @@
# Test and Google Mock's option() definitions, and thus must be # Test and Google Mock's option() definitions, and thus must be
# called *after* the options have been defined. # called *after* the options have been defined.
if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif (POLICY CMP0054)
# Tweaks CMake's default compiler/linker settings to suit Google Test's needs. # Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
# #
# This must be a macro(), as inside a function string() can only # This must be a macro(), as inside a function string() can only
@ -20,8 +24,10 @@ macro(fix_default_compiler_settings_)
if (MSVC) if (MSVC)
# For MSVC, CMake sets certain flags to defaults we want to override. # For MSVC, CMake sets certain flags to defaults we want to override.
# This replacement code is taken from sample in the CMake Wiki at # This replacement code is taken from sample in the CMake Wiki at
# http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace. # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.
foreach (flag_var foreach (flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt) if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
@ -38,6 +44,11 @@ macro(fix_default_compiler_settings_)
# We prefer more strict warning checking for building Google Test. # We prefer more strict warning checking for building Google Test.
# Replaces /W3 with /W4 in defaults. # Replaces /W3 with /W4 in defaults.
string(REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}") string(REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}")
# Prevent D9025 warning for targets that have exception handling
# turned off (/EHs-c- flag). Where required, exceptions are explicitly
# re-enabled using the cxx_exception_flags variable.
string(REPLACE "/EHsc" "" ${flag_var} "${${flag_var}}")
endforeach() endforeach()
endif() endif()
endmacro() endmacro()
@ -46,52 +57,43 @@ endmacro()
# Google Mock. You can tweak these definitions to suit your need. A # Google Mock. You can tweak these definitions to suit your need. A
# variable's value is empty before it's explicitly assigned to. # variable's value is empty before it's explicitly assigned to.
macro(config_compiler_and_linker) macro(config_compiler_and_linker)
if (NOT gtest_disable_pthreads) # Note: pthreads on MinGW is not supported, even if available
# instead, we use windows threading primitives
unset(GTEST_HAS_PTHREAD)
if (NOT gtest_disable_pthreads AND NOT MINGW)
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT. # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
find_package(Threads) find_package(Threads)
if (CMAKE_USE_PTHREADS_INIT)
set(GTEST_HAS_PTHREAD ON)
endif()
endif() endif()
fix_default_compiler_settings_() fix_default_compiler_settings_()
if (MSVC) if (MSVC)
# Newlines inside flags variables break CMake's NMake generator. # Newlines inside flags variables break CMake's NMake generator.
# TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J -Zi") set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J")
if (MSVC_VERSION LESS 1400) # 1400 is Visual Studio 2005
# Suppress spurious warnings MSVC 7.1 sometimes issues.
# Forcing value to bool.
set(cxx_base_flags "${cxx_base_flags} -wd4800")
# Copy constructor and assignment operator could not be generated.
set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512")
# Compatibility warnings not applicable to Google Test.
# Resolved overload was found by argument-dependent lookup.
set(cxx_base_flags "${cxx_base_flags} -wd4675")
endif()
if (MSVC_VERSION LESS 1500) # 1500 is Visual Studio 2008
# Conditional expression is constant.
# When compiling with /W4, we get several instances of C4127
# (Conditional expression is constant). In our code, we disable that
# warning on a case-by-case basis. However, on Visual Studio 2005,
# the warning fires on std::list. Therefore on that compiler and earlier,
# we disable the warning project-wide.
set(cxx_base_flags "${cxx_base_flags} -wd4127")
endif()
if (NOT (MSVC_VERSION LESS 1700)) # 1700 is Visual Studio 2012.
# Suppress "unreachable code" warning on VS 2012 and later.
# http://stackoverflow.com/questions/3232669 explains the issue.
set(cxx_base_flags "${cxx_base_flags} -wd4702")
endif()
if (NOT (MSVC_VERSION GREATER 1900)) # 1900 is Visual Studio 2015
# BigObj required for tests.
set(cxx_base_flags "${cxx_base_flags} -bigobj")
endif()
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0") set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-GR-") set(cxx_no_rtti_flags "-GR-")
# Suppress "unreachable code" warning
# http://stackoverflow.com/questions/3232669 explains the issue.
set(cxx_base_flags "${cxx_base_flags} -wd4702")
# Ensure MSVC treats source files as UTF-8 encoded.
set(cxx_base_flags "${cxx_base_flags} -utf-8")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion")
set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions")
set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wredundant-decls")
set(cxx_no_rtti_flags "-fno-rtti")
elseif (CMAKE_COMPILER_IS_GNUCXX) elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow") set(cxx_base_flags "-Wall -Wshadow -Werror")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
endif()
set(cxx_exception_flags "-fexceptions") set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions") set(cxx_no_exception_flags "-fno-exceptions")
# Until version 4.3.2, GCC doesn't define a macro to indicate # Until version 4.3.2, GCC doesn't define a macro to indicate
@ -123,19 +125,20 @@ macro(config_compiler_and_linker)
set(cxx_no_rtti_flags "") set(cxx_no_rtti_flags "")
endif() endif()
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed. # The pthreads library is available and allowed?
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1") if (DEFINED GTEST_HAS_PTHREAD)
set(GTEST_HAS_PTHREAD_MACRO "-DGTEST_HAS_PTHREAD=1")
else() else()
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0") set(GTEST_HAS_PTHREAD_MACRO "-DGTEST_HAS_PTHREAD=0")
endif() endif()
set(cxx_base_flags "${cxx_base_flags} ${GTEST_HAS_PTHREAD_MACRO}")
# For building gtest's own tests and samples. # For building gtest's own tests and samples.
set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}") set(cxx_exception "${cxx_base_flags} ${cxx_exception_flags}")
set(cxx_no_exception set(cxx_no_exception
"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}") "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
set(cxx_default "${cxx_exception}") set(cxx_default "${cxx_exception}")
set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}") set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
# For building the gtest libraries. # For building the gtest libraries.
set(cxx_strict "${cxx_default} ${cxx_strict_flags}") set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
@ -147,16 +150,50 @@ function(cxx_library_with_type name type cxx_flags)
# type can be either STATIC or SHARED to denote a static or shared library. # type can be either STATIC or SHARED to denote a static or shared library.
# ARGN refers to additional arguments after 'cxx_flags'. # ARGN refers to additional arguments after 'cxx_flags'.
add_library(${name} ${type} ${ARGN}) add_library(${name} ${type} ${ARGN})
add_library(${cmake_package_name}::${name} ALIAS ${name})
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES
COMPILE_FLAGS "${cxx_flags}") COMPILE_FLAGS "${cxx_flags}")
# Generate debug library name with a postfix.
set_target_properties(${name}
PROPERTIES
DEBUG_POSTFIX "d")
# Set the output directory for build artifacts
set_target_properties(${name}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# make PDBs match library name
get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX)
set_target_properties(${name}
PROPERTIES
PDB_NAME "${name}"
PDB_NAME_DEBUG "${name}${pdb_debug_postfix}"
COMPILE_PDB_NAME "${name}"
COMPILE_PDB_NAME_DEBUG "${name}${pdb_debug_postfix}")
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1") COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
if (NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
target_compile_definitions(${name} INTERFACE
$<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)
endif() endif()
if (CMAKE_USE_PTHREADS_INIT) endif()
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT}) if (DEFINED GTEST_HAS_PTHREAD)
if ("${CMAKE_VERSION}" VERSION_LESS "3.1.0")
set(threads_spec ${CMAKE_THREAD_LIBS_INIT})
else()
set(threads_spec Threads::Threads)
endif()
target_link_libraries(${name} PUBLIC ${threads_spec})
endif()
if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8")
target_compile_features(${name} PUBLIC cxx_std_11)
endif() endif()
endfunction() endfunction()
@ -178,6 +215,10 @@ endfunction()
# is built from the given source files with the given compiler flags. # is built from the given source files with the given compiler flags.
function(cxx_executable_with_flags name cxx_flags libs) function(cxx_executable_with_flags name cxx_flags libs)
add_executable(${name} ${ARGN}) add_executable(${name} ${ARGN})
if (MSVC)
# BigObj required for tests.
set(cxx_flags "${cxx_flags} -bigobj")
endif()
if (cxx_flags) if (cxx_flags)
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES
@ -206,7 +247,13 @@ function(cxx_executable name dir libs)
endfunction() endfunction()
# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE. # Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
find_package(PythonInterp) if ("${CMAKE_VERSION}" VERSION_LESS "3.12.0")
find_package(PythonInterp)
else()
find_package(Python COMPONENTS Interpreter)
set(PYTHONINTERP_FOUND ${Python_Interpreter_FOUND})
set(PYTHON_EXECUTABLE ${Python_EXECUTABLE})
endif()
# cxx_test_with_flags(name cxx_flags libs srcs...) # cxx_test_with_flags(name cxx_flags libs srcs...)
# #
@ -214,7 +261,7 @@ find_package(PythonInterp)
# from the given source files with the given compiler flags. # from the given source files with the given compiler flags.
function(cxx_test_with_flags name cxx_flags libs) function(cxx_test_with_flags name cxx_flags libs)
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN}) cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
add_test(${name} ${name}) add_test(NAME ${name} COMMAND "$<TARGET_FILE:${name}>")
endfunction() endfunction()
# cxx_test(name libs srcs...) # cxx_test(name libs srcs...)
@ -232,23 +279,66 @@ endfunction()
# creates a Python test with the given name whose main module is in # creates a Python test with the given name whose main module is in
# test/name.py. It does nothing if Python is not installed. # test/name.py. It does nothing if Python is not installed.
function(py_test name) function(py_test name)
# We are not supporting Python tests on Linux yet as they consider
# all Linux environments to be google3 and try to use google3 features.
if (PYTHONINTERP_FOUND) if (PYTHONINTERP_FOUND)
# ${CMAKE_BINARY_DIR} is known at configuration time, so we can if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 3.1)
if (CMAKE_CONFIGURATION_TYPES)
# Multi-configuration build generators as for Visual Studio save
# output in a subdirectory of CMAKE_CURRENT_BINARY_DIR (Debug,
# Release etc.), so we have to provide it here.
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG> ${ARGN})
else (CMAKE_CONFIGURATION_TYPES)
# Single-configuration build generators like Makefile generators
# don't have subdirs below CMAKE_CURRENT_BINARY_DIR.
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN})
endif (CMAKE_CONFIGURATION_TYPES)
else()
# ${CMAKE_CURRENT_BINARY_DIR} is known at configuration time, so we can
# directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known
# only at ctest runtime (by calling ctest -c <Configuration>), so # only at ctest runtime (by calling ctest -c <Configuration>), so
# we have to escape $ to delay variable substitution here. # we have to escape $ to delay variable substitution here.
if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1) add_test(NAME ${name}
add_test(
NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>) --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN})
else (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1) endif()
add_test( endif(PYTHONINTERP_FOUND)
${name} endfunction()
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE}) # install_project(targets...)
endif (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1) #
# Installs the specified targets and configures the associated pkgconfig files.
function(install_project)
if(INSTALL_GTEST)
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
# Install the project targets.
install(TARGETS ${ARGN}
EXPORT ${targets_export_name}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Install PDBs
foreach(t ${ARGN})
get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME)
get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG)
get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)
install(FILES
"${t_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<$<CONFIG:Debug>:${t_pdb_name_debug}>$<$<NOT:$<CONFIG:Debug>>:${t_pdb_name}>.pdb"
DESTINATION ${CMAKE_INSTALL_LIBDIR}
OPTIONAL)
endforeach()
endif()
# Configure and install pkgconfig files.
foreach(t ${ARGN})
set(configured_pc "${generated_dir}/${t}.pc")
configure_file("${PROJECT_SOURCE_DIR}/cmake/${t}.pc.in"
"${configured_pc}" @ONLY)
install(FILES "${configured_pc}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endforeach()
endif() endif()
endfunction() endfunction()

View File

@ -0,0 +1,21 @@
# libgtest.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6
# Please DO NOT delete this file!
# It is necessary for linking the library.
# Names of this library.
library_names='libgtest.so'
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='@CMAKE_INSTALL_FULL_LIBDIR@'

View File

@ -0,0 +1,4 @@
# Content Moved
We are working on updates to the GoogleTest documentation, which has moved to
the top-level [docs](../../docs) directory.

View File

@ -26,17 +26,17 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Author: wan@google.com (Zhanyong Wan) // The Google C++ Testing and Mocking Framework (Google Test)
//
// The Google C++ Testing Framework (Google Test)
// //
// This header file defines the public API for death tests. It is // This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this // #included by gtest.h so a user doesn't need to include this
// directly. // directly.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h" #include "gtest/internal/gtest-death-test-internal.h"
@ -97,12 +97,17 @@ GTEST_API_ bool InDeathTestChild();
// //
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
// //
// The final parameter to each of these macros is a matcher applied to any data
// the sub-process wrote to stderr. For compatibility with existing tests, a
// bare string is interpreted as a regular expression matcher.
//
// On the regular expressions used in death tests: // On the regular expressions used in death tests:
// //
// GOOGLETEST_CM0005 DO NOT DELETE
// On POSIX-compliant systems (*nix), we use the <regex.h> library, // On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax. // which uses the POSIX extended regex syntax.
// //
// On other platforms (e.g. Windows), we only support a simple regex // On other platforms (e.g. Windows or Mac), we only support a simple regex
// syntax implemented as part of Google Test. This limited // syntax implemented as part of Google Test. This limited
// implementation should be enough most of the time when writing // implementation should be enough most of the time when writing
// death tests; though it lacks many features you can find in PCRE // death tests; though it lacks many features you can find in PCRE
@ -160,29 +165,28 @@ GTEST_API_ bool InDeathTestChild();
// is rarely a problem as people usually don't put the test binary // is rarely a problem as people usually don't put the test binary
// directory in PATH. // directory in PATH.
// //
// TODO(wan@google.com): make thread-safe death tests search the PATH.
// Asserts that a given statement causes the program to exit, with an // Asserts that a given `statement` causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output // integer exit status that satisfies `predicate`, and emitting error output
// that matches regex. // that matches `matcher`.
# define ASSERT_EXIT(statement, predicate, regex) \ # define ASSERT_EXIT(statement, predicate, matcher) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_)
// Like ASSERT_EXIT, but continues on to successive tests in the // Like `ASSERT_EXIT`, but continues on to successive tests in the
// test case, if any: // test suite, if any:
# define EXPECT_EXIT(statement, predicate, regex) \ # define EXPECT_EXIT(statement, predicate, matcher) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_)
// Asserts that a given statement causes the program to exit, either by // Asserts that a given `statement` causes the program to exit, either by
// explicitly exiting with a nonzero exit code or being killed by a // explicitly exiting with a nonzero exit code or being killed by a
// signal, and emitting error output that matches regex. // signal, and emitting error output that matches `matcher`.
# define ASSERT_DEATH(statement, regex) \ # define ASSERT_DEATH(statement, matcher) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Like ASSERT_DEATH, but continues on to successive tests in the // Like `ASSERT_DEATH`, but continues on to successive tests in the
// test case, if any: // test suite, if any:
# define EXPECT_DEATH(statement, regex) \ # define EXPECT_DEATH(statement, matcher) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
@ -190,17 +194,17 @@ GTEST_API_ bool InDeathTestChild();
class GTEST_API_ ExitedWithCode { class GTEST_API_ ExitedWithCode {
public: public:
explicit ExitedWithCode(int exit_code); explicit ExitedWithCode(int exit_code);
ExitedWithCode(const ExitedWithCode&) = default;
void operator=(const ExitedWithCode& other) = delete;
bool operator()(int exit_status) const; bool operator()(int exit_status) const;
private: private:
// No implementation - assignment is unsupported.
void operator=(const ExitedWithCode& other);
const int exit_code_; const int exit_code_;
}; };
# if !GTEST_OS_WINDOWS # if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Tests that an exit code describes an exit due to termination by a // Tests that an exit code describes an exit due to termination by a
// given signal. // given signal.
// GOOGLETEST_CM0006 DO NOT DELETE
class GTEST_API_ KilledBySignal { class GTEST_API_ KilledBySignal {
public: public:
explicit KilledBySignal(int signum); explicit KilledBySignal(int signum);
@ -226,7 +230,7 @@ class GTEST_API_ KilledBySignal {
// return 12; // return 12;
// } // }
// //
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { // TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
// int sideeffect = 0; // int sideeffect = 0;
// // Only asserts in dbg. // // Only asserts in dbg.
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
@ -272,6 +276,54 @@ class GTEST_API_ KilledBySignal {
# endif // NDEBUG for EXPECT_DEBUG_DEATH # endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
// death tests are not supported. Those macros must compile on such systems
// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters
// on systems that support death tests. This allows one to write such a macro on
// a system that does not support death tests and be sure that it will compile
// on a death-test supporting system. It is exposed publicly so that systems
// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST
// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and
// ASSERT_DEATH_IF_SUPPORTED.
//
// Parameters:
// statement - A statement that a macro such as EXPECT_DEATH would test
// for program termination. This macro has to make sure this
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter if and only if EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
// compile inside functions where ASSERT_DEATH doesn't
// compile.
//
// The branch that has an always false condition is used to ensure that
// statement and regex are compiled (and thus syntactically correct) but
// never executed. The unreachable code macro protects the terminator
// statement from generating an 'unreachable code' warning in case
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
// death tests are supported; otherwise they just issue a warning. This is // death tests are supported; otherwise they just issue a warning. This is
@ -284,11 +336,11 @@ class GTEST_API_ KilledBySignal {
ASSERT_DEATH(statement, regex) ASSERT_DEATH(statement, regex)
#else #else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
#endif #endif
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_

View File

@ -0,0 +1,930 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#include <atomic>
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>
#include "gtest/gtest-printers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
// MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915
#define GTEST_MAYBE_5046_ 5046
#else
#define GTEST_MAYBE_5046_
#endif
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
clients of class B */
/* Symbol involving type with internal linkage not defined */)
namespace testing {
// To implement a matcher Foo for type T, define:
// 1. a class FooMatcherMatcher that implements the matcher interface:
// using is_gtest_matcher = void;
// bool MatchAndExplain(const T&, std::ostream*);
// (MatchResultListener* can also be used instead of std::ostream*)
// void DescribeTo(std::ostream*);
// void DescribeNegationTo(std::ostream*);
//
// 2. a factory function that creates a Matcher<T> object from a
// FooMatcherMatcher.
class MatchResultListener {
public:
// Creates a listener object with the given underlying ostream. The
// listener does not own the ostream, and does not dereference it
// in the constructor or destructor.
explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
virtual ~MatchResultListener() = 0; // Makes this class abstract.
// Streams x to the underlying ostream; does nothing if the ostream
// is NULL.
template <typename T>
MatchResultListener& operator<<(const T& x) {
if (stream_ != nullptr) *stream_ << x;
return *this;
}
// Returns the underlying ostream.
::std::ostream* stream() { return stream_; }
// Returns true if and only if the listener is interested in an explanation
// of the match result. A matcher's MatchAndExplain() method can use
// this information to avoid generating the explanation when no one
// intends to hear it.
bool IsInterested() const { return stream_ != nullptr; }
private:
::std::ostream* const stream_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
};
inline MatchResultListener::~MatchResultListener() {
}
// An instance of a subclass of this knows how to describe itself as a
// matcher.
class GTEST_API_ MatcherDescriberInterface {
public:
virtual ~MatcherDescriberInterface() {}
// Describes this matcher to an ostream. The function should print
// a verb phrase that describes the property a value matching this
// matcher should have. The subject of the verb phrase is the value
// being matched. For example, the DescribeTo() method of the Gt(7)
// matcher prints "is greater than 7".
virtual void DescribeTo(::std::ostream* os) const = 0;
// Describes the negation of this matcher to an ostream. For
// example, if the description of this matcher is "is greater than
// 7", the negated description could be "is not greater than 7".
// You are not required to override this when implementing
// MatcherInterface, but it is highly advised so that your matcher
// can produce good error messages.
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "not (";
DescribeTo(os);
*os << ")";
}
};
// The implementation of a matcher.
template <typename T>
class MatcherInterface : public MatcherDescriberInterface {
public:
// Returns true if and only if the matcher matches x; also explains the
// match result to 'listener' if necessary (see the next paragraph), in
// the form of a non-restrictive relative clause ("which ...",
// "whose ...", etc) that describes x. For example, the
// MatchAndExplain() method of the Pointee(...) matcher should
// generate an explanation like "which points to ...".
//
// Implementations of MatchAndExplain() should add an explanation of
// the match result *if and only if* they can provide additional
// information that's not already present (or not obvious) in the
// print-out of x and the matcher's description. Whether the match
// succeeds is not a factor in deciding whether an explanation is
// needed, as sometimes the caller needs to print a failure message
// when the match succeeds (e.g. when the matcher is used inside
// Not()).
//
// For example, a "has at least 10 elements" matcher should explain
// what the actual element count is, regardless of the match result,
// as it is useful information to the reader; on the other hand, an
// "is empty" matcher probably only needs to explain what the actual
// size is when the match fails, as it's redundant to say that the
// size is 0 when the value is already known to be empty.
//
// You should override this method when defining a new matcher.
//
// It's the responsibility of the caller (Google Test) to guarantee
// that 'listener' is not NULL. This helps to simplify a matcher's
// implementation when it doesn't care about the performance, as it
// can talk to 'listener' without checking its validity first.
// However, in order to implement dummy listeners efficiently,
// listener->stream() may be NULL.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
// Inherits these methods from MatcherDescriberInterface:
// virtual void DescribeTo(::std::ostream* os) const = 0;
// virtual void DescribeNegationTo(::std::ostream* os) const;
};
namespace internal {
struct AnyEq {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a == b; }
};
struct AnyNe {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a != b; }
};
struct AnyLt {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a < b; }
};
struct AnyGt {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a > b; }
};
struct AnyLe {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a <= b; }
};
struct AnyGe {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a >= b; }
};
// A match result listener that ignores the explanation.
class DummyMatchResultListener : public MatchResultListener {
public:
DummyMatchResultListener() : MatchResultListener(nullptr) {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
};
// A match result listener that forwards the explanation to a given
// ostream. The difference between this and MatchResultListener is
// that the former is concrete.
class StreamMatchResultListener : public MatchResultListener {
public:
explicit StreamMatchResultListener(::std::ostream* os)
: MatchResultListener(os) {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
};
struct SharedPayloadBase {
std::atomic<int> ref{1};
void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
};
template <typename T>
struct SharedPayload : SharedPayloadBase {
explicit SharedPayload(const T& v) : value(v) {}
explicit SharedPayload(T&& v) : value(std::move(v)) {}
static void Destroy(SharedPayloadBase* shared) {
delete static_cast<SharedPayload*>(shared);
}
T value;
};
// An internal class for implementing Matcher<T>, which will derive
// from it. We put functionalities common to all Matcher<T>
// specializations here to avoid code duplication.
template <typename T>
class MatcherBase : private MatcherDescriberInterface {
public:
// Returns true if and only if the matcher matches x; also explains the
// match result to 'listener'.
bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
GTEST_CHECK_(vtable_ != nullptr);
return vtable_->match_and_explain(*this, x, listener);
}
// Returns true if and only if this matcher matches x.
bool Matches(const T& x) const {
DummyMatchResultListener dummy;
return MatchAndExplain(x, &dummy);
}
// Describes this matcher to an ostream.
void DescribeTo(::std::ostream* os) const final {
GTEST_CHECK_(vtable_ != nullptr);
vtable_->describe(*this, os, false);
}
// Describes the negation of this matcher to an ostream.
void DescribeNegationTo(::std::ostream* os) const final {
GTEST_CHECK_(vtable_ != nullptr);
vtable_->describe(*this, os, true);
}
// Explains why x matches, or doesn't match, the matcher.
void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
StreamMatchResultListener listener(os);
MatchAndExplain(x, &listener);
}
// Returns the describer for this matcher object; retains ownership
// of the describer, which is only guaranteed to be alive when
// this matcher object is alive.
const MatcherDescriberInterface* GetDescriber() const {
if (vtable_ == nullptr) return nullptr;
return vtable_->get_describer(*this);
}
protected:
MatcherBase() : vtable_(nullptr) {}
// Constructs a matcher from its implementation.
template <typename U>
explicit MatcherBase(const MatcherInterface<U>* impl) {
Init(impl);
}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
MatcherBase(M&& m) { // NOLINT
Init(std::forward<M>(m));
}
MatcherBase(const MatcherBase& other)
: vtable_(other.vtable_), buffer_(other.buffer_) {
if (IsShared()) buffer_.shared->Ref();
}
MatcherBase& operator=(const MatcherBase& other) {
if (this == &other) return *this;
Destroy();
vtable_ = other.vtable_;
buffer_ = other.buffer_;
if (IsShared()) buffer_.shared->Ref();
return *this;
}
MatcherBase(MatcherBase&& other)
: vtable_(other.vtable_), buffer_(other.buffer_) {
other.vtable_ = nullptr;
}
MatcherBase& operator=(MatcherBase&& other) {
if (this == &other) return *this;
Destroy();
vtable_ = other.vtable_;
buffer_ = other.buffer_;
other.vtable_ = nullptr;
return *this;
}
~MatcherBase() override { Destroy(); }
private:
struct VTable {
bool (*match_and_explain)(const MatcherBase&, const T&,
MatchResultListener*);
void (*describe)(const MatcherBase&, std::ostream*, bool negation);
// Returns the captured object if it implements the interface, otherwise
// returns the MatcherBase itself.
const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);
// Called on shared instances when the reference count reaches 0.
void (*shared_destroy)(SharedPayloadBase*);
};
bool IsShared() const {
return vtable_ != nullptr && vtable_->shared_destroy != nullptr;
}
// If the implementation uses a listener, call that.
template <typename P>
static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
MatchResultListener* listener)
-> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
return P::Get(m).MatchAndExplain(value, listener->stream());
}
template <typename P>
static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
MatchResultListener* listener)
-> decltype(P::Get(m).MatchAndExplain(value, listener)) {
return P::Get(m).MatchAndExplain(value, listener);
}
template <typename P>
static void DescribeImpl(const MatcherBase& m, std::ostream* os,
bool negation) {
if (negation) {
P::Get(m).DescribeNegationTo(os);
} else {
P::Get(m).DescribeTo(os);
}
}
template <typename P>
static const MatcherDescriberInterface* GetDescriberImpl(
const MatcherBase& m) {
// If the impl is a MatcherDescriberInterface, then return it.
// Otherwise use MatcherBase itself.
// This allows us to implement the GetDescriber() function without support
// from the impl, but some users really want to get their impl back when
// they call GetDescriber().
// We use std::get on a tuple as a workaround of not having `if constexpr`.
return std::get<(
std::is_convertible<decltype(&P::Get(m)),
const MatcherDescriberInterface*>::value
? 1
: 0)>(std::make_tuple(&m, &P::Get(m)));
}
template <typename P>
const VTable* GetVTable() {
static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
&DescribeImpl<P>, &GetDescriberImpl<P>,
P::shared_destroy};
return &kVTable;
}
union Buffer {
// Add some types to give Buffer some common alignment/size use cases.
void* ptr;
double d;
int64_t i;
// And add one for the out-of-line cases.
SharedPayloadBase* shared;
};
void Destroy() {
if (IsShared() && buffer_.shared->Unref()) {
vtable_->shared_destroy(buffer_.shared);
}
}
template <typename M>
static constexpr bool IsInlined() {
return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
std::is_trivially_copy_constructible<M>::value &&
std::is_trivially_destructible<M>::value;
}
template <typename M, bool = MatcherBase::IsInlined<M>()>
struct ValuePolicy {
static const M& Get(const MatcherBase& m) {
// When inlined along with Init, need to be explicit to avoid violating
// strict aliasing rules.
const M *ptr = static_cast<const M*>(
static_cast<const void*>(&m.buffer_));
return *ptr;
}
static void Init(MatcherBase& m, M impl) {
::new (static_cast<void*>(&m.buffer_)) M(impl);
}
static constexpr auto shared_destroy = nullptr;
};
template <typename M>
struct ValuePolicy<M, false> {
using Shared = SharedPayload<M>;
static const M& Get(const MatcherBase& m) {
return static_cast<Shared*>(m.buffer_.shared)->value;
}
template <typename Arg>
static void Init(MatcherBase& m, Arg&& arg) {
m.buffer_.shared = new Shared(std::forward<Arg>(arg));
}
static constexpr auto shared_destroy = &Shared::Destroy;
};
template <typename U, bool B>
struct ValuePolicy<const MatcherInterface<U>*, B> {
using M = const MatcherInterface<U>;
using Shared = SharedPayload<std::unique_ptr<M>>;
static const M& Get(const MatcherBase& m) {
return *static_cast<Shared*>(m.buffer_.shared)->value;
}
static void Init(MatcherBase& m, M* impl) {
m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));
}
static constexpr auto shared_destroy = &Shared::Destroy;
};
template <typename M>
void Init(M&& m) {
using MM = typename std::decay<M>::type;
using Policy = ValuePolicy<MM>;
vtable_ = GetVTable<Policy>();
Policy::Init(*this, std::forward<M>(m));
}
const VTable* vtable_;
Buffer buffer_;
};
} // namespace internal
// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
// object that can check whether a value of type T matches. The
// implementation of Matcher<T> is just a std::shared_ptr to const
// MatcherInterface<T>. Don't inherit from Matcher!
template <typename T>
class Matcher : public internal::MatcherBase<T> {
public:
// Constructs a null matcher. Needed for storing Matcher objects in STL
// containers. A default-constructed matcher is not yet initialized. You
// cannot use it until a valid value has been assigned to it.
explicit Matcher() {} // NOLINT
// Constructs a matcher from its implementation.
explicit Matcher(const MatcherInterface<const T&>* impl)
: internal::MatcherBase<T>(impl) {}
template <typename U>
explicit Matcher(
const MatcherInterface<U>* impl,
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
nullptr)
: internal::MatcherBase<T>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
// Implicit constructor here allows people to write
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
Matcher(T value); // NOLINT
};
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected.
template <>
class GTEST_API_ Matcher<const std::string&>
: public internal::MatcherBase<const std::string&> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<const std::string&>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
};
template <>
class GTEST_API_ Matcher<std::string>
: public internal::MatcherBase<std::string> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<std::string>(impl) {}
explicit Matcher(const MatcherInterface<std::string>* impl)
: internal::MatcherBase<std::string>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<std::string>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
};
#if GTEST_INTERNAL_HAS_STRING_VIEW
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
// matcher is expected.
template <>
class GTEST_API_ Matcher<const internal::StringView&>
: public internal::MatcherBase<const internal::StringView&> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
: internal::MatcherBase<const internal::StringView&>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
Matcher(internal::StringView s); // NOLINT
};
template <>
class GTEST_API_ Matcher<internal::StringView>
: public internal::MatcherBase<internal::StringView> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
: internal::MatcherBase<internal::StringView>(impl) {}
explicit Matcher(const MatcherInterface<internal::StringView>* impl)
: internal::MatcherBase<internal::StringView>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
Matcher(internal::StringView s); // NOLINT
};
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Prints a matcher in a human-readable format.
template <typename T>
std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
matcher.DescribeTo(&os);
return os;
}
// The PolymorphicMatcher class template makes it easy to implement a
// polymorphic matcher (i.e. a matcher that can match values of more
// than one type, e.g. Eq(n) and NotNull()).
//
// To define a polymorphic matcher, a user should provide an Impl
// class that has a DescribeTo() method and a DescribeNegationTo()
// method, and define a member function (or member function template)
//
// bool MatchAndExplain(const Value& value,
// MatchResultListener* listener) const;
//
// See the definition of NotNull() for a complete example.
template <class Impl>
class PolymorphicMatcher {
public:
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
// Returns a mutable reference to the underlying matcher
// implementation object.
Impl& mutable_impl() { return impl_; }
// Returns an immutable reference to the underlying matcher
// implementation object.
const Impl& impl() const { return impl_; }
template <typename T>
operator Matcher<T>() const {
return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
}
private:
template <typename T>
class MonomorphicImpl : public MatcherInterface<T> {
public:
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
void DescribeNegationTo(::std::ostream* os) const override {
impl_.DescribeNegationTo(os);
}
bool MatchAndExplain(T x, MatchResultListener* listener) const override {
return impl_.MatchAndExplain(x, listener);
}
private:
const Impl impl_;
};
Impl impl_;
};
// Creates a matcher from its implementation.
// DEPRECATED: Especially in the generic code, prefer:
// Matcher<T>(new MyMatcherImpl<const T&>(...));
//
// MakeMatcher may create a Matcher that accepts its argument by value, which
// leads to unnecessary copies & lack of support for non-copyable types.
template <typename T>
inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
return Matcher<T>(impl);
}
// Creates a polymorphic matcher from its implementation. This is
// easier to use than the PolymorphicMatcher<Impl> constructor as it
// doesn't require you to explicitly write the template argument, e.g.
//
// MakePolymorphicMatcher(foo);
// vs
// PolymorphicMatcher<TypeOfFoo>(foo);
template <class Impl>
inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
return PolymorphicMatcher<Impl>(impl);
}
namespace internal {
// Implements a matcher that compares a given value with a
// pre-supplied value using one of the ==, <=, <, etc, operators. The
// two values being compared don't have to have the same type.
//
// The matcher defined here is polymorphic (for example, Eq(5) can be
// used to match an int, a short, a double, etc). Therefore we use
// a template type conversion operator in the implementation.
//
// The following template definition assumes that the Rhs parameter is
// a "bare" type (i.e. neither 'const T' nor 'T&').
template <typename D, typename Rhs, typename Op>
class ComparisonBase {
public:
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
using is_gtest_matcher = void;
template <typename Lhs>
bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
return Op()(lhs, Unwrap(rhs_));
}
void DescribeTo(std::ostream* os) const {
*os << D::Desc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << D::NegatedDesc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
private:
template <typename T>
static const T& Unwrap(const T& v) {
return v;
}
template <typename T>
static const T& Unwrap(std::reference_wrapper<T> v) {
return v;
}
Rhs rhs_;
};
template <typename Rhs>
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
public:
explicit EqMatcher(const Rhs& rhs)
: ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
static const char* Desc() { return "is equal to"; }
static const char* NegatedDesc() { return "isn't equal to"; }
};
template <typename Rhs>
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
public:
explicit NeMatcher(const Rhs& rhs)
: ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
static const char* Desc() { return "isn't equal to"; }
static const char* NegatedDesc() { return "is equal to"; }
};
template <typename Rhs>
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
public:
explicit LtMatcher(const Rhs& rhs)
: ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
static const char* Desc() { return "is <"; }
static const char* NegatedDesc() { return "isn't <"; }
};
template <typename Rhs>
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
public:
explicit GtMatcher(const Rhs& rhs)
: ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
static const char* Desc() { return "is >"; }
static const char* NegatedDesc() { return "isn't >"; }
};
template <typename Rhs>
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
public:
explicit LeMatcher(const Rhs& rhs)
: ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
static const char* Desc() { return "is <="; }
static const char* NegatedDesc() { return "isn't <="; }
};
template <typename Rhs>
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
public:
explicit GeMatcher(const Rhs& rhs)
: ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
static const char* Desc() { return "is >="; }
static const char* NegatedDesc() { return "isn't >="; }
};
template <typename T, typename = typename std::enable_if<
std::is_constructible<std::string, T>::value>::type>
using StringLike = T;
// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
class MatchesRegexMatcher {
public:
MatchesRegexMatcher(const RE* regex, bool full_match)
: regex_(regex), full_match_(full_match) {}
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const {
return MatchAndExplain(std::string(s), listener);
}
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
// char*
// const wchar_t*
// wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != nullptr && MatchAndExplain(std::string(s), listener);
}
// Matches anything that can convert to std::string.
//
// This is a template, not just a plain function with const std::string&,
// because absl::string_view has some interfering non-explicit constructors.
template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
const std::string& s2(s);
return full_match_ ? RE::FullMatch(s2, *regex_)
: RE::PartialMatch(s2, *regex_);
}
void DescribeTo(::std::ostream* os) const {
*os << (full_match_ ? "matches" : "contains") << " regular expression ";
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't " << (full_match_ ? "match" : "contain")
<< " regular expression ";
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
}
private:
const std::shared_ptr<const RE> regex_;
const bool full_match_;
};
} // namespace internal
// Matches a string that fully matches regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const internal::RE* regex) {
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
}
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const internal::StringLike<T>& regex) {
return MatchesRegex(new internal::RE(std::string(regex)));
}
// Matches a string that contains regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const internal::RE* regex) {
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
}
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const internal::StringLike<T>& regex) {
return ContainsRegex(new internal::RE(std::string(regex)));
}
// Creates a polymorphic matcher that matches anything equal to x.
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// wouldn't compile.
template <typename T>
inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'.
template <typename T>
Matcher<T>::Matcher(T value) { *this = Eq(value); }
// Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity.
//
// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
// or Matcher<T>(x), but more readable than the latter.
//
// We could define similar monomorphic matchers for other comparison
// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
// it yet as those are used much less than Eq() in practice. A user
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
// for example.
template <typename Lhs, typename Rhs>
inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
// Creates a polymorphic matcher that matches anything >= x.
template <typename Rhs>
inline internal::GeMatcher<Rhs> Ge(Rhs x) {
return internal::GeMatcher<Rhs>(x);
}
// Creates a polymorphic matcher that matches anything > x.
template <typename Rhs>
inline internal::GtMatcher<Rhs> Gt(Rhs x) {
return internal::GtMatcher<Rhs>(x);
}
// Creates a polymorphic matcher that matches anything <= x.
template <typename Rhs>
inline internal::LeMatcher<Rhs> Le(Rhs x) {
return internal::LeMatcher<Rhs>(x);
}
// Creates a polymorphic matcher that matches anything < x.
template <typename Rhs>
inline internal::LtMatcher<Rhs> Lt(Rhs x) {
return internal::LtMatcher<Rhs>(x);
}
// Creates a polymorphic matcher that matches anything != x.
template <typename Rhs>
inline internal::NeMatcher<Rhs> Ne(Rhs x) {
return internal::NeMatcher<Rhs>(x);
}
} // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_

View File

@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Author: wan@google.com (Zhanyong Wan) // The Google C++ Testing and Mocking Framework (Google Test)
//
// The Google C++ Testing Framework (Google Test)
// //
// This header file defines the Message class. // This header file defines the Message class.
// //
@ -43,13 +42,20 @@
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program! // program!
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ // GOOGLETEST_CM0001 DO NOT DELETE
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits> #include <limits>
#include <memory>
#include <sstream>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
// Ensures that there is at least one operator<< in the global namespace. // Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why. // See Message& operator<<(...) below for why.
void operator<<(const testing::internal::Secret&, int); void operator<<(const testing::internal::Secret&, int);
@ -102,14 +108,6 @@ class GTEST_API_ Message {
*ss_ << str; *ss_ << str;
} }
#if GTEST_OS_SYMBIAN
// Streams a value (either a pointer or not) to this object.
template <typename T>
inline Message& operator <<(const T& value) {
StreamHelper(typename internal::is_pointer<T>::type(), value);
return *this;
}
#else
// Streams a non-pointer value to this object. // Streams a non-pointer value to this object.
template <typename T> template <typename T>
inline Message& operator <<(const T& val) { inline Message& operator <<(const T& val) {
@ -147,14 +145,13 @@ class GTEST_API_ Message {
// as "(null)". // as "(null)".
template <typename T> template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT inline Message& operator <<(T* const& pointer) { // NOLINT
if (pointer == NULL) { if (pointer == nullptr) {
*ss_ << "(null)"; *ss_ << "(null)";
} else { } else {
*ss_ << pointer; *ss_ << pointer;
} }
return *this; return *this;
} }
#endif // GTEST_OS_SYMBIAN
// Since the basic IO manipulators are overloaded for both narrow // Since the basic IO manipulators are overloaded for both narrow
// and wide streams, we have to provide this specialized definition // and wide streams, we have to provide this specialized definition
@ -183,12 +180,6 @@ class GTEST_API_ Message {
Message& operator <<(const ::std::wstring& wstr); Message& operator <<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_GLOBAL_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::wstring& wstr);
#endif // GTEST_HAS_GLOBAL_WSTRING
// Gets the text streamed to this object so far as an std::string. // Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0". // Each '\0' character in the buffer is replaced with "\\0".
// //
@ -196,32 +187,8 @@ class GTEST_API_ Message {
std::string GetString() const; std::string GetString() const;
private: private:
#if GTEST_OS_SYMBIAN
// These are needed as the Nokia Symbian Compiler cannot decide between
// const T& and const T* in a function template. The Nokia compiler _can_
// decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that.
template <typename T>
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
}
template <typename T>
inline void StreamHelper(internal::false_type /*is_pointer*/,
const T& value) {
// See the comments in Message& operator <<(const T&) above for why
// we need this using statement.
using ::operator <<;
*ss_ << value;
}
#endif // GTEST_OS_SYMBIAN
// We'll hold the text streamed to this object here. // We'll hold the text streamed to this object here.
const internal::scoped_ptr< ::std::stringstream> ss_; const std::unique_ptr< ::std::stringstream> ss_;
// We declare (but don't implement) this to prevent the compiler // We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator. // from implementing the assignment operator.
@ -247,4 +214,6 @@ std::string StreamableToString(const T& streamable) {
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,17 +26,21 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// //
// Utilities for testing Google Test itself and code that uses Google Test // Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test). // (e.g. frameworks built on top of Google Test).
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ // GOOGLETEST_CM0004 DO NOT DELETE
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
#include "gtest/gtest.h" #include "gtest/gtest.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing { namespace testing {
// This helper class can be used to mock out Google Test failure reporting // This helper class can be used to mock out Google Test failure reporting
@ -68,14 +72,15 @@ class GTEST_API_ ScopedFakeTestPartResultReporter
TestPartResultArray* result); TestPartResultArray* result);
// The d'tor restores the previous test part result reporter. // The d'tor restores the previous test part result reporter.
virtual ~ScopedFakeTestPartResultReporter(); ~ScopedFakeTestPartResultReporter() override;
// Appends the TestPartResult object to the TestPartResultArray // Appends the TestPartResult object to the TestPartResultArray
// received in the constructor. // received in the constructor.
// //
// This method is from the TestPartResultReporterInterface // This method is from the TestPartResultReporterInterface
// interface. // interface.
virtual void ReportTestPartResult(const TestPartResult& result); void ReportTestPartResult(const TestPartResult& result) override;
private: private:
void Init(); void Init();
@ -97,13 +102,12 @@ class GTEST_API_ SingleFailureChecker {
public: public:
// The constructor remembers the arguments. // The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results, SingleFailureChecker(const TestPartResultArray* results,
TestPartResult::Type type, TestPartResult::Type type, const std::string& substr);
const string& substr);
~SingleFailureChecker(); ~SingleFailureChecker();
private: private:
const TestPartResultArray* const results_; const TestPartResultArray* const results_;
const TestPartResult::Type type_; const TestPartResult::Type type_;
const string substr_; const std::string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
}; };
@ -112,6 +116,8 @@ class GTEST_API_ SingleFailureChecker {
} // namespace testing } // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// A set of macros for testing Google Test assertions or code that's expected // A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given // to generate Google Test fatal failures. It verifies that the given
// statement will cause exactly one fatal Google Test failure with 'substr' // statement will cause exactly one fatal Google Test failure with 'substr'
@ -229,4 +235,4 @@ class GTEST_API_ SingleFailureChecker {
}\ }\
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_

View File

@ -27,17 +27,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Author: mheule@google.com (Markus Heule) // GOOGLETEST_CM0001 DO NOT DELETE
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd> #include <iosfwd>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing { namespace testing {
// A copyable object representing the result of a test part (i.e. an // A copyable object representing the result of a test part (i.e. an
@ -51,22 +53,20 @@ class GTEST_API_ TestPartResult {
enum Type { enum Type {
kSuccess, // Succeeded. kSuccess, // Succeeded.
kNonFatalFailure, // Failed but the test can continue. kNonFatalFailure, // Failed but the test can continue.
kFatalFailure // Failed and the test should be terminated. kFatalFailure, // Failed and the test should be terminated.
kSkip // Skipped.
}; };
// C'tor. TestPartResult does NOT have a default constructor. // C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a // Always use this constructor (with parameters) to create a
// TestPartResult object. // TestPartResult object.
TestPartResult(Type a_type, TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
const char* a_file_name,
int a_line_number,
const char* a_message) const char* a_message)
: type_(a_type), : type_(a_type),
file_name_(a_file_name == NULL ? "" : a_file_name), file_name_(a_file_name == nullptr ? "" : a_file_name),
line_number_(a_line_number), line_number_(a_line_number),
summary_(ExtractSummary(a_message)), summary_(ExtractSummary(a_message)),
message_(a_message) { message_(a_message) {}
}
// Gets the outcome of the test part. // Gets the outcome of the test part.
Type type() const { return type_; } Type type() const { return type_; }
@ -74,7 +74,7 @@ class GTEST_API_ TestPartResult {
// Gets the name of the source file where the test part took place, or // Gets the name of the source file where the test part took place, or
// NULL if it's unknown. // NULL if it's unknown.
const char* file_name() const { const char* file_name() const {
return file_name_.empty() ? NULL : file_name_.c_str(); return file_name_.empty() ? nullptr : file_name_.c_str();
} }
// Gets the line in the source file where the test part took place, // Gets the line in the source file where the test part took place,
@ -87,18 +87,21 @@ class GTEST_API_ TestPartResult {
// Gets the message associated with the test part. // Gets the message associated with the test part.
const char* message() const { return message_.c_str(); } const char* message() const { return message_.c_str(); }
// Returns true iff the test part passed. // Returns true if and only if the test part was skipped.
bool skipped() const { return type_ == kSkip; }
// Returns true if and only if the test part passed.
bool passed() const { return type_ == kSuccess; } bool passed() const { return type_ == kSuccess; }
// Returns true iff the test part failed. // Returns true if and only if the test part non-fatally failed.
bool failed() const { return type_ != kSuccess; }
// Returns true iff the test part non-fatally failed.
bool nonfatally_failed() const { return type_ == kNonFatalFailure; } bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
// Returns true iff the test part fatally failed. // Returns true if and only if the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; } bool fatally_failed() const { return type_ == kFatalFailure; }
// Returns true if and only if the test part failed.
bool failed() const { return fatally_failed() || nonfatally_failed(); }
private: private:
Type type_; Type type_;
@ -143,7 +146,7 @@ class GTEST_API_ TestPartResultArray {
}; };
// This interface knows how to report a test part result. // This interface knows how to report a test part result.
class TestPartResultReporterInterface { class GTEST_API_ TestPartResultReporterInterface {
public: public:
virtual ~TestPartResultReporterInterface() {} virtual ~TestPartResultReporterInterface() {}
@ -162,8 +165,8 @@ class GTEST_API_ HasNewFatalFailureHelper
: public TestPartResultReporterInterface { : public TestPartResultReporterInterface {
public: public:
HasNewFatalFailureHelper(); HasNewFatalFailureHelper();
virtual ~HasNewFatalFailureHelper(); ~HasNewFatalFailureHelper() override;
virtual void ReportTestPartResult(const TestPartResult& result); void ReportTestPartResult(const TestPartResult& result) override;
bool has_new_fatal_failure() const { return has_new_fatal_failure_; } bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private: private:
bool has_new_fatal_failure_; bool has_new_fatal_failure_;
@ -176,4 +179,6 @@ class GTEST_API_ HasNewFatalFailureHelper
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

View File

@ -26,11 +26,11 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ // GOOGLETEST_CM0001 DO NOT DELETE
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
// This header implements typed tests and type-parameterized tests. // This header implements typed tests and type-parameterized tests.
@ -51,22 +51,22 @@ class FooTest : public testing::Test {
T value_; T value_;
}; };
// Next, associate a list of types with the test case, which will be // Next, associate a list of types with the test suite, which will be
// repeated for each type in the list. The typedef is necessary for // repeated for each type in the list. The typedef is necessary for
// the macro to parse correctly. // the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes; typedef testing::Types<char, int, unsigned int> MyTypes;
TYPED_TEST_CASE(FooTest, MyTypes); TYPED_TEST_SUITE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type // If the type list contains only one type, you can write that type
// directly without Types<...>: // directly without Types<...>:
// TYPED_TEST_CASE(FooTest, int); // TYPED_TEST_SUITE(FooTest, int);
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed // Then, use TYPED_TEST() instead of TEST_F() to define as many typed
// tests for this test case as you want. // tests for this test suite as you want.
TYPED_TEST(FooTest, DoesBlah) { TYPED_TEST(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter. // Inside a test, refer to the special name TypeParam to get the type
// Since we are inside a derived class template, C++ requires use to // parameter. Since we are inside a derived class template, C++ requires
// visit the members of FooTest via 'this'. // us to visit the members of FooTest via 'this'.
TypeParam n = this->value_; TypeParam n = this->value_;
// To visit static members of the fixture, add the TestFixture:: // To visit static members of the fixture, add the TestFixture::
@ -82,6 +82,24 @@ TYPED_TEST(FooTest, DoesBlah) {
TYPED_TEST(FooTest, HasPropertyA) { ... } TYPED_TEST(FooTest, HasPropertyA) { ... }
// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
// class that generates custom test name suffixes based on the type. This should
// be a class which has a static template function GetName(int index) returning
// a string for each type. The provided integer index equals the index of the
// type in the provided type list. In many cases the index can be ignored.
//
// For example:
// class MyTypeNames {
// public:
// template <typename T>
// static std::string GetName(int) {
// if (std::is_same<T, char>()) return "char";
// if (std::is_same<T, int>()) return "int";
// if (std::is_same<T, unsigned int>()) return "unsignedInt";
// }
// };
// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
#endif // 0 #endif // 0
// Type-parameterized tests are abstract test patterns parameterized // Type-parameterized tests are abstract test patterns parameterized
@ -107,13 +125,13 @@ class FooTest : public testing::Test {
... ...
}; };
// Next, declare that you will define a type-parameterized test case // Next, declare that you will define a type-parameterized test suite
// (the _P suffix is for "parameterized" or "pattern", whichever you // (the _P suffix is for "parameterized" or "pattern", whichever you
// prefer): // prefer):
TYPED_TEST_CASE_P(FooTest); TYPED_TEST_SUITE_P(FooTest);
// Then, use TYPED_TEST_P() to define as many type-parameterized tests // Then, use TYPED_TEST_P() to define as many type-parameterized tests
// for this type-parameterized test case as you want. // for this type-parameterized test suite as you want.
TYPED_TEST_P(FooTest, DoesBlah) { TYPED_TEST_P(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter. // Inside a test, refer to TypeParam to get the type parameter.
TypeParam n = 0; TypeParam n = 0;
@ -124,9 +142,9 @@ TYPED_TEST_P(FooTest, HasPropertyA) { ... }
// Now the tricky part: you need to register all test patterns before // Now the tricky part: you need to register all test patterns before
// you can instantiate them. The first argument of the macro is the // you can instantiate them. The first argument of the macro is the
// test case name; the rest are the names of the tests in this test // test suite name; the rest are the names of the tests in this test
// case. // case.
REGISTER_TYPED_TEST_CASE_P(FooTest, REGISTER_TYPED_TEST_SUITE_P(FooTest,
DoesBlah, HasPropertyA); DoesBlah, HasPropertyA);
// Finally, you are free to instantiate the pattern with the types you // Finally, you are free to instantiate the pattern with the types you
@ -135,129 +153,177 @@ REGISTER_TYPED_TEST_CASE_P(FooTest,
// //
// To distinguish different instances of the pattern, the first // To distinguish different instances of the pattern, the first
// argument to the INSTANTIATE_* macro is a prefix that will be added // argument to the INSTANTIATE_* macro is a prefix that will be added
// to the actual test case name. Remember to pick unique prefixes for // to the actual test suite name. Remember to pick unique prefixes for
// different instances. // different instances.
typedef testing::Types<char, int, unsigned int> MyTypes; typedef testing::Types<char, int, unsigned int> MyTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type // If the type list contains only one type, you can write that type
// directly without Types<...>: // directly without Types<...>:
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); // INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
//
// Similar to the optional argument of TYPED_TEST_SUITE above,
// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
// generate custom names.
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
#endif // 0 #endif // 0
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-type-util.h" #include "gtest/internal/gtest-type-util.h"
// Implements typed tests. // Implements typed tests.
#if GTEST_HAS_TYPED_TEST
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// Expands to the name of the typedef for the type parameters of the // Expands to the name of the typedef for the type parameters of the
// given test case. // given test suite.
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ #define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
// The 'Types' template argument below must have spaces around it // Expands to the name of the typedef for the NameGenerator, responsible for
// since some compilers may choke on '>>' when passing a template // creating the suffixes of the name.
// instance (e.g. Types<int>) #define GTEST_NAME_GENERATOR_(TestSuiteName) \
# define TYPED_TEST_CASE(CaseName, Types) \ gtest_type_params_##TestSuiteName##_NameGenerator
typedef ::testing::internal::TypeList< Types >::type \
GTEST_TYPE_PARAMS_(CaseName)
# define TYPED_TEST(CaseName, TestName) \ #define TYPED_TEST_SUITE(CaseName, Types, ...) \
typedef ::testing::internal::GenerateTypeList<Types>::type \
GTEST_TYPE_PARAMS_(CaseName); \
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
GTEST_NAME_GENERATOR_(CaseName)
#define TYPED_TEST(CaseName, TestName) \
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
"test-name must not be empty"); \
template <typename gtest_TypeParam_> \ template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \ : public CaseName<gtest_TypeParam_> { \
private: \ private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \ typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \ typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \ void TestBody() override; \
}; \ }; \
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ static bool gtest_##CaseName##_##TestName##_registered_ \
::testing::internal::TypeParameterizedTest< \ GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
CaseName, \ CaseName, \
::testing::internal::TemplateSel< \ ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ TestName)>, \
GTEST_TYPE_PARAMS_(CaseName)>::Register(\ GTEST_TYPE_PARAMS_( \
"", ::testing::internal::CodeLocation(__FILE__, __LINE__), \ CaseName)>::Register("", \
#CaseName, #TestName, 0); \ ::testing::internal::CodeLocation( \
__FILE__, __LINE__), \
GTEST_STRINGIFY_(CaseName), \
GTEST_STRINGIFY_(TestName), 0, \
::testing::internal::GenerateNames< \
GTEST_NAME_GENERATOR_(CaseName), \
GTEST_TYPE_PARAMS_(CaseName)>()); \
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()
#endif // GTEST_HAS_TYPED_TEST // Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define TYPED_TEST_CASE \
static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
TYPED_TEST_SUITE
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Implements type-parameterized tests. // Implements type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// Expands to the namespace name that the type-parameterized tests for // Expands to the namespace name that the type-parameterized tests for
// the given type-parameterized test case are defined in. The exact // the given type-parameterized test suite are defined in. The exact
// name of the namespace is subject to change without notice. // name of the namespace is subject to change without notice.
# define GTEST_CASE_NAMESPACE_(TestCaseName) \ #define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
gtest_case_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// Expands to the name of the variable used to remember the names of // Expands to the name of the variable used to remember the names of
// the defined tests in the given test case. // the defined tests in the given test suite.
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ #define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
gtest_typed_test_case_p_state_##TestCaseName##_ gtest_typed_test_suite_p_state_##TestSuiteName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
// //
// Expands to the name of the variable used to remember the names of // Expands to the name of the variable used to remember the names of
// the registered tests in the given test case. // the registered tests in the given test suite.
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ #define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
gtest_registered_test_names_##TestCaseName##_ gtest_registered_test_names_##TestSuiteName##_
// The variables defined in the type-parameterized test macros are // The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be // static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together. // #included in multiple translation units linked together.
# define TYPED_TEST_CASE_P(CaseName) \ #define TYPED_TEST_SUITE_P(SuiteName) \
static ::testing::internal::TypedTestCasePState \ static ::testing::internal::TypedTestSuitePState \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
# define TYPED_TEST_P(CaseName, TestName) \ // Legacy API is deprecated but still available
namespace GTEST_CASE_NAMESPACE_(CaseName) { \ #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define TYPED_TEST_CASE_P \
static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \ template <typename gtest_TypeParam_> \
class TestName : public CaseName<gtest_TypeParam_> { \ class TestName : public SuiteName<gtest_TypeParam_> { \
private: \ private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \ typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \ typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \ void TestBody() override; \
}; \ }; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, #CaseName, #TestName); \ __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \ } \
template <typename gtest_TypeParam_> \ template <typename gtest_TypeParam_> \
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody() void GTEST_SUITE_NAMESPACE_( \
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ // Note: this won't work correctly if the trailing arguments are macros.
namespace GTEST_CASE_NAMESPACE_(CaseName) { \ #define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
} \ } \
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ static const char* const GTEST_REGISTERED_TEST_NAMES_( \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
__FILE__, __LINE__, #__VA_ARGS__) GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
// The 'Types' template argument below must have spaces around it // Legacy API is deprecated but still available
// since some compilers may choke on '>>' when passing a template #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// instance (e.g. Types<int>) #define REGISTER_TYPED_TEST_CASE_P \
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ ""); \
::testing::internal::TypeParameterizedTestCase<CaseName, \ REGISTER_TYPED_TEST_SUITE_P
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, \ #define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
"test-suit-prefix must not be empty"); \
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestSuite< \
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
::testing::internal::GenerateTypeList<Types>::type>:: \
Register(GTEST_STRINGIFY_(Prefix), \
::testing::internal::CodeLocation(__FILE__, __LINE__), \ ::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), \ &GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
#CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) GTEST_STRINGIFY_(SuiteName), \
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
::testing::internal::GenerateNames< \
::testing::internal::NameGeneratorSelector< \
__VA_ARGS__>::type, \
::testing::internal::GenerateTypeList<Types>::type>())
#endif // GTEST_HAS_TYPED_TEST_P // Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define INSTANTIATE_TYPED_TEST_CASE_P \
static_assert( \
::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
INSTANTIATE_TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_

File diff suppressed because it is too large Load Diff

View File

@ -27,18 +27,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
// //
// Implements a family of generic predicate assertion macros. // Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h. #include "gtest/gtest.h"
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. namespace testing {
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion // This header implements a family of generic predicate assertion
// macros: // macros:
@ -90,9 +90,10 @@ AssertionResult AssertPred1Helper(const char* pred_text,
const T1& v1) { const T1& v1) {
if (pred(v1)) return AssertionSuccess(); if (pred(v1)) return AssertionSuccess();
return AssertionFailure() << pred_text << "(" return AssertionFailure()
<< e1 << ") evaluates to false, where" << pred_text << "(" << e1 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1; << "\n"
<< e1 << " evaluates to " << ::testing::PrintToString(v1);
} }
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
@ -134,11 +135,12 @@ AssertionResult AssertPred2Helper(const char* pred_text,
const T2& v2) { const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess(); if (pred(v1, v2)) return AssertionSuccess();
return AssertionFailure() << pred_text << "(" return AssertionFailure()
<< e1 << ", " << pred_text << "(" << e1 << ", " << e2
<< e2 << ") evaluates to false, where" << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1 << "\n"
<< "\n" << e2 << " evaluates to " << v2; << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
<< e2 << " evaluates to " << ::testing::PrintToString(v2);
} }
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
@ -185,13 +187,13 @@ AssertionResult AssertPred3Helper(const char* pred_text,
const T3& v3) { const T3& v3) {
if (pred(v1, v2, v3)) return AssertionSuccess(); if (pred(v1, v2, v3)) return AssertionSuccess();
return AssertionFailure() << pred_text << "(" return AssertionFailure()
<< e1 << ", " << pred_text << "(" << e1 << ", " << e2 << ", " << e3
<< e2 << ", " << ") evaluates to false, where"
<< e3 << ") evaluates to false, where" << "\n"
<< "\n" << e1 << " evaluates to " << v1 << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
<< "\n" << e2 << " evaluates to " << v2 << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
<< "\n" << e3 << " evaluates to " << v3; << e3 << " evaluates to " << ::testing::PrintToString(v3);
} }
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
@ -243,15 +245,14 @@ AssertionResult AssertPred4Helper(const char* pred_text,
const T4& v4) { const T4& v4) {
if (pred(v1, v2, v3, v4)) return AssertionSuccess(); if (pred(v1, v2, v3, v4)) return AssertionSuccess();
return AssertionFailure() << pred_text << "(" return AssertionFailure()
<< e1 << ", " << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
<< e2 << ", " << ") evaluates to false, where"
<< e3 << ", " << "\n"
<< e4 << ") evaluates to false, where" << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
<< "\n" << e1 << " evaluates to " << v1 << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
<< "\n" << e2 << " evaluates to " << v2 << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
<< "\n" << e3 << " evaluates to " << v3 << e4 << " evaluates to " << ::testing::PrintToString(v4);
<< "\n" << e4 << " evaluates to " << v4;
} }
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
@ -308,17 +309,15 @@ AssertionResult AssertPred5Helper(const char* pred_text,
const T5& v5) { const T5& v5) {
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
return AssertionFailure() << pred_text << "(" return AssertionFailure()
<< e1 << ", " << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
<< e2 << ", " << ", " << e5 << ") evaluates to false, where"
<< e3 << ", " << "\n"
<< e4 << ", " << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
<< e5 << ") evaluates to false, where" << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
<< "\n" << e1 << " evaluates to " << v1 << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
<< "\n" << e2 << " evaluates to " << v2 << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
<< "\n" << e3 << " evaluates to " << v3 << e5 << " evaluates to " << ::testing::PrintToString(v5);
<< "\n" << e4 << " evaluates to " << v4
<< "\n" << e5 << " evaluates to " << v5;
} }
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
@ -355,4 +354,6 @@ AssertionResult AssertPred5Helper(const char* pred_text,
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ } // namespace testing
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_

View File

@ -26,13 +26,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Google C++ Testing Framework definitions useful in production code.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ //
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ // Google C++ Testing and Mocking Framework definitions useful in production code.
// GOOGLETEST_CM0003 DO NOT DELETE
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
// When you need to test the private or protected members of a class, // When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the // use the FRIEND_TEST macro to declare your tests as friends of the
@ -40,19 +40,22 @@
// //
// class MyClass { // class MyClass {
// private: // private:
// void MyMethod(); // void PrivateMethod();
// FRIEND_TEST(MyClassTest, MyMethod); // FRIEND_TEST(MyClassTest, PrivateMethodWorks);
// }; // };
// //
// class MyClassTest : public testing::Test { // class MyClassTest : public testing::Test {
// // ... // // ...
// }; // };
// //
// TEST_F(MyClassTest, MyMethod) { // TEST_F(MyClassTest, PrivateMethodWorks) {
// // Can call MyClass::MyMethod() here. // // Can call MyClass::PrivateMethod() here.
// } // }
//
// Note: The test class must be in the same namespace as the class being tested.
// For example, putting MyClassTest in an anonymous namespace will not work.
#define FRIEND_TEST(test_case_name, test_name)\ #define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_

View File

@ -0,0 +1,56 @@
# Customization Points
The custom directory is an injection point for custom user configurations.
## Header `gtest.h`
### The following macros can be defined:
* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of
`OsStackTraceGetterInterface`.
* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See
`testing::TempDir` for semantics and signature.
## Header `gtest-port.h`
The following macros can be defined:
### Flag related macros:
* `GTEST_FLAG(flag_name)`
* `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its
own flagfile flag parsing.
* `GTEST_DECLARE_bool_(name)`
* `GTEST_DECLARE_int32_(name)`
* `GTEST_DECLARE_string_(name)`
* `GTEST_DEFINE_bool_(name, default_val, doc)`
* `GTEST_DEFINE_int32_(name, default_val, doc)`
* `GTEST_DEFINE_string_(name, default_val, doc)`
### Logging:
* `GTEST_LOG_(severity)`
* `GTEST_CHECK_(condition)`
* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.
### Threading:
* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.
* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`
are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`
and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`
* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`
* `GTEST_LOCK_EXCLUDED_(locks)`
### Underlying library support features
* `GTEST_HAS_CXXABI_H_`
### Exporting API symbols:
* `GTEST_API_` - Specifier for exported symbols.
## Header `gtest-printers.h`
* See documentation at `gtest/gtest-printers.h` for details on how to define a
custom printer.

View File

@ -27,43 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Injection point for custom user configurations. // Injection point for custom user configurations. See README for details
// The following macros can be defined:
//
// Flag related macros:
// GTEST_FLAG(flag_name)
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its
// own flagfile flag parsing.
// GTEST_DECLARE_bool_(name)
// GTEST_DECLARE_int32_(name)
// GTEST_DECLARE_string_(name)
// GTEST_DEFINE_bool_(name, default_val, doc)
// GTEST_DEFINE_int32_(name, default_val, doc)
// GTEST_DEFINE_string_(name, default_val, doc)
//
// Test filtering:
// GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that
// will be used if --GTEST_FLAG(test_filter)
// is not provided.
//
// Logging:
// GTEST_LOG_(severity)
// GTEST_CHECK_(condition)
// Functions LogToStderr() and FlushInfoLog() have to be provided too.
//
// Threading:
// GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided.
// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are
// already provided.
// Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and
// GTEST_DEFINE_STATIC_MUTEX_(mutex)
//
// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
// GTEST_LOCK_EXCLUDED_(locks)
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_

View File

@ -31,12 +31,12 @@
// installation of gTest. // installation of gTest.
// It will be included from gtest-printers.h and the overrides in this file // It will be included from gtest-printers.h and the overrides in this file
// will be visible to everyone. // will be visible to everyone.
// See documentation at gtest/gtest-printers.h for details on how to define a //
// custom printer. // Injection point for custom user configurations. See README for details
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_

View File

@ -27,15 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Injection point for custom user configurations. // Injection point for custom user configurations. See README for details
// The following macros can be defined:
//
// GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of
// OsStackTraceGetterInterface.
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_

View File

@ -27,19 +27,20 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // The Google C++ Testing and Mocking Framework (Google Test)
//
// The Google C++ Testing Framework (Google Test)
// //
// This header file defines internal utilities needed for implementing // This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice. // death tests. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include <stdio.h> #include <stdio.h>
#include <memory>
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -53,6 +54,9 @@ const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
// DeathTest is a class that hides much of the complexity of the // DeathTest is a class that hides much of the complexity of the
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
// returns a concrete class that depends on the prevailing death test // returns a concrete class that depends on the prevailing death test
@ -76,7 +80,7 @@ class GTEST_API_ DeathTest {
// argument is set. If the death test should be skipped, the pointer // argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete // is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test. // DeathTest object that controls the execution of the current test.
static bool Create(const char* statement, const RE* regex, static bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test); const char* file, int line, DeathTest** test);
DeathTest(); DeathTest();
virtual ~DeathTest() { } virtual ~DeathTest() { }
@ -136,25 +140,50 @@ class GTEST_API_ DeathTest {
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
}; };
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// Factory interface for death tests. May be mocked out for testing. // Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory { class DeathTestFactory {
public: public:
virtual ~DeathTestFactory() { } virtual ~DeathTestFactory() { }
virtual bool Create(const char* statement, const RE* regex, virtual bool Create(const char* statement,
const char* file, int line, DeathTest** test) = 0; Matcher<const std::string&> matcher, const char* file,
int line, DeathTest** test) = 0;
}; };
// A concrete DeathTestFactory implementation for normal use. // A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory { class DefaultDeathTestFactory : public DeathTestFactory {
public: public:
virtual bool Create(const char* statement, const RE* regex, bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test); const char* file, int line, DeathTest** test) override;
}; };
// Returns true if exit_status describes a process that was terminated // Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code. // by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status); GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
// Traps C++ exceptions escaping statement and reports them as test // Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here. // failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS # if GTEST_HAS_EXCEPTIONS
@ -182,18 +211,18 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*. // ASSERT_EXIT*, and EXPECT_EXIT*.
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ #define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ if (::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \ ::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \ if (!::testing::internal::DeathTest::Create( \
#statement, \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \
__FILE__, __LINE__, &gtest_dt)) { \ __FILE__, __LINE__, &gtest_dt)) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \ } \
if (gtest_dt != NULL) { \ if (gtest_dt != nullptr) { \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) { \ switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \ case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
@ -201,8 +230,8 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
} \ } \
break; \ break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \ case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \ ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
gtest_sentinel(gtest_dt); \ gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \ break; \
@ -212,19 +241,22 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
} \ } \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
fail(::testing::internal::DeathTest::LastMessage()) : fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message // The symbol "fail" here expands to something into which a message
// can be streamed. // can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is // NDEBUG mode. In this case we need the statements to be executed and the macro
// ignored, and the macro must accept a streamed message even though the message // must accept a streamed message even though the message is never printed.
// is never printed. // The regex object is not evaluated, but it is used to prevent "unused"
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ // warnings and to avoid an expression that doesn't compile in debug mode.
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else if (!::testing::internal::AlwaysTrue()) { \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
} else \ } else \
::testing::Message() ::testing::Message()
@ -264,56 +296,9 @@ class InternalRunDeathTestFlag {
// the flag is specified; otherwise returns NULL. // the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
#else // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
// death tests are not supported. Those macros must compile on such systems
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
// systems that support death tests. This allows one to write such a macro
// on a system that does not support death tests and be sure that it will
// compile on a death-test supporting system.
//
// Parameters:
// statement - A statement that a macro such as EXPECT_DEATH would test
// for program termination. This macro has to make sure this
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter iff EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
// compile inside functions where ASSERT_DEATH doesn't
// compile.
//
// The branch that has an always false condition is used to ensure that
// statement and regex are compiled (and thus syntactically correct) but
// never executed. The unreachable code macro protects the terminator
// statement from generating an 'unreachable code' warning in case
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_

View File

@ -27,21 +27,24 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Author: keith.ray@gmail.com (Keith Ray)
//
// Google Test filepath utilities // Google Test filepath utilities
// //
// This header file declares classes and functions used internally by // This header file declares classes and functions used internally by
// Google Test. They are subject to change without notice. // Google Test. They are subject to change without notice.
// //
// This file is #included in <gtest/internal/gtest-internal.h>. // This file is #included in gtest/internal/gtest-internal.h.
// Do not include this header file separately! // Do not include this header file separately!
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ // GOOGLETEST_CM0001 DO NOT DELETE
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -107,7 +110,7 @@ class GTEST_API_ FilePath {
const FilePath& base_name, const FilePath& base_name,
const char* extension); const char* extension);
// Returns true iff the path is "". // Returns true if and only if the path is "".
bool IsEmpty() const { return pathname_.empty(); } bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns // If input name has a trailing separator character, removes it and returns
@ -192,7 +195,7 @@ class GTEST_API_ FilePath {
void Normalize(); void Normalize();
// Returns a pointer to the last occurence of a valid path separator in // Returns a pointer to the last occurrence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path // the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found. // separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const; const char* FindLastPathSeparator() const;
@ -203,4 +206,6 @@ class GTEST_API_ FilePath {
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_

File diff suppressed because it is too large Load Diff

View File

@ -26,33 +26,32 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests. // Type and function utilities for implementing parameterized tests.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ // GOOGLETEST_CM0001 DO NOT DELETE
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <ctype.h> #include <ctype.h>
#include <cassert>
#include <iterator> #include <iterator>
#include <memory>
#include <set> #include <set>
#include <tuple>
#include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-linked_ptr.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h"
#if GTEST_HAS_PARAM_TEST
namespace testing { namespace testing {
// Input to a parameterized test name generator, describing a test parameter. // Input to a parameterized test name generator, describing a test parameter.
// Consists of the parameter value and the integer parameter index. // Consists of the parameter value and the integer parameter index.
template <class ParamType> template <class ParamType>
@ -76,12 +75,13 @@ struct PrintToStringParamName {
namespace internal { namespace internal {
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// // Utility Functions
// Outputs a message explaining invalid registration of different // Outputs a message explaining invalid registration of different
// fixture class for the same test case. This may happen when // fixture class for the same test suite. This may happen when
// 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 ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location); CodeLocation code_location);
template <typename> class ParamGeneratorInterface; template <typename> class ParamGeneratorInterface;
@ -157,7 +157,7 @@ class ParamIterator {
private: private:
friend class ParamGenerator<T>; friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
scoped_ptr<ParamIteratorInterface<T> > impl_; std::unique_ptr<ParamIteratorInterface<T> > impl_;
}; };
// ParamGeneratorInterface<T> is the binary interface to access generators // ParamGeneratorInterface<T> is the binary interface to access generators
@ -196,7 +196,7 @@ class ParamGenerator {
iterator end() const { return iterator(impl_->End()); } iterator end() const { return iterator(impl_->End()); }
private: private:
linked_ptr<const ParamGeneratorInterface<T> > impl_; std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
}; };
// Generates values from a range of two comparable values. Can be used to // Generates values from a range of two comparable values. Can be used to
@ -209,12 +209,12 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
RangeGenerator(T begin, T end, IncrementT step) RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end), : begin_(begin), end_(end),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
virtual ~RangeGenerator() {} ~RangeGenerator() override {}
virtual ParamIteratorInterface<T>* Begin() const { ParamIteratorInterface<T>* Begin() const override {
return new Iterator(this, begin_, 0, step_); return new Iterator(this, begin_, 0, step_);
} }
virtual ParamIteratorInterface<T>* End() const { ParamIteratorInterface<T>* End() const override {
return new Iterator(this, end_, end_index_, step_); return new Iterator(this, end_, end_index_, step_);
} }
@ -224,20 +224,20 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
Iterator(const ParamGeneratorInterface<T>* base, T value, int index, Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
IncrementT step) IncrementT step)
: base_(base), value_(value), index_(index), step_(step) {} : base_(base), value_(value), index_(index), step_(step) {}
virtual ~Iterator() {} ~Iterator() override {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const { const ParamGeneratorInterface<T>* BaseGenerator() const override {
return base_; return base_;
} }
virtual void Advance() { void Advance() override {
value_ = static_cast<T>(value_ + step_); value_ = static_cast<T>(value_ + step_);
index_++; index_++;
} }
virtual ParamIteratorInterface<T>* Clone() const { ParamIteratorInterface<T>* Clone() const override {
return new Iterator(*this); return new Iterator(*this);
} }
virtual const T* Current() const { return &value_; } const T* Current() const override { return &value_; }
virtual bool Equals(const ParamIteratorInterface<T>& other) const { bool Equals(const ParamIteratorInterface<T>& other) const override {
// Having the same base generator guarantees that the other // Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast. // iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
@ -294,12 +294,12 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
template <typename ForwardIterator> template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
: container_(begin, end) {} : container_(begin, end) {}
virtual ~ValuesInIteratorRangeGenerator() {} ~ValuesInIteratorRangeGenerator() override {}
virtual ParamIteratorInterface<T>* Begin() const { ParamIteratorInterface<T>* Begin() const override {
return new Iterator(this, container_.begin()); return new Iterator(this, container_.begin());
} }
virtual ParamIteratorInterface<T>* End() const { ParamIteratorInterface<T>* End() const override {
return new Iterator(this, container_.end()); return new Iterator(this, container_.end());
} }
@ -311,16 +311,16 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
Iterator(const ParamGeneratorInterface<T>* base, Iterator(const ParamGeneratorInterface<T>* base,
typename ContainerType::const_iterator iterator) typename ContainerType::const_iterator iterator)
: base_(base), iterator_(iterator) {} : base_(base), iterator_(iterator) {}
virtual ~Iterator() {} ~Iterator() override {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const { const ParamGeneratorInterface<T>* BaseGenerator() const override {
return base_; return base_;
} }
virtual void Advance() { void Advance() override {
++iterator_; ++iterator_;
value_.reset(); value_.reset();
} }
virtual ParamIteratorInterface<T>* Clone() const { ParamIteratorInterface<T>* Clone() const override {
return new Iterator(*this); return new Iterator(*this);
} }
// We need to use cached value referenced by iterator_ because *iterator_ // We need to use cached value referenced by iterator_ because *iterator_
@ -330,12 +330,11 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
// can advance iterator_ beyond the end of the range, and we cannot // can advance iterator_ beyond the end of the range, and we cannot
// detect that fact. The client code, on the other hand, is // detect that fact. The client code, on the other hand, is
// responsible for not calling Current() on an out-of-range iterator. // responsible for not calling Current() on an out-of-range iterator.
virtual const T* Current() const { const T* Current() const override {
if (value_.get() == NULL) if (value_.get() == nullptr) value_.reset(new T(*iterator_));
value_.reset(new T(*iterator_));
return value_.get(); return value_.get();
} }
virtual bool Equals(const ParamIteratorInterface<T>& other) const { bool Equals(const ParamIteratorInterface<T>& other) const override {
// Having the same base generator guarantees that the other // Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast. // iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
@ -358,9 +357,9 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
// A cached value of *iterator_. We keep it here to allow access by // A cached value of *iterator_. We keep it here to allow access by
// pointer in the wrapping iterator's operator->(). // pointer in the wrapping iterator's operator->().
// value_ needs to be mutable to be accessed in Current(). // value_ needs to be mutable to be accessed in Current().
// Use of scoped_ptr helps manage cached value's lifetime, // Use of std::unique_ptr helps manage cached value's lifetime,
// which is bound by the lifespan of the iterator itself. // which is bound by the lifespan of the iterator itself.
mutable scoped_ptr<const T> value_; mutable std::unique_ptr<const T> value_;
}; // class ValuesInIteratorRangeGenerator::Iterator }; // class ValuesInIteratorRangeGenerator::Iterator
// No implementation - assignment is unsupported. // No implementation - assignment is unsupported.
@ -380,25 +379,12 @@ std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
return name_stream.GetString(); return name_stream.GetString();
} }
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. template <typename T = int>
// void TestNotEmpty() {
// Parameterized test name overload helpers, which help the static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
// 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;
} }
template <typename T = int>
void TestNotEmpty(const T&) {}
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
@ -410,7 +396,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
typedef typename TestClass::ParamType ParamType; typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) : explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {} parameter_(parameter) {}
virtual Test* CreateTest() { Test* CreateTest() override {
TestClass::SetParam(&parameter_); TestClass::SetParam(&parameter_);
return new TestClass(); return new TestClass();
} }
@ -438,19 +424,19 @@ class TestMetaFactoryBase {
// TestMetaFactory creates test factories for passing into // TestMetaFactory creates test factories for passing into
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
// ownership of test factory pointer, same factory object cannot be passed // ownership of test factory pointer, same factory object cannot be passed
// into that method twice. But ParameterizedTestCaseInfo is going to call // into that method twice. But ParameterizedTestSuiteInfo is going to call
// it for each Test/Parameter value combination. Thus it needs meta factory // it for each Test/Parameter value combination. Thus it needs meta factory
// creator class. // creator class.
template <class TestCase> template <class TestSuite>
class TestMetaFactory class TestMetaFactory
: public TestMetaFactoryBase<typename TestCase::ParamType> { : public TestMetaFactoryBase<typename TestSuite::ParamType> {
public: public:
typedef typename TestCase::ParamType ParamType; using ParamType = typename TestSuite::ParamType;
TestMetaFactory() {} TestMetaFactory() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { TestFactoryBase* CreateTestFactory(ParamType parameter) override {
return new ParameterizedTestFactory<TestCase>(parameter); return new ParameterizedTestFactory<TestSuite>(parameter);
} }
private: private:
@ -459,113 +445,128 @@ class TestMetaFactory
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// ParameterizedTestCaseInfoBase is a generic interface // ParameterizedTestSuiteInfoBase is a generic interface
// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase // to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
// accumulates test information provided by TEST_P macro invocations // accumulates test information provided by TEST_P macro invocations
// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations // and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
// and uses that information to register all resulting test instances // and uses that information to register all resulting test instances
// in RegisterTests method. The ParameterizeTestCaseRegistry class holds // in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
// a collection of pointers to the ParameterizedTestCaseInfo objects // a collection of pointers to the ParameterizedTestSuiteInfo objects
// and calls RegisterTests() on each of them when asked. // and calls RegisterTests() on each of them when asked.
class ParameterizedTestCaseInfoBase { class ParameterizedTestSuiteInfoBase {
public: public:
virtual ~ParameterizedTestCaseInfoBase() {} virtual ~ParameterizedTestSuiteInfoBase() {}
// Base part of test case name for display purposes. // Base part of test suite name for display purposes.
virtual const string& GetTestCaseName() const = 0; virtual const std::string& GetTestSuiteName() const = 0;
// Test case id to verify identity. // Test suite id to verify identity.
virtual TypeId GetTestCaseTypeId() const = 0; virtual TypeId GetTestSuiteTypeId() const = 0;
// UnitTest class invokes this method to register tests in this // UnitTest class invokes this method to register tests in this
// test case right before running them in RUN_ALL_TESTS macro. // test suite right before running them in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single // This method should not be called more than once on any single
// instance of a ParameterizedTestCaseInfoBase derived class. // instance of a ParameterizedTestSuiteInfoBase derived class.
virtual void RegisterTests() = 0; virtual void RegisterTests() = 0;
protected: protected:
ParameterizedTestCaseInfoBase() {} ParameterizedTestSuiteInfoBase() {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
}; };
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P // Report a the name of a test_suit as safe to ignore
// macro invocations for a particular test case and generators // as the side effect of construction of this type.
// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that struct GTEST_API_ MarkAsIgnored {
// test case. It registers tests with all values generated by all explicit MarkAsIgnored(const char* test_suite);
};
GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
CodeLocation location, bool has_test_p);
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
// macro invocations for a particular test suite and generators
// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
// test suite. It registers tests with all values generated by all
// generators when asked. // generators when asked.
template <class TestCase> template <class TestSuite>
class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
public: public:
// ParamType and GeneratorCreationFunc are private types but are required // ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and // for declarations of public methods AddTestPattern() and
// AddTestCaseInstantiation(). // AddTestSuiteInstantiation().
typedef typename TestCase::ParamType ParamType; using ParamType = typename TestSuite::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; using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
explicit ParameterizedTestCaseInfo( explicit ParameterizedTestSuiteInfo(const char* name,
const char* name, CodeLocation code_location) CodeLocation code_location)
: test_case_name_(name), code_location_(code_location) {} : test_suite_name_(name), code_location_(code_location) {}
// Test case base name for display purposes. // Test suite base name for display purposes.
virtual const string& GetTestCaseName() const { return test_case_name_; } const std::string& GetTestSuiteName() const override {
// Test case id to verify identity. return test_suite_name_;
virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } }
// Test suite id to verify identity.
TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
// TEST_P macro uses AddTestPattern() to record information // TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure. // about a single test in a LocalTestInfo structure.
// test_case_name is the base name of the test case (without invocation // test_suite_name is the base name of the test suite (without invocation
// prefix). test_base_name is the name of an individual test without // prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test case base name and DoBar is test base name. // test suite base name and DoBar is test base name.
void AddTestPattern(const char* test_case_name, void AddTestPattern(const char* test_suite_name, const char* test_base_name,
const char* test_base_name, TestMetaFactoryBase<ParamType>* meta_factory,
TestMetaFactoryBase<ParamType>* meta_factory) { CodeLocation code_location) {
tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
test_base_name, test_suite_name, test_base_name, meta_factory, code_location)));
meta_factory)));
} }
// INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator. // about a generator.
int AddTestCaseInstantiation(const string& instantiation_name, int AddTestSuiteInstantiation(const std::string& instantiation_name,
GeneratorCreationFunc* func, GeneratorCreationFunc* func,
ParamNameGeneratorFunc* name_func, ParamNameGeneratorFunc* name_func,
const char* file, const char* file, int line) {
int line) {
instantiations_.push_back( instantiations_.push_back(
InstantiationInfo(instantiation_name, func, name_func, file, line)); 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 suite
// test cases right before running tests in RUN_ALL_TESTS macro. // right before running tests in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single // This method should not be called more than once on any single
// instance of a ParameterizedTestCaseInfoBase derived class. // instance of a ParameterizedTestSuiteInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more then once. // UnitTest has a guard to prevent from calling this method more than once.
virtual void RegisterTests() { void RegisterTests() override {
bool generated_instantiations = false;
for (typename TestInfoContainer::iterator test_it = tests_.begin(); for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) { test_it != tests_.end(); ++test_it) {
linked_ptr<TestInfo> test_info = *test_it; std::shared_ptr<TestInfo> test_info = *test_it;
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->name; const std::string& instantiation_name = gen_it->name;
ParamGenerator<ParamType> generator((*gen_it->generator)()); ParamGenerator<ParamType> generator((*gen_it->generator)());
ParamNameGeneratorFunc* name_func = gen_it->name_func; ParamNameGeneratorFunc* name_func = gen_it->name_func;
const char* file = gen_it->file; const char* file = gen_it->file;
int line = gen_it->line; int line = gen_it->line;
string test_case_name; std::string test_suite_name;
if ( !instantiation_name.empty() ) if ( !instantiation_name.empty() )
test_case_name = instantiation_name + "/"; test_suite_name = instantiation_name + "/";
test_case_name += test_info->test_case_base_name; test_suite_name += test_info->test_suite_base_name;
size_t i = 0; size_t i = 0;
std::set<std::string> test_param_names; 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) {
generated_instantiations = true;
Message test_name_stream; Message test_name_stream;
std::string param_name = name_func( std::string param_name = name_func(
@ -582,39 +583,48 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
test_param_names.insert(param_name); test_param_names.insert(param_name);
test_name_stream << test_info->test_base_name << "/" << param_name; if (!test_info->test_base_name.empty()) {
test_name_stream << test_info->test_base_name << "/";
}
test_name_stream << param_name;
MakeAndRegisterTestInfo( MakeAndRegisterTestInfo(
test_case_name.c_str(), test_suite_name.c_str(), test_name_stream.GetString().c_str(),
test_name_stream.GetString().c_str(), nullptr, // No type parameter.
NULL, // No type parameter. PrintToString(*param_it).c_str(), test_info->code_location,
PrintToString(*param_it).c_str(), GetTestSuiteTypeId(),
code_location_, SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
GetTestCaseTypeId(), SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
TestCase::SetUpTestCase,
TestCase::TearDownTestCase,
test_info->test_meta_factory->CreateTestFactory(*param_it)); test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it } // for param_it
} // for gen_it } // for gen_it
} // for test_it } // for test_it
if (!generated_instantiations) {
// There are no generaotrs, or they all generate nothing ...
InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
!tests_.empty());
}
} // RegisterTests } // RegisterTests
private: private:
// LocalTestInfo structure keeps information about a single test registered // LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro. // with TEST_P macro.
struct TestInfo { struct TestInfo {
TestInfo(const char* a_test_case_base_name, TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
const char* a_test_base_name, TestMetaFactoryBase<ParamType>* a_test_meta_factory,
TestMetaFactoryBase<ParamType>* a_test_meta_factory) : CodeLocation a_code_location)
test_case_base_name(a_test_case_base_name), : test_suite_base_name(a_test_suite_base_name),
test_base_name(a_test_base_name), test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory) {} test_meta_factory(a_test_meta_factory),
code_location(a_code_location) {}
const string test_case_base_name; const std::string test_suite_base_name;
const string test_base_name; const std::string test_base_name;
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
const CodeLocation code_location;
}; };
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
// Records data received from INSTANTIATE_TEST_CASE_P macros: // Records data received from INSTANTIATE_TEST_SUITE_P macros:
// <Instantiation name, Sequence generator creation function, // <Instantiation name, Sequence generator creation function,
// Name generator function, Source file, Source line> // Name generator function, Source file, Source line>
struct InstantiationInfo { struct InstantiationInfo {
@ -651,81 +661,287 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
return true; return true;
} }
const string test_case_name_; const std::string test_suite_name_;
CodeLocation code_location_; CodeLocation code_location_;
TestInfoContainer tests_; TestInfoContainer tests_;
InstantiationContainer instantiations_; InstantiationContainer instantiations_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
}; // class ParameterizedTestCaseInfo }; // class ParameterizedTestSuiteInfo
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
template <class TestCase>
using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase // ParameterizedTestSuiteRegistry contains a map of
// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P // ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
// macros use it to locate their corresponding ParameterizedTestCaseInfo // and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
// descriptors. // ParameterizedTestSuiteInfo descriptors.
class ParameterizedTestCaseRegistry { class ParameterizedTestSuiteRegistry {
public: public:
ParameterizedTestCaseRegistry() {} ParameterizedTestSuiteRegistry() {}
~ParameterizedTestCaseRegistry() { ~ParameterizedTestSuiteRegistry() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); for (auto& test_suite_info : test_suite_infos_) {
it != test_case_infos_.end(); ++it) { delete test_suite_info;
delete *it;
} }
} }
// Looks up or creates and returns a structure containing information about // Looks up or creates and returns a structure containing information about
// tests and instantiations of a particular test case. // tests and instantiations of a particular test suite.
template <class TestCase> template <class TestSuite>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
const char* test_case_name, const char* test_suite_name, CodeLocation code_location) {
CodeLocation code_location) { ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; for (auto& test_suite_info : test_suite_infos_) {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); if (test_suite_info->GetTestSuiteName() == test_suite_name) {
it != test_case_infos_.end(); ++it) { if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
if ((*it)->GetTestCaseName() == test_case_name) {
if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
// 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 suite setup and tear-down in this case.
ReportInvalidTestCaseType(test_case_name, code_location); ReportInvalidTestSuiteType(test_suite_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
// type we are looking for, so we downcast it to that type // type we are looking for, so we downcast it to that type
// without further checks. // without further checks.
typed_test_info = CheckedDowncastToActualType< typed_test_info = CheckedDowncastToActualType<
ParameterizedTestCaseInfo<TestCase> >(*it); ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
} }
break; break;
} }
} }
if (typed_test_info == NULL) { if (typed_test_info == nullptr) {
typed_test_info = new ParameterizedTestCaseInfo<TestCase>( typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
test_case_name, code_location); test_suite_name, code_location);
test_case_infos_.push_back(typed_test_info); test_suite_infos_.push_back(typed_test_info);
} }
return typed_test_info; return typed_test_info;
} }
void RegisterTests() { void RegisterTests() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); for (auto& test_suite_info : test_suite_infos_) {
it != test_case_infos_.end(); ++it) { test_suite_info->RegisterTests();
(*it)->RegisterTests();
} }
} }
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
private:
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
TestSuiteInfoContainer test_suite_infos_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
};
// Keep track of what type-parameterized test suite are defined and
// where as well as which are intatiated. This allows susequently
// identifying suits that are defined but never used.
class TypeParameterizedTestSuiteRegistry {
public:
// Add a suite definition
void RegisterTestSuite(const char* test_suite_name,
CodeLocation code_location);
// Add an instantiation of a suit.
void RegisterInstantiation(const char* test_suite_name);
// For each suit repored as defined but not reported as instantiation,
// emit a test that reports that fact (configurably, as an error).
void CheckForInstantiations();
private:
struct TypeParameterizedTestSuiteInfo {
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
: code_location(c), instantiated(false) {}
CodeLocation code_location;
bool instantiated;
};
std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
};
} // namespace internal
// Forward declarations of ValuesIn(), which is implemented in
// include/gtest/gtest-param-test.h.
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container);
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4100)
#endif
template <typename... Ts>
class ValueArray {
public:
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
}
private: private:
typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; template <typename T, size_t... I>
std::vector<T> MakeVector(IndexSequence<I...>) const {
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
}
TestCaseInfoContainer test_case_infos_; FlatTuple<Ts...> v_;
};
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); #ifdef _MSC_VER
#pragma warning(pop)
#endif
template <typename... T>
class CartesianProductGenerator
: public ParamGeneratorInterface<::std::tuple<T...>> {
public:
typedef ::std::tuple<T...> ParamType;
CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
: generators_(g) {}
~CartesianProductGenerator() override {}
ParamIteratorInterface<ParamType>* Begin() const override {
return new Iterator(this, generators_, false);
}
ParamIteratorInterface<ParamType>* End() const override {
return new Iterator(this, generators_, true);
}
private:
template <class I>
class IteratorImpl;
template <size_t... I>
class IteratorImpl<IndexSequence<I...>>
: public ParamIteratorInterface<ParamType> {
public:
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
: base_(base),
begin_(std::get<I>(generators).begin()...),
end_(std::get<I>(generators).end()...),
current_(is_end ? end_ : begin_) {
ComputeCurrentValue();
}
~IteratorImpl() override {}
const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void Advance() override {
assert(!AtEnd());
// Advance the last iterator.
++std::get<sizeof...(T) - 1>(current_);
// if that reaches end, propagate that up.
AdvanceIfEnd<sizeof...(T) - 1>();
ComputeCurrentValue();
}
ParamIteratorInterface<ParamType>* Clone() const override {
return new IteratorImpl(*this);
}
const ParamType* Current() const override { return current_value_.get(); }
bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const IteratorImpl* typed_other =
CheckedDowncastToActualType<const IteratorImpl>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
if (AtEnd() && typed_other->AtEnd()) return true;
bool same = true;
bool dummy[] = {
(same = same && std::get<I>(current_) ==
std::get<I>(typed_other->current_))...};
(void)dummy;
return same;
}
private:
template <size_t ThisI>
void AdvanceIfEnd() {
if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
bool last = ThisI == 0;
if (last) {
// We are done. Nothing else to propagate.
return;
}
constexpr size_t NextI = ThisI - (ThisI != 0);
std::get<ThisI>(current_) = std::get<ThisI>(begin_);
++std::get<NextI>(current_);
AdvanceIfEnd<NextI>();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
}
bool AtEnd() const {
bool at_end = false;
bool dummy[] = {
(at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
(void)dummy;
return at_end;
}
const ParamGeneratorInterface<ParamType>* const base_;
std::tuple<typename ParamGenerator<T>::iterator...> begin_;
std::tuple<typename ParamGenerator<T>::iterator...> end_;
std::tuple<typename ParamGenerator<T>::iterator...> current_;
std::shared_ptr<ParamType> current_value_;
};
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
std::tuple<ParamGenerator<T>...> generators_;
};
template <class... Gen>
class CartesianProductHolder {
public:
CartesianProductHolder(const Gen&... g) : generators_(g...) {}
template <typename... T>
operator ParamGenerator<::std::tuple<T...>>() const {
return ParamGenerator<::std::tuple<T...>>(
new CartesianProductGenerator<T...>(generators_));
}
private:
std::tuple<Gen...> generators_;
}; };
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_HAS_PARAM_TEST #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_

View File

@ -27,25 +27,24 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// The Google C++ Testing Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file defines the GTEST_OS_* macro. // This header file defines the GTEST_OS_* macro.
// It is separate from gtest-port.h so that custom/gtest-port.h can include it. // It is separate from gtest-port.h so that custom/gtest-port.h can include it.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
// Determines the platform on which Google Test is compiled. // Determines the platform on which Google Test is compiled.
#ifdef __CYGWIN__ #ifdef __CYGWIN__
# define GTEST_OS_CYGWIN 1 # define GTEST_OS_CYGWIN 1
#elif defined __SYMBIAN32__ # elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
# define GTEST_OS_SYMBIAN 1 # define GTEST_OS_WINDOWS_MINGW 1
# define GTEST_OS_WINDOWS 1
#elif defined _WIN32 #elif defined _WIN32
# define GTEST_OS_WINDOWS 1 # define GTEST_OS_WINDOWS 1
# ifdef _WIN32_WCE # ifdef _WIN32_WCE
# define GTEST_OS_WINDOWS_MOBILE 1 # define GTEST_OS_WINDOWS_MOBILE 1
# elif defined(__MINGW__) || defined(__MINGW32__)
# define GTEST_OS_WINDOWS_MINGW 1
# elif defined(WINAPI_FAMILY) # elif defined(WINAPI_FAMILY)
# include <winapifamily.h> # include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
@ -54,6 +53,9 @@
# define GTEST_OS_WINDOWS_PHONE 1 # define GTEST_OS_WINDOWS_PHONE 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
# define GTEST_OS_WINDOWS_RT 1 # define GTEST_OS_WINDOWS_RT 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
# define GTEST_OS_WINDOWS_PHONE 1
# define GTEST_OS_WINDOWS_TV_TITLE 1
# else # else
// WINAPI_FAMILY defined but no known partition matched. // WINAPI_FAMILY defined but no known partition matched.
// Default to desktop. // Default to desktop.
@ -62,13 +64,22 @@
# else # else
# define GTEST_OS_WINDOWS_DESKTOP 1 # define GTEST_OS_WINDOWS_DESKTOP 1
# endif // _WIN32_WCE # endif // _WIN32_WCE
#elif defined __OS2__
# define GTEST_OS_OS2 1
#elif defined __APPLE__ #elif defined __APPLE__
# define GTEST_OS_MAC 1 # define GTEST_OS_MAC 1
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE # if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1 # define GTEST_OS_IOS 1
# endif # endif
#elif defined __DragonFly__
# define GTEST_OS_DRAGONFLY 1
#elif defined __FreeBSD__ #elif defined __FreeBSD__
# define GTEST_OS_FREEBSD 1 # define GTEST_OS_FREEBSD 1
#elif defined __Fuchsia__
# define GTEST_OS_FUCHSIA 1
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
# define GTEST_OS_GNU_KFREEBSD 1
#elif defined __linux__ #elif defined __linux__
# define GTEST_OS_LINUX 1 # define GTEST_OS_LINUX 1
# if defined __ANDROID__ # if defined __ANDROID__
@ -84,10 +95,20 @@
# define GTEST_OS_HPUX 1 # define GTEST_OS_HPUX 1
#elif defined __native_client__ #elif defined __native_client__
# define GTEST_OS_NACL 1 # define GTEST_OS_NACL 1
#elif defined __NetBSD__
# define GTEST_OS_NETBSD 1
#elif defined __OpenBSD__ #elif defined __OpenBSD__
# define GTEST_OS_OPENBSD 1 # define GTEST_OS_OPENBSD 1
#elif defined __QNX__ #elif defined __QNX__
# define GTEST_OS_QNX 1 # define GTEST_OS_QNX 1
#elif defined(__HAIKU__)
#define GTEST_OS_HAIKU 1
#elif defined ESP8266
#define GTEST_OS_ESP8266 1
#elif defined ESP32
#define GTEST_OS_ESP32 1
#elif defined(__XTENSA__)
#define GTEST_OS_XTENSA 1
#endif // __CYGWIN__ #endif // __CYGWIN__
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_

File diff suppressed because it is too large Load Diff

View File

@ -27,19 +27,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // The Google C++ Testing and Mocking Framework (Google Test)
//
// The Google C++ Testing Framework (Google Test)
// //
// This header file declares the String class and functions used internally by // This header file declares the String class and functions used internally by
// Google Test. They are subject to change without notice. They should not used // Google Test. They are subject to change without notice. They should not used
// by code external to Google Test. // by code external to Google Test.
// //
// This header file is #included by <gtest/internal/gtest-internal.h>. // This header file is #included by gtest-internal.h.
// It should not be #included by other files. // It should not be #included by other files.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ // GOOGLETEST_CM0001 DO NOT DELETE
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder. // string.h is not guaranteed to provide strcpy on C++ Builder.
@ -47,6 +47,7 @@
#endif #endif
#include <string.h> #include <string.h>
#include <cstdint>
#include <string> #include <string>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
@ -94,7 +95,8 @@ class GTEST_API_ String {
static const char* Utf16ToAnsi(LPCWSTR utf16_str); static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#endif #endif
// Compares two C strings. Returns true iff they have the same content. // Compares two C strings. Returns true if and only if they have the same
// content.
// //
// Unlike strcmp(), this function can handle NULL argument(s). A // Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string, // NULL C string is considered different to any non-NULL C string,
@ -107,16 +109,16 @@ class GTEST_API_ String {
// returned. // returned.
static std::string ShowWideCString(const wchar_t* wide_c_str); static std::string ShowWideCString(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same // Compares two wide C strings. Returns true if and only if they have the
// content. // same content.
// //
// Unlike wcscmp(), this function can handle NULL argument(s). A // Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string, // NULL C string is considered different to any non-NULL C string,
// including the empty string. // including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two C strings, ignoring case. Returns true iff they // Compares two C strings, ignoring case. Returns true if and only if
// have the same content. // they have the same content.
// //
// Unlike strcasecmp(), this function can handle NULL argument(s). // Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string, // A NULL C string is considered different to any non-NULL C string,
@ -124,8 +126,8 @@ class GTEST_API_ String {
static bool CaseInsensitiveCStringEquals(const char* lhs, static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs); const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they // Compares two wide C strings, ignoring case. Returns true if and only if
// have the same content. // they have the same content.
// //
// Unlike wcscasecmp(), this function can handle NULL argument(s). // Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string, // A NULL C string is considered different to any non-NULL wide C string,
@ -139,17 +141,23 @@ class GTEST_API_ String {
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs); const wchar_t* rhs);
// Returns true iff the given string ends with the given suffix, ignoring // Returns true if and only if the given string ends with the given suffix,
// case. Any string is considered to end with an empty suffix. // ignoring case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive( static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix); const std::string& str, const std::string& suffix);
// Formats an int value as "%02d". // Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2 static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value to given width with leading zeros.
static std::string FormatIntWidthN(int value, int width);
// Formats an int value as "%X". // Formats an int value as "%X".
static std::string FormatHexInt(int value); static std::string FormatHexInt(int value);
// Formats an int value as "%X".
static std::string FormatHexUInt32(uint32_t value);
// Formats a byte as "%02X". // Formats a byte as "%02X".
static std::string FormatByte(unsigned char value); static std::string FormatByte(unsigned char value);
@ -164,4 +172,4 @@ GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_

File diff suppressed because it is too large Load Diff

View File

@ -26,16 +26,15 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Author: vladl@google.com (Vlad Losev)
// This provides interface PrimeTable that determines whether a number is a // This provides interface PrimeTable that determines whether a number is a
// prime and determines a next prime number. This interface is used // prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests. // in Google Test samples demonstrating use of parameterized tests.
#ifndef GTEST_SAMPLES_PRIME_TABLES_H_ #ifndef GOOGLETEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_ #define GOOGLETEST_SAMPLES_PRIME_TABLES_H_
#include <algorithm> #include <algorithm>
@ -44,7 +43,7 @@ class PrimeTable {
public: public:
virtual ~PrimeTable() {} virtual ~PrimeTable() {}
// Returns true iff n is a prime number. // Returns true if and only if n is a prime number.
virtual bool IsPrime(int n) const = 0; virtual bool IsPrime(int n) const = 0;
// Returns the smallest prime number greater than p; or returns -1 // Returns the smallest prime number greater than p; or returns -1
@ -55,7 +54,7 @@ class PrimeTable {
// Implementation #1 calculates the primes on-the-fly. // Implementation #1 calculates the primes on-the-fly.
class OnTheFlyPrimeTable : public PrimeTable { class OnTheFlyPrimeTable : public PrimeTable {
public: public:
virtual bool IsPrime(int n) const { bool IsPrime(int n) const override {
if (n <= 1) return false; if (n <= 1) return false;
for (int i = 2; i*i <= n; i++) { for (int i = 2; i*i <= n; i++) {
@ -66,12 +65,12 @@ class OnTheFlyPrimeTable : public PrimeTable {
return true; return true;
} }
virtual int GetNextPrime(int p) const { int GetNextPrime(int p) const override {
for (int n = p + 1; n > 0; n++) { if (p < 0) return -1;
for (int n = p + 1;; n++) {
if (IsPrime(n)) return n; if (IsPrime(n)) return n;
} }
return -1;
} }
}; };
@ -84,13 +83,13 @@ class PreCalculatedPrimeTable : public PrimeTable {
: is_prime_size_(max + 1), is_prime_(new bool[max + 1]) { : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
CalculatePrimesUpTo(max); CalculatePrimesUpTo(max);
} }
virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; } ~PreCalculatedPrimeTable() override { delete[] is_prime_; }
virtual bool IsPrime(int n) const { bool IsPrime(int n) const override {
return 0 <= n && n < is_prime_size_ && is_prime_[n]; return 0 <= n && n < is_prime_size_ && is_prime_[n];
} }
virtual int GetNextPrime(int p) const { int GetNextPrime(int p) const override {
for (int n = p + 1; n < is_prime_size_; n++) { for (int n = p + 1; n < is_prime_size_; n++) {
if (is_prime_[n]) return n; if (is_prime_[n]) return n;
} }
@ -103,11 +102,15 @@ class PreCalculatedPrimeTable : public PrimeTable {
::std::fill(is_prime_, is_prime_ + is_prime_size_, true); ::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
is_prime_[0] = is_prime_[1] = false; is_prime_[0] = is_prime_[1] = false;
for (int i = 2; i <= max; i++) { // Checks every candidate for prime number (we know that 2 is the only even
// prime).
for (int i = 2; i*i <= max; i += i%2+1) {
if (!is_prime_[i]) continue; if (!is_prime_[i]) continue;
// Marks all multiples of i (except i itself) as non-prime. // Marks all multiples of i (except i itself) as non-prime.
for (int j = 2*i; j <= max; j += i) { // We are starting here from i-th multiplier, because all smaller
// complex numbers were already marked.
for (int j = i*i; j <= max; j += i) {
is_prime_[j] = false; is_prime_[j] = false;
} }
} }
@ -120,4 +123,4 @@ class PreCalculatedPrimeTable : public PrimeTable {
void operator=(const PreCalculatedPrimeTable& rhs); void operator=(const PreCalculatedPrimeTable& rhs);
}; };
#endif // GTEST_SAMPLES_PRIME_TABLES_H_ #endif // GOOGLETEST_SAMPLES_PRIME_TABLES_H_

View File

@ -28,8 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include "sample1.h" #include "sample1.h"
@ -43,7 +41,7 @@ int Factorial(int n) {
return result; return result;
} }
// Returns true iff n is a prime number. // Returns true if and only if n is a prime number.
bool IsPrime(int n) { bool IsPrime(int n) {
// Trivial case 1: small numbers // Trivial case 1: small numbers
if (n <= 1) return false; if (n <= 1) return false;
@ -55,7 +53,7 @@ bool IsPrime(int n) {
// Try to divide n by every odd number i, starting from 3 // Try to divide n by every odd number i, starting from 3
for (int i = 3; ; i += 2) { for (int i = 3; ; i += 2) {
// We only have to try i up to the squre root of n // We only have to try i up to the square root of n
if (i > n/i) break; if (i > n/i) break;
// Now, we have i <= n/i < n. // Now, we have i <= n/i < n.

View File

@ -28,16 +28,14 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE1_H_ #ifndef GOOGLETEST_SAMPLES_SAMPLE1_H_
#define GTEST_SAMPLES_SAMPLE1_H_ #define GOOGLETEST_SAMPLES_SAMPLE1_H_
// Returns n! (the factorial of n). For negative n, n! is defined to be 1. // Returns n! (the factorial of n). For negative n, n! is defined to be 1.
int Factorial(int n); int Factorial(int n);
// Returns true iff n is a prime number. // Returns true if and only if n is a prime number.
bool IsPrime(int n); bool IsPrime(int n);
#endif // GTEST_SAMPLES_SAMPLE1_H_ #endif // GOOGLETEST_SAMPLES_SAMPLE1_H_

View File

@ -25,8 +25,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to use Google Test listener API to implement // This sample shows how to use Google Test listener API to implement
// a primitive leak checker. // a primitive leak checker.
@ -35,18 +34,15 @@
#include <stdlib.h> #include <stdlib.h>
#include "gtest/gtest.h" #include "gtest/gtest.h"
using ::testing::EmptyTestEventListener; using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest; using ::testing::InitGoogleTest;
using ::testing::Test; using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners; using ::testing::TestEventListeners;
using ::testing::TestInfo; using ::testing::TestInfo;
using ::testing::TestPartResult; using ::testing::TestPartResult;
using ::testing::UnitTest; using ::testing::UnitTest;
namespace { namespace {
// We will track memory used by this class. // We will track memory used by this class.
class Water { class Water {
public: public:
@ -78,12 +74,12 @@ int Water::allocated_ = 0;
class LeakChecker : public EmptyTestEventListener { class LeakChecker : public EmptyTestEventListener {
private: private:
// Called before a test starts. // Called before a test starts.
virtual void OnTestStart(const TestInfo& /* test_info */) { void OnTestStart(const TestInfo& /* test_info */) override {
initially_allocated_ = Water::allocated(); initially_allocated_ = Water::allocated();
} }
// Called after a test ends. // Called after a test ends.
virtual void OnTestEnd(const TestInfo& /* test_info */) { void OnTestEnd(const TestInfo& /* test_info */) override {
int difference = Water::allocated() - initially_allocated_; int difference = Water::allocated() - initially_allocated_;
// You can generate a failure in any event handler except // You can generate a failure in any event handler except
@ -104,9 +100,8 @@ TEST(ListenersTest, DoesNotLeak) {
// specified. // specified.
TEST(ListenersTest, LeaksWater) { TEST(ListenersTest, LeaksWater) {
Water* water = new Water; Water* water = new Water;
EXPECT_TRUE(water != NULL); EXPECT_TRUE(water != nullptr);
} }
} // namespace } // namespace
int main(int argc, char **argv) { int main(int argc, char **argv) {

View File

@ -28,9 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to write a simple unit test for a function, // This sample shows how to write a simple unit test for a function,
// using Google C++ testing framework. // using Google C++ testing framework.
@ -46,7 +43,7 @@
#include <limits.h> #include <limits.h>
#include "sample1.h" #include "sample1.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
// Step 2. Use the TEST macro to define your tests. // Step 2. Use the TEST macro to define your tests.
// //
@ -139,6 +136,7 @@ TEST(IsPrimeTest, Positive) {
EXPECT_FALSE(IsPrime(6)); EXPECT_FALSE(IsPrime(6));
EXPECT_TRUE(IsPrime(23)); EXPECT_TRUE(IsPrime(23));
} }
} // namespace
// Step 3. Call RUN_ALL_TESTS() in main(). // Step 3. Call RUN_ALL_TESTS() in main().
// //

View File

@ -28,8 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include "sample2.h" #include "sample2.h"
@ -37,7 +35,7 @@
// Clones a 0-terminated C string, allocating memory using new. // Clones a 0-terminated C string, allocating memory using new.
const char* MyString::CloneCString(const char* a_c_string) { const char* MyString::CloneCString(const char* a_c_string) {
if (a_c_string == NULL) return NULL; if (a_c_string == nullptr) return nullptr;
const size_t len = strlen(a_c_string); const size_t len = strlen(a_c_string);
char* const clone = new char[ len + 1 ]; char* const clone = new char[ len + 1 ];

View File

@ -28,11 +28,9 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE2_H_ #ifndef GOOGLETEST_SAMPLES_SAMPLE2_H_
#define GTEST_SAMPLES_SAMPLE2_H_ #define GOOGLETEST_SAMPLES_SAMPLE2_H_
#include <string.h> #include <string.h>
@ -52,15 +50,15 @@ class MyString {
// C'tors // C'tors
// The default c'tor constructs a NULL string. // The default c'tor constructs a NULL string.
MyString() : c_string_(NULL) {} MyString() : c_string_(nullptr) {}
// Constructs a MyString by cloning a 0-terminated C string. // Constructs a MyString by cloning a 0-terminated C string.
explicit MyString(const char* a_c_string) : c_string_(NULL) { explicit MyString(const char* a_c_string) : c_string_(nullptr) {
Set(a_c_string); Set(a_c_string);
} }
// Copy c'tor // Copy c'tor
MyString(const MyString& string) : c_string_(NULL) { MyString(const MyString& string) : c_string_(nullptr) {
Set(string.c_string_); Set(string.c_string_);
} }
@ -73,13 +71,10 @@ class MyString {
// Gets the 0-terminated C string this MyString object represents. // Gets the 0-terminated C string this MyString object represents.
const char* c_string() const { return c_string_; } const char* c_string() const { return c_string_; }
size_t Length() const { size_t Length() const { return c_string_ == nullptr ? 0 : strlen(c_string_); }
return c_string_ == NULL ? 0 : strlen(c_string_);
}
// Sets the 0-terminated C string this MyString object represents. // Sets the 0-terminated C string this MyString object represents.
void Set(const char* c_string); void Set(const char* c_string);
}; };
#endif // GOOGLETEST_SAMPLES_SAMPLE2_H_
#endif // GTEST_SAMPLES_SAMPLE2_H_

View File

@ -28,9 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to write a more complex unit test for a class // This sample shows how to write a more complex unit test for a class
// that has multiple member functions. // that has multiple member functions.
@ -42,7 +39,7 @@
#include "sample2.h" #include "sample2.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
// In this example, we test the MyString class (a simple string). // In this example, we test the MyString class (a simple string).
// Tests the default c'tor. // Tests the default c'tor.
@ -69,7 +66,7 @@ TEST(MyString, DefaultConstructor) {
// we have to live with this fact. // we have to live with this fact.
// //
// </TechnicalDetails> // </TechnicalDetails>
EXPECT_STREQ(NULL, s.c_string()); EXPECT_STREQ(nullptr, s.c_string());
EXPECT_EQ(0u, s.Length()); EXPECT_EQ(0u, s.Length());
} }
@ -104,6 +101,7 @@ TEST(MyString, Set) {
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Can we set the MyString to NULL? // Can we set the MyString to NULL?
s.Set(NULL); s.Set(nullptr);
EXPECT_STREQ(NULL, s.c_string()); EXPECT_STREQ(nullptr, s.c_string());
} }
} // namespace

View File

@ -28,11 +28,9 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ #ifndef GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
#define GTEST_SAMPLES_SAMPLE3_INL_H_ #define GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
#include <stddef.h> #include <stddef.h>
@ -60,7 +58,8 @@ class QueueNode {
private: private:
// Creates a node with a given element value. The next pointer is // Creates a node with a given element value. The next pointer is
// set to NULL. // set to NULL.
explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} explicit QueueNode(const E& an_element)
: element_(an_element), next_(nullptr) {}
// We disable the default assignment operator and copy c'tor. // We disable the default assignment operator and copy c'tor.
const QueueNode& operator = (const QueueNode&); const QueueNode& operator = (const QueueNode&);
@ -74,7 +73,7 @@ template <typename E> // E is the element type.
class Queue { class Queue {
public: public:
// Creates an empty queue. // Creates an empty queue.
Queue() : head_(NULL), last_(NULL), size_(0) {} Queue() : head_(nullptr), last_(nullptr), size_(0) {}
// D'tor. Clears the queue. // D'tor. Clears the queue.
~Queue() { Clear(); } ~Queue() { Clear(); }
@ -88,12 +87,12 @@ class Queue {
for (; ;) { for (; ;) {
delete node; delete node;
node = next; node = next;
if (node == NULL) break; if (node == nullptr) break;
next = node->next(); next = node->next();
} }
// 2. Resets the member variables. // 2. Resets the member variables.
head_ = last_ = NULL; head_ = last_ = nullptr;
size_ = 0; size_ = 0;
} }
} }
@ -130,14 +129,14 @@ class Queue {
// the queue is empty. // the queue is empty.
E* Dequeue() { E* Dequeue() {
if (size_ == 0) { if (size_ == 0) {
return NULL; return nullptr;
} }
const QueueNode<E>* const old_head = head_; const QueueNode<E>* const old_head = head_;
head_ = head_->next_; head_ = head_->next_;
size_--; size_--;
if (size_ == 0) { if (size_ == 0) {
last_ = NULL; last_ = nullptr;
} }
E* element = new E(old_head->element()); E* element = new E(old_head->element());
@ -152,7 +151,8 @@ class Queue {
template <typename F> template <typename F>
Queue* Map(F function) const { Queue* Map(F function) const {
Queue* new_queue = new Queue(); Queue* new_queue = new Queue();
for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) { for (const QueueNode<E>* node = head_; node != nullptr;
node = node->next_) {
new_queue->Enqueue(function(node->element())); new_queue->Enqueue(function(node->element()));
} }
@ -169,4 +169,4 @@ class Queue {
const Queue& operator = (const Queue&); const Queue& operator = (const Queue&);
}; };
#endif // GTEST_SAMPLES_SAMPLE3_INL_H_ #endif // GOOGLETEST_SAMPLES_SAMPLE3_INL_H_

View File

@ -28,9 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// In this example, we use a more advanced feature of Google Test called // In this example, we use a more advanced feature of Google Test called
// test fixture. // test fixture.
@ -65,16 +62,16 @@
#include "sample3-inl.h" #include "sample3-inl.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
// To use a test fixture, derive a class from testing::Test. // To use a test fixture, derive a class from testing::Test.
class QueueTest : public testing::Test { class QueueTestSmpl3 : public testing::Test {
protected: // You should make the members protected s.t. they can be protected: // You should make the members protected s.t. they can be
// accessed from sub-classes. // accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You // virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles. // should define it if you need to initialize the variables.
// Otherwise, this can be skipped. // Otherwise, this can be skipped.
virtual void SetUp() { void SetUp() override {
q1_.Enqueue(1); q1_.Enqueue(1);
q2_.Enqueue(2); q2_.Enqueue(2);
q2_.Enqueue(3); q2_.Enqueue(3);
@ -102,8 +99,8 @@ class QueueTest : public testing::Test {
ASSERT_EQ(q->Size(), new_q->Size()); ASSERT_EQ(q->Size(), new_q->Size());
// Verifies the relationship between the elements of the two queues. // Verifies the relationship between the elements of the two queues.
for ( const QueueNode<int> * n1 = q->Head(), * n2 = new_q->Head(); for (const QueueNode<int>*n1 = q->Head(), *n2 = new_q->Head();
n1 != NULL; n1 = n1->next(), n2 = n2->next() ) { n1 != nullptr; n1 = n1->next(), n2 = n2->next()) {
EXPECT_EQ(2 * n1->element(), n2->element()); EXPECT_EQ(2 * n1->element(), n2->element());
} }
@ -120,32 +117,33 @@ class QueueTest : public testing::Test {
// instead of TEST. // instead of TEST.
// Tests the default c'tor. // Tests the default c'tor.
TEST_F(QueueTest, DefaultConstructor) { TEST_F(QueueTestSmpl3, DefaultConstructor) {
// You can access data in the test fixture here. // You can access data in the test fixture here.
EXPECT_EQ(0u, q0_.Size()); EXPECT_EQ(0u, q0_.Size());
} }
// Tests Dequeue(). // Tests Dequeue().
TEST_F(QueueTest, Dequeue) { TEST_F(QueueTestSmpl3, Dequeue) {
int * n = q0_.Dequeue(); int * n = q0_.Dequeue();
EXPECT_TRUE(n == NULL); EXPECT_TRUE(n == nullptr);
n = q1_.Dequeue(); n = q1_.Dequeue();
ASSERT_TRUE(n != NULL); ASSERT_TRUE(n != nullptr);
EXPECT_EQ(1, *n); EXPECT_EQ(1, *n);
EXPECT_EQ(0u, q1_.Size()); EXPECT_EQ(0u, q1_.Size());
delete n; delete n;
n = q2_.Dequeue(); n = q2_.Dequeue();
ASSERT_TRUE(n != NULL); ASSERT_TRUE(n != nullptr);
EXPECT_EQ(2, *n); EXPECT_EQ(2, *n);
EXPECT_EQ(1u, q2_.Size()); EXPECT_EQ(1u, q2_.Size());
delete n; delete n;
} }
// Tests the Queue::Map() function. // Tests the Queue::Map() function.
TEST_F(QueueTest, Map) { TEST_F(QueueTestSmpl3, Map) {
MapTester(&q0_); MapTester(&q0_);
MapTester(&q1_); MapTester(&q1_);
MapTester(&q2_); MapTester(&q2_);
} }
} // namespace

View File

@ -28,8 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include <stdio.h> #include <stdio.h>
@ -40,6 +38,16 @@ int Counter::Increment() {
return counter_++; return counter_++;
} }
// Returns the current counter value, and decrements it.
// counter can not be less than 0, return 0 in this case
int Counter::Decrement() {
if (counter_ == 0) {
return counter_;
} else {
return counter_--;
}
}
// Prints the current counter value to STDOUT. // Prints the current counter value to STDOUT.
void Counter::Print() const { void Counter::Print() const {
printf("%d", counter_); printf("%d", counter_);

View File

@ -28,11 +28,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
// #ifndef GOOGLETEST_SAMPLES_SAMPLE4_H_
// Author: wan@google.com (Zhanyong Wan) #define GOOGLETEST_SAMPLES_SAMPLE4_H_
#ifndef GTEST_SAMPLES_SAMPLE4_H_
#define GTEST_SAMPLES_SAMPLE4_H_
// A simple monotonic counter. // A simple monotonic counter.
class Counter { class Counter {
@ -46,8 +43,11 @@ class Counter {
// Returns the current counter value, and increments it. // Returns the current counter value, and increments it.
int Increment(); int Increment();
// Returns the current counter value, and decrements it.
int Decrement();
// Prints the current counter value to STDOUT. // Prints the current counter value to STDOUT.
void Print() const; void Print() const;
}; };
#endif // GTEST_SAMPLES_SAMPLE4_H_ #endif // GOOGLETEST_SAMPLES_SAMPLE4_H_

View File

@ -26,20 +26,28 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest.h"
#include "sample4.h" #include "sample4.h"
#include "gtest/gtest.h"
namespace {
// Tests the Increment() method. // Tests the Increment() method.
TEST(Counter, Increment) { TEST(Counter, Increment) {
Counter c; Counter c;
// Test that counter 0 returns 0
EXPECT_EQ(0, c.Decrement());
// EXPECT_EQ() evaluates its arguments exactly once, so they // EXPECT_EQ() evaluates its arguments exactly once, so they
// can have side effects. // can have side effects.
EXPECT_EQ(0, c.Increment()); EXPECT_EQ(0, c.Increment());
EXPECT_EQ(1, c.Increment()); EXPECT_EQ(1, c.Increment());
EXPECT_EQ(2, c.Increment()); EXPECT_EQ(2, c.Increment());
EXPECT_EQ(3, c.Decrement());
} }
} // namespace

View File

@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample teaches how to reuse a test fixture in multiple test // This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it. // cases by deriving sub-fixtures from it.
@ -46,10 +45,10 @@
#include <limits.h> #include <limits.h>
#include <time.h> #include <time.h>
#include "sample3-inl.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "sample1.h" #include "sample1.h"
#include "sample3-inl.h"
namespace {
// In this sample, we want to ensure that every test finishes within // In this sample, we want to ensure that every test finishes within
// ~5 seconds. If a test takes longer to run, we consider it a // ~5 seconds. If a test takes longer to run, we consider it a
// failure. // failure.
@ -64,15 +63,13 @@ class QuickTest : public testing::Test {
protected: protected:
// Remember that SetUp() is run immediately before a test starts. // Remember that SetUp() is run immediately before a test starts.
// This is a good place to record the start time. // This is a good place to record the start time.
virtual void SetUp() { void SetUp() override { start_time_ = time(nullptr); }
start_time_ = time(NULL);
}
// TearDown() is invoked immediately after a test finishes. Here we // TearDown() is invoked immediately after a test finishes. Here we
// check if the test was too slow. // check if the test was too slow.
virtual void TearDown() { void TearDown() override {
// Gets the time when the test finishes // Gets the time when the test finishes
const time_t end_time = time(NULL); const time_t end_time = time(nullptr);
// Asserts that the test took no more than ~5 seconds. Did you // Asserts that the test took no more than ~5 seconds. Did you
// know that you can use assertions in SetUp() and TearDown() as // know that you can use assertions in SetUp() and TearDown() as
@ -143,7 +140,7 @@ TEST_F(IntegerFunctionTest, IsPrime) {
// stuff inside the body of the test fixture, as usual. // stuff inside the body of the test fixture, as usual.
class QueueTest : public QuickTest { class QueueTest : public QuickTest {
protected: protected:
virtual void SetUp() { void SetUp() override {
// First, we need to set up the super fixture (QuickTest). // First, we need to set up the super fixture (QuickTest).
QuickTest::SetUp(); QuickTest::SetUp();
@ -177,21 +174,21 @@ TEST_F(QueueTest, DefaultConstructor) {
// Tests Dequeue(). // Tests Dequeue().
TEST_F(QueueTest, Dequeue) { TEST_F(QueueTest, Dequeue) {
int* n = q0_.Dequeue(); int* n = q0_.Dequeue();
EXPECT_TRUE(n == NULL); EXPECT_TRUE(n == nullptr);
n = q1_.Dequeue(); n = q1_.Dequeue();
EXPECT_TRUE(n != NULL); EXPECT_TRUE(n != nullptr);
EXPECT_EQ(1, *n); EXPECT_EQ(1, *n);
EXPECT_EQ(0u, q1_.Size()); EXPECT_EQ(0u, q1_.Size());
delete n; delete n;
n = q2_.Dequeue(); n = q2_.Dequeue();
EXPECT_TRUE(n != NULL); EXPECT_TRUE(n != nullptr);
EXPECT_EQ(2, *n); EXPECT_EQ(2, *n);
EXPECT_EQ(1u, q2_.Size()); EXPECT_EQ(1u, q2_.Size());
delete n; delete n;
} }
} // namespace
// If necessary, you can derive further test fixtures from a derived // If necessary, you can derive further test fixtures from a derived
// fixture itself. For example, you can derive another fixture from // fixture itself. For example, you can derive another fixture from
// QueueTest. Google Test imposes no limit on how deep the hierarchy // QueueTest. Google Test imposes no limit on how deep the hierarchy

View File

@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to test common properties of multiple // This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests). // implementations of the same interface (aka interface tests).
@ -36,7 +35,7 @@
#include "prime_tables.h" #include "prime_tables.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
// First, we define some factory functions for creating instances of // First, we define some factory functions for creating instances of
// the implementations. You may be able to skip this step if all your // the implementations. You may be able to skip this step if all your
// implementations can be constructed the same way. // implementations can be constructed the same way.
@ -62,7 +61,7 @@ class PrimeTableTest : public testing::Test {
// implemented by T. // implemented by T.
PrimeTableTest() : table_(CreatePrimeTable<T>()) {} PrimeTableTest() : table_(CreatePrimeTable<T>()) {}
virtual ~PrimeTableTest() { delete table_; } ~PrimeTableTest() override { delete table_; }
// Note that we test an implementation via the base interface // Note that we test an implementation via the base interface
// instead of the actual implementation class. This is important // instead of the actual implementation class. This is important
@ -74,8 +73,6 @@ class PrimeTableTest : public testing::Test {
PrimeTable* const table_; PrimeTable* const table_;
}; };
#if GTEST_HAS_TYPED_TEST
using testing::Types; using testing::Types;
// Google Test offers two ways for reusing tests for different types. // Google Test offers two ways for reusing tests for different types.
@ -85,7 +82,7 @@ using testing::Types;
// To write a typed test case, first use // To write a typed test case, first use
// //
// TYPED_TEST_CASE(TestCaseName, TypeList); // TYPED_TEST_SUITE(TestCaseName, TypeList);
// //
// to declare it and specify the type parameters. As with TEST_F, // to declare it and specify the type parameters. As with TEST_F,
// TestCaseName must match the test fixture name. // TestCaseName must match the test fixture name.
@ -93,7 +90,7 @@ using testing::Types;
// The list of types we want to test. // The list of types we want to test.
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations; typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;
TYPED_TEST_CASE(PrimeTableTest, Implementations); TYPED_TEST_SUITE(PrimeTableTest, Implementations);
// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test, // Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
// similar to TEST_F. // similar to TEST_F.
@ -132,13 +129,9 @@ TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
} }
// That's it! Google Test will repeat each TYPED_TEST for each type // That's it! Google Test will repeat each TYPED_TEST for each type
// in the type list specified in TYPED_TEST_CASE. Sit back and be // in the type list specified in TYPED_TEST_SUITE. Sit back and be
// happy that you don't have to define them multiple times. // happy that you don't have to define them multiple times.
#endif // GTEST_HAS_TYPED_TEST
#if GTEST_HAS_TYPED_TEST_P
using testing::Types; using testing::Types;
// Sometimes, however, you don't yet know all the types that you want // Sometimes, however, you don't yet know all the types that you want
@ -164,7 +157,7 @@ class PrimeTableTest2 : public PrimeTableTest<T> {
// Then, declare the test case. The argument is the name of the test // Then, declare the test case. The argument is the name of the test
// fixture, and also the name of the test case (as usual). The _P // fixture, and also the name of the test case (as usual). The _P
// suffix is for "parameterized" or "pattern". // suffix is for "parameterized" or "pattern".
TYPED_TEST_CASE_P(PrimeTableTest2); TYPED_TEST_SUITE_P(PrimeTableTest2);
// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test, // Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
// similar to what you do with TEST_F. // similar to what you do with TEST_F.
@ -197,7 +190,7 @@ TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) {
// Type-parameterized tests involve one extra step: you have to // Type-parameterized tests involve one extra step: you have to
// enumerate the tests you defined: // enumerate the tests you defined:
REGISTER_TYPED_TEST_CASE_P( REGISTER_TYPED_TEST_SUITE_P(
PrimeTableTest2, // The first argument is the test case name. PrimeTableTest2, // The first argument is the test case name.
// The rest of the arguments are the test names. // The rest of the arguments are the test names.
ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime); ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);
@ -217,8 +210,8 @@ REGISTER_TYPED_TEST_CASE_P(
// defined at the time we write the TYPED_TEST_P()s. // defined at the time we write the TYPED_TEST_P()s.
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>
PrimeTableImplementations; PrimeTableImplementations;
INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated, // Instance name INSTANTIATE_TYPED_TEST_SUITE_P(OnTheFlyAndPreCalculated, // Instance name
PrimeTableTest2, // Test case name PrimeTableTest2, // Test case name
PrimeTableImplementations); // Type list PrimeTableImplementations); // Type list
#endif // GTEST_HAS_TYPED_TEST_P } // namespace

View File

@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test common properties of multiple // This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using // implementations of an interface (aka interface tests) using
@ -39,8 +38,7 @@
#include "prime_tables.h" #include "prime_tables.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
#if GTEST_HAS_PARAM_TEST
using ::testing::TestWithParam; using ::testing::TestWithParam;
using ::testing::Values; using ::testing::Values;
@ -65,20 +63,20 @@ PrimeTable* CreatePreCalculatedPrimeTable() {
// can refer to the test parameter by GetParam(). In this case, the test // can refer to the test parameter by GetParam(). In this case, the test
// parameter is a factory function which we call in fixture's SetUp() to // parameter is a factory function which we call in fixture's SetUp() to
// create and store an instance of PrimeTable. // create and store an instance of PrimeTable.
class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> { class PrimeTableTestSmpl7 : public TestWithParam<CreatePrimeTableFunc*> {
public: public:
virtual ~PrimeTableTest() { delete table_; } ~PrimeTableTestSmpl7() override { delete table_; }
virtual void SetUp() { table_ = (*GetParam())(); } void SetUp() override { table_ = (*GetParam())(); }
virtual void TearDown() { void TearDown() override {
delete table_; delete table_;
table_ = NULL; table_ = nullptr;
} }
protected: protected:
PrimeTable* table_; PrimeTable* table_;
}; };
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { TEST_P(PrimeTableTestSmpl7, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(table_->IsPrime(-5)); EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0)); EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1)); EXPECT_FALSE(table_->IsPrime(1));
@ -87,7 +85,7 @@ TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(table_->IsPrime(100)); EXPECT_FALSE(table_->IsPrime(100));
} }
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { TEST_P(PrimeTableTestSmpl7, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2)); EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3)); EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5)); EXPECT_TRUE(table_->IsPrime(5));
@ -96,7 +94,7 @@ TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(131)); EXPECT_TRUE(table_->IsPrime(131));
} }
TEST_P(PrimeTableTest, CanGetNextPrime) { TEST_P(PrimeTableTestSmpl7, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0)); EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2)); EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3)); EXPECT_EQ(5, table_->GetNextPrime(3));
@ -112,19 +110,8 @@ TEST_P(PrimeTableTest, CanGetNextPrime) {
// //
// Here, we instantiate our tests with a list of two PrimeTable object // Here, we instantiate our tests with a list of two PrimeTable object
// factory functions: // factory functions:
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_SUITE_P(OnTheFlyAndPreCalculated, PrimeTableTestSmpl7,
OnTheFlyAndPreCalculated, Values(&CreateOnTheFlyPrimeTable,
PrimeTableTest, &CreatePreCalculatedPrimeTable<1000>));
Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));
#else } // namespace
// Google Test may not support value-parameterized tests with some
// compilers. If we use conditional compilation to compile out all
// code referring to the gtest_main library, MSVC linker will not link
// that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point
// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_PARAM_TEST

View File

@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test code relying on some global flag variables. // This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags, // Combine() helps with generating all possible combinations of such flags,
@ -37,8 +36,7 @@
#include "prime_tables.h" #include "prime_tables.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace {
#if GTEST_HAS_COMBINE
// Suppose we want to introduce a new, improved implementation of PrimeTable // Suppose we want to introduce a new, improved implementation of PrimeTable
// which combines speed of PrecalcPrimeTable and versatility of // which combines speed of PrecalcPrimeTable and versatility of
@ -51,24 +49,25 @@ class HybridPrimeTable : public PrimeTable {
public: public:
HybridPrimeTable(bool force_on_the_fly, int max_precalculated) HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
: on_the_fly_impl_(new OnTheFlyPrimeTable), : on_the_fly_impl_(new OnTheFlyPrimeTable),
precalc_impl_(force_on_the_fly ? NULL : precalc_impl_(force_on_the_fly
new PreCalculatedPrimeTable(max_precalculated)), ? nullptr
: new PreCalculatedPrimeTable(max_precalculated)),
max_precalculated_(max_precalculated) {} max_precalculated_(max_precalculated) {}
virtual ~HybridPrimeTable() { ~HybridPrimeTable() override {
delete on_the_fly_impl_; delete on_the_fly_impl_;
delete precalc_impl_; delete precalc_impl_;
} }
virtual bool IsPrime(int n) const { bool IsPrime(int n) const override {
if (precalc_impl_ != NULL && n < max_precalculated_) if (precalc_impl_ != nullptr && n < max_precalculated_)
return precalc_impl_->IsPrime(n); return precalc_impl_->IsPrime(n);
else else
return on_the_fly_impl_->IsPrime(n); return on_the_fly_impl_->IsPrime(n);
} }
virtual int GetNextPrime(int p) const { int GetNextPrime(int p) const override {
int next_prime = -1; int next_prime = -1;
if (precalc_impl_ != NULL && p < max_precalculated_) if (precalc_impl_ != nullptr && p < max_precalculated_)
next_prime = precalc_impl_->GetNextPrime(p); next_prime = precalc_impl_->GetNextPrime(p);
return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p); return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
@ -90,24 +89,17 @@ using ::testing::Combine;
// PreCalculatedPrimeTable disabled. We do this by defining fixture which will // PreCalculatedPrimeTable disabled. We do this by defining fixture which will
// accept different combinations of parameters for instantiating a // accept different combinations of parameters for instantiating a
// HybridPrimeTable instance. // HybridPrimeTable instance.
class PrimeTableTest : public TestWithParam< ::testing::tuple<bool, int> > { class PrimeTableTest : public TestWithParam< ::std::tuple<bool, int> > {
protected: protected:
virtual void SetUp() { void SetUp() override {
// This can be written as bool force_on_the_fly;
// int max_precalculated;
// bool force_on_the_fly; std::tie(force_on_the_fly, max_precalculated) = GetParam();
// int max_precalculated;
// tie(force_on_the_fly, max_precalculated) = GetParam();
//
// once the Google C++ Style Guide allows use of ::std::tr1::tie.
//
bool force_on_the_fly = ::testing::get<0>(GetParam());
int max_precalculated = ::testing::get<1>(GetParam());
table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated); table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
} }
virtual void TearDown() { void TearDown() override {
delete table_; delete table_;
table_ = NULL; table_ = nullptr;
} }
HybridPrimeTable* table_; HybridPrimeTable* table_;
}; };
@ -156,18 +148,7 @@ TEST_P(PrimeTableTest, CanGetNextPrime) {
// will put some of the tested numbers beyond the capability of the // will put some of the tested numbers beyond the capability of the
// PrecalcPrimeTable instance and some inside it (10). Combine will produce all // PrecalcPrimeTable instance and some inside it (10). Combine will produce all
// possible combinations. // possible combinations.
INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters, INSTANTIATE_TEST_SUITE_P(MeaningfulTestParameters, PrimeTableTest,
PrimeTableTest,
Combine(Bool(), Values(1, 10))); Combine(Bool(), Values(1, 10)));
#else } // namespace
// Google Test may not support Combine() with some compilers. If we
// use conditional compilation to compile out all code referring to
// the gtest_main library, MSVC linker will not link that library at
// all and consequently complain about missing entry point defined in
// that library (fatal error LNK1561: entry point must be
// defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_COMBINE

View File

@ -25,8 +25,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to use Google Test listener API to implement // This sample shows how to use Google Test listener API to implement
// an alternative console output and how to use the UnitTest reflection API // an alternative console output and how to use the UnitTest reflection API
@ -44,24 +43,22 @@ using ::testing::TestEventListeners;
using ::testing::TestInfo; using ::testing::TestInfo;
using ::testing::TestPartResult; using ::testing::TestPartResult;
using ::testing::UnitTest; using ::testing::UnitTest;
namespace { namespace {
// Provides alternative output mode which produces minimal amount of // Provides alternative output mode which produces minimal amount of
// information about tests. // information about tests.
class TersePrinter : public EmptyTestEventListener { class TersePrinter : public EmptyTestEventListener {
private: private:
// Called before any test activity starts. // Called before any test activity starts.
virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {} void OnTestProgramStart(const UnitTest& /* unit_test */) override {}
// Called after all test activities have ended. // Called after all test activities have ended.
virtual void OnTestProgramEnd(const UnitTest& unit_test) { void OnTestProgramEnd(const UnitTest& unit_test) override {
fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED");
fflush(stdout); fflush(stdout);
} }
// Called before a test starts. // Called before a test starts.
virtual void OnTestStart(const TestInfo& test_info) { void OnTestStart(const TestInfo& test_info) override {
fprintf(stdout, fprintf(stdout,
"*** Test %s.%s starting.\n", "*** Test %s.%s starting.\n",
test_info.test_case_name(), test_info.test_case_name(),
@ -70,7 +67,7 @@ class TersePrinter : public EmptyTestEventListener {
} }
// Called after a failed assertion or a SUCCEED() invocation. // Called after a failed assertion or a SUCCEED() invocation.
virtual void OnTestPartResult(const TestPartResult& test_part_result) { void OnTestPartResult(const TestPartResult& test_part_result) override {
fprintf(stdout, fprintf(stdout,
"%s in %s:%d\n%s\n", "%s in %s:%d\n%s\n",
test_part_result.failed() ? "*** Failure" : "Success", test_part_result.failed() ? "*** Failure" : "Success",
@ -81,7 +78,7 @@ class TersePrinter : public EmptyTestEventListener {
} }
// Called after a test ends. // Called after a test ends.
virtual void OnTestEnd(const TestInfo& test_info) { void OnTestEnd(const TestInfo& test_info) override {
fprintf(stdout, fprintf(stdout,
"*** Test %s.%s ending.\n", "*** Test %s.%s ending.\n",
test_info.test_case_name(), test_info.test_case_name(),
@ -102,7 +99,6 @@ TEST(CustomOutputTest, Fails) {
EXPECT_EQ(1, 2) EXPECT_EQ(1, 2)
<< "This test fails in order to demonstrate alternative failure messages"; << "This test fails in order to demonstrate alternative failure messages";
} }
} // namespace } // namespace
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -139,10 +135,10 @@ int main(int argc, char **argv) {
// This is an example of using the UnitTest reflection API to inspect test // This is an example of using the UnitTest reflection API to inspect test
// results. Here we discount failures from the tests we expected to fail. // results. Here we discount failures from the tests we expected to fail.
int unexpectedly_failed_tests = 0; int unexpectedly_failed_tests = 0;
for (int i = 0; i < unit_test.total_test_case_count(); ++i) { for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
const TestCase& test_case = *unit_test.GetTestCase(i); const testing::TestSuite& test_suite = *unit_test.GetTestSuite(i);
for (int j = 0; j < test_case.total_test_count(); ++j) { for (int j = 0; j < test_suite.total_test_count(); ++j) {
const TestInfo& test_info = *test_case.GetTestInfo(j); const TestInfo& test_info = *test_suite.GetTestInfo(j);
// Counts failed tests that were not meant to fail (those without // Counts failed tests that were not meant to fail (those without
// 'Fails' in the name). // 'Fails' in the name).
if (test_info.result()->Failed() && if (test_info.result()->Failed() &&

View File

@ -0,0 +1,5 @@
# Please Note:
Files in this directory are no longer supported by the maintainers. They
represent mosty historical artifacts and supported by the community only. There
is no guarantee whatsoever that these scripts still work.

View File

@ -52,7 +52,7 @@ EXAMPLES
This tool is experimental. In particular, it assumes that there is no This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Test headers. Please report any conditional inclusion of Google Test headers. Please report any
problems to googletestframework@googlegroups.com. You can read problems to googletestframework@googlegroups.com. You can read
http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for https://github.com/google/googletest/blob/master/googletest/docs/advanced.md for
more information. more information.
""" """

View File

@ -78,7 +78,7 @@ def HeaderPreamble(n):
} }
return ( return (
"""// Copyright 2006, Google Inc. """// Copyright 2006, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -111,14 +111,15 @@ def HeaderPreamble(n):
// '%(command)s'. DO NOT EDIT BY HAND! // '%(command)s'. DO NOT EDIT BY HAND!
// //
// Implements a family of generic predicate assertion macros. // Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h. #include "gtest/gtest.h"
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. namespace testing {
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion // This header implements a family of generic predicate assertion
// macros: // macros:
@ -247,8 +248,10 @@ AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
impl += ' << ") evaluates to false, where"' impl += ' << ") evaluates to false, where"'
impl += Iter(n, """ impl += Iter(
<< "\\n" << e%s << " evaluates to " << v%s""") n, """
<< "\\n" << e%s << " evaluates to " << ::testing::PrintToString(v%s)"""
)
impl += """; impl += """;
} }
@ -295,16 +298,17 @@ def HeaderPostamble():
return """ return """
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
""" """
def GenerateFile(path, content): def GenerateFile(path, content):
"""Given a file path and a content string, overwrites it with the """Given a file path and a content string
given content.""" overwrites it with the given content.
"""
print 'Updating file %s . . .' % path print 'Updating file %s . . .' % path
f = file(path, 'w+') f = file(path, 'w+')
print >>f, content, print >>f, content,
f.close() f.close()
@ -314,8 +318,8 @@ def GenerateFile(path, content):
def GenerateHeader(n): def GenerateHeader(n):
"""Given the maximum arity n, updates the header file that implements """Given the maximum arity n, updates the header file that implements
the predicate assertions.""" the predicate assertions.
"""
GenerateFile(HEADER, GenerateFile(HEADER,
HeaderPreamble(n) HeaderPreamble(n)
+ ''.join([ImplementationForArity(i) for i in OneTo(n)]) + ''.join([ImplementationForArity(i) for i in OneTo(n)])
@ -333,7 +337,7 @@ def UnitTestPreamble():
} }
return ( return (
"""// Copyright 2006, Google Inc. """// Copyright 2006, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -427,7 +431,7 @@ def TestsForArity(n):
} }
tests = ( tests = (
"""// Sample functions/functors for testing %(arity)s predicate assertions. """// Sample functions/functors for testing %(arity)s predicate assertions.
// A %(arity)s predicate function. // A %(arity)s predicate function.
template <%(types)s> template <%(types)s>
@ -435,9 +439,8 @@ bool PredFunction%(n)s(%(tvs)s) {
return %(v_sum)s > 0; return %(v_sum)s > 0;
} }
// The following two functions are needed to circumvent a bug in // The following two functions are needed because a compiler doesn't have
// gcc 2.95.3, which sometimes has problem with the above template // a context yet to know which template function must be instantiated.
// function.
bool PredFunction%(n)sInt(%(int_vs)s) { bool PredFunction%(n)sInt(%(int_vs)s) {
return %(v_sum)s > 0; return %(v_sum)s > 0;
} }
@ -510,7 +513,7 @@ struct PredFormatFunctor%(n)s {
class Predicate%(n)sTest : public testing::Test { class Predicate%(n)sTest : public testing::Test {
protected: protected:
virtual void SetUp() { void SetUp() override {
expected_to_finish_ = true; expected_to_finish_ = true;
finished_ = false;""" % DEFS finished_ = false;""" % DEFS
@ -520,7 +523,7 @@ class Predicate%(n)sTest : public testing::Test {
""" """
tests += """ tests += """
virtual void TearDown() { void TearDown() override {
// Verifies that each of the predicate's arguments was evaluated // Verifies that each of the predicate's arguments was evaluated
// exactly once.""" // exactly once."""
@ -540,10 +543,10 @@ class Predicate%(n)sTest : public testing::Test {
} }
} }
// true iff the test function is expected to run to finish. // true if and only if the test function is expected to run to finish.
static bool expected_to_finish_; static bool expected_to_finish_;
// true iff the test function did run to finish. // true if and only if the test function did run to finish.
static bool finished_; static bool finished_;
""" % DEFS """ % DEFS
@ -572,12 +575,12 @@ typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
"""Returns the test for a predicate assertion macro. """Returns the test for a predicate assertion macro.
Args: Args:
use_format: true iff the assertion is a *_PRED_FORMAT*. use_format: true if and only if the assertion is a *_PRED_FORMAT*.
use_assert: true iff the assertion is a ASSERT_*. use_assert: true if and only if the assertion is a ASSERT_*.
expect_failure: true iff the assertion is expected to fail. expect_failure: true if and only if the assertion is expected to fail.
use_functor: true iff the first argument of the assertion is use_functor: true if and only if the first argument of the assertion is
a functor (as opposed to a function) a functor (as opposed to a function)
use_user_type: true iff the predicate functor/function takes use_user_type: true if and only if the predicate functor/function takes
argument(s) of a user-defined type. argument(s) of a user-defined type.
Example: Example:

View File

@ -37,7 +37,7 @@ SYNOPSIS
interlinked wiki files. When we release a new version of interlinked wiki files. When we release a new version of
Google Test or Google Mock, we need to branch the wiki files Google Test or Google Mock, we need to branch the wiki files
such that users of a specific version of Google Test/Mock can such that users of a specific version of Google Test/Mock can
look up documenation relevant for that version. This script look up documentation relevant for that version. This script
automates that process by: automates that process by:
- branching the current wiki pages (which document the - branching the current wiki pages (which document the

View File

@ -0,0 +1,32 @@
#!/usr/bin/env python
#
# Copyright 2010 Google Inc. All Rights Reserved.
"""Runs program specified in the command line with the substituted PATH.
This script is needed for to support building under Pulse which is unable
to override the existing PATH variable.
"""
import os
import subprocess
import sys
SUBST_PATH_ENV_VAR_NAME = "SUBST_PATH"
def main():
if SUBST_PATH_ENV_VAR_NAME in os.environ:
os.environ["PATH"] = os.environ[SUBST_PATH_ENV_VAR_NAME]
exit_code = subprocess.Popen(sys.argv[1:]).wait()
# exit_code is negative (-signal) if the process has been terminated by
# a signal. Returning negative exit code is not portable and so we return
# 100 instead.
if exit_code < 0:
exit_code = 100
sys.exit(exit_code)
if __name__ == "__main__":
main()

View File

@ -1,18 +1,33 @@
#!/usr/bin/env python #!/usr/bin/env python
# #
# Copyright 2007 Google Inc. # Copyright 2007, Google Inc.
# All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Redistribution and use in source and binary forms, with or without
# you may not use this file except in compliance with the License. # modification, are permitted provided that the following conditions are
# You may obtain a copy of the License at # met:
# #
# http://www.apache.org/licenses/LICENSE-2.0 # * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
# #
# Unless required by applicable law or agreed to in writing, software # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# distributed under the License is distributed on an "AS IS" BASIS, # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# See the License for the specific language governing permissions and # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# limitations under the License. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tool for uploading diffs from a version control system to the codereview app. """Tool for uploading diffs from a version control system to the codereview app.
@ -242,7 +257,7 @@ class AbstractRpcServer(object):
The authentication process works as follows: The authentication process works as follows:
1) We get a username and password from the user 1) We get a username and password from the user
2) We use ClientLogin to obtain an AUTH token for the user 2) We use ClientLogin to obtain an AUTH token for the user
(see http://code.google.com/apis/accounts/AuthForInstalledApps.html). (see https://developers.google.com/identity/protocols/AuthForInstalledApps).
3) We pass the auth token to /_ah/login on the server to obtain an 3) We pass the auth token to /_ah/login on the server to obtain an
authentication cookie. If login was successful, it tries to redirect authentication cookie. If login was successful, it tries to redirect
us to the URL we provided. us to the URL we provided.
@ -506,7 +521,7 @@ def EncodeMultipartFormData(fields, files):
(content_type, body) ready for httplib.HTTP instance. (content_type, body) ready for httplib.HTTP instance.
Source: Source:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 https://web.archive.org/web/20160116052001/code.activestate.com/recipes/146306
""" """
BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-'
CRLF = '\r\n' CRLF = '\r\n'
@ -732,7 +747,7 @@ class SubversionVCS(VersionControlSystem):
else: else:
self.rev_start = self.rev_end = None self.rev_start = self.rev_end = None
# Cache output from "svn list -r REVNO dirname". # Cache output from "svn list -r REVNO dirname".
# Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). # Keys: dirname, Values: 2-tuple (output for start rev and end rev).
self.svnls_cache = {} self.svnls_cache = {}
# SVN base URL is required to fetch files deleted in an older revision. # SVN base URL is required to fetch files deleted in an older revision.
# Result is cached to not guess it over and over again in GetBaseFile(). # Result is cached to not guess it over and over again in GetBaseFile().
@ -807,7 +822,7 @@ class SubversionVCS(VersionControlSystem):
# svn cat translates keywords but svn diff doesn't. As a result of this # svn cat translates keywords but svn diff doesn't. As a result of this
# behavior patching.PatchChunks() fails with a chunk mismatch error. # behavior patching.PatchChunks() fails with a chunk mismatch error.
# This part was originally written by the Review Board development team # This part was originally written by the Review Board development team
# who had the same problem (http://reviews.review-board.org/r/276/). # who had the same problem (https://reviews.reviewboard.org/r/276/).
# Mapping of keywords to known aliases # Mapping of keywords to known aliases
svn_keywords = { svn_keywords = {
# Standard keywords # Standard keywords
@ -860,7 +875,7 @@ class SubversionVCS(VersionControlSystem):
status_lines = status.splitlines() status_lines = status.splitlines()
# If file is in a cl, the output will begin with # If file is in a cl, the output will begin with
# "\n--- Changelist 'cl_name':\n". See # "\n--- Changelist 'cl_name':\n". See
# http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt # https://web.archive.org/web/20090918234815/svn.collab.net/repos/svn/trunk/notes/changelist-design.txt
if (len(status_lines) == 3 and if (len(status_lines) == 3 and
not status_lines[0] and not status_lines[0] and
status_lines[1].startswith("--- Changelist")): status_lines[1].startswith("--- Changelist")):

View File

@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Author: mheule@google.com (Markus Heule) // Google C++ Testing and Mocking Framework (Google Test)
//
// Google C++ Testing Framework (Google Test)
// //
// Sometimes it's desirable to build Google Test by compiling a single file. // Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose. // This file serves this purpose.
@ -42,6 +41,7 @@
#include "src/gtest.cc" #include "src/gtest.cc"
#include "src/gtest-death-test.cc" #include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc" #include "src/gtest-filepath.cc"
#include "src/gtest-matchers.cc"
#include "src/gtest-port.cc" #include "src/gtest-port.cc"
#include "src/gtest-printers.cc" #include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc" #include "src/gtest-test-part.cc"

View File

@ -26,12 +26,15 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
// //
// This file implements death tests. // This file implements death tests.
#include "gtest/gtest-death-test.h" #include "gtest/gtest-death-test.h"
#include <functional>
#include <utility>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "gtest/internal/custom/gtest.h" #include "gtest/internal/custom/gtest.h"
@ -62,26 +65,36 @@
# include <spawn.h> # include <spawn.h>
# endif // GTEST_OS_QNX # endif // GTEST_OS_QNX
# if GTEST_OS_FUCHSIA
# include <lib/fdio/fd.h>
# include <lib/fdio/io.h>
# include <lib/fdio/spawn.h>
# include <lib/zx/channel.h>
# include <lib/zx/port.h>
# include <lib/zx/process.h>
# include <lib/zx/socket.h>
# include <zircon/processargs.h>
# include <zircon/syscalls.h>
# include <zircon/syscalls/policy.h>
# include <zircon/syscalls/port.h>
# endif // GTEST_OS_FUCHSIA
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick exists to
// prevent the accidental inclusion of gtest-internal-inl.h in the
// user's code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing { namespace testing {
// Constants. // Constants.
// The default death test style. // The default death test style.
static const char kDefaultDeathTestStyle[] = "fast"; //
// This is defined in internal/gtest-port.h as "fast", but can be overridden by
// a definition in internal/custom/gtest-port.h. The recommended value, which is
// used internally at Google, is "threadsafe".
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
death_test_style, death_test_style,
@ -110,8 +123,8 @@ GTEST_DEFINE_string_(
"Indicates the file, line number, temporal index of " "Indicates the file, line number, temporal index of "
"the single death test to run, and a file descriptor to " "the single death test to run, and a file descriptor to "
"which a success code may be sent, all separated by " "which a success code may be sent, all separated by "
"the '|' characters. This flag is specified if and only if the current " "the '|' characters. This flag is specified if and only if the "
"process is a sub-process launched for running a thread-safe " "current process is a sub-process launched for running a thread-safe "
"death test. FOR INTERNAL USE ONLY."); "death test. FOR INTERNAL USE ONLY.");
} // namespace internal } // namespace internal
@ -121,7 +134,7 @@ 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 # if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
static bool g_in_fast_death_test_child = false; static bool g_in_fast_death_test_child = false;
# endif # endif
@ -131,10 +144,10 @@ static bool g_in_fast_death_test_child = false;
// tests. IMPORTANT: This is an internal utility. Using it may break the // tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it. // implementation of death tests. User code MUST NOT use it.
bool InDeathTestChild() { bool InDeathTestChild() {
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
// On Windows, death tests are thread-safe regardless of the value of the // On Windows and Fuchsia, death tests are thread-safe regardless of the value
// death_test_style flag. // of the death_test_style flag.
return !GTEST_FLAG(internal_run_death_test).empty(); return !GTEST_FLAG(internal_run_death_test).empty();
# else # else
@ -154,7 +167,7 @@ ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
// ExitedWithCode function-call operator. // ExitedWithCode function-call operator.
bool ExitedWithCode::operator()(int exit_status) const { bool ExitedWithCode::operator()(int exit_status) const {
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
return exit_status == exit_code_; return exit_status == exit_code_;
@ -162,10 +175,10 @@ bool ExitedWithCode::operator()(int exit_status) const {
return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
} }
# if !GTEST_OS_WINDOWS # if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// KilledBySignal constructor. // KilledBySignal constructor.
KilledBySignal::KilledBySignal(int signum) : signum_(signum) { KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
} }
@ -182,7 +195,7 @@ bool KilledBySignal::operator()(int exit_status) const {
# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) # 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 && !GTEST_OS_FUCHSIA
namespace internal { namespace internal {
@ -193,7 +206,7 @@ namespace internal {
static std::string ExitSummary(int exit_code) { static std::string ExitSummary(int exit_code) {
Message m; Message m;
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
m << "Exited with exit status " << exit_code; m << "Exited with exit status " << exit_code;
@ -209,7 +222,7 @@ static std::string ExitSummary(int exit_code) {
m << " (core dumped)"; m << " (core dumped)";
} }
# endif # endif
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
return m.GetString(); return m.GetString();
} }
@ -220,7 +233,7 @@ bool ExitedUnsuccessfully(int exit_status) {
return !ExitedWithCode(0)(exit_status); return !ExitedWithCode(0)(exit_status);
} }
# if !GTEST_OS_WINDOWS # if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Generates a textual failure message when a death test finds more than // Generates a textual failure message when a death test finds more than
// one thread running, or cannot determine the number of threads, prior // one thread running, or cannot determine the number of threads, prior
// to executing the given statement. It is the responsibility of the // to executing the given statement. It is the responsibility of the
@ -229,13 +242,19 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
Message msg; Message msg;
msg << "Death tests use fork(), which is unsafe particularly" msg << "Death tests use fork(), which is unsafe particularly"
<< " in a threaded context. For this test, " << GTEST_NAME_ << " "; << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
if (thread_count == 0) if (thread_count == 0) {
msg << "couldn't detect the number of threads."; msg << "couldn't detect the number of threads.";
else } else {
msg << "detected " << thread_count << " threads."; msg << "detected " << thread_count << " threads.";
}
msg << " See "
"https://github.com/google/googletest/blob/master/docs/"
"advanced.md#death-tests-and-threads"
<< " for more explanation and suggested solutions, especially if"
<< " this is the last message you see before your test times out.";
return msg.GetString(); return msg.GetString();
} }
# endif // !GTEST_OS_WINDOWS # endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Flag characters for reporting a death test that did not die. // Flag characters for reporting a death test that did not die.
static const char kDeathTestLived = 'L'; static const char kDeathTestLived = 'L';
@ -243,6 +262,13 @@ static const char kDeathTestReturned = 'R';
static const char kDeathTestThrew = 'T'; static const char kDeathTestThrew = 'T';
static const char kDeathTestInternalError = 'I'; static const char kDeathTestInternalError = 'I';
#if GTEST_OS_FUCHSIA
// File descriptor used for the pipe in the child process.
static const int kFuchsiaReadPipeFd = 3;
#endif
// An enumeration describing all of the possible ways that a death test can // An enumeration describing all of the possible ways that a death test can
// conclude. DIED means that the process died while executing the test // conclude. DIED means that the process died while executing the test
// code; LIVED means that process lived beyond the end of the test code; // code; LIVED means that process lived beyond the end of the test code;
@ -250,8 +276,6 @@ static const char kDeathTestInternalError = 'I';
// statement, which is not allowed; THREW means that the test statement // statement, which is not allowed; THREW means that the test statement
// returned control by throwing an exception. IN_PROGRESS means the test // returned control by throwing an exception. IN_PROGRESS means the test
// has not yet concluded. // has not yet concluded.
// TODO(vladl@google.com): Unify names and possibly values for
// AbortReason, DeathTestOutcome, and flag characters above.
enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
// Routine for aborting the program which is safe to call from an // Routine for aborting the program which is safe to call from an
@ -259,13 +283,13 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
// message is propagated back to the parent process. Otherwise, the // message is propagated back to the parent process. Otherwise, the
// message is simply printed to stderr. In either case, the program // message is simply printed to stderr. In either case, the program
// then exits with status 1. // then exits with status 1.
void DeathTestAbort(const std::string& message) { static void DeathTestAbort(const std::string& message) {
// On a POSIX system, this function may be called from a threadsafe-style // On a POSIX system, this function may be called from a threadsafe-style
// death test child process, which operates on a very small stack. Use // death test child process, which operates on a very small stack. Use
// the heap for any additional non-minuscule memory requirements. // the heap for any additional non-minuscule memory requirements.
const InternalRunDeathTestFlag* const flag = const InternalRunDeathTestFlag* const flag =
GetUnitTestImpl()->internal_run_death_test_flag(); GetUnitTestImpl()->internal_run_death_test_flag();
if (flag != NULL) { if (flag != nullptr) {
FILE* parent = posix::FDOpen(flag->write_fd(), "w"); FILE* parent = posix::FDOpen(flag->write_fd(), "w");
fputc(kDeathTestInternalError, parent); fputc(kDeathTestInternalError, parent);
fprintf(parent, "%s", message.c_str()); fprintf(parent, "%s", message.c_str());
@ -345,7 +369,7 @@ static void FailFromInternalError(int fd) {
// for the current test. // for the current test.
DeathTest::DeathTest() { DeathTest::DeathTest() {
TestInfo* const info = GetUnitTestImpl()->current_test_info(); TestInfo* const info = GetUnitTestImpl()->current_test_info();
if (info == NULL) { if (info == nullptr) {
DeathTestAbort("Cannot run a death test outside of a TEST or " DeathTestAbort("Cannot run a death test outside of a TEST or "
"TEST_F construct"); "TEST_F construct");
} }
@ -353,10 +377,11 @@ DeathTest::DeathTest() {
// Creates and returns a death test by dispatching to the current // Creates and returns a death test by dispatching to the current
// death test factory. // death test factory.
bool DeathTest::Create(const char* statement, const RE* regex, bool DeathTest::Create(const char* statement,
const char* file, int line, DeathTest** test) { Matcher<const std::string&> matcher, const char* file,
int line, DeathTest** test) {
return GetUnitTestImpl()->death_test_factory()->Create( return GetUnitTestImpl()->death_test_factory()->Create(
statement, regex, file, line, test); statement, std::move(matcher), file, line, test);
} }
const char* DeathTest::LastMessage() { const char* DeathTest::LastMessage() {
@ -372,9 +397,9 @@ std::string DeathTest::last_death_test_message_;
// Provides cross platform implementation for some death functionality. // Provides cross platform implementation for some death functionality.
class DeathTestImpl : public DeathTest { class DeathTestImpl : public DeathTest {
protected: protected:
DeathTestImpl(const char* a_statement, const RE* a_regex) DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher)
: statement_(a_statement), : statement_(a_statement),
regex_(a_regex), matcher_(std::move(matcher)),
spawned_(false), spawned_(false),
status_(-1), status_(-1),
outcome_(IN_PROGRESS), outcome_(IN_PROGRESS),
@ -382,13 +407,12 @@ class DeathTestImpl : public DeathTest {
write_fd_(-1) {} write_fd_(-1) {}
// read_fd_ is expected to be closed and cleared by a derived class. // read_fd_ is expected to be closed and cleared by a derived class.
~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
void Abort(AbortReason reason); void Abort(AbortReason reason) override;
virtual bool Passed(bool status_ok); bool Passed(bool status_ok) override;
const char* statement() const { return statement_; } const char* statement() const { return statement_; }
const RE* regex() const { return regex_; }
bool spawned() const { return spawned_; } bool spawned() const { return spawned_; }
void set_spawned(bool is_spawned) { spawned_ = is_spawned; } void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
int status() const { return status_; } int status() const { return status_; }
@ -406,13 +430,15 @@ class DeathTestImpl : public DeathTest {
// case of unexpected codes. // case of unexpected codes.
void ReadAndInterpretStatusByte(); void ReadAndInterpretStatusByte();
// Returns stderr output from the child process.
virtual std::string GetErrorLogs();
private: private:
// The textual content of the code this object is testing. This class // The textual content of the code this object is testing. This class
// doesn't own this string and should not attempt to delete it. // doesn't own this string and should not attempt to delete it.
const char* const statement_; const char* const statement_;
// The regular expression which test output must match. DeathTestImpl // A matcher that's expected to match the stderr output by the child process.
// doesn't own this object and should not attempt to delete it. Matcher<const std::string&> matcher_;
const RE* const regex_;
// True if the death test child process has been successfully spawned. // True if the death test child process has been successfully spawned.
bool spawned_; bool spawned_;
// The exit status of the child process. // The exit status of the child process.
@ -474,6 +500,10 @@ void DeathTestImpl::ReadAndInterpretStatusByte() {
set_read_fd(-1); set_read_fd(-1);
} }
std::string DeathTestImpl::GetErrorLogs() {
return GetCapturedStderr();
}
// Signals that the death test code which should have exited, didn't. // Signals that the death test code which should have exited, didn't.
// Should be called only in a death test child process. // Should be called only in a death test child process.
// Writes a status byte to the child's status file descriptor, then // Writes a status byte to the child's status file descriptor, then
@ -527,22 +557,21 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) {
// in the format specified by wait(2). On Windows, this is the // in the format specified by wait(2). On Windows, this is the
// value supplied to the ExitProcess() API or a numeric code // value supplied to the ExitProcess() API or a numeric code
// of the exception that terminated the program. // of the exception that terminated the program.
// regex: A regular expression object to be applied to // matcher_: A matcher that's expected to match the stderr output by the child
// the test's captured standard error output; the death test // process.
// fails if it does not match.
// //
// Argument: // Argument:
// status_ok: true if exit_status is acceptable in the context of // status_ok: true if exit_status is acceptable in the context of
// this particular death test, which fails if it is false // this particular death test, which fails if it is false
// //
// Returns true iff all of the above conditions are met. Otherwise, the // Returns true if and only if all of the above conditions are met. Otherwise,
// first failing condition, in the order given above, is the one that is // the first failing condition, in the order given above, is the one that is
// reported. Also sets the last death test message string. // reported. Also sets the last death test message string.
bool DeathTestImpl::Passed(bool status_ok) { bool DeathTestImpl::Passed(bool status_ok) {
if (!spawned()) if (!spawned())
return false; return false;
const std::string error_message = GetCapturedStderr(); const std::string error_message = GetErrorLogs();
bool success = false; bool success = false;
Message buffer; Message buffer;
@ -563,13 +592,15 @@ bool DeathTestImpl::Passed(bool status_ok) {
break; break;
case DIED: case DIED:
if (status_ok) { if (status_ok) {
const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); if (matcher_.Matches(error_message)) {
if (matched) {
success = true; success = true;
} else { } else {
std::ostringstream stream;
matcher_.DescribeTo(&stream);
buffer << " Result: died but not with expected error.\n" buffer << " Result: died but not with expected error.\n"
<< " Expected: " << regex()->pattern() << "\n" << " Expected: " << stream.str() << "\n"
<< "Actual msg:\n" << FormatDeathTestOutput(error_message); << "Actual msg:\n"
<< FormatDeathTestOutput(error_message);
} }
} else { } else {
buffer << " Result: died but not with expected exit code:\n" buffer << " Result: died but not with expected exit code:\n"
@ -618,11 +649,11 @@ bool DeathTestImpl::Passed(bool status_ok) {
// //
class WindowsDeathTest : public DeathTestImpl { class WindowsDeathTest : public DeathTestImpl {
public: public:
WindowsDeathTest(const char* a_statement, WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
const RE* a_regex, const char* file, int line)
const char* file, : DeathTestImpl(a_statement, std::move(matcher)),
int line) file_(file),
: DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} line_(line) {}
// All of these virtual functions are inherited from DeathTest. // All of these virtual functions are inherited from DeathTest.
virtual int Wait(); virtual int Wait();
@ -699,7 +730,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
const TestInfo* const info = impl->current_test_info(); const TestInfo* const info = impl->current_test_info();
const int death_test_index = info->result()->death_test_count(); const int death_test_index = info->result()->death_test_count();
if (flag != NULL) { if (flag != nullptr) {
// ParseInternalRunDeathTestFlag() has performed all the necessary // ParseInternalRunDeathTestFlag() has performed all the necessary
// processing. // processing.
set_write_fd(flag->write_fd()); set_write_fd(flag->write_fd());
@ -708,8 +739,8 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
// WindowsDeathTest uses an anonymous pipe to communicate results of // WindowsDeathTest uses an anonymous pipe to communicate results of
// a death test. // a death test.
SECURITY_ATTRIBUTES handles_are_inheritable = { SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),
sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; nullptr, TRUE};
HANDLE read_handle, write_handle; HANDLE read_handle, write_handle;
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(
::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
@ -722,11 +753,11 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
&handles_are_inheritable, &handles_are_inheritable,
TRUE, // The event will automatically reset to non-signaled state. TRUE, // The event will automatically reset to non-signaled state.
FALSE, // The initial state is non-signalled. FALSE, // The initial state is non-signalled.
NULL)); // The even is unnamed. nullptr)); // The even is unnamed.
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
const std::string filter_flag = const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + kFilterFlag + "=" + info->test_suite_name() +
info->test_case_name() + "." + info->name(); "." + info->name();
const std::string internal_flag = const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
"=" + file_ + "|" + StreamableToString(line_) + "|" + "=" + file_ + "|" + StreamableToString(line_) + "|" +
@ -739,8 +770,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
"|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get())); "|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
char executable_path[_MAX_PATH + 1]; // NOLINT char executable_path[_MAX_PATH + 1]; // NOLINT
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
_MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
executable_path, executable_path,
_MAX_PATH)); _MAX_PATH));
@ -763,33 +793,288 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION process_info; PROCESS_INFORMATION process_info;
GTEST_DEATH_TEST_CHECK_(::CreateProcessA( GTEST_DEATH_TEST_CHECK_(
executable_path, ::CreateProcessA(
const_cast<char*>(command_line.c_str()), executable_path, const_cast<char*>(command_line.c_str()),
NULL, // Retuned process handle is not inheritable. nullptr, // Retuned process handle is not inheritable.
NULL, // Retuned thread handle is not inheritable. nullptr, // Retuned thread handle is not inheritable.
TRUE, // Child inherits all inheritable handles (for write_handle_). TRUE, // Child inherits all inheritable handles (for write_handle_).
0x0, // Default creation flags. 0x0, // Default creation flags.
NULL, // Inherit the parent's environment. nullptr, // Inherit the parent's environment.
UnitTest::GetInstance()->original_working_dir(), UnitTest::GetInstance()->original_working_dir(), &startup_info,
&startup_info,
&process_info) != FALSE); &process_info) != FALSE);
child_handle_.Reset(process_info.hProcess); child_handle_.Reset(process_info.hProcess);
::CloseHandle(process_info.hThread); ::CloseHandle(process_info.hThread);
set_spawned(true); set_spawned(true);
return OVERSEE_TEST; return OVERSEE_TEST;
} }
# else // We are not on Windows.
# elif GTEST_OS_FUCHSIA
class FuchsiaDeathTest : public DeathTestImpl {
public:
FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
const char* file, int line)
: DeathTestImpl(a_statement, std::move(matcher)),
file_(file),
line_(line) {}
// All of these virtual functions are inherited from DeathTest.
int Wait() override;
TestRole AssumeRole() override;
std::string GetErrorLogs() override;
private:
// The name of the file in which the death test is located.
const char* const file_;
// The line number on which the death test is located.
const int line_;
// The stderr data captured by the child process.
std::string captured_stderr_;
zx::process child_process_;
zx::channel exception_channel_;
zx::socket stderr_socket_;
};
// Utility class for accumulating command-line arguments.
class Arguments {
public:
Arguments() { args_.push_back(nullptr); }
~Arguments() {
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
++i) {
free(*i);
}
}
void AddArgument(const char* argument) {
args_.insert(args_.end() - 1, posix::StrDup(argument));
}
template <typename Str>
void AddArguments(const ::std::vector<Str>& arguments) {
for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
i != arguments.end();
++i) {
args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
}
}
char* const* Argv() {
return &args_[0];
}
int size() {
return static_cast<int>(args_.size()) - 1;
}
private:
std::vector<char*> args_;
};
// Waits for the child in a death test to exit, returning its exit
// status, or 0 if no child process exists. As a side effect, sets the
// outcome data member.
int FuchsiaDeathTest::Wait() {
const int kProcessKey = 0;
const int kSocketKey = 1;
const int kExceptionKey = 2;
if (!spawned())
return 0;
// Create a port to wait for socket/task/exception events.
zx_status_t status_zx;
zx::port port;
status_zx = zx::port::create(0, &port);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Register to wait for the child process to terminate.
status_zx = child_process_.wait_async(
port, kProcessKey, ZX_PROCESS_TERMINATED, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Register to wait for the socket to be readable or closed.
status_zx = stderr_socket_.wait_async(
port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Register to wait for an exception.
status_zx = exception_channel_.wait_async(
port, kExceptionKey, ZX_CHANNEL_READABLE, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
bool process_terminated = false;
bool socket_closed = false;
do {
zx_port_packet_t packet = {};
status_zx = port.wait(zx::time::infinite(), &packet);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
if (packet.key == kExceptionKey) {
// Process encountered an exception. Kill it directly rather than
// letting other handlers process the event. We will get a kProcessKey
// event when the process actually terminates.
status_zx = child_process_.kill();
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
} else if (packet.key == kProcessKey) {
// Process terminated.
GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);
process_terminated = true;
} else if (packet.key == kSocketKey) {
GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
if (packet.signal.observed & ZX_SOCKET_READABLE) {
// Read data from the socket.
constexpr size_t kBufferSize = 1024;
do {
size_t old_length = captured_stderr_.length();
size_t bytes_read = 0;
captured_stderr_.resize(old_length + kBufferSize);
status_zx = stderr_socket_.read(
0, &captured_stderr_.front() + old_length, kBufferSize,
&bytes_read);
captured_stderr_.resize(old_length + bytes_read);
} while (status_zx == ZX_OK);
if (status_zx == ZX_ERR_PEER_CLOSED) {
socket_closed = true;
} else {
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT);
status_zx = stderr_socket_.wait_async(
port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
}
} else {
GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED);
socket_closed = true;
}
}
} while (!process_terminated && !socket_closed);
ReadAndInterpretStatusByte();
zx_info_process_t buffer;
status_zx = child_process_.get_info(ZX_INFO_PROCESS, &buffer, sizeof(buffer),
nullptr, nullptr);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED);
set_status(static_cast<int>(buffer.return_code));
return status();
}
// The AssumeRole process for a Fuchsia death test. It creates a child
// process with the same executable as the current process to run the
// death test. The child process is given the --gtest_filter and
// --gtest_internal_run_death_test flags such that it knows to run the
// current death test only.
DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
const UnitTestImpl* const impl = GetUnitTestImpl();
const InternalRunDeathTestFlag* const flag =
impl->internal_run_death_test_flag();
const TestInfo* const info = impl->current_test_info();
const int death_test_index = info->result()->death_test_count();
if (flag != nullptr) {
// ParseInternalRunDeathTestFlag() has performed all the necessary
// processing.
set_write_fd(kFuchsiaReadPipeFd);
return EXECUTE_TEST;
}
// Flush the log buffers since the log streams are shared with the child.
FlushInfoLog();
// Build the child process command line.
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
kFilterFlag + "=" + info->test_suite_name() +
"." + info->name();
const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
+ file_ + "|"
+ StreamableToString(line_) + "|"
+ StreamableToString(death_test_index);
Arguments args;
args.AddArguments(GetInjectableArgvs());
args.AddArgument(filter_flag.c_str());
args.AddArgument(internal_flag.c_str());
// Build the pipe for communication with the child.
zx_status_t status;
zx_handle_t child_pipe_handle;
int child_pipe_fd;
status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
set_read_fd(child_pipe_fd);
// Set the pipe handle for the child.
fdio_spawn_action_t spawn_actions[2] = {};
fdio_spawn_action_t* add_handle_action = &spawn_actions[0];
add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;
add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd);
add_handle_action->h.handle = child_pipe_handle;
// Create a socket pair will be used to receive the child process' stderr.
zx::socket stderr_producer_socket;
status =
zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);
GTEST_DEATH_TEST_CHECK_(status >= 0);
int stderr_producer_fd = -1;
status =
fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd);
GTEST_DEATH_TEST_CHECK_(status >= 0);
// Make the stderr socket nonblocking.
GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0);
fdio_spawn_action_t* add_stderr_action = &spawn_actions[1];
add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD;
add_stderr_action->fd.local_fd = stderr_producer_fd;
add_stderr_action->fd.target_fd = STDERR_FILENO;
// Create a child job.
zx_handle_t child_job = ZX_HANDLE_INVALID;
status = zx_job_create(zx_job_default(), 0, & child_job);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
zx_policy_basic_t policy;
policy.condition = ZX_POL_NEW_ANY;
policy.policy = ZX_POL_ACTION_ALLOW;
status = zx_job_set_policy(
child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Create an exception channel attached to the |child_job|, to allow
// us to suppress the system default exception handler from firing.
status =
zx_task_create_exception_channel(
child_job, 0, exception_channel_.reset_and_get_address());
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Spawn the child process.
status = fdio_spawn_etc(
child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr,
2, spawn_actions, child_process_.reset_and_get_address(), nullptr);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
set_spawned(true);
return OVERSEE_TEST;
}
std::string FuchsiaDeathTest::GetErrorLogs() {
return captured_stderr_;
}
#else // We are neither on Windows, nor on Fuchsia.
// ForkingDeathTest provides implementations for most of the abstract // ForkingDeathTest provides implementations for most of the abstract
// methods of the DeathTest interface. Only the AssumeRole method is // methods of the DeathTest interface. Only the AssumeRole method is
// left undefined. // left undefined.
class ForkingDeathTest : public DeathTestImpl { class ForkingDeathTest : public DeathTestImpl {
public: public:
ForkingDeathTest(const char* statement, const RE* regex); ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher);
// All of these virtual functions are inherited from DeathTest. // All of these virtual functions are inherited from DeathTest.
virtual int Wait(); int Wait() override;
protected: protected:
void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
@ -800,9 +1085,9 @@ class ForkingDeathTest : public DeathTestImpl {
}; };
// Constructs a ForkingDeathTest. // Constructs a ForkingDeathTest.
ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) ForkingDeathTest::ForkingDeathTest(const char* a_statement,
: DeathTestImpl(a_statement, a_regex), Matcher<const std::string&> matcher)
child_pid_(-1) {} : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {}
// Waits for the child in a death test to exit, returning its exit // Waits for the child in a death test to exit, returning its exit
// status, or 0 if no child process exists. As a side effect, sets the // status, or 0 if no child process exists. As a side effect, sets the
@ -823,9 +1108,9 @@ int ForkingDeathTest::Wait() {
// in the child process. // in the child process.
class NoExecDeathTest : public ForkingDeathTest { class NoExecDeathTest : public ForkingDeathTest {
public: public:
NoExecDeathTest(const char* a_statement, const RE* a_regex) : NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher)
ForkingDeathTest(a_statement, a_regex) { } : ForkingDeathTest(a_statement, std::move(matcher)) {}
virtual TestRole AssumeRole(); TestRole AssumeRole() override;
}; };
// The AssumeRole process for a fork-and-run death test. It implements a // The AssumeRole process for a fork-and-run death test. It implements a
@ -878,16 +1163,18 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// only this specific death test to be run. // only this specific death test to be run.
class ExecDeathTest : public ForkingDeathTest { class ExecDeathTest : public ForkingDeathTest {
public: public:
ExecDeathTest(const char* a_statement, const RE* a_regex, ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
const char* file, int line) : const char* file, int line)
ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } : ForkingDeathTest(a_statement, std::move(matcher)),
virtual TestRole AssumeRole(); file_(file),
line_(line) {}
TestRole AssumeRole() override;
private: private:
static ::std::vector<testing::internal::string> static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {
GetArgvsForDeathTestChildProcess() { ::std::vector<std::string> args = GetInjectableArgvs();
::std::vector<testing::internal::string> args = GetInjectableArgvs();
# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) # if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
::std::vector<testing::internal::string> extra_args = ::std::vector<std::string> extra_args =
GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();
args.insert(args.end(), extra_args.begin(), extra_args.end()); args.insert(args.end(), extra_args.begin(), extra_args.end());
# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) # endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
@ -902,9 +1189,7 @@ class ExecDeathTest : public ForkingDeathTest {
// Utility class for accumulating command-line arguments. // Utility class for accumulating command-line arguments.
class Arguments { class Arguments {
public: public:
Arguments() { Arguments() { args_.push_back(nullptr); }
args_.push_back(NULL);
}
~Arguments() { ~Arguments() {
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
@ -939,21 +1224,9 @@ struct ExecDeathTestArgs {
int close_fd; // File descriptor to close; the read end of a pipe int close_fd; // File descriptor to close; the read end of a pipe
}; };
# if GTEST_OS_MAC # if GTEST_OS_QNX
inline char** GetEnviron() {
// When Google Test is built as a framework on MacOS X, the environ variable
// is unavailable. Apple's documentation (man environ) recommends using
// _NSGetEnviron() instead.
return *_NSGetEnviron();
}
# else
// Some POSIX platforms expect you to declare environ. extern "C" makes
// it reside in the global namespace.
extern "C" char** environ; extern "C" char** environ;
inline char** GetEnviron() { return environ; } # else // GTEST_OS_QNX
# endif // GTEST_OS_MAC
# if !GTEST_OS_QNX
// The main function for a threadsafe-style death test child process. // The main function for a threadsafe-style death test child process.
// This function is called in a clone()-ed process and thus must avoid // This function is called in a clone()-ed process and thus must avoid
// any potentially unsafe operations like malloc or libc functions. // any potentially unsafe operations like malloc or libc functions.
@ -973,19 +1246,20 @@ static int ExecDeathTestChildMain(void* child_arg) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// We can safely call execve() as it's a direct system call. We // We can safely call execv() as it's almost a direct system call. We
// cannot use execvp() as it's a libc function and thus potentially // cannot use execvp() as it's a libc function and thus potentially
// unsafe. Since execve() doesn't search the PATH, the user must // unsafe. Since execv() doesn't search the PATH, the user must
// invoke the test program via a valid path that contains at least // invoke the test program via a valid path that contains at least
// one path separator. // one path separator.
execve(args->argv[0], args->argv, GetEnviron()); execv(args->argv[0], args->argv);
DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " +
original_dir + " failed: " + original_dir + " failed: " +
GetLastErrnoDescription()); GetLastErrnoDescription());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
# endif // !GTEST_OS_QNX # endif // GTEST_OS_QNX
# if GTEST_HAS_CLONE
// Two utility routines that together determine the direction the stack // Two utility routines that together determine the direction the stack
// grows. // grows.
// This could be accomplished more elegantly by a single recursive // This could be accomplished more elegantly by a single recursive
@ -995,20 +1269,31 @@ static int ExecDeathTestChildMain(void* child_arg) {
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
// StackLowerThanAddress into StackGrowsDown, which then doesn't give // StackLowerThanAddress into StackGrowsDown, which then doesn't give
// correct answer. // correct answer.
void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; static void StackLowerThanAddress(const void* ptr,
void StackLowerThanAddress(const void* ptr, bool* result) { bool* result) GTEST_NO_INLINE_;
int dummy; // Make sure sanitizers do not tamper with the stack here.
*result = (&dummy < ptr); // Ideally, we want to use `__builtin_frame_address` instead of a local variable
// address with sanitizer disabled, but it does not work when the
// compiler optimizes the stack frame out, which happens on PowerPC targets.
// HWAddressSanitizer add a random tag to the MSB of the local variable address,
// making comparison result unpredictable.
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
static void StackLowerThanAddress(const void* ptr, bool* result) {
int dummy = 0;
*result = std::less<const void*>()(&dummy, ptr);
} }
// Make sure AddressSanitizer does not tamper with the stack here. // Make sure AddressSanitizer does not tamper with the stack here.
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
bool StackGrowsDown() { GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
int dummy; static bool StackGrowsDown() {
int dummy = 0;
bool result; bool result;
StackLowerThanAddress(&dummy, &result); StackLowerThanAddress(&dummy, &result);
return result; return result;
} }
# endif // GTEST_HAS_CLONE
// Spawns a child process with the same executable as the current process in // Spawns a child process with the same executable as the current process in
// a thread-safe manner and instructs it to run the death test. The // a thread-safe manner and instructs it to run the death test. The
@ -1046,7 +1331,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
fd_flags | FD_CLOEXEC)); fd_flags | FD_CLOEXEC));
struct inheritance inherit = {0}; struct inheritance inherit = {0};
// spawn is a system call. // spawn is a system call.
child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ);
// Restores the current working directory. // Restores the current working directory.
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
@ -1070,9 +1355,9 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
if (!use_fork) { if (!use_fork) {
static const bool stack_grows_down = StackGrowsDown(); static const bool stack_grows_down = StackGrowsDown();
const size_t stack_size = getpagesize(); const auto stack_size = static_cast<size_t>(getpagesize() * 2);
// MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0); MAP_ANON | MAP_PRIVATE, -1, 0);
GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
@ -1086,8 +1371,9 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
void* const stack_top = void* const stack_top =
static_cast<char*>(stack) + static_cast<char*>(stack) +
(stack_grows_down ? stack_size - kMaxStackAlignment : 0); (stack_grows_down ? stack_size - kMaxStackAlignment : 0);
GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && GTEST_DEATH_TEST_CHECK_(
reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0); static_cast<size_t>(stack_size) > kMaxStackAlignment &&
reinterpret_cast<uintptr_t>(stack_top) % kMaxStackAlignment == 0);
child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
@ -1104,7 +1390,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
# endif // GTEST_OS_QNX # endif // GTEST_OS_QNX
# if GTEST_OS_LINUX # if GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_SYSCALL_( GTEST_DEATH_TEST_CHECK_SYSCALL_(
sigaction(SIGPROF, &saved_sigprof_action, NULL)); sigaction(SIGPROF, &saved_sigprof_action, nullptr));
# endif // GTEST_OS_LINUX # endif // GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_(child_pid != -1); GTEST_DEATH_TEST_CHECK_(child_pid != -1);
@ -1122,7 +1408,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
const TestInfo* const info = impl->current_test_info(); const TestInfo* const info = impl->current_test_info();
const int death_test_index = info->result()->death_test_count(); const int death_test_index = info->result()->death_test_count();
if (flag != NULL) { if (flag != nullptr) {
set_write_fd(flag->write_fd()); set_write_fd(flag->write_fd());
return EXECUTE_TEST; return EXECUTE_TEST;
} }
@ -1133,9 +1419,9 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// it be closed when the child process does an exec: // it be closed when the child process does an exec:
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
const std::string filter_flag = const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" kFilterFlag + "=" + info->test_suite_name() +
+ info->test_case_name() + "." + info->name(); "." + info->name();
const std::string internal_flag = const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
+ file_ + "|" + StreamableToString(line_) + "|" + file_ + "|" + StreamableToString(line_) + "|"
@ -1168,7 +1454,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// by the "test" argument to its address. If the test should be // by the "test" argument to its address. If the test should be
// skipped, sets that pointer to NULL. Returns true, unless the // skipped, sets that pointer to NULL. Returns true, unless the
// flag is set to an invalid value. // flag is set to an invalid value.
bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, bool DefaultDeathTestFactory::Create(const char* statement,
Matcher<const std::string&> matcher,
const char* file, int line, const char* file, int line,
DeathTest** test) { DeathTest** test) {
UnitTestImpl* const impl = GetUnitTestImpl(); UnitTestImpl* const impl = GetUnitTestImpl();
@ -1177,7 +1464,7 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
const int death_test_index = impl->current_test_info() const int death_test_index = impl->current_test_info()
->increment_death_test_count(); ->increment_death_test_count();
if (flag != NULL) { if (flag != nullptr) {
if (death_test_index > flag->index()) { if (death_test_index > flag->index()) {
DeathTest::set_last_death_test_message( DeathTest::set_last_death_test_message(
"Death test count (" + StreamableToString(death_test_index) "Death test count (" + StreamableToString(death_test_index)
@ -1188,7 +1475,7 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
if (!(flag->file() == file && flag->line() == line && if (!(flag->file() == file && flag->line() == line &&
flag->index() == death_test_index)) { flag->index() == death_test_index)) {
*test = NULL; *test = nullptr;
return true; return true;
} }
} }
@ -1197,15 +1484,22 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
if (GTEST_FLAG(death_test_style) == "threadsafe" || if (GTEST_FLAG(death_test_style) == "threadsafe" ||
GTEST_FLAG(death_test_style) == "fast") { GTEST_FLAG(death_test_style) == "fast") {
*test = new WindowsDeathTest(statement, regex, file, line); *test = new WindowsDeathTest(statement, std::move(matcher), file, line);
}
# elif GTEST_OS_FUCHSIA
if (GTEST_FLAG(death_test_style) == "threadsafe" ||
GTEST_FLAG(death_test_style) == "fast") {
*test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
} }
# else # else
if (GTEST_FLAG(death_test_style) == "threadsafe") { if (GTEST_FLAG(death_test_style) == "threadsafe") {
*test = new ExecDeathTest(statement, regex, file, line); *test = new ExecDeathTest(statement, std::move(matcher), file, line);
} else if (GTEST_FLAG(death_test_style) == "fast") { } else if (GTEST_FLAG(death_test_style) == "fast") {
*test = new NoExecDeathTest(statement, regex); *test = new NoExecDeathTest(statement, std::move(matcher));
} }
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
@ -1224,7 +1518,7 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
// 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
// handle. This function is called in the child process only. // handle. This function is called in the child process only.
int GetStatusFileDescriptor(unsigned int parent_process_id, static int GetStatusFileDescriptor(unsigned int parent_process_id,
size_t write_handle_as_size_t, size_t write_handle_as_size_t,
size_t event_handle_as_size_t) { size_t event_handle_as_size_t) {
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
@ -1235,15 +1529,13 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
StreamableToString(parent_process_id)); StreamableToString(parent_process_id));
} }
// TODO(vladl@google.com): Replace the following check with a
// compile-time assertion when available.
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
const HANDLE write_handle = const HANDLE write_handle =
reinterpret_cast<HANDLE>(write_handle_as_size_t); reinterpret_cast<HANDLE>(write_handle_as_size_t);
HANDLE dup_write_handle; HANDLE dup_write_handle;
// The newly initialized handle is accessible only in in the parent // The newly initialized handle is accessible only in the parent
// process. To obtain one accessible within the child, we need to use // process. To obtain one accessible within the child, we need to use
// DuplicateHandle. // DuplicateHandle.
if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
@ -1292,7 +1584,7 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
// initialized from the GTEST_FLAG(internal_run_death_test) flag if // initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL. // the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
if (GTEST_FLAG(internal_run_death_test) == "") return NULL; if (GTEST_FLAG(internal_run_death_test) == "") return nullptr;
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
// can use it here. // can use it here.
@ -1320,6 +1612,16 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
write_fd = GetStatusFileDescriptor(parent_process_id, write_fd = GetStatusFileDescriptor(parent_process_id,
write_handle_as_size_t, write_handle_as_size_t,
event_handle_as_size_t); event_handle_as_size_t);
# elif GTEST_OS_FUCHSIA
if (fields.size() != 3
|| !ParseNaturalNumber(fields[1], &line)
|| !ParseNaturalNumber(fields[2], &index)) {
DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
+ GTEST_FLAG(internal_run_death_test));
}
# else # else
if (fields.size() != 4 if (fields.size() != 4

View File

@ -26,28 +26,25 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: keith.ray@gmail.com (Keith Ray)
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h"
#include <stdlib.h> #include <stdlib.h>
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-message.h"
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
# include <windows.h> # include <windows.h>
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
# include <direct.h> # include <direct.h>
# include <io.h> # include <io.h>
#elif GTEST_OS_SYMBIAN
// Symbian OpenC has PATH_MAX in sys/syslimits.h
# include <sys/syslimits.h>
#else #else
# include <limits.h> # include <limits.h>
# include <climits> // Some Linux distributions define PATH_MAX here. # include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
#include "gtest/internal/gtest-string.h"
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# define GTEST_PATH_MAX_ _MAX_PATH # define GTEST_PATH_MAX_ _MAX_PATH
#elif defined(PATH_MAX) #elif defined(PATH_MAX)
@ -58,8 +55,6 @@
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX # define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include "gtest/internal/gtest-string.h"
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -97,13 +92,15 @@ static bool IsPathSeparator(char c) {
// Returns the current working directory, or "" if unsuccessful. // Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() { FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
// Windows CE doesn't have a current directory, so we just return GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \
GTEST_OS_XTENSA
// These platforms do not have a current directory, so we just return
// something reasonable. // something reasonable.
return FilePath(kCurrentDirectoryString); return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
#else #else
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
char* result = getcwd(cwd, sizeof(cwd)); char* result = getcwd(cwd, sizeof(cwd));
@ -111,9 +108,9 @@ FilePath FilePath::GetCurrentDir() {
// getcwd will likely fail in NaCl due to the sandbox, so return something // getcwd will likely fail in NaCl due to the sandbox, so return something
// reasonable. The user may have provided a shim implementation for getcwd, // reasonable. The user may have provided a shim implementation for getcwd,
// however, so fallback only when failure is detected. // however, so fallback only when failure is detected.
return FilePath(result == NULL ? kCurrentDirectoryString : cwd); return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
# endif // GTEST_OS_NACL # endif // GTEST_OS_NACL
return FilePath(result == NULL ? "" : cwd); return FilePath(result == nullptr ? "" : cwd);
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
} }
@ -130,7 +127,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
return *this; return *this;
} }
// Returns a pointer to the last occurence of a valid path separator in // Returns a pointer to the last occurrence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path // the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found. // separators. Returns NULL if no path separator was found.
const char* FilePath::FindLastPathSeparator() const { const char* FilePath::FindLastPathSeparator() const {
@ -138,8 +135,8 @@ const char* FilePath::FindLastPathSeparator() const {
#if GTEST_HAS_ALT_PATH_SEP_ #if GTEST_HAS_ALT_PATH_SEP_
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
// Comparing two pointers of which only one is NULL is undefined. // Comparing two pointers of which only one is NULL is undefined.
if (last_alt_sep != NULL && if (last_alt_sep != nullptr &&
(last_sep == NULL || last_alt_sep > last_sep)) { (last_sep == nullptr || last_alt_sep > last_sep)) {
return last_alt_sep; return last_alt_sep;
} }
#endif #endif
@ -167,7 +164,7 @@ FilePath FilePath::RemoveFileName() const {
const char* const last_sep = FindLastPathSeparator(); const char* const last_sep = FindLastPathSeparator();
std::string dir; std::string dir;
if (last_sep) { if (last_sep) {
dir = std::string(c_str(), last_sep + 1 - c_str()); dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));
} else { } else {
dir = kCurrentDirectoryString; dir = kCurrentDirectoryString;
} }
@ -213,7 +210,7 @@ bool FilePath::FileOrDirectoryExists() const {
delete [] unicode; delete [] unicode;
return attributes != kInvalidFileAttributes; return attributes != kInvalidFileAttributes;
#else #else
posix::StatStruct file_stat; posix::StatStruct file_stat{};
return posix::Stat(pathname_.c_str(), &file_stat) == 0; return posix::Stat(pathname_.c_str(), &file_stat) == 0;
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
} }
@ -240,7 +237,7 @@ bool FilePath::DirectoryExists() const {
result = true; result = true;
} }
#else #else
posix::StatStruct file_stat; posix::StatStruct file_stat{};
result = posix::Stat(path.c_str(), &file_stat) == 0 && result = posix::Stat(path.c_str(), &file_stat) == 0 &&
posix::IsDir(file_stat); posix::IsDir(file_stat);
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
@ -252,9 +249,6 @@ bool FilePath::DirectoryExists() const {
// root directory per disk drive.) // root directory per disk drive.)
bool FilePath::IsRootDirectory() const { bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// TODO(wan@google.com): on Windows a network share like
// \\server\share can be a root directory, although it cannot be the
// current directory. Handle this properly.
return pathname_.length() == 3 && IsAbsolutePath(); return pathname_.length() == 3 && IsAbsolutePath();
#else #else
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
@ -326,10 +320,13 @@ bool FilePath::CreateFolder() const {
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
FilePath removed_sep(this->RemoveTrailingPathSeparator()); FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
int result = CreateDirectory(unicode, NULL) ? 0 : -1; int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
delete [] unicode; delete [] unicode;
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str()); int result = _mkdir(pathname_.c_str());
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA
// do nothing
int result = 0;
#else #else
int result = mkdir(pathname_.c_str(), 0777); int result = mkdir(pathname_.c_str(), 0777);
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
@ -352,35 +349,20 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {
// Removes any redundant separators that might be in the pathname. // Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..". // redundancies that might be in a pathname involving "." or "..".
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() { void FilePath::Normalize() {
if (pathname_.c_str() == NULL) { auto out = pathname_.begin();
pathname_ = "";
return;
}
const char* src = pathname_.c_str();
char* const dest = new char[pathname_.length() + 1];
char* dest_ptr = dest;
memset(dest_ptr, 0, pathname_.length() + 1);
while (*src != '\0') { for (const char character : pathname_) {
*dest_ptr = *src; if (!IsPathSeparator(character)) {
if (!IsPathSeparator(*src)) { *(out++) = character;
src++; } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
*(out++) = kPathSeparator;
} else { } else {
#if GTEST_HAS_ALT_PATH_SEP_ continue;
if (*dest_ptr == kAlternatePathSeparator) {
*dest_ptr = kPathSeparator;
} }
#endif
while (IsPathSeparator(*src))
src++;
} }
dest_ptr++;
} pathname_.erase(out, pathname_.end());
*dest_ptr = '\0';
pathname_ = dest;
delete[] dest;
} }
} // namespace internal } // namespace internal

View File

@ -27,23 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Utility functions and classes used by the Google C++ testing framework. // Utility functions and classes used by the Google C++ testing framework.//
//
// Author: wan@google.com (Zhanyong Wan)
//
// This file contains purely Google Test's internal implementation. Please // This file contains purely Google Test's internal implementation. Please
// DO NOT #INCLUDE IT IN A USER PROGRAM. // DO NOT #INCLUDE IT IN A USER PROGRAM.
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
#define GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
// part of Google Test's implementation; otherwise it's undefined.
#if !GTEST_IMPLEMENTATION_
// If this file is included from the user's code, just say no.
# error "gtest-internal-inl.h is part of Google Test's internal implementation."
# error "It must not be included except by Google Test itself."
#endif // GTEST_IMPLEMENTATION_
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
# include <errno.h> # include <errno.h>
@ -53,6 +42,8 @@
#include <string.h> // For memmove. #include <string.h> // For memmove.
#include <algorithm> #include <algorithm>
#include <cstdint>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -67,9 +58,12 @@
# include <windows.h> // NOLINT # include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include "gtest/gtest.h" // NOLINT #include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing { namespace testing {
// Declares the flags. // Declares the flags.
@ -90,10 +84,13 @@ const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure"; const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color"; const char kColorFlag[] = "color";
const char kFailFast[] = "fail_fast";
const char kFilterFlag[] = "filter"; const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests"; const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output"; const char kOutputFlag[] = "output";
const char kBriefFlag[] = "brief";
const char kPrintTimeFlag[] = "print_time"; const char kPrintTimeFlag[] = "print_time";
const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed"; const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat"; const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle"; const char kShuffleFlag[] = "shuffle";
@ -105,14 +102,14 @@ 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;
// g_help_flag is true iff the --help flag or an equivalent form is // g_help_flag is true if and only if the --help flag or an equivalent form
// specified on the command line. // is specified on the command line.
GTEST_API_ extern bool g_help_flag; GTEST_API_ extern bool g_help_flag;
// Returns the current time in milliseconds. // Returns the current time in milliseconds.
GTEST_API_ TimeInMillis GetTimeInMillis(); GTEST_API_ TimeInMillis GetTimeInMillis();
// Returns true iff Google Test should use colors in the output. // Returns true if and only if Google Test should use colors in the output.
GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
// Formats the given time in milliseconds as seconds. // Formats the given time in milliseconds as seconds.
@ -129,11 +126,11 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
// On success, stores the value of the flag in *value, and returns // On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value. // true. On failure, returns false without changing *value.
GTEST_API_ bool ParseInt32Flag( GTEST_API_ bool ParseInt32Flag(
const char* str, const char* flag, Int32* value); const char* str, const char* flag, int32_t* value);
// Returns a random seed in range [1, kMaxRandomSeed] based on the // Returns a random seed in range [1, kMaxRandomSeed] based on the
// given --gtest_random_seed flag value. // given --gtest_random_seed flag value.
inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { inline int GetRandomSeedFromFlag(int32_t random_seed_flag) {
const unsigned int raw_seed = (random_seed_flag == 0) ? const unsigned int raw_seed = (random_seed_flag == 0) ?
static_cast<unsigned int>(GetTimeInMillis()) : static_cast<unsigned int>(GetTimeInMillis()) :
static_cast<unsigned int>(random_seed_flag); static_cast<unsigned int>(random_seed_flag);
@ -169,11 +166,14 @@ class GTestFlagSaver {
color_ = GTEST_FLAG(color); color_ = GTEST_FLAG(color);
death_test_style_ = GTEST_FLAG(death_test_style); death_test_style_ = GTEST_FLAG(death_test_style);
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
fail_fast_ = GTEST_FLAG(fail_fast);
filter_ = GTEST_FLAG(filter); filter_ = GTEST_FLAG(filter);
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
list_tests_ = GTEST_FLAG(list_tests); list_tests_ = GTEST_FLAG(list_tests);
output_ = GTEST_FLAG(output); output_ = GTEST_FLAG(output);
brief_ = GTEST_FLAG(brief);
print_time_ = GTEST_FLAG(print_time); print_time_ = GTEST_FLAG(print_time);
print_utf8_ = GTEST_FLAG(print_utf8);
random_seed_ = GTEST_FLAG(random_seed); random_seed_ = GTEST_FLAG(random_seed);
repeat_ = GTEST_FLAG(repeat); repeat_ = GTEST_FLAG(repeat);
shuffle_ = GTEST_FLAG(shuffle); shuffle_ = GTEST_FLAG(shuffle);
@ -191,10 +191,13 @@ class GTestFlagSaver {
GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_style) = death_test_style_;
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
GTEST_FLAG(filter) = filter_; GTEST_FLAG(filter) = filter_;
GTEST_FLAG(fail_fast) = fail_fast_;
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_; GTEST_FLAG(output) = output_;
GTEST_FLAG(brief) = brief_;
GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(print_time) = print_time_;
GTEST_FLAG(print_utf8) = print_utf8_;
GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(random_seed) = random_seed_;
GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(repeat) = repeat_;
GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(shuffle) = shuffle_;
@ -211,15 +214,18 @@ class GTestFlagSaver {
std::string color_; std::string color_;
std::string death_test_style_; std::string death_test_style_;
bool death_test_use_fork_; bool death_test_use_fork_;
bool fail_fast_;
std::string filter_; std::string filter_;
std::string internal_run_death_test_; std::string internal_run_death_test_;
bool list_tests_; bool list_tests_;
std::string output_; std::string output_;
bool brief_;
bool print_time_; bool print_time_;
internal::Int32 random_seed_; bool print_utf8_;
internal::Int32 repeat_; int32_t random_seed_;
int32_t repeat_;
bool shuffle_; bool shuffle_;
internal::Int32 stack_trace_depth_; int32_t stack_trace_depth_;
std::string stream_result_to_; std::string stream_result_to_;
bool throw_on_failure_; bool throw_on_failure_;
} GTEST_ATTRIBUTE_UNUSED_; } GTEST_ATTRIBUTE_UNUSED_;
@ -230,11 +236,11 @@ class GTestFlagSaver {
// If the code_point is not a valid Unicode code point // If the code_point is not a valid Unicode code point
// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted
// to "(Invalid Unicode 0xXXXXXXXX)". // to "(Invalid Unicode 0xXXXXXXXX)".
GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); GTEST_API_ std::string CodePointToUtf8(uint32_t code_point);
// Converts a wide string to a narrow string in UTF-8 encoding. // Converts a wide string to a narrow string in UTF-8 encoding.
// The wide string is assumed to have the following encoding: // The wide string is assumed to have the following encoding:
// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
// UTF-32 if sizeof(wchar_t) == 4 (on Linux) // UTF-32 if sizeof(wchar_t) == 4 (on Linux)
// Parameter str points to a null-terminated wide string. // Parameter str points to a null-terminated wide string.
// Parameter num_chars may additionally limit the number // Parameter num_chars may additionally limit the number
@ -263,14 +269,14 @@ GTEST_API_ bool ShouldShard(const char* total_shards_str,
const char* shard_index_str, const char* shard_index_str,
bool in_subprocess_for_death_test); bool in_subprocess_for_death_test);
// Parses the environment variable var as an Int32. If it is unset, // Parses the environment variable var as a 32-bit integer. If it is unset,
// returns default_val. If it is not an Int32, prints an error and // returns default_val. If it is not a 32-bit integer, prints an error and
// and aborts. // and aborts.
GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val);
// Given the total number of shards, the shard index, and the test id, // Given the total number of shards, the shard index, and the test id,
// returns true iff the test should be run on this shard. The test id is // returns true if and only if the test should be run on this shard. The test id
// some arbitrary but unique non-negative integer assigned to each test // is some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards. // method. Assumes that 0 <= shard_index < total_shards.
GTEST_API_ bool ShouldRunTestOnShard( GTEST_API_ bool ShouldRunTestOnShard(
int total_shards, int shard_index, int test_id); int total_shards, int shard_index, int test_id);
@ -301,7 +307,8 @@ void ForEach(const Container& c, Functor functor) {
// in range [0, v.size()). // in range [0, v.size()).
template <typename E> template <typename E>
inline E GetElementOr(const std::vector<E>& v, int i, E default_value) { inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i]; return (i < 0 || i >= static_cast<int>(v.size())) ? default_value
: v[static_cast<size_t>(i)];
} }
// Performs an in-place shuffle of a range of the vector's elements. // Performs an in-place shuffle of a range of the vector's elements.
@ -323,8 +330,11 @@ void ShuffleRange(internal::Random* random, int begin, int end,
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
for (int range_width = end - begin; range_width >= 2; range_width--) { for (int range_width = end - begin; range_width >= 2; range_width--) {
const int last_in_range = begin + range_width - 1; const int last_in_range = begin + range_width - 1;
const int selected = begin + random->Generate(range_width); const int selected =
std::swap((*v)[selected], (*v)[last_in_range]); begin +
static_cast<int>(random->Generate(static_cast<uint32_t>(range_width)));
std::swap((*v)[static_cast<size_t>(selected)],
(*v)[static_cast<size_t>(last_in_range)]);
} }
} }
@ -351,7 +361,7 @@ class TestPropertyKeyIs {
// TestPropertyKeyIs has NO default constructor. // TestPropertyKeyIs has NO default constructor.
explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}
// Returns true iff the test name of test property matches on key_. // Returns true if and only if the test name of test property matches on key_.
bool operator()(const TestProperty& test_property) const { bool operator()(const TestProperty& test_property) const {
return test_property.key() == key_; return test_property.key() == key_;
} }
@ -384,17 +394,10 @@ class GTEST_API_ UnitTestOptions {
// Functions for processing the gtest_filter flag. // Functions for processing the gtest_filter flag.
// Returns true iff the wildcard pattern matches the string. The // Returns true if and only if the user-specified filter matches the test
// first ':' or '\0' character in pattern marks the end of it. // suite name and the test name.
// static bool FilterMatchesTest(const std::string& test_suite_name,
// This recursive algorithm isn't very efficient, but is clear and const std::string& test_name);
// works well enough for matching test names, which are short.
static bool PatternMatchesString(const char *pattern, const char *str);
// Returns true iff the user-specified filter matches the test case
// name and the test name.
static bool FilterMatchesTest(const std::string &test_case_name,
const std::string &test_name);
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// Function for supporting the gtest_catch_exception flag. // Function for supporting the gtest_catch_exception flag.
@ -426,7 +429,7 @@ class OsStackTraceGetterInterface {
// in the trace. // in the trace.
// skip_count - the number of top frames to be skipped; doesn't count // skip_count - the number of top frames to be skipped; doesn't count
// against max_depth. // against max_depth.
virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0;
// UponLeavingGTest() should be called immediately before Google Test calls // UponLeavingGTest() should be called immediately before Google Test calls
// user code. It saves some information about the current stack that // user code. It saves some information about the current stack that
@ -446,10 +449,20 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface {
public: public:
OsStackTraceGetter() {} OsStackTraceGetter() {}
virtual string CurrentStackTrace(int max_depth, int skip_count); std::string CurrentStackTrace(int max_depth, int skip_count) override;
virtual void UponLeavingGTest(); void UponLeavingGTest() override;
private: private:
#if GTEST_HAS_ABSL
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 the stack trace code from within the user code.
void* caller_frame_ = nullptr;
#endif // GTEST_HAS_ABSL
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
}; };
@ -468,7 +481,7 @@ class DefaultGlobalTestPartResultReporter
explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
// Implements the TestPartResultReporterInterface. Reports the test part // Implements the TestPartResultReporterInterface. Reports the test part
// result in the current test. // result in the current test.
virtual void ReportTestPartResult(const TestPartResult& result); void ReportTestPartResult(const TestPartResult& result) override;
private: private:
UnitTestImpl* const unit_test_; UnitTestImpl* const unit_test_;
@ -484,7 +497,7 @@ class DefaultPerThreadTestPartResultReporter
explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
// Implements the TestPartResultReporterInterface. The implementation just // Implements the TestPartResultReporterInterface. The implementation just
// delegates to the current global test part result reporter of *unit_test_. // delegates to the current global test part result reporter of *unit_test_.
virtual void ReportTestPartResult(const TestPartResult& result); void ReportTestPartResult(const TestPartResult& result) override;
private: private:
UnitTestImpl* const unit_test_; UnitTestImpl* const unit_test_;
@ -522,22 +535,25 @@ class GTEST_API_ UnitTestImpl {
void SetTestPartResultReporterForCurrentThread( void SetTestPartResultReporterForCurrentThread(
TestPartResultReporterInterface* reporter); TestPartResultReporterInterface* reporter);
// Gets the number of successful test cases. // Gets the number of successful test suites.
int successful_test_case_count() const; int successful_test_suite_count() const;
// Gets the number of failed test cases. // Gets the number of failed test suites.
int failed_test_case_count() const; int failed_test_suite_count() const;
// Gets the number of all test cases. // Gets the number of all test suites.
int total_test_case_count() const; int total_test_suite_count() const;
// Gets the number of all test cases that contain at least one test // Gets the number of all test suites that contain at least one test
// that should run. // that should run.
int test_case_to_run_count() const; int test_suite_to_run_count() const;
// Gets the number of successful tests. // Gets the number of successful tests.
int successful_test_count() const; int successful_test_count() const;
// Gets the number of skipped tests.
int skipped_test_count() const;
// Gets the number of failed tests. // Gets the number of failed tests.
int failed_test_count() const; int failed_test_count() const;
@ -563,27 +579,33 @@ class GTEST_API_ UnitTestImpl {
// Gets the elapsed time, in milliseconds. // Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; } TimeInMillis elapsed_time() const { return elapsed_time_; }
// Returns true iff the unit test passed (i.e. all test cases passed). // Returns true if and only if the unit test passed (i.e. all test suites
// passed).
bool Passed() const { return !Failed(); } bool Passed() const { return !Failed(); }
// Returns true iff the unit test failed (i.e. some test case failed // Returns true if and only if the unit test failed (i.e. some test suite
// or something outside of all tests failed). // failed or something outside of all tests failed).
bool Failed() const { bool Failed() const {
return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed();
} }
// Gets the i-th test case among all the test cases. i can range from 0 to // Gets the i-th test suite among all the test suites. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL. // total_test_suite_count() - 1. If i is not in that range, returns NULL.
const TestCase* GetTestCase(int i) const { const TestSuite* GetTestSuite(int i) const {
const int index = GetElementOr(test_case_indices_, i, -1); const int index = GetElementOr(test_suite_indices_, i, -1);
return index < 0 ? NULL : test_cases_[i]; return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];
} }
// Gets the i-th test case among all the test cases. i can range from 0 to // Legacy API is deprecated but still available
// total_test_case_count() - 1. If i is not in that range, returns NULL. #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
TestCase* GetMutableTestCase(int i) { const TestCase* GetTestCase(int i) const { return GetTestSuite(i); }
const int index = GetElementOr(test_case_indices_, i, -1); #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
return index < 0 ? NULL : test_cases_[index];
// Gets the i-th test suite among all the test suites. i can range from 0 to
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
TestSuite* GetMutableSuiteCase(int i) {
const int index = GetElementOr(test_suite_indices_, i, -1);
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];
} }
// Provides access to the event listener list. // Provides access to the event listener list.
@ -620,31 +642,40 @@ class GTEST_API_ UnitTestImpl {
// trace but Bar() and CurrentOsStackTraceExceptTop() won't. // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
// Finds and returns a TestCase with the given name. If one doesn't // Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it. // exist, creates one and returns it.
// //
// Arguments: // Arguments:
// //
// test_case_name: name of the test case // test_suite_name: name of the test suite
// type_param: the name of the test's type parameter, or NULL if // type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test. // this is not a typed or a type-parameterized test.
// 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 suite
// 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 suite
TestCase* GetTestCase(const char* test_case_name, TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
const char* type_param, internal::SetUpTestSuiteFunc set_up_tc,
Test::SetUpTestCaseFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc);
Test::TearDownTestCaseFunc tear_down_tc);
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
TestCase* GetTestCase(const char* test_case_name, const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc) {
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Adds a TestInfo to the unit test. // Adds a TestInfo to the unit test.
// //
// Arguments: // Arguments:
// //
// 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 suite
// 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 suite
// test_info: the TestInfo object // test_info: the TestInfo object
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc, internal::TearDownTestSuiteFunc tear_down_tc,
TestInfo* test_info) { TestInfo* test_info) {
#if GTEST_HAS_DEATH_TEST
// In order to support thread-safe death tests, we need to // In order to support thread-safe death tests, we need to
// remember the original working directory when the test program // remember the original working directory when the test program
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as // was first invoked. We cannot do this in RUN_ALL_TESTS(), as
@ -657,24 +688,33 @@ class GTEST_API_ UnitTestImpl {
GTEST_CHECK_(!original_working_dir_.IsEmpty()) GTEST_CHECK_(!original_working_dir_.IsEmpty())
<< "Failed to get the current working directory."; << "Failed to get the current working directory.";
} }
#endif // GTEST_HAS_DEATH_TEST
GetTestCase(test_info->test_case_name(), GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
test_info->type_param(), set_up_tc, tear_down_tc)
set_up_tc, ->AddTestInfo(test_info);
tear_down_tc)->AddTestInfo(test_info);
} }
#if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestSuiteRegistry object used to keep track of
// Returns ParameterizedTestCaseRegistry object used to keep track of
// value-parameterized tests and instantiate and register them. // value-parameterized tests and instantiate and register them.
internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() {
return parameterized_test_registry_; return parameterized_test_registry_;
} }
#endif // GTEST_HAS_PARAM_TEST
// Sets the TestCase object for the test that's currently running. std::set<std::string>* ignored_parameterized_test_suites() {
void set_current_test_case(TestCase* a_current_test_case) { return &ignored_parameterized_test_suites_;
current_test_case_ = a_current_test_case; }
// Returns TypeParameterizedTestSuiteRegistry object used to keep track of
// type-parameterized tests and instantiations of them.
internal::TypeParameterizedTestSuiteRegistry&
type_parameterized_test_registry() {
return type_parameterized_test_registry_;
}
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
} }
// Sets the TestInfo object for the test that's currently running. If // Sets the TestInfo object for the test that's currently running. If
@ -685,7 +725,7 @@ class GTEST_API_ UnitTestImpl {
} }
// Registers all parameterized tests defined using TEST_P and // Registers all parameterized tests defined using TEST_P and
// INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has guards // combination. This method can be called more then once; it has guards
// protecting from registering the tests more then once. If // protecting from registering the tests more then once. If
// value-parameterized tests are disabled, RegisterParameterizedTests is // value-parameterized tests are disabled, RegisterParameterizedTests is
@ -700,7 +740,7 @@ class GTEST_API_ UnitTestImpl {
// Clears the results of all tests, except the ad hoc tests. // Clears the results of all tests, except the ad hoc tests.
void ClearNonAdHocTestResult() { void ClearNonAdHocTestResult() {
ForEach(test_cases_, TestCase::ClearTestCaseResult); ForEach(test_suites_, TestSuite::ClearTestSuiteResult);
} }
// Clears the results of ad-hoc test assertions. // Clears the results of ad-hoc test assertions.
@ -709,7 +749,7 @@ class GTEST_API_ UnitTestImpl {
} }
// Adds a TestProperty to the current TestResult object when invoked in a // Adds a TestProperty to the current TestResult object when invoked in a
// context of a test or a test case, or to the global property set. If the // context of a test or a test suite, or to the global property set. If the
// result already contains a property with the same key, the value will be // result already contains a property with the same key, the value will be
// updated. // updated.
void RecordProperty(const TestProperty& test_property); void RecordProperty(const TestProperty& test_property);
@ -721,7 +761,7 @@ class GTEST_API_ UnitTestImpl {
// Matches the full name of each test against the user-specified // Matches the full name of each test against the user-specified
// filter to decide whether the test should run, then records the // filter to decide whether the test should run, then records the
// result in each TestCase and TestInfo object. // result in each TestSuite and TestInfo object.
// If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
// based on sharding variables in the environment. // based on sharding variables in the environment.
// Returns the number of tests that should run. // Returns the number of tests that should run.
@ -730,7 +770,7 @@ class GTEST_API_ UnitTestImpl {
// Prints the names of the tests matching the user-specified filter flag. // Prints the names of the tests matching the user-specified filter flag.
void ListTestsMatchingFilter(); void ListTestsMatchingFilter();
const TestCase* current_test_case() const { return current_test_case_; } const TestSuite* current_test_suite() const { return current_test_suite_; }
TestInfo* current_test_info() { return current_test_info_; } TestInfo* current_test_info() { return current_test_info_; }
const TestInfo* current_test_info() const { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; }
@ -791,11 +831,11 @@ class GTEST_API_ UnitTestImpl {
// Gets the random number generator. // Gets the random number generator.
internal::Random* random() { return &random_; } internal::Random* random() { return &random_; }
// Shuffles all test cases, and the tests within each test case, // Shuffles all test suites, and the tests within each test suite,
// making sure that death tests are still run first. // making sure that death tests are still run first.
void ShuffleTests(); void ShuffleTests();
// Restores the test cases and tests to their order before the first shuffle. // Restores the test suites and tests to their order before the first shuffle.
void UnshuffleTests(); void UnshuffleTests();
// Returns the value of GTEST_FLAG(catch_exceptions) at the moment // Returns the value of GTEST_FLAG(catch_exceptions) at the moment
@ -835,33 +875,37 @@ class GTEST_API_ UnitTestImpl {
// before/after the tests are run. // before/after the tests are run.
std::vector<Environment*> environments_; std::vector<Environment*> environments_;
// The vector of TestCases in their original order. It owns the // The vector of TestSuites in their original order. It owns the
// elements in the vector. // elements in the vector.
std::vector<TestCase*> test_cases_; std::vector<TestSuite*> test_suites_;
// Provides a level of indirection for the test case list to allow // Provides a level of indirection for the test suite list to allow
// easy shuffling and restoring the test case order. The i-th // easy shuffling and restoring the test suite order. The i-th
// element of this vector is the index of the i-th test case in the // element of this vector is the index of the i-th test suite in the
// shuffled order. // shuffled order.
std::vector<int> test_case_indices_; std::vector<int> test_suite_indices_;
#if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized // ParameterizedTestRegistry object used to register value-parameterized
// tests. // tests.
internal::ParameterizedTestCaseRegistry parameterized_test_registry_; internal::ParameterizedTestSuiteRegistry parameterized_test_registry_;
internal::TypeParameterizedTestSuiteRegistry
type_parameterized_test_registry_;
// The set holding the name of parameterized
// test suites that may go uninstantiated.
std::set<std::string> ignored_parameterized_test_suites_;
// Indicates whether RegisterParameterizedTests() has been called already. // Indicates whether RegisterParameterizedTests() has been called already.
bool parameterized_tests_registered_; bool parameterized_tests_registered_;
#endif // GTEST_HAS_PARAM_TEST
// Index of the last death test case registered. Initially -1. // Index of the last death test suite registered. Initially -1.
int last_death_test_case_; int last_death_test_suite_;
// This points to the TestCase for the currently running test. It // This points to the TestSuite for the currently running test. It
// changes as Google Test goes through one test case after another. // changes as Google Test goes through one test suite after another.
// When no test is running, this is set to NULL and Google Test // When no test is running, this is set to NULL and Google Test
// stores assertion results in ad_hoc_test_result_. Initially NULL. // stores assertion results in ad_hoc_test_result_. Initially NULL.
TestCase* current_test_case_; TestSuite* current_test_suite_;
// This points to the TestInfo for the currently running test. It // This points to the TestInfo for the currently running test. It
// changes as Google Test goes through one test after another. When // changes as Google Test goes through one test after another. When
@ -889,7 +933,7 @@ class GTEST_API_ UnitTestImpl {
// desired. // desired.
OsStackTraceGetterInterface* os_stack_trace_getter_; OsStackTraceGetterInterface* os_stack_trace_getter_;
// True iff PostFlagParsingInit() has been called. // True if and only if PostFlagParsingInit() has been called.
bool post_flag_parse_init_performed_; bool post_flag_parse_init_performed_;
// The random number seed used at the beginning of the test run. // The random number seed used at the beginning of the test run.
@ -908,8 +952,8 @@ class GTEST_API_ UnitTestImpl {
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
// The decomposed components of the gtest_internal_run_death_test flag, // The decomposed components of the gtest_internal_run_death_test flag,
// parsed when RUN_ALL_TESTS is called. // parsed when RUN_ALL_TESTS is called.
internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_; std::unique_ptr<internal::DeathTestFactory> death_test_factory_;
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
// A per-thread stack of traces created by the SCOPED_TRACE() macro. // A per-thread stack of traces created by the SCOPED_TRACE() macro.
@ -976,24 +1020,11 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
char* end; char* end;
// BiggestConvertible is the largest integer type that system-provided // BiggestConvertible is the largest integer type that system-provided
// string-to-number conversion routines can return. // string-to-number conversion routines can return.
using BiggestConvertible = unsigned long long; // NOLINT
# if GTEST_OS_WINDOWS && !defined(__GNUC__) const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT
// MSVC and C++ Builder define __int64 instead of the standard long long.
typedef unsigned __int64 BiggestConvertible;
const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
# else
typedef unsigned long long BiggestConvertible; // NOLINT
const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
# endif // GTEST_OS_WINDOWS && !defined(__GNUC__)
const bool parse_success = *end == '\0' && errno == 0; const bool parse_success = *end == '\0' && errno == 0;
// TODO(vladl@google.com): Convert this to compile time assertion when it is
// available.
GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
const Integer result = static_cast<Integer>(parsed); const Integer result = static_cast<Integer>(parsed);
@ -1032,7 +1063,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 GTEST_API_ StreamingListener : public EmptyTestEventListener { class 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 {
@ -1040,37 +1071,35 @@ class GTEST_API_ StreamingListener : public EmptyTestEventListener {
virtual ~AbstractSocketWriter() {} virtual ~AbstractSocketWriter() {}
// Sends a string to the socket. // Sends a string to the socket.
virtual void Send(const string& message) = 0; virtual void Send(const std::string& message) = 0;
// Closes the socket. // Closes the socket.
virtual void CloseConnection() {} virtual void CloseConnection() {}
// Sends a string and a newline to the socket. // Sends a string and a newline to the socket.
void SendLn(const string& message) { void SendLn(const std::string& message) { Send(message + "\n"); }
Send(message + "\n");
}
}; };
// Concrete class for actually writing strings to a socket. // Concrete class for actually writing strings to a socket.
class SocketWriter : public AbstractSocketWriter { class SocketWriter : public AbstractSocketWriter {
public: public:
SocketWriter(const string& host, const string& port) SocketWriter(const std::string& host, const std::string& port)
: sockfd_(-1), host_name_(host), port_num_(port) { : sockfd_(-1), host_name_(host), port_num_(port) {
MakeConnection(); MakeConnection();
} }
virtual ~SocketWriter() { ~SocketWriter() override {
if (sockfd_ != -1) if (sockfd_ != -1)
CloseConnection(); CloseConnection();
} }
// Sends a string to the socket. // Sends a string to the socket.
virtual void Send(const string& message) { void Send(const std::string& message) override {
GTEST_CHECK_(sockfd_ != -1) GTEST_CHECK_(sockfd_ != -1)
<< "Send() can be called only when there is a connection."; << "Send() can be called only when there is a connection.";
const int len = static_cast<int>(message.length()); const auto len = static_cast<size_t>(message.length());
if (write(sockfd_, message.c_str(), len) != len) { if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
GTEST_LOG_(WARNING) GTEST_LOG_(WARNING)
<< "stream_result_to: failed to stream to " << "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_; << host_name_ << ":" << port_num_;
@ -1082,7 +1111,7 @@ class GTEST_API_ StreamingListener : public EmptyTestEventListener {
void MakeConnection(); void MakeConnection();
// Closes the socket. // Closes the socket.
void CloseConnection() { void CloseConnection() override {
GTEST_CHECK_(sockfd_ != -1) GTEST_CHECK_(sockfd_ != -1)
<< "CloseConnection() can be called only when there is a connection."; << "CloseConnection() can be called only when there is a connection.";
@ -1091,26 +1120,28 @@ class GTEST_API_ StreamingListener : public EmptyTestEventListener {
} }
int sockfd_; // socket file descriptor int sockfd_; // socket file descriptor
const string host_name_; const std::string host_name_;
const string port_num_; const std::string port_num_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);
}; // class SocketWriter }; // class SocketWriter
// Escapes '=', '&', '%', and '\n' characters in str as "%xx". // Escapes '=', '&', '%', and '\n' characters in str as "%xx".
static string UrlEncode(const char* str); static std::string UrlEncode(const char* str);
StreamingListener(const string& host, const string& port) StreamingListener(const std::string& host, const std::string& port)
: socket_writer_(new SocketWriter(host, port)) { Start(); } : socket_writer_(new SocketWriter(host, port)) {
Start();
}
explicit StreamingListener(AbstractSocketWriter* socket_writer) explicit StreamingListener(AbstractSocketWriter* socket_writer)
: socket_writer_(socket_writer) { Start(); } : socket_writer_(socket_writer) { Start(); }
void OnTestProgramStart(const UnitTest& /* unit_test */) { void OnTestProgramStart(const UnitTest& /* unit_test */) override {
SendLn("event=TestProgramStart"); SendLn("event=TestProgramStart");
} }
void OnTestProgramEnd(const UnitTest& unit_test) { void OnTestProgramEnd(const UnitTest& unit_test) override {
// Note that Google Test current only report elapsed time for each // Note that Google Test current only report elapsed time for each
// test iteration, not for the entire test program. // test iteration, not for the entire test program.
SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed()));
@ -1119,42 +1150,47 @@ class GTEST_API_ StreamingListener : public EmptyTestEventListener {
socket_writer_->CloseConnection(); socket_writer_->CloseConnection();
} }
void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { void OnTestIterationStart(const UnitTest& /* unit_test */,
int iteration) override {
SendLn("event=TestIterationStart&iteration=" + SendLn("event=TestIterationStart&iteration=" +
StreamableToString(iteration)); StreamableToString(iteration));
} }
void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { void OnTestIterationEnd(const UnitTest& unit_test,
int /* iteration */) override {
SendLn("event=TestIterationEnd&passed=" + SendLn("event=TestIterationEnd&passed=" +
FormatBool(unit_test.Passed()) + "&elapsed_time=" + FormatBool(unit_test.Passed()) + "&elapsed_time=" +
StreamableToString(unit_test.elapsed_time()) + "ms"); StreamableToString(unit_test.elapsed_time()) + "ms");
} }
void OnTestCaseStart(const TestCase& test_case) { // Note that "event=TestCaseStart" is a wire format and has to remain
// "case" for compatibility
void OnTestCaseStart(const TestCase& test_case) override {
SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
} }
void OnTestCaseEnd(const TestCase& test_case) { // Note that "event=TestCaseEnd" is a wire format and has to remain
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) // "case" for compatibility
+ "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) void OnTestCaseEnd(const TestCase& test_case) override {
+ "ms"); SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) +
"&elapsed_time=" + StreamableToString(test_case.elapsed_time()) +
"ms");
} }
void OnTestStart(const TestInfo& test_info) { void OnTestStart(const TestInfo& test_info) override {
SendLn(std::string("event=TestStart&name=") + test_info.name()); SendLn(std::string("event=TestStart&name=") + test_info.name());
} }
void OnTestEnd(const TestInfo& test_info) { void OnTestEnd(const TestInfo& test_info) override {
SendLn("event=TestEnd&passed=" + SendLn("event=TestEnd&passed=" +
FormatBool((test_info.result())->Passed()) + FormatBool((test_info.result())->Passed()) +
"&elapsed_time=" + "&elapsed_time=" +
StreamableToString((test_info.result())->elapsed_time()) + "ms"); StreamableToString((test_info.result())->elapsed_time()) + "ms");
} }
void OnTestPartResult(const TestPartResult& test_part_result) { void OnTestPartResult(const TestPartResult& test_part_result) override {
const char* file_name = test_part_result.file_name(); const char* file_name = test_part_result.file_name();
if (file_name == NULL) if (file_name == nullptr) file_name = "";
file_name = "";
SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) +
"&line=" + StreamableToString(test_part_result.line_number()) + "&line=" + StreamableToString(test_part_result.line_number()) +
"&message=" + UrlEncode(test_part_result.message())); "&message=" + UrlEncode(test_part_result.message()));
@ -1162,15 +1198,15 @@ class GTEST_API_ StreamingListener : public EmptyTestEventListener {
private: private:
// Sends the given message and a newline to the socket. // Sends the given message and a newline to the socket.
void SendLn(const string& message) { socket_writer_->SendLn(message); } void SendLn(const std::string& message) { socket_writer_->SendLn(message); }
// Called at the start of streaming to notify the receiver what // Called at the start of streaming to notify the receiver what
// protocol we are using. // protocol we are using.
void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } void Start() { SendLn("gtest_streaming_protocol_version=1.0"); }
string FormatBool(bool value) { return value ? "1" : "0"; } std::string FormatBool(bool value) { return value ? "1" : "0"; }
const scoped_ptr<AbstractSocketWriter> socket_writer_; const std::unique_ptr<AbstractSocketWriter> socket_writer_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
}; // class StreamingListener }; // class StreamingListener
@ -1180,4 +1216,6 @@ class GTEST_API_ StreamingListener : public EmptyTestEventListener {
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_

View File

@ -0,0 +1,97 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-matchers.h"
#include <string>
namespace testing {
// Constructs a matcher that matches a const std::string& whose value is
// equal to s.
Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a const std::string& whose value is
// equal to s.
Matcher<const std::string&>::Matcher(const char* s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a std::string whose value is equal to
// s.
Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a std::string whose value is equal to
// s.
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const internal::StringView&>::Matcher(const std::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const internal::StringView&>::Matcher(const char* s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const internal::StringView&>::Matcher(internal::StringView s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a StringView whose value is equal to
// s.
Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a StringView whose value is equal to
// s.
Matcher<internal::StringView>::Matcher(const char* s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a StringView whose value is equal to
// s.
Matcher<internal::StringView>::Matcher(internal::StringView s) {
*this = Eq(std::string(s));
}
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
} // namespace testing

View File

@ -26,22 +26,26 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include <limits.h> #include <limits.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <cstdint>
#include <fstream> #include <fstream>
#include <memory>
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# include <windows.h> # include <windows.h>
# include <io.h> # include <io.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <map> // Used in ThreadLocal. # include <map> // Used in ThreadLocal.
# ifdef _MSC_VER
# include <crtdbg.h>
# endif // _MSC_VER
#else #else
# include <unistd.h> # include <unistd.h>
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
@ -52,6 +56,14 @@
# include <mach/vm_map.h> # include <mach/vm_map.h>
#endif // GTEST_OS_MAC #endif // GTEST_OS_MAC
#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
GTEST_OS_NETBSD || GTEST_OS_OPENBSD
# include <sys/sysctl.h>
# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
# include <sys/user.h>
# endif
#endif
#if GTEST_OS_QNX #if GTEST_OS_QNX
# include <devctl.h> # include <devctl.h>
# include <fcntl.h> # include <fcntl.h>
@ -63,19 +75,16 @@
# include <sys/types.h> # include <sys/types.h>
#endif // GTEST_OS_AIX #endif // GTEST_OS_AIX
#if GTEST_OS_FUCHSIA
# include <zircon/process.h>
# include <zircon/syscalls.h>
#endif // GTEST_OS_FUCHSIA
#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"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick exists to
// prevent the accidental inclusion of gtest-internal-inl.h in the
// user's code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -93,7 +102,7 @@ const int kStdErrFileno = STDERR_FILENO;
namespace { namespace {
template <typename T> template <typename T>
T ReadProcFileField(const string& filename, int field) { T ReadProcFileField(const std::string& filename, int field) {
std::string dummy; std::string dummy;
std::ifstream file(filename.c_str()); std::ifstream file(filename.c_str());
while (field-- > 0) { while (field-- > 0) {
@ -107,9 +116,9 @@ T ReadProcFileField(const string& filename, int field) {
// Returns the number of active threads, or 0 when there is an error. // Returns the number of active threads, or 0 when there is an error.
size_t GetThreadCount() { size_t GetThreadCount() {
const string filename = const std::string filename =
(Message() << "/proc/" << getpid() << "/stat").GetString(); (Message() << "/proc/" << getpid() << "/stat").GetString();
return ReadProcFileField<int>(filename, 19); return ReadProcFileField<size_t>(filename, 19);
} }
#elif GTEST_OS_MAC #elif GTEST_OS_MAC
@ -131,6 +140,82 @@ size_t GetThreadCount() {
} }
} }
#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
GTEST_OS_NETBSD
#if GTEST_OS_NETBSD
#undef KERN_PROC
#define KERN_PROC KERN_PROC2
#define kinfo_proc kinfo_proc2
#endif
#if GTEST_OS_DRAGONFLY
#define KP_NLWP(kp) (kp.kp_nthreads)
#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
#define KP_NLWP(kp) (kp.ki_numthreads)
#elif GTEST_OS_NETBSD
#define KP_NLWP(kp) (kp.p_nlwps)
#endif
// Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it.
size_t GetThreadCount() {
int mib[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid(),
#if GTEST_OS_NETBSD
sizeof(struct kinfo_proc),
1,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
struct kinfo_proc info;
size_t size = sizeof(info);
if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
return 0;
}
return static_cast<size_t>(KP_NLWP(info));
}
#elif GTEST_OS_OPENBSD
// Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it.
size_t GetThreadCount() {
int mib[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
getpid(),
sizeof(struct kinfo_proc),
0,
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
// get number of structs
size_t size;
if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {
return 0;
}
mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4]));
// populate array of structs
struct kinfo_proc info[mib[5]];
if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
return 0;
}
// exclude empty members
size_t nthreads = 0;
for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) {
if (info[i].p_tid != -1)
nthreads++;
}
return nthreads;
}
#elif GTEST_OS_QNX #elif GTEST_OS_QNX
// Returns the number of threads running in the process, or 0 to indicate that // Returns the number of threads running in the process, or 0 to indicate that
@ -142,7 +227,7 @@ size_t GetThreadCount() {
} }
procfs_info process_info; procfs_info process_info;
const int status = const int status =
devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr);
close(fd); close(fd);
if (status == EOK) { if (status == EOK) {
return static_cast<size_t>(process_info.num_threads); return static_cast<size_t>(process_info.num_threads);
@ -156,7 +241,7 @@ size_t GetThreadCount() {
size_t GetThreadCount() { size_t GetThreadCount() {
struct procentry64 entry; struct procentry64 entry;
pid_t pid = getpid(); pid_t pid = getpid();
int status = getprocs64(&entry, sizeof(entry), NULL, 0, &pid, 1); int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1);
if (status == 1) { if (status == 1) {
return entry.pi_thcount; return entry.pi_thcount;
} else { } else {
@ -164,6 +249,25 @@ size_t GetThreadCount() {
} }
} }
#elif GTEST_OS_FUCHSIA
size_t GetThreadCount() {
int dummy_buffer;
size_t avail;
zx_status_t status = zx_object_get_info(
zx_process_self(),
ZX_INFO_PROCESS_THREADS,
&dummy_buffer,
0,
nullptr,
&avail);
if (status == ZX_OK) {
return avail;
} else {
return 0;
}
}
#else #else
size_t GetThreadCount() { size_t GetThreadCount() {
@ -177,7 +281,7 @@ size_t GetThreadCount() {
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
void SleepMilliseconds(int n) { void SleepMilliseconds(int n) {
::Sleep(n); ::Sleep(static_cast<DWORD>(n));
} }
AutoHandle::AutoHandle() AutoHandle::AutoHandle()
@ -215,15 +319,15 @@ void AutoHandle::Reset(HANDLE handle) {
bool AutoHandle::IsCloseable() const { bool AutoHandle::IsCloseable() const {
// Different Windows APIs may use either of these values to represent an // Different Windows APIs may use either of these values to represent an
// invalid handle. // invalid handle.
return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
} }
Notification::Notification() Notification::Notification()
: event_(::CreateEvent(NULL, // Default security attributes. : event_(::CreateEvent(nullptr, // Default security attributes.
TRUE, // Do not reset automatically. TRUE, // Do not reset automatically.
FALSE, // Initially unset. FALSE, // Initially unset.
NULL)) { // Anonymous event. nullptr)) { // Anonymous event.
GTEST_CHECK_(event_.Get() != NULL); GTEST_CHECK_(event_.Get() != nullptr);
} }
void Notification::Notify() { void Notification::Notify() {
@ -246,13 +350,10 @@ Mutex::Mutex()
Mutex::~Mutex() { Mutex::~Mutex() {
// Static mutexes are leaked intentionally. It is not thread-safe to try // Static mutexes are leaked intentionally. It is not thread-safe to try
// to clean them up. // to clean them up.
// TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires
// nothing to clean it up but is available only on Vista and later.
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx
if (type_ == kDynamic) { if (type_ == kDynamic) {
::DeleteCriticalSection(critical_section_); ::DeleteCriticalSection(critical_section_);
delete critical_section_; delete critical_section_;
critical_section_ = NULL; critical_section_ = nullptr;
} }
} }
@ -279,6 +380,41 @@ void Mutex::AssertHeld() {
<< "The current thread is not holding the mutex @" << this; << "The current thread is not holding the mutex @" << this;
} }
namespace {
#ifdef _MSC_VER
// Use the RAII idiom to flag mem allocs that are intentionally never
// deallocated. The motivation is to silence the false positive mem leaks
// that are reported by the debug version of MS's CRT which can only detect
// if an alloc is missing a matching deallocation.
// Example:
// MemoryIsNotDeallocated memory_is_not_deallocated;
// critical_section_ = new CRITICAL_SECTION;
//
class MemoryIsNotDeallocated
{
public:
MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
// doesn't report mem leak if there's no matching deallocation.
_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
}
~MemoryIsNotDeallocated() {
// Restore the original _CRTDBG_ALLOC_MEM_DF flag
_CrtSetDbgFlag(old_crtdbg_flag_);
}
private:
int old_crtdbg_flag_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated);
};
#endif // _MSC_VER
} // namespace
// Initializes owner_thread_id_ and critical_section_ in static mutexes. // Initializes owner_thread_id_ and critical_section_ in static mutexes.
void Mutex::ThreadSafeLazyInit() { void Mutex::ThreadSafeLazyInit() {
// Dynamic mutexes are initialized in the constructor. // Dynamic mutexes are initialized in the constructor.
@ -289,7 +425,13 @@ void Mutex::ThreadSafeLazyInit() {
// If critical_section_init_phase_ was 0 before the exchange, we // If critical_section_init_phase_ was 0 before the exchange, we
// are the first to test it and need to perform the initialization. // are the first to test it and need to perform the initialization.
owner_thread_id_ = 0; owner_thread_id_ = 0;
{
// Use RAII to flag that following mem alloc is never deallocated.
#ifdef _MSC_VER
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
critical_section_ = new CRITICAL_SECTION; critical_section_ = new CRITICAL_SECTION;
}
::InitializeCriticalSection(critical_section_); ::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal // Updates the critical_section_init_phase_ to 2 to signal
// initialization complete. // initialization complete.
@ -328,17 +470,16 @@ class ThreadWithParamSupport : public ThreadWithParamBase {
Notification* thread_can_start) { Notification* thread_can_start) {
ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
DWORD thread_id; DWORD thread_id;
// TODO(yukawa): Consider to use _beginthreadex instead.
HANDLE thread_handle = ::CreateThread( HANDLE thread_handle = ::CreateThread(
NULL, // Default security. nullptr, // Default security.
0, // Default stack size. 0, // Default stack size.
&ThreadWithParamSupport::ThreadMain, &ThreadWithParamSupport::ThreadMain,
param, // Parameter to ThreadMainStatic param, // Parameter to ThreadMainStatic
0x0, // Default creation flags. 0x0, // Default creation flags.
&thread_id); // Need a valid pointer for the call to work under Win98. &thread_id); // Need a valid pointer for the call to work under Win98.
GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " GTEST_CHECK_(thread_handle != nullptr)
<< ::GetLastError() << "."; << "CreateThread failed with error " << ::GetLastError() << ".";
if (thread_handle == NULL) { if (thread_handle == nullptr) {
delete param; delete param;
} }
return thread_handle; return thread_handle;
@ -350,15 +491,15 @@ class ThreadWithParamSupport : public ThreadWithParamBase {
: runnable_(runnable), : runnable_(runnable),
thread_can_start_(thread_can_start) { thread_can_start_(thread_can_start) {
} }
scoped_ptr<Runnable> runnable_; std::unique_ptr<Runnable> runnable_;
// Does not own. // Does not own.
Notification* thread_can_start_; Notification* thread_can_start_;
}; };
static DWORD WINAPI ThreadMain(void* ptr) { static DWORD WINAPI ThreadMain(void* ptr) {
// Transfers ownership. // Transfers ownership.
scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr)); std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
if (param->thread_can_start_ != NULL) if (param->thread_can_start_ != nullptr)
param->thread_can_start_->WaitForNotification(); param->thread_can_start_->WaitForNotification();
param->runnable_->Run(); param->runnable_->Run();
return 0; return 0;
@ -397,6 +538,9 @@ class ThreadLocalRegistryImpl {
// Returns a value that can be used to identify the thread from other threads. // Returns a value that can be used to identify the thread from other threads.
static ThreadLocalValueHolderBase* GetValueOnCurrentThread( static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
#ifdef _MSC_VER
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
DWORD current_thread = ::GetCurrentThreadId(); DWORD current_thread = ::GetCurrentThreadId();
MutexLock lock(&mutex_); MutexLock lock(&mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals = ThreadIdToThreadLocals* const thread_to_thread_locals =
@ -416,7 +560,7 @@ class ThreadLocalRegistryImpl {
thread_local_values thread_local_values
.insert(std::make_pair( .insert(std::make_pair(
thread_local_instance, thread_local_instance,
linked_ptr<ThreadLocalValueHolderBase>( std::shared_ptr<ThreadLocalValueHolderBase>(
thread_local_instance->NewValueForCurrentThread()))) thread_local_instance->NewValueForCurrentThread())))
.first; .first;
} }
@ -425,7 +569,7 @@ class ThreadLocalRegistryImpl {
static void OnThreadLocalDestroyed( static void OnThreadLocalDestroyed(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders; std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
// Clean up the ThreadLocalValues data structure while holding the lock, but // Clean up the ThreadLocalValues data structure while holding the lock, but
// defer the destruction of the ThreadLocalValueHolderBases. // defer the destruction of the ThreadLocalValueHolderBases.
{ {
@ -453,7 +597,7 @@ class ThreadLocalRegistryImpl {
static void OnThreadExit(DWORD thread_id) { static void OnThreadExit(DWORD thread_id) {
GTEST_CHECK_(thread_id != 0) << ::GetLastError(); GTEST_CHECK_(thread_id != 0) << ::GetLastError();
std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders; std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
// Clean up the ThreadIdToThreadLocals data structure while holding the // Clean up the ThreadIdToThreadLocals data structure while holding the
// lock, but defer the destruction of the ThreadLocalValueHolderBases. // lock, but defer the destruction of the ThreadLocalValueHolderBases.
{ {
@ -480,7 +624,8 @@ class ThreadLocalRegistryImpl {
private: private:
// In a particular thread, maps a ThreadLocal object to its value. // In a particular thread, maps a ThreadLocal object to its value.
typedef std::map<const ThreadLocalBase*, typedef std::map<const ThreadLocalBase*,
linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues; std::shared_ptr<ThreadLocalValueHolderBase> >
ThreadLocalValues;
// Stores all ThreadIdToThreadLocals having values in a thread, indexed by // Stores all ThreadIdToThreadLocals having values in a thread, indexed by
// thread's ID. // thread's ID.
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
@ -495,18 +640,17 @@ class ThreadLocalRegistryImpl {
HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
FALSE, FALSE,
thread_id); thread_id);
GTEST_CHECK_(thread != NULL); GTEST_CHECK_(thread != nullptr);
// We need to to pass a valid thread ID pointer into CreateThread for it // We need to pass a valid thread ID pointer into CreateThread for it
// to work correctly under Win98. // to work correctly under Win98.
DWORD watcher_thread_id; DWORD watcher_thread_id;
HANDLE watcher_thread = ::CreateThread( HANDLE watcher_thread = ::CreateThread(
NULL, // Default security. nullptr, // Default security.
0, // Default stack size 0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc, &ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
CREATE_SUSPENDED, CREATE_SUSPENDED, &watcher_thread_id);
&watcher_thread_id); GTEST_CHECK_(watcher_thread != nullptr);
GTEST_CHECK_(watcher_thread != NULL);
// Give the watcher thread the same priority as ours to avoid being // Give the watcher thread the same priority as ours to avoid being
// blocked by it. // blocked by it.
::SetThreadPriority(watcher_thread, ::SetThreadPriority(watcher_thread,
@ -531,7 +675,10 @@ class ThreadLocalRegistryImpl {
// Returns map of thread local instances. // Returns map of thread local instances.
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
mutex_.AssertHeld(); mutex_.AssertHeld();
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; #ifdef _MSC_VER
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
return map; return map;
} }
@ -541,8 +688,8 @@ class ThreadLocalRegistryImpl {
static Mutex thread_map_mutex_; static Mutex thread_map_mutex_;
}; };
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); // NOLINT
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
@ -573,7 +720,7 @@ RE::~RE() {
free(const_cast<char*>(pattern_)); free(const_cast<char*>(pattern_));
} }
// Returns true iff regular expression re matches the entire str. // Returns true if and only if regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) { bool RE::FullMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false; if (!re.is_valid_) return false;
@ -581,8 +728,8 @@ bool RE::FullMatch(const char* str, const RE& re) {
return regexec(&re.full_regex_, str, 1, &match, 0) == 0; return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
} }
// Returns true iff regular expression re matches a substring of str // Returns true if and only if regular expression re matches a substring of
// (including str itself). // str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) { bool RE::PartialMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false; if (!re.is_valid_) return false;
@ -622,14 +769,14 @@ void RE::Init(const char* regex) {
#elif GTEST_USES_SIMPLE_RE #elif GTEST_USES_SIMPLE_RE
// Returns true iff ch appears anywhere in str (excluding the // Returns true if and only if ch appears anywhere in str (excluding the
// terminating '\0' character). // terminating '\0' character).
bool IsInSet(char ch, const char* str) { bool IsInSet(char ch, const char* str) {
return ch != '\0' && strchr(str, ch) != NULL; return ch != '\0' && strchr(str, ch) != nullptr;
} }
// Returns true iff ch belongs to the given classification. Unlike // Returns true if and only if ch belongs to the given classification.
// similar functions in <ctype.h>, these aren't affected by the // Unlike similar functions in <ctype.h>, these aren't affected by the
// current locale. // current locale.
bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
bool IsAsciiPunct(char ch) { bool IsAsciiPunct(char ch) {
@ -642,13 +789,13 @@ bool IsAsciiWordChar(char ch) {
('0' <= ch && ch <= '9') || ch == '_'; ('0' <= ch && ch <= '9') || ch == '_';
} }
// Returns true iff "\\c" is a supported escape sequence. // Returns true if and only if "\\c" is a supported escape sequence.
bool IsValidEscape(char c) { bool IsValidEscape(char c) {
return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
} }
// Returns true iff the given atom (specified by escaped and pattern) // Returns true if and only if the given atom (specified by escaped and
// matches ch. The result is undefined if the atom is invalid. // pattern) matches ch. The result is undefined if the atom is invalid.
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
if (escaped) { // "\\p" where p is pattern_char. if (escaped) { // "\\p" where p is pattern_char.
switch (pattern_char) { switch (pattern_char) {
@ -671,7 +818,7 @@ bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
} }
// Helper function used by ValidateRegex() to format error messages. // Helper function used by ValidateRegex() to format error messages.
std::string FormatRegexSyntaxError(const char* regex, int index) { static std::string FormatRegexSyntaxError(const char* regex, int index) {
return (Message() << "Syntax error at index " << index return (Message() << "Syntax error at index " << index
<< " in simple regular expression \"" << regex << "\": ").GetString(); << " in simple regular expression \"" << regex << "\": ").GetString();
} }
@ -679,17 +826,14 @@ std::string FormatRegexSyntaxError(const char* regex, int index) {
// Generates non-fatal failures and returns false if regex is invalid; // Generates non-fatal failures and returns false if regex is invalid;
// otherwise returns true. // otherwise returns true.
bool ValidateRegex(const char* regex) { bool ValidateRegex(const char* regex) {
if (regex == NULL) { if (regex == nullptr) {
// TODO(wan@google.com): fix the source file location in the
// assertion failures to match where the regex is used in user
// code.
ADD_FAILURE() << "NULL is not a valid simple regular expression."; ADD_FAILURE() << "NULL is not a valid simple regular expression.";
return false; return false;
} }
bool is_valid = true; bool is_valid = true;
// True iff ?, *, or + can follow the previous atom. // True if and only if ?, *, or + can follow the previous atom.
bool prev_repeatable = false; bool prev_repeatable = false;
for (int i = 0; regex[i]; i++) { for (int i = 0; regex[i]; i++) {
if (regex[i] == '\\') { // An escape sequence if (regex[i] == '\\') { // An escape sequence
@ -765,8 +909,8 @@ bool MatchRepetitionAndRegexAtHead(
return false; return false;
} }
// Returns true iff regex matches a prefix of str. regex must be a // Returns true if and only if regex matches a prefix of str. regex must
// valid simple regular expression and not start with "^", or the // be a valid simple regular expression and not start with "^", or the
// result is undefined. // result is undefined.
bool MatchRegexAtHead(const char* regex, const char* str) { bool MatchRegexAtHead(const char* regex, const char* str) {
if (*regex == '\0') // An empty regex matches a prefix of anything. if (*regex == '\0') // An empty regex matches a prefix of anything.
@ -796,8 +940,8 @@ bool MatchRegexAtHead(const char* regex, const char* str) {
} }
} }
// Returns true iff regex matches any substring of str. regex must be // Returns true if and only if regex matches any substring of str. regex must
// a valid simple regular expression, or the result is undefined. // be a valid simple regular expression, or the result is undefined.
// //
// The algorithm is recursive, but the recursion depth doesn't exceed // The algorithm is recursive, but the recursion depth doesn't exceed
// the regex length, so we won't need to worry about running out of // the regex length, so we won't need to worry about running out of
@ -805,8 +949,7 @@ bool MatchRegexAtHead(const char* regex, const char* str) {
// exponential with respect to the regex length + the string length, // exponential with respect to the regex length + the string length,
// but usually it's must faster (often close to linear). // but usually it's must faster (often close to linear).
bool MatchRegexAnywhere(const char* regex, const char* str) { bool MatchRegexAnywhere(const char* regex, const char* str) {
if (regex == NULL || str == NULL) if (regex == nullptr || str == nullptr) return false;
return false;
if (*regex == '^') if (*regex == '^')
return MatchRegexAtHead(regex + 1, str); return MatchRegexAtHead(regex + 1, str);
@ -826,21 +969,21 @@ RE::~RE() {
free(const_cast<char*>(full_pattern_)); free(const_cast<char*>(full_pattern_));
} }
// Returns true iff regular expression re matches the entire str. // Returns true if and only if regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) { bool RE::FullMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
} }
// Returns true iff regular expression re matches a substring of str // Returns true if and only if regular expression re matches a substring of
// (including str itself). // str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) { bool RE::PartialMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
} }
// Initializes an RE from its string representation. // Initializes an RE from its string representation.
void RE::Init(const char* regex) { void RE::Init(const char* regex) {
pattern_ = full_pattern_ = NULL; pattern_ = full_pattern_ = nullptr;
if (regex != NULL) { if (regex != nullptr) {
pattern_ = posix::StrDup(regex); pattern_ = posix::StrDup(regex);
} }
@ -878,7 +1021,7 @@ const char kUnknownFile[] = "unknown file";
// Formats a source file path and a line number as they would appear // Formats a source file path and a line number as they would appear
// in an error message from the compiler used to compile this code. // in an error message from the compiler used to compile this code.
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
const std::string file_name(file == NULL ? kUnknownFile : file); const std::string file_name(file == nullptr ? kUnknownFile : file);
if (line < 0) { if (line < 0) {
return file_name + ":"; return file_name + ":";
@ -897,7 +1040,7 @@ GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
// to the file location it produces, unlike FormatFileLocation(). // to the file location it produces, unlike FormatFileLocation().
GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
const char* file, int line) { const char* file, int line) {
const std::string file_name(file == NULL ? kUnknownFile : file); const std::string file_name(file == nullptr ? kUnknownFile : file);
if (line < 0) if (line < 0)
return file_name; return file_name;
@ -923,10 +1066,11 @@ GTestLog::~GTestLog() {
posix::Abort(); posix::Abort();
} }
} }
// Disable Microsoft deprecation warnings for POSIX functions called from // Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close) // this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
GTEST_DISABLE_CLANG_DEPRECATED_WARNINGS_PUSH_()
#if GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_STREAM_REDIRECTION
// Object that captures an output stream (stdout/stderr). // Object that captures an output stream (stdout/stderr).
@ -951,9 +1095,9 @@ class CapturedStream {
filename_ = temp_file_path; filename_ = temp_file_path;
# else # else
// There's no guarantee that a test has write access to the current // There's no guarantee that a test has write access to the current
// directory, so we create the temporary file in the /tmp directory // directory, so we create the temporary file in a temporary directory.
// instead. We use /tmp on most systems, and /sdcard on Android. std::string name_template;
// That's because Android doesn't have /tmp.
# if GTEST_OS_LINUX_ANDROID # if GTEST_OS_LINUX_ANDROID
// Note: Android applications are expected to call the framework's // Note: Android applications are expected to call the framework's
// Context.getExternalStorageDirectory() method through JNI to get // Context.getExternalStorageDirectory() method through JNI to get
@ -963,20 +1107,51 @@ class CapturedStream {
// code as part of a regular standalone executable, which doesn't // code as part of a regular standalone executable, which doesn't
// run in a Dalvik process (e.g. when running it through 'adb shell'). // run in a Dalvik process (e.g. when running it through 'adb shell').
// //
// The location /sdcard is directly accessible from native code // The location /data/local/tmp is directly accessible from native code.
// and is the only location (unofficially) supported by the Android // '/sdcard' and other variants cannot be relied on, as they are not
// team. It's generally a symlink to the real SD Card mount point // guaranteed to be mounted, or may have a delay in mounting.
// which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or name_template = "/data/local/tmp/";
// other OEM-customized locations. Never rely on these, and always # elif GTEST_OS_IOS
// use /sdcard. char user_temp_dir[PATH_MAX + 1];
char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
// Documented alternative to NSTemporaryDirectory() (for obtaining creating
// a temporary directory) at
// https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10
//
// _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not
// documented in the confstr() man page at
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr
// but are still available, according to the WebKit patches at
// https://trac.webkit.org/changeset/262004/webkit
// https://trac.webkit.org/changeset/263705/webkit
//
// The confstr() implementation falls back to getenv("TMPDIR"). See
// https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.auto.html
::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));
name_template = user_temp_dir;
if (name_template.back() != GTEST_PATH_SEP_[0])
name_template.push_back(GTEST_PATH_SEP_[0]);
# else # else
char name_template[] = "/tmp/captured_stream.XXXXXX"; name_template = "/tmp/";
# endif // GTEST_OS_LINUX_ANDROID # endif
const int captured_fd = mkstemp(name_template); name_template.append("gtest_captured_stream.XXXXXX");
filename_ = name_template;
// mkstemp() modifies the string bytes in place, and does not go beyond the
// string's length. This results in well-defined behavior in C++17.
//
// The const_cast is needed below C++17. The constraints on std::string
// implementations in C++11 and above make assumption behind the const_cast
// fairly safe.
const int captured_fd = ::mkstemp(const_cast<char*>(name_template.data()));
if (captured_fd == -1) {
GTEST_LOG_(WARNING)
<< "Failed to create tmp file " << name_template
<< " for test; does the test have access to the /tmp directory?";
}
filename_ = std::move(name_template);
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
fflush(NULL); fflush(nullptr);
dup2(captured_fd, fd_); dup2(captured_fd, fd_);
close(captured_fd); close(captured_fd);
} }
@ -988,13 +1163,17 @@ class CapturedStream {
std::string GetCapturedString() { std::string GetCapturedString() {
if (uncaptured_fd_ != -1) { if (uncaptured_fd_ != -1) {
// Restores the original stream. // Restores the original stream.
fflush(NULL); fflush(nullptr);
dup2(uncaptured_fd_, fd_); dup2(uncaptured_fd_, fd_);
close(uncaptured_fd_); close(uncaptured_fd_);
uncaptured_fd_ = -1; uncaptured_fd_ = -1;
} }
FILE* const file = posix::FOpen(filename_.c_str(), "r"); FILE* const file = posix::FOpen(filename_.c_str(), "r");
if (file == nullptr) {
GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_
<< " for capturing stream.";
}
const std::string content = ReadEntireFile(file); const std::string content = ReadEntireFile(file);
posix::FClose(file); posix::FClose(file);
return content; return content;
@ -1009,15 +1188,15 @@ class CapturedStream {
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
}; };
GTEST_DISABLE_MSC_WARNINGS_POP_() GTEST_DISABLE_MSC_DEPRECATED_POP_()
GTEST_DISABLE_CLANG_WARNINGS_POP_()
static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stderr = nullptr;
static CapturedStream* g_captured_stdout = NULL; static CapturedStream* g_captured_stdout = nullptr;
// Starts capturing an output stream (stdout/stderr). // Starts capturing an output stream (stdout/stderr).
void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { static void CaptureStream(int fd, const char* stream_name,
if (*stream != NULL) { CapturedStream** stream) {
if (*stream != nullptr) {
GTEST_LOG_(FATAL) << "Only one " << stream_name GTEST_LOG_(FATAL) << "Only one " << stream_name
<< " capturer can exist at a time."; << " capturer can exist at a time.";
} }
@ -1025,11 +1204,11 @@ void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
} }
// Stops capturing the output stream and returns the captured string. // Stops capturing the output stream and returns the captured string.
std::string GetCapturedStream(CapturedStream** captured_stream) { static std::string GetCapturedStream(CapturedStream** captured_stream) {
const std::string content = (*captured_stream)->GetCapturedString(); const std::string content = (*captured_stream)->GetCapturedString();
delete *captured_stream; delete *captured_stream;
*captured_stream = NULL; *captured_stream = nullptr;
return content; return content;
} }
@ -1056,23 +1235,9 @@ std::string GetCapturedStderr() {
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
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
}
size_t GetFileSize(FILE* file) { size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
@ -1102,22 +1267,30 @@ std::string ReadEntireFile(FILE* file) {
} }
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
static const std::vector<std::string>* g_injected_test_argvs =
nullptr; // Owned.
static const ::std::vector<testing::internal::string>* g_injected_test_argvs = std::vector<std::string> GetInjectableArgvs() {
NULL; // Owned. if (g_injected_test_argvs != nullptr) {
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
if (g_injected_test_argvs != argvs)
delete g_injected_test_argvs;
g_injected_test_argvs = argvs;
}
const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
if (g_injected_test_argvs != NULL) {
return *g_injected_test_argvs; return *g_injected_test_argvs;
} }
return GetArgvs(); return GetArgvs();
} }
void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
g_injected_test_argvs = new_argvs;
}
void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
void ClearInjectableArgvs() {
delete g_injected_test_argvs;
g_injected_test_argvs = nullptr;
}
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
@ -1147,9 +1320,9 @@ static std::string FlagToEnvVar(const char* flag) {
// Parses 'str' for a 32-bit signed integer. If successful, writes // Parses 'str' for a 32-bit signed integer. If successful, writes
// the result to *value and returns true; otherwise leaves *value // the result to *value and returns true; otherwise leaves *value
// unchanged and returns false. // unchanged and returns false.
bool ParseInt32(const Message& src_text, const char* str, Int32* value) { bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
// Parses the environment variable as a decimal integer. // Parses the environment variable as a decimal integer.
char* end = NULL; char* end = nullptr;
const long long_value = strtol(str, &end, 10); // NOLINT const long long_value = strtol(str, &end, 10); // NOLINT
// Has strtol() consumed all characters in the string? // Has strtol() consumed all characters in the string?
@ -1164,13 +1337,13 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
return false; return false;
} }
// Is the parsed value in the range of an Int32? // Is the parsed value in the range of an int32_t?
const Int32 result = static_cast<Int32>(long_value); const auto result = static_cast<int32_t>(long_value);
if (long_value == LONG_MAX || long_value == LONG_MIN || if (long_value == LONG_MAX || long_value == LONG_MIN ||
// The parsed value overflows as a long. (strtol() returns // The parsed value overflows as a long. (strtol() returns
// LONG_MAX or LONG_MIN when the input overflows.) // LONG_MAX or LONG_MIN when the input overflows.)
result != long_value result != long_value
// The parsed value overflows as an Int32. // The parsed value overflows as an int32_t.
) { ) {
Message msg; Message msg;
msg << "WARNING: " << src_text msg << "WARNING: " << src_text
@ -1188,32 +1361,33 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
// Reads and returns the Boolean environment variable corresponding to // Reads and returns the Boolean 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.
// //
// The value is considered true iff it's not "0". // The value is considered true if and only if 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_) #if defined(GTEST_GET_BOOL_FROM_ENV_)
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_BOOL_FROM_ENV_) #else
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 == nullptr ? default_value
default_value : strcmp(string_value, "0") != 0; : strcmp(string_value, "0") != 0;
#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
} }
// Reads and returns a 32-bit integer stored in the environment // Reads and returns a 32-bit integer stored in the environment
// 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_t Int32FromGTestEnv(const char* flag, int32_t default_value) {
#if defined(GTEST_GET_INT32_FROM_ENV_) #if defined(GTEST_GET_INT32_FROM_ENV_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value); return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_INT32_FROM_ENV_) #else
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 == nullptr) {
// The environment variable is not set. // The environment variable is not set.
return default_value; return default_value;
} }
Int32 result = default_value; int32_t result = default_value;
if (!ParseInt32(Message() << "Environment variable " << env_var, if (!ParseInt32(Message() << "Environment variable " << env_var,
string_value, &result)) { string_value, &result)) {
printf("The default value %s is used.\n", printf("The default value %s is used.\n",
@ -1223,37 +1397,36 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
} }
return result; return result;
#endif // defined(GTEST_GET_INT32_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
// Note that this is meant to be called at the call site so it does
// not check that the flag is 'output'
// In essence this checks an env variable called XML_OUTPUT_FILE
// and if it is set we prepend "xml:" to its value, if it not set we return ""
std::string OutputFlagAlsoCheckEnvVar(){
std::string default_value_for_output_flag = "";
const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
if (nullptr != xml_output_file_env) {
default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
}
return default_value_for_output_flag;
} }
// 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.
std::string 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_) #if defined(GTEST_GET_STRING_FROM_ENV_)
return GTEST_GET_STRING_FROM_ENV_(flag, default_value); return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_STRING_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* value = posix::GetEnv(env_var.c_str()); const char* const value = posix::GetEnv(env_var.c_str());
if (value != NULL) { return value == nullptr ? default_value : value;
return value; #endif // defined(GTEST_GET_STRING_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
//
// The net priority order after flag processing is thus:
// --gtest_output command line flag
// GTEST_OUTPUT environment variable
// XML_OUTPUT_FILE environment variable
// 'default_value'
if (strcmp(flag, "output") == 0) {
value = posix::GetEnv("XML_OUTPUT_FILE");
if (value != NULL) {
return std::string("xml:") + value;
}
}
return default_value;
} }
} // namespace internal } // namespace internal

View File

@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Test - The Google C++ Testing Framework
// Google Test - The Google C++ Testing and Mocking Framework
// //
// This file implements a universal value printer that can print a // This file implements a universal value printer that can print a
// value of any type T: // value of any type T:
@ -43,12 +42,18 @@
// defines Foo. // defines Foo.
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <cctype>
#include <cstdint>
#include <cwchar> #include <cwchar>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <string> #include <string>
#include <type_traits>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
namespace testing { namespace testing {
@ -59,6 +64,7 @@ using ::std::ostream;
// Prints a segment of bytes in the given object. // Prints a segment of bytes in the given object.
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
size_t count, ostream* os) { size_t count, ostream* os) {
@ -89,7 +95,6 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
// If the object size is bigger than kThreshold, we'll have to omit // If the object size is bigger than kThreshold, we'll have to omit
// some details by printing only the first and the last kChunkSize // some details by printing only the first and the last kChunkSize
// bytes. // bytes.
// TODO(wan): let the user control the threshold using a flag.
if (count < kThreshold) { if (count < kThreshold) {
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
} else { } else {
@ -102,9 +107,19 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
*os << ">"; *os << ">";
} }
// Helpers for widening a character to char32_t. Since the standard does not
// specify if char / wchar_t is signed or unsigned, it is important to first
// convert it to the unsigned type of the same width before widening it to
// char32_t.
template <typename CharType>
char32_t ToChar32(CharType in) {
return static_cast<char32_t>(
static_cast<typename std::make_unsigned<CharType>::type>(in));
}
} // namespace } // namespace
namespace internal2 { namespace internal {
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the // Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object. The delegation simplifies the implementation, which // given object. The delegation simplifies the implementation, which
@ -116,14 +131,10 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
PrintBytesInObjectToImpl(obj_bytes, count, os); PrintBytesInObjectToImpl(obj_bytes, count, os);
} }
} // namespace internal2
namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one // Depending on the value of a char (or wchar_t), we print it in one
// of three formats: // of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
// - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a hexadecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n'). // - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat { enum CharFormat {
kAsIs, kAsIs,
@ -134,17 +145,15 @@ enum CharFormat {
// Returns true if c is a printable ASCII character. We test the // Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on // value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile. // Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) { inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; }
return 0x20 <= c && c <= 0x7E;
}
// Prints a wide or narrow char c as a character literal without the // Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a
// quotes, escaping it when necessary; returns how c was formatted. // character literal without the quotes, escaping it when necessary; returns how
// The template argument UnsignedChar is the unsigned version of Char, // c was formatted.
// which is the type of c. template <typename Char>
template <typename UnsignedChar, typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
switch (static_cast<wchar_t>(c)) { const char32_t u_c = ToChar32(c);
switch (u_c) {
case L'\0': case L'\0':
*os << "\\0"; *os << "\\0";
break; break;
@ -176,20 +185,22 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
*os << "\\v"; *os << "\\v";
break; break;
default: default:
if (IsPrintableAscii(c)) { if (IsPrintableAscii(u_c)) {
*os << static_cast<char>(c); *os << static_cast<char>(c);
return kAsIs; return kAsIs;
} else { } else {
*os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c)); ostream::fmtflags flags = os->flags();
*os << "\\x" << std::hex << std::uppercase << static_cast<int>(u_c);
os->flags(flags);
return kHexEscape; return kHexEscape;
} }
} }
return kSpecialEscape; return kSpecialEscape;
} }
// Prints a wchar_t c as if it's part of a string literal, escaping it when // Prints a char32_t c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted. // necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {
switch (c) { switch (c) {
case L'\'': case L'\'':
*os << "'"; *os << "'";
@ -198,26 +209,68 @@ static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
*os << "\\\""; *os << "\\\"";
return kSpecialEscape; return kSpecialEscape;
default: default:
return PrintAsCharLiteralTo<wchar_t>(c, os); return PrintAsCharLiteralTo(c, os);
} }
} }
static const char* GetCharWidthPrefix(char) {
return "";
}
static const char* GetCharWidthPrefix(signed char) {
return "";
}
static const char* GetCharWidthPrefix(unsigned char) {
return "";
}
#ifdef __cpp_char8_t
static const char* GetCharWidthPrefix(char8_t) {
return "u8";
}
#endif
static const char* GetCharWidthPrefix(char16_t) {
return "u";
}
static const char* GetCharWidthPrefix(char32_t) {
return "U";
}
static const char* GetCharWidthPrefix(wchar_t) {
return "L";
}
// Prints a char c as if it's part of a string literal, escaping it when // Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted. // necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
return PrintAsStringLiteralTo( return PrintAsStringLiteralTo(ToChar32(c), os);
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
} }
// Prints a wide or narrow character c and its code. '\0' is printed #ifdef __cpp_char8_t
// as "'\\0'", other unprintable characters are also properly escaped static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) {
// using the standard C++ escape sequence. The template argument return PrintAsStringLiteralTo(ToChar32(c), os);
// UnsignedChar is the unsigned version of Char, which is the type of c. }
template <typename UnsignedChar, typename Char> #endif
static CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) {
return PrintAsStringLiteralTo(ToChar32(c), os);
}
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
return PrintAsStringLiteralTo(ToChar32(c), os);
}
// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t)
// and its code. '\0' is printed as "'\\0'", other unprintable characters are
// also properly escaped using the standard C++ escape sequence.
template <typename Char>
void PrintCharAndCodeTo(Char c, ostream* os) { void PrintCharAndCodeTo(Char c, ostream* os) {
// First, print c as a literal in the most readable form we can find. // First, print c as a literal in the most readable form we can find.
*os << ((sizeof(c) > 1) ? "L'" : "'"); *os << GetCharWidthPrefix(c) << "'";
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); const CharFormat format = PrintAsCharLiteralTo(c, os);
*os << "'"; *os << "'";
// To aid user debugging, we also print c's code in decimal, unless // To aid user debugging, we also print c's code in decimal, unless
@ -227,54 +280,61 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
return; return;
*os << " (" << static_cast<int>(c); *os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexidecimal, // For more convenience, we print c's code again in hexadecimal,
// unless c was already printed in the form '\x##' or the code is in // unless c was already printed in the form '\x##' or the code is in
// [1, 9]. // [1, 9].
if (format == kHexEscape || (1 <= c && c <= 9)) { if (format == kHexEscape || (1 <= c && c <= 9)) {
// Do nothing. // Do nothing.
} else { } else {
*os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c)); *os << ", 0x" << String::FormatHexInt(static_cast<int>(c));
} }
*os << ")"; *os << ")";
} }
void PrintTo(unsigned char c, ::std::ostream* os) { void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }
PrintCharAndCodeTo<unsigned char>(c, os); void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }
}
void PrintTo(signed char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
// Prints a wchar_t as a symbol if it is printable or as its internal // Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its code. L'\0' is printed as "L'\\0'". // code otherwise and also as its code. L'\0' is printed as "L'\\0'".
void PrintTo(wchar_t wc, ostream* os) { void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); }
PrintCharAndCodeTo<wchar_t>(wc, os);
// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well.
void PrintTo(char32_t c, ::std::ostream* os) {
*os << std::hex << "U+" << std::uppercase << std::setfill('0') << std::setw(4)
<< static_cast<uint32_t>(c);
} }
// Prints the given array of characters to the ostream. CharType must be either // Prints the given array of characters to the ostream. CharType must be either
// char or wchar_t. // char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters // The array starts at begin, the length is len, it may include '\0' characters
// and may not be NUL-terminated. // and may not be NUL-terminated.
template <typename CharType> template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void PrintCharsAsStringTo( static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) { const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; const char* const quote_prefix = GetCharWidthPrefix(*begin);
*os << kQuoteBegin; *os << quote_prefix << "\"";
bool is_previous_hex = false; bool is_previous_hex = false;
CharFormat print_format = kAsIs;
for (size_t index = 0; index < len; ++index) { for (size_t index = 0; index < len; ++index) {
const CharType cur = begin[index]; const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) { if (is_previous_hex && IsXDigit(cur)) {
// Previous character is of '\x..' form and this character can be // Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to // interpreted as another hexadecimal digit in its number. Break string to
// disambiguate. // disambiguate.
*os << "\" " << kQuoteBegin; *os << "\" " << quote_prefix << "\"";
} }
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
// Remember if any characters required hex escaping.
if (is_previous_hex) {
print_format = kHexEscape;
}
} }
*os << "\""; *os << "\"";
return print_format;
} }
// Prints a (const) char/wchar_t array of 'len' elements, starting at address // Prints a (const) char/wchar_t array of 'len' elements, starting at address
@ -282,6 +342,7 @@ static void PrintCharsAsStringTo(
template <typename CharType> template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void UniversalPrintCharArray( static void UniversalPrintCharArray(
const CharType* begin, size_t len, ostream* os) { const CharType* begin, size_t len, ostream* os) {
@ -310,22 +371,57 @@ void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os); UniversalPrintCharArray(begin, len, os);
} }
#ifdef __cpp_char8_t
// Prints a (const) char8_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
#endif
// Prints a (const) char16_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints a (const) char32_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints a (const) wchar_t array of 'len' elements, starting at address // Prints a (const) wchar_t array of 'len' elements, starting at address
// 'begin'. // 'begin'.
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os); UniversalPrintCharArray(begin, len, os);
} }
// Prints the given C string to the ostream. namespace {
void PrintTo(const char* s, ostream* os) {
if (s == NULL) { // Prints a null-terminated C-style string to the ostream.
template <typename Char>
void PrintCStringTo(const Char* s, ostream* os) {
if (s == nullptr) {
*os << "NULL"; *os << "NULL";
} else { } else {
*os << ImplicitCast_<const void*>(s) << " pointing to "; *os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, strlen(s), os); PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os);
} }
} }
} // anonymous namespace
void PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); }
#ifdef __cpp_char8_t
void PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); }
#endif
void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); }
void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); }
// MSVC compiler can be configured to define whar_t as a typedef // MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case // of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings, // would cause pointers to unsigned shorts be printed as wide strings,
@ -334,33 +430,97 @@ void PrintTo(const char* s, ostream* os) {
// wchar_t is implemented as a native type. // wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream. // Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) { void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
if (s == NULL) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, std::wcslen(s), os);
}
}
#endif // wchar_t is native #endif // wchar_t is native
// Prints a ::string object. namespace {
#if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) { bool ContainsUnprintableControlCodes(const char* str, size_t length) {
PrintCharsAsStringTo(s.data(), s.size(), os); const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
for (size_t i = 0; i < length; i++) {
unsigned char ch = *s++;
if (std::iscntrl(ch)) {
switch (ch) {
case '\t':
case '\n':
case '\r':
break;
default:
return true;
}
}
}
return false;
} }
#endif // GTEST_HAS_GLOBAL_STRING
bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; }
bool IsValidUTF8(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
for (size_t i = 0; i < length;) {
unsigned char lead = s[i++];
if (lead <= 0x7f) {
continue; // single-byte character (ASCII) 0..7F
}
if (lead < 0xc2) {
return false; // trail byte or non-shortest form
} else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
++i; // 2-byte character
} else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
IsUTF8TrailByte(s[i]) &&
IsUTF8TrailByte(s[i + 1]) &&
// check for non-shortest form and surrogate
(lead != 0xe0 || s[i] >= 0xa0) &&
(lead != 0xed || s[i] < 0xa0)) {
i += 2; // 3-byte character
} else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
IsUTF8TrailByte(s[i]) &&
IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i + 2]) &&
// check for non-shortest form
(lead != 0xf0 || s[i] >= 0x90) &&
(lead != 0xf4 || s[i] < 0x90)) {
i += 3; // 4-byte character
} else {
return false;
}
}
return true;
}
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
if (!ContainsUnprintableControlCodes(str, length) &&
IsValidUTF8(str, length)) {
*os << "\n As Text: \"" << str << "\"";
}
}
} // anonymous namespace
void PrintStringTo(const ::std::string& s, ostream* os) { void PrintStringTo(const ::std::string& s, ostream* os) {
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os);
}
}
}
#ifdef __cpp_char8_t
void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif
void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
// Prints a ::wstring object. void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
#if GTEST_HAS_GLOBAL_WSTRING
void PrintWideStringTo(const ::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); PrintCharsAsStringTo(s.data(), s.size(), os);
} }
#endif // GTEST_HAS_GLOBAL_WSTRING
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) { void PrintWideStringTo(const ::std::wstring& s, ostream* os) {

View File

@ -26,21 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Author: mheule@google.com (Markus Heule) // The Google C++ Testing and Mocking Framework (Google Test)
//
// The Google C++ Testing Framework (Google Test)
#include "gtest/gtest-test-part.h" #include "gtest/gtest-test-part.h"
// Indicates that this translation unit is part of Google Test's #include "gtest/internal/gtest-port.h"
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick exists to
// prevent the accidental inclusion of gtest-internal-inl.h in the
// user's code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing { namespace testing {
@ -50,17 +43,22 @@ using internal::GetUnitTestImpl;
// in it. // in it.
std::string TestPartResult::ExtractSummary(const char* message) { std::string TestPartResult::ExtractSummary(const char* message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker); const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
return stack_trace == NULL ? message : return stack_trace == nullptr ? message : std::string(message, stack_trace);
std::string(message, stack_trace);
} }
// Prints a TestPartResult object. // Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
return os return os << internal::FormatFileLocation(result.file_name(),
<< result.file_name() << ":" << result.line_number() << ": " result.line_number())
<< (result.type() == TestPartResult::kSuccess ? "Success" : << " "
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : << (result.type() == TestPartResult::kSuccess
"Non-fatal failure") << ":\n" ? "Success"
: result.type() == TestPartResult::kSkip
? "Skipped"
: result.type() == TestPartResult::kFatalFailure
? "Fatal failure"
: "Non-fatal failure")
<< ":\n"
<< result.message() << std::endl; << result.message() << std::endl;
} }
@ -76,7 +74,7 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
internal::posix::Abort(); internal::posix::Abort();
} }
return array_[index]; return array_[static_cast<size_t>(index)];
} }
// Returns the number of TestPartResult objects in the array. // Returns the number of TestPartResult objects in the array.

View File

@ -26,17 +26,15 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest-typed-test.h" #include "gtest/gtest-typed-test.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace testing { namespace testing {
namespace internal { namespace internal {
#if GTEST_HAS_TYPED_TEST_P
// Skips to the first non-space char in str. Returns an empty string if str // Skips to the first non-space char in str. Returns an empty string if str
// contains only whitespace characters. // contains only whitespace characters.
static const char* SkipSpaces(const char* str) { static const char* SkipSpaces(const char* str) {
@ -48,7 +46,7 @@ static const char* SkipSpaces(const char* str) {
static std::vector<std::string> SplitIntoTestNames(const char* src) { static std::vector<std::string> SplitIntoTestNames(const char* src) {
std::vector<std::string> name_vec; std::vector<std::string> name_vec;
src = SkipSpaces(src); src = SkipSpaces(src);
for (; src != NULL; src = SkipComma(src)) { for (; src != nullptr; src = SkipComma(src)) {
name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));
} }
return name_vec; return name_vec;
@ -57,8 +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
// registered_tests_; 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* TypedTestSuitePState::VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests) { const char* test_suite_name, const char* file, int line,
const char* registered_tests) {
RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));
typedef RegisteredTestsMap::const_iterator RegisteredTestIter; typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
registered_ = true; registered_ = true;
@ -75,21 +76,11 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
continue; continue;
} }
bool found = false; if (registered_tests_.count(name) != 0) {
for (RegisteredTestIter it = registered_tests_.begin();
it != registered_tests_.end();
++it) {
if (name == it->first) {
found = true;
break;
}
}
if (found) {
tests.insert(name); tests.insert(name);
} else { } else {
errors << "No test named " << name errors << "No test named " << name
<< " can be found in this test case.\n"; << " can be found in this test suite.\n";
} }
} }
@ -112,7 +103,5 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
return registered_tests; return registered_tests;
} }
#endif // GTEST_HAS_TYPED_TEST_P
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,28 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h> #include <cstdio>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
#if GTEST_OS_ESP8266
extern "C" {
#endif
void setup() {
testing::InitGoogleTest();
}
void loop() { RUN_ALL_TESTS(); }
#if GTEST_OS_ESP8266
}
#endif
#else
GTEST_API_ int main(int argc, char **argv) { GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from gtest_main.cc\n"); printf("Running main() from %s\n", __FILE__);
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
#endif

View File

@ -1,93 +0,0 @@
// Copyright 2010, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
//
// Tests that verify interaction of exceptions and death tests.
#include "gtest/gtest-death-test.h"
#include "gtest/gtest.h"
#if GTEST_HAS_DEATH_TEST
# if GTEST_HAS_SEH
# include <windows.h> // For RaiseException().
# endif
# include "gtest/gtest-spi.h"
# if GTEST_HAS_EXCEPTIONS
# include <exception> // For std::exception.
// Tests that death tests report thrown exceptions as failures and that the
// exceptions do not escape death test macros.
TEST(CxxExceptionDeathTest, ExceptionIsFailure) {
try {
EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception");
} catch (...) { // NOLINT
FAIL() << "An exception escaped a death test macro invocation "
<< "with catch_exceptions "
<< (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
}
}
class TestException : public std::exception {
public:
virtual const char* what() const throw() { return "exceptional message"; }
};
TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) {
// Verifies that the exception message is quoted in the failure text.
EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""),
"exceptional message");
// Verifies that the location is mentioned in the failure text.
EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""),
"gtest-death-test_ex_test.cc");
}
# endif // GTEST_HAS_EXCEPTIONS
# if GTEST_HAS_SEH
// Tests that enabling interception of SEH exceptions with the
// catch_exceptions flag does not interfere with SEH exceptions being
// treated as death by death tests.
TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) {
EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "")
<< "with catch_exceptions "
<< (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled");
}
# endif
#endif // GTEST_HAS_DEATH_TEST
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0;
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,662 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: keith.ray@gmail.com (Keith Ray)
//
// Google Test filepath utilities
//
// This file tests classes and functions used internally by
// Google Test. They are subject to change without notice.
//
// This file is #included from gtest_unittest.cc, to avoid changing
// build or make-files for some existing Google Test clients. Do not
// #include this file anywhere else!
#include "gtest/internal/gtest-filepath.h"
#include "gtest/gtest.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// his code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
#if GTEST_OS_WINDOWS_MOBILE
# include <windows.h> // NOLINT
#elif GTEST_OS_WINDOWS
# include <direct.h> // NOLINT
#endif // GTEST_OS_WINDOWS_MOBILE
namespace testing {
namespace internal {
namespace {
#if GTEST_OS_WINDOWS_MOBILE
// TODO(wan@google.com): Move these to the POSIX adapter section in
// gtest-port.h.
// Windows CE doesn't have the remove C function.
int remove(const char* path) {
LPCWSTR wpath = String::AnsiToUtf16(path);
int ret = DeleteFile(wpath) ? 0 : -1;
delete [] wpath;
return ret;
}
// Windows CE doesn't have the _rmdir C function.
int _rmdir(const char* path) {
FilePath filepath(path);
LPCWSTR wpath = String::AnsiToUtf16(
filepath.RemoveTrailingPathSeparator().c_str());
int ret = RemoveDirectory(wpath) ? 0 : -1;
delete [] wpath;
return ret;
}
#else
TEST(GetCurrentDirTest, ReturnsCurrentDir) {
const FilePath original_dir = FilePath::GetCurrentDir();
EXPECT_FALSE(original_dir.IsEmpty());
posix::ChDir(GTEST_PATH_SEP_);
const FilePath cwd = FilePath::GetCurrentDir();
posix::ChDir(original_dir.c_str());
# if GTEST_OS_WINDOWS
// Skips the ":".
const char* const cwd_without_drive = strchr(cwd.c_str(), ':');
ASSERT_TRUE(cwd_without_drive != NULL);
EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1);
# else
EXPECT_EQ(GTEST_PATH_SEP_, cwd.string());
# endif
}
#endif // GTEST_OS_WINDOWS_MOBILE
TEST(IsEmptyTest, ReturnsTrueForEmptyPath) {
EXPECT_TRUE(FilePath("").IsEmpty());
}
TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) {
EXPECT_FALSE(FilePath("a").IsEmpty());
EXPECT_FALSE(FilePath(".").IsEmpty());
EXPECT_FALSE(FilePath("a/b").IsEmpty());
EXPECT_FALSE(FilePath("a\\b\\").IsEmpty());
}
// RemoveDirectoryName "" -> ""
TEST(RemoveDirectoryNameTest, WhenEmptyName) {
EXPECT_EQ("", FilePath("").RemoveDirectoryName().string());
}
// RemoveDirectoryName "afile" -> "afile"
TEST(RemoveDirectoryNameTest, ButNoDirectory) {
EXPECT_EQ("afile",
FilePath("afile").RemoveDirectoryName().string());
}
// RemoveDirectoryName "/afile" -> "afile"
TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) {
EXPECT_EQ("afile",
FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string());
}
// RemoveDirectoryName "adir/" -> ""
TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) {
EXPECT_EQ("",
FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string());
}
// RemoveDirectoryName "adir/afile" -> "afile"
TEST(RemoveDirectoryNameTest, ShouldGiveFileName) {
EXPECT_EQ("afile",
FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string());
}
// RemoveDirectoryName "adir/subdir/afile" -> "afile"
TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
EXPECT_EQ("afile",
FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
.RemoveDirectoryName().string());
}
#if GTEST_HAS_ALT_PATH_SEP_
// Tests that RemoveDirectoryName() works with the alternate separator
// on Windows.
// RemoveDirectoryName("/afile") -> "afile"
TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) {
EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string());
}
// RemoveDirectoryName("adir/") -> ""
TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) {
EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string());
}
// RemoveDirectoryName("adir/afile") -> "afile"
TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) {
EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string());
}
// RemoveDirectoryName("adir/subdir/afile") -> "afile"
TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
EXPECT_EQ("afile",
FilePath("adir/subdir/afile").RemoveDirectoryName().string());
}
#endif
// RemoveFileName "" -> "./"
TEST(RemoveFileNameTest, EmptyName) {
#if GTEST_OS_WINDOWS_MOBILE
// On Windows CE, we use the root as the current directory.
EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string());
#else
EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string());
#endif
}
// RemoveFileName "adir/" -> "adir/"
TEST(RemoveFileNameTest, ButNoFile) {
EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string());
}
// RemoveFileName "adir/afile" -> "adir/"
TEST(RemoveFileNameTest, GivesDirName) {
EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string());
}
// RemoveFileName "adir/subdir/afile" -> "adir/subdir/"
TEST(RemoveFileNameTest, GivesDirAndSubDirName) {
EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
.RemoveFileName().string());
}
// RemoveFileName "/afile" -> "/"
TEST(RemoveFileNameTest, GivesRootDir) {
EXPECT_EQ(GTEST_PATH_SEP_,
FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string());
}
#if GTEST_HAS_ALT_PATH_SEP_
// Tests that RemoveFileName() works with the alternate separator on
// Windows.
// RemoveFileName("adir/") -> "adir/"
TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) {
EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir/").RemoveFileName().string());
}
// RemoveFileName("adir/afile") -> "adir/"
TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) {
EXPECT_EQ("adir" GTEST_PATH_SEP_,
FilePath("adir/afile").RemoveFileName().string());
}
// RemoveFileName("adir/subdir/afile") -> "adir/subdir/"
TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) {
EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
FilePath("adir/subdir/afile").RemoveFileName().string());
}
// RemoveFileName("/afile") -> "\"
TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string());
}
#endif
TEST(MakeFileNameTest, GenerateWhenNumberIsZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
0, "xml");
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
}
TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
12, "xml");
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string());
}
TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar"), 0, "xml");
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
}
TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) {
FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar"), 12, "xml");
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string());
}
TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) {
FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"),
0, "xml");
EXPECT_EQ("bar.xml", actual.string());
}
TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) {
FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"),
14, "xml");
EXPECT_EQ("bar_14.xml", actual.string());
}
TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
FilePath("bar.xml"));
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
}
TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar.xml"));
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string());
}
TEST(ConcatPathsTest, Path1BeingEmpty) {
FilePath actual = FilePath::ConcatPaths(FilePath(""),
FilePath("bar.xml"));
EXPECT_EQ("bar.xml", actual.string());
}
TEST(ConcatPathsTest, Path2BeingEmpty) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath(""));
EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string());
}
TEST(ConcatPathsTest, BothPathBeingEmpty) {
FilePath actual = FilePath::ConcatPaths(FilePath(""),
FilePath(""));
EXPECT_EQ("", actual.string());
}
TEST(ConcatPathsTest, Path1ContainsPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"),
FilePath("foobar.xml"));
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml",
actual.string());
}
TEST(ConcatPathsTest, Path2ContainsPathSep) {
FilePath actual = FilePath::ConcatPaths(
FilePath("foo" GTEST_PATH_SEP_),
FilePath("bar" GTEST_PATH_SEP_ "bar.xml"));
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml",
actual.string());
}
TEST(ConcatPathsTest, Path2EndsWithPathSep) {
FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
FilePath("bar" GTEST_PATH_SEP_));
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string());
}
// RemoveTrailingPathSeparator "" -> ""
TEST(RemoveTrailingPathSeparatorTest, EmptyString) {
EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string());
}
// RemoveTrailingPathSeparator "foo" -> "foo"
TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) {
EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string());
}
// RemoveTrailingPathSeparator "foo/" -> "foo"
TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) {
EXPECT_EQ("foo",
FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string());
#if GTEST_HAS_ALT_PATH_SEP_
EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string());
#endif
}
// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/"
TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) {
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_)
.RemoveTrailingPathSeparator().string());
}
// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar"
TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) {
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ "bar")
.RemoveTrailingPathSeparator().string());
}
TEST(DirectoryTest, RootDirectoryExists) {
#if GTEST_OS_WINDOWS // We are on Windows.
char current_drive[_MAX_PATH]; // NOLINT
current_drive[0] = static_cast<char>(_getdrive() + 'A' - 1);
current_drive[1] = ':';
current_drive[2] = '\\';
current_drive[3] = '\0';
EXPECT_TRUE(FilePath(current_drive).DirectoryExists());
#else
EXPECT_TRUE(FilePath("/").DirectoryExists());
#endif // GTEST_OS_WINDOWS
}
#if GTEST_OS_WINDOWS
TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) {
const int saved_drive_ = _getdrive();
// Find a drive that doesn't exist. Start with 'Z' to avoid common ones.
for (char drive = 'Z'; drive >= 'A'; drive--)
if (_chdrive(drive - 'A' + 1) == -1) {
char non_drive[_MAX_PATH]; // NOLINT
non_drive[0] = drive;
non_drive[1] = ':';
non_drive[2] = '\\';
non_drive[3] = '\0';
EXPECT_FALSE(FilePath(non_drive).DirectoryExists());
break;
}
_chdrive(saved_drive_);
}
#endif // GTEST_OS_WINDOWS
#if !GTEST_OS_WINDOWS_MOBILE
// Windows CE _does_ consider an empty directory to exist.
TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) {
EXPECT_FALSE(FilePath("").DirectoryExists());
}
#endif // !GTEST_OS_WINDOWS_MOBILE
TEST(DirectoryTest, CurrentDirectoryExists) {
#if GTEST_OS_WINDOWS // We are on Windows.
# ifndef _WIN32_CE // Windows CE doesn't have a current directory.
EXPECT_TRUE(FilePath(".").DirectoryExists());
EXPECT_TRUE(FilePath(".\\").DirectoryExists());
# endif // _WIN32_CE
#else
EXPECT_TRUE(FilePath(".").DirectoryExists());
EXPECT_TRUE(FilePath("./").DirectoryExists());
#endif // GTEST_OS_WINDOWS
}
// "foo/bar" == foo//bar" == "foo///bar"
TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) {
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ "bar").string());
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar",
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_
GTEST_PATH_SEP_ "bar").string());
}
// "/bar" == //bar" == "///bar"
TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) {
EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ "bar").string());
EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
EXPECT_EQ(GTEST_PATH_SEP_ "bar",
FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string());
}
// "foo/" == foo//" == "foo///"
TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) {
EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_).string());
EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string());
EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string());
}
#if GTEST_HAS_ALT_PATH_SEP_
// Tests that separators at the end of the string are normalized
// regardless of their combination (e.g. "foo\" =="foo/\" ==
// "foo\\/").
TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) {
EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo/").string());
EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo" GTEST_PATH_SEP_ "/").string());
EXPECT_EQ("foo" GTEST_PATH_SEP_,
FilePath("foo//" GTEST_PATH_SEP_).string());
}
#endif
TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) {
FilePath default_path;
FilePath non_default_path("path");
non_default_path = default_path;
EXPECT_EQ("", non_default_path.string());
EXPECT_EQ("", default_path.string()); // RHS var is unchanged.
}
TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) {
FilePath non_default_path("path");
FilePath default_path;
default_path = non_default_path;
EXPECT_EQ("path", default_path.string());
EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged.
}
TEST(AssignmentOperatorTest, ConstAssignedToNonConst) {
const FilePath const_default_path("const_path");
FilePath non_default_path("path");
non_default_path = const_default_path;
EXPECT_EQ("const_path", non_default_path.string());
}
class DirectoryCreationTest : public Test {
protected:
virtual void SetUp() {
testdata_path_.Set(FilePath(
TempDir() + GetCurrentExecutableName().string() +
"_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_));
testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator());
unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"),
0, "txt"));
unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"),
1, "txt"));
remove(testdata_file_.c_str());
remove(unique_file0_.c_str());
remove(unique_file1_.c_str());
posix::RmDir(testdata_path_.c_str());
}
virtual void TearDown() {
remove(testdata_file_.c_str());
remove(unique_file0_.c_str());
remove(unique_file1_.c_str());
posix::RmDir(testdata_path_.c_str());
}
void CreateTextFile(const char* filename) {
FILE* f = posix::FOpen(filename, "w");
fprintf(f, "text\n");
fclose(f);
}
// Strings representing a directory and a file, with identical paths
// except for the trailing separator character that distinquishes
// a directory named 'test' from a file named 'test'. Example names:
FilePath testdata_path_; // "/tmp/directory_creation/test/"
FilePath testdata_file_; // "/tmp/directory_creation/test"
FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt"
FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt"
};
TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) {
EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string();
EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
EXPECT_TRUE(testdata_path_.DirectoryExists());
}
TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) {
EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string();
EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
// Call 'create' again... should still succeed.
EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
}
TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) {
FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_,
FilePath("unique"), "txt"));
EXPECT_EQ(unique_file0_.string(), file_path.string());
EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there
testdata_path_.CreateDirectoriesRecursively();
EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there
CreateTextFile(file_path.c_str());
EXPECT_TRUE(file_path.FileOrDirectoryExists());
FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_,
FilePath("unique"), "txt"));
EXPECT_EQ(unique_file1_.string(), file_path2.string());
EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there
CreateTextFile(file_path2.c_str());
EXPECT_TRUE(file_path2.FileOrDirectoryExists());
}
TEST_F(DirectoryCreationTest, CreateDirectoriesFail) {
// force a failure by putting a file where we will try to create a directory.
CreateTextFile(testdata_file_.c_str());
EXPECT_TRUE(testdata_file_.FileOrDirectoryExists());
EXPECT_FALSE(testdata_file_.DirectoryExists());
EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively());
}
TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) {
const FilePath test_detail_xml("test_detail.xml");
EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively());
}
TEST(FilePathTest, DefaultConstructor) {
FilePath fp;
EXPECT_EQ("", fp.string());
}
TEST(FilePathTest, CharAndCopyConstructors) {
const FilePath fp("spicy");
EXPECT_EQ("spicy", fp.string());
const FilePath fp_copy(fp);
EXPECT_EQ("spicy", fp_copy.string());
}
TEST(FilePathTest, StringConstructor) {
const FilePath fp(std::string("cider"));
EXPECT_EQ("cider", fp.string());
}
TEST(FilePathTest, Set) {
const FilePath apple("apple");
FilePath mac("mac");
mac.Set(apple); // Implement Set() since overloading operator= is forbidden.
EXPECT_EQ("apple", mac.string());
EXPECT_EQ("apple", apple.string());
}
TEST(FilePathTest, ToString) {
const FilePath file("drink");
EXPECT_EQ("drink", file.string());
}
TEST(FilePathTest, RemoveExtension) {
EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string());
EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string());
EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string());
}
TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) {
EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string());
}
TEST(FilePathTest, IsDirectory) {
EXPECT_FALSE(FilePath("cola").IsDirectory());
EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory());
#if GTEST_HAS_ALT_PATH_SEP_
EXPECT_TRUE(FilePath("koala/").IsDirectory());
#endif
}
TEST(FilePathTest, IsAbsolutePath) {
EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath());
EXPECT_FALSE(FilePath("").IsAbsolutePath());
#if GTEST_OS_WINDOWS
EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not"
GTEST_PATH_SEP_ "relative").IsAbsolutePath());
EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath());
EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not"
GTEST_PATH_SEP_ "relative").IsAbsolutePath());
#else
EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
.IsAbsolutePath());
#endif // GTEST_OS_WINDOWS
}
TEST(FilePathTest, IsRootDirectory) {
#if GTEST_OS_WINDOWS
EXPECT_TRUE(FilePath("a:\\").IsRootDirectory());
EXPECT_TRUE(FilePath("Z:/").IsRootDirectory());
EXPECT_TRUE(FilePath("e://").IsRootDirectory());
EXPECT_FALSE(FilePath("").IsRootDirectory());
EXPECT_FALSE(FilePath("b:").IsRootDirectory());
EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
#else
EXPECT_TRUE(FilePath("/").IsRootDirectory());
EXPECT_TRUE(FilePath("//").IsRootDirectory());
EXPECT_FALSE(FilePath("").IsRootDirectory());
EXPECT_FALSE(FilePath("\\").IsRootDirectory());
EXPECT_FALSE(FilePath("/x").IsRootDirectory());
#endif
}
} // namespace
} // namespace internal
} // namespace testing

View File

@ -1,154 +0,0 @@
// Copyright 2003, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Dan Egnor (egnor@google.com)
// Ported to Windows: Vadim Berman (vadimb@google.com)
#include "gtest/internal/gtest-linked_ptr.h"
#include <stdlib.h>
#include "gtest/gtest.h"
namespace {
using testing::Message;
using testing::internal::linked_ptr;
int num;
Message* history = NULL;
// Class which tracks allocation/deallocation
class A {
public:
A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; }
virtual ~A() { *history << "A" << mynum << " dtor\n"; }
virtual void Use() { *history << "A" << mynum << " use\n"; }
protected:
int mynum;
};
// Subclass
class B : public A {
public:
B() { *history << "B" << mynum << " ctor\n"; }
~B() { *history << "B" << mynum << " dtor\n"; }
virtual void Use() { *history << "B" << mynum << " use\n"; }
};
class LinkedPtrTest : public testing::Test {
public:
LinkedPtrTest() {
num = 0;
history = new Message;
}
virtual ~LinkedPtrTest() {
delete history;
history = NULL;
}
};
TEST_F(LinkedPtrTest, GeneralTest) {
{
linked_ptr<A> a0, a1, a2;
// Use explicit function call notation here to suppress self-assign warning.
a0.operator=(a0);
a1 = a2;
ASSERT_EQ(a0.get(), static_cast<A*>(NULL));
ASSERT_EQ(a1.get(), static_cast<A*>(NULL));
ASSERT_EQ(a2.get(), static_cast<A*>(NULL));
ASSERT_TRUE(a0 == NULL);
ASSERT_TRUE(a1 == NULL);
ASSERT_TRUE(a2 == NULL);
{
linked_ptr<A> a3(new A);
a0 = a3;
ASSERT_TRUE(a0 == a3);
ASSERT_TRUE(a0 != NULL);
ASSERT_TRUE(a0.get() == a3);
ASSERT_TRUE(a0 == a3.get());
linked_ptr<A> a4(a0);
a1 = a4;
linked_ptr<A> a5(new A);
ASSERT_TRUE(a5.get() != a3);
ASSERT_TRUE(a5 != a3.get());
a2 = a5;
linked_ptr<B> b0(new B);
linked_ptr<A> a6(b0);
ASSERT_TRUE(b0 == a6);
ASSERT_TRUE(a6 == b0);
ASSERT_TRUE(b0 != NULL);
a5 = b0;
a5 = b0;
a3->Use();
a4->Use();
a5->Use();
a6->Use();
b0->Use();
(*b0).Use();
b0.get()->Use();
}
a0->Use();
a1->Use();
a2->Use();
a1 = a2;
a2.reset(new A);
a0.reset();
linked_ptr<A> a7;
}
ASSERT_STREQ(
"A0 ctor\n"
"A1 ctor\n"
"A2 ctor\n"
"B2 ctor\n"
"A0 use\n"
"A0 use\n"
"B2 use\n"
"B2 use\n"
"B2 use\n"
"B2 use\n"
"B2 use\n"
"B2 dtor\n"
"A2 dtor\n"
"A0 use\n"
"A0 use\n"
"A1 use\n"
"A3 ctor\n"
"A0 dtor\n"
"A3 dtor\n"
"A1 dtor\n",
history->GetString().c_str());
}
} // Unnamed namespace

View File

@ -1,311 +0,0 @@
// Copyright 2009 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
//
// The Google C++ Testing Framework (Google Test)
//
// This file verifies Google Test event listeners receive events at the
// right times.
#include "gtest/gtest.h"
#include <vector>
using ::testing::AddGlobalTestEnvironment;
using ::testing::Environment;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListener;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;
// Used by tests to register their events.
std::vector<std::string>* g_events = NULL;
namespace testing {
namespace internal {
class EventRecordingListener : public TestEventListener {
public:
explicit EventRecordingListener(const char* name) : name_(name) {}
protected:
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
g_events->push_back(GetFullMethodName("OnTestProgramStart"));
}
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
int iteration) {
Message message;
message << GetFullMethodName("OnTestIterationStart")
<< "(" << iteration << ")";
g_events->push_back(message.GetString());
}
virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {
g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart"));
}
virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {
g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd"));
}
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {
g_events->push_back(GetFullMethodName("OnTestCaseStart"));
}
virtual void OnTestStart(const TestInfo& /*test_info*/) {
g_events->push_back(GetFullMethodName("OnTestStart"));
}
virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {
g_events->push_back(GetFullMethodName("OnTestPartResult"));
}
virtual void OnTestEnd(const TestInfo& /*test_info*/) {
g_events->push_back(GetFullMethodName("OnTestEnd"));
}
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {
g_events->push_back(GetFullMethodName("OnTestCaseEnd"));
}
virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {
g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart"));
}
virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {
g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd"));
}
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
int iteration) {
Message message;
message << GetFullMethodName("OnTestIterationEnd")
<< "(" << iteration << ")";
g_events->push_back(message.GetString());
}
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
g_events->push_back(GetFullMethodName("OnTestProgramEnd"));
}
private:
std::string GetFullMethodName(const char* name) {
return name_ + "." + name;
}
std::string name_;
};
class EnvironmentInvocationCatcher : public Environment {
protected:
virtual void SetUp() {
g_events->push_back("Environment::SetUp");
}
virtual void TearDown() {
g_events->push_back("Environment::TearDown");
}
};
class ListenerTest : public Test {
protected:
static void SetUpTestCase() {
g_events->push_back("ListenerTest::SetUpTestCase");
}
static void TearDownTestCase() {
g_events->push_back("ListenerTest::TearDownTestCase");
}
virtual void SetUp() {
g_events->push_back("ListenerTest::SetUp");
}
virtual void TearDown() {
g_events->push_back("ListenerTest::TearDown");
}
};
TEST_F(ListenerTest, DoesFoo) {
// Test execution order within a test case is not guaranteed so we are not
// recording the test name.
g_events->push_back("ListenerTest::* Test Body");
SUCCEED(); // Triggers OnTestPartResult.
}
TEST_F(ListenerTest, DoesBar) {
g_events->push_back("ListenerTest::* Test Body");
SUCCEED(); // Triggers OnTestPartResult.
}
} // namespace internal
} // namespace testing
using ::testing::internal::EnvironmentInvocationCatcher;
using ::testing::internal::EventRecordingListener;
void VerifyResults(const std::vector<std::string>& data,
const char* const* expected_data,
size_t expected_data_size) {
const size_t actual_size = data.size();
// If the following assertion fails, a new entry will be appended to
// data. Hence we save data.size() first.
EXPECT_EQ(expected_data_size, actual_size);
// Compares the common prefix.
const size_t shorter_size = expected_data_size <= actual_size ?
expected_data_size : actual_size;
size_t i = 0;
for (; i < shorter_size; ++i) {
ASSERT_STREQ(expected_data[i], data[i].c_str())
<< "at position " << i;
}
// Prints extra elements in the actual data.
for (; i < actual_size; ++i) {
printf(" Actual event #%lu: %s\n",
static_cast<unsigned long>(i), data[i].c_str());
}
}
int main(int argc, char **argv) {
std::vector<std::string> events;
g_events = &events;
InitGoogleTest(&argc, argv);
UnitTest::GetInstance()->listeners().Append(
new EventRecordingListener("1st"));
UnitTest::GetInstance()->listeners().Append(
new EventRecordingListener("2nd"));
AddGlobalTestEnvironment(new EnvironmentInvocationCatcher);
GTEST_CHECK_(events.size() == 0)
<< "AddGlobalTestEnvironment should not generate any events itself.";
::testing::GTEST_FLAG(repeat) = 2;
int ret_val = RUN_ALL_TESTS();
const char* const expected_events[] = {
"1st.OnTestProgramStart",
"2nd.OnTestProgramStart",
"1st.OnTestIterationStart(0)",
"2nd.OnTestIterationStart(0)",
"1st.OnEnvironmentsSetUpStart",
"2nd.OnEnvironmentsSetUpStart",
"Environment::SetUp",
"2nd.OnEnvironmentsSetUpEnd",
"1st.OnEnvironmentsSetUpEnd",
"1st.OnTestCaseStart",
"2nd.OnTestCaseStart",
"ListenerTest::SetUpTestCase",
"1st.OnTestStart",
"2nd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"ListenerTest::TearDown",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"1st.OnTestStart",
"2nd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"ListenerTest::TearDown",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"ListenerTest::TearDownTestCase",
"2nd.OnTestCaseEnd",
"1st.OnTestCaseEnd",
"1st.OnEnvironmentsTearDownStart",
"2nd.OnEnvironmentsTearDownStart",
"Environment::TearDown",
"2nd.OnEnvironmentsTearDownEnd",
"1st.OnEnvironmentsTearDownEnd",
"2nd.OnTestIterationEnd(0)",
"1st.OnTestIterationEnd(0)",
"1st.OnTestIterationStart(1)",
"2nd.OnTestIterationStart(1)",
"1st.OnEnvironmentsSetUpStart",
"2nd.OnEnvironmentsSetUpStart",
"Environment::SetUp",
"2nd.OnEnvironmentsSetUpEnd",
"1st.OnEnvironmentsSetUpEnd",
"1st.OnTestCaseStart",
"2nd.OnTestCaseStart",
"ListenerTest::SetUpTestCase",
"1st.OnTestStart",
"2nd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"ListenerTest::TearDown",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"1st.OnTestStart",
"2nd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"ListenerTest::TearDown",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"ListenerTest::TearDownTestCase",
"2nd.OnTestCaseEnd",
"1st.OnTestCaseEnd",
"1st.OnEnvironmentsTearDownStart",
"2nd.OnEnvironmentsTearDownStart",
"Environment::TearDown",
"2nd.OnEnvironmentsTearDownEnd",
"1st.OnEnvironmentsTearDownEnd",
"2nd.OnTestIterationEnd(1)",
"1st.OnTestIterationEnd(1)",
"2nd.OnTestProgramEnd",
"1st.OnTestProgramEnd"
};
VerifyResults(events,
expected_events,
sizeof(expected_events)/sizeof(expected_events[0]));
// We need to check manually for ad hoc test failures that happen after
// RUN_ALL_TESTS finishes.
if (UnitTest::GetInstance()->Failed())
ret_val = 1;
return ret_val;
}

View File

@ -1,159 +0,0 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Tests for the Message class.
#include "gtest/gtest-message.h"
#include "gtest/gtest.h"
namespace {
using ::testing::Message;
// Tests the testing::Message class
// Tests the default constructor.
TEST(MessageTest, DefaultConstructor) {
const Message msg;
EXPECT_EQ("", msg.GetString());
}
// Tests the copy constructor.
TEST(MessageTest, CopyConstructor) {
const Message msg1("Hello");
const Message msg2(msg1);
EXPECT_EQ("Hello", msg2.GetString());
}
// Tests constructing a Message from a C-string.
TEST(MessageTest, ConstructsFromCString) {
Message msg("Hello");
EXPECT_EQ("Hello", msg.GetString());
}
// Tests streaming a float.
TEST(MessageTest, StreamsFloat) {
const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString();
// Both numbers should be printed with enough precision.
EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str());
EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str());
}
// Tests streaming a double.
TEST(MessageTest, StreamsDouble) {
const std::string s = (Message() << 1260570880.4555497 << " "
<< 1260572265.1954534).GetString();
// Both numbers should be printed with enough precision.
EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str());
EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str());
}
// Tests streaming a non-char pointer.
TEST(MessageTest, StreamsPointer) {
int n = 0;
int* p = &n;
EXPECT_NE("(null)", (Message() << p).GetString());
}
// Tests streaming a NULL non-char pointer.
TEST(MessageTest, StreamsNullPointer) {
int* p = NULL;
EXPECT_EQ("(null)", (Message() << p).GetString());
}
// Tests streaming a C string.
TEST(MessageTest, StreamsCString) {
EXPECT_EQ("Foo", (Message() << "Foo").GetString());
}
// Tests streaming a NULL C string.
TEST(MessageTest, StreamsNullCString) {
char* p = NULL;
EXPECT_EQ("(null)", (Message() << p).GetString());
}
// Tests streaming std::string.
TEST(MessageTest, StreamsString) {
const ::std::string str("Hello");
EXPECT_EQ("Hello", (Message() << str).GetString());
}
// Tests that we can output strings containing embedded NULs.
TEST(MessageTest, StreamsStringWithEmbeddedNUL) {
const char char_array_with_nul[] =
"Here's a NUL\0 and some more string";
const ::std::string string_with_nul(char_array_with_nul,
sizeof(char_array_with_nul) - 1);
EXPECT_EQ("Here's a NUL\\0 and some more string",
(Message() << string_with_nul).GetString());
}
// Tests streaming a NUL char.
TEST(MessageTest, StreamsNULChar) {
EXPECT_EQ("\\0", (Message() << '\0').GetString());
}
// Tests streaming int.
TEST(MessageTest, StreamsInt) {
EXPECT_EQ("123", (Message() << 123).GetString());
}
// Tests that basic IO manipulators (endl, ends, and flush) can be
// streamed to Message.
TEST(MessageTest, StreamsBasicIoManip) {
EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.",
(Message() << "Line 1." << std::endl
<< "A NUL char " << std::ends << std::flush
<< " in line 2.").GetString());
}
// Tests Message::GetString()
TEST(MessageTest, GetString) {
Message msg;
msg << 1 << " lamb";
EXPECT_EQ("1 lamb", msg.GetString());
}
// Tests streaming a Message object to an ostream.
TEST(MessageTest, StreamsToOStream) {
Message msg("Hello");
::std::stringstream ss;
ss << msg;
EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss));
}
// Tests that a Message object doesn't take up too much stack space.
TEST(MessageTest, DoesNotTakeUpMuchStackSpace) {
EXPECT_LE(sizeof(Message), 16U);
}
} // namespace

View File

@ -1,215 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: keith.ray@gmail.com (Keith Ray)
//
// Google Test UnitTestOptions tests
//
// This file tests classes and functions used internally by
// Google Test. They are subject to change without notice.
//
// This file is #included from gtest.cc, to avoid changing build or
// make-files on Windows and other platforms. Do not #include this file
// anywhere else!
#include "gtest/gtest.h"
#if GTEST_OS_WINDOWS_MOBILE
# include <windows.h>
#elif GTEST_OS_WINDOWS
# include <direct.h>
#endif // GTEST_OS_WINDOWS_MOBILE
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// his code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing {
namespace internal {
namespace {
// Turns the given relative path into an absolute path.
FilePath GetAbsolutePathOf(const FilePath& relative_path) {
return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path);
}
// Testing UnitTestOptions::GetOutputFormat/GetOutputFile.
TEST(XmlOutputTest, GetOutputFormatDefault) {
GTEST_FLAG(output) = "";
EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str());
}
TEST(XmlOutputTest, GetOutputFormat) {
GTEST_FLAG(output) = "xml:filename";
EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str());
}
TEST(XmlOutputTest, GetOutputFileDefault) {
GTEST_FLAG(output) = "";
EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
}
TEST(XmlOutputTest, GetOutputFileSingleFile) {
GTEST_FLAG(output) = "xml:filename.abc";
EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
}
TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) {
GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_;
const std::string expected_output_file =
GetAbsolutePathOf(
FilePath(std::string("path") + GTEST_PATH_SEP_ +
GetCurrentExecutableName().string() + ".xml")).string();
const std::string& output_file =
UnitTestOptions::GetAbsolutePathToOutputFile();
#if GTEST_OS_WINDOWS
EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else
EXPECT_EQ(expected_output_file, output_file.c_str());
#endif
}
TEST(OutputFileHelpersTest, GetCurrentExecutableName) {
const std::string exe_str = GetCurrentExecutableName().string();
#if GTEST_OS_WINDOWS
const bool success =
_strcmpi("gtest-options_test", exe_str.c_str()) == 0 ||
_strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 ||
_strcmpi("gtest_all_test", exe_str.c_str()) == 0 ||
_strcmpi("gtest_dll_test", exe_str.c_str()) == 0;
#else
// TODO(wan@google.com): remove the hard-coded "lt-" prefix when
// Chandler Carruth's libtool replacement is ready.
const bool success =
exe_str == "gtest-options_test" ||
exe_str == "gtest_all_test" ||
exe_str == "lt-gtest_all_test" ||
exe_str == "gtest_dll_test";
#endif // GTEST_OS_WINDOWS
if (!success)
FAIL() << "GetCurrentExecutableName() returns " << exe_str;
}
class XmlOutputChangeDirTest : public Test {
protected:
virtual void SetUp() {
original_working_dir_ = FilePath::GetCurrentDir();
posix::ChDir("..");
// This will make the test fail if run from the root directory.
EXPECT_NE(original_working_dir_.string(),
FilePath::GetCurrentDir().string());
}
virtual void TearDown() {
posix::ChDir(original_working_dir_.string().c_str());
}
FilePath original_working_dir_;
};
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) {
GTEST_FLAG(output) = "";
EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_,
FilePath("test_detail.xml")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
}
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) {
GTEST_FLAG(output) = "xml";
EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_,
FilePath("test_detail.xml")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
}
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) {
GTEST_FLAG(output) = "xml:filename.abc";
EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_,
FilePath("filename.abc")).string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
}
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) {
GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_;
const std::string expected_output_file =
FilePath::ConcatPaths(
original_working_dir_,
FilePath(std::string("path") + GTEST_PATH_SEP_ +
GetCurrentExecutableName().string() + ".xml")).string();
const std::string& output_file =
UnitTestOptions::GetAbsolutePathToOutputFile();
#if GTEST_OS_WINDOWS
EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else
EXPECT_EQ(expected_output_file, output_file.c_str());
#endif
}
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) {
#if GTEST_OS_WINDOWS
GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc";
EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
#else
GTEST_FLAG(output) ="xml:/tmp/filename.abc";
EXPECT_EQ(FilePath("/tmp/filename.abc").string(),
UnitTestOptions::GetAbsolutePathToOutputFile());
#endif
}
TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) {
#if GTEST_OS_WINDOWS
const std::string path = "c:\\tmp\\";
#else
const std::string path = "/tmp/";
#endif
GTEST_FLAG(output) = "xml:" + path;
const std::string expected_output_file =
path + GetCurrentExecutableName().string() + ".xml";
const std::string& output_file =
UnitTestOptions::GetAbsolutePathToOutputFile();
#if GTEST_OS_WINDOWS
EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
#else
EXPECT_EQ(expected_output_file, output_file.c_str());
#endif
}
} // namespace
} // namespace internal
} // namespace testing

View File

@ -1,65 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
//
// Tests for Google Test itself. This verifies that the basic constructs of
// Google Test work.
#include "gtest/gtest.h"
#include "test/gtest-param-test_test.h"
#if GTEST_HAS_PARAM_TEST
using ::testing::Values;
using ::testing::internal::ParamGenerator;
// Tests that generators defined in a different translation unit
// are functional. The test using extern_gen is defined
// in gtest-param-test_test.cc.
ParamGenerator<int> extern_gen = Values(33);
// Tests that a parameterized test case can be defined in one translation unit
// and instantiated in another. The test is defined in gtest-param-test_test.cc
// and ExternalInstantiationTest fixture class is defined in
// gtest-param-test_test.h.
INSTANTIATE_TEST_CASE_P(MultiplesOf33,
ExternalInstantiationTest,
Values(33, 66));
// Tests that a parameterized test case can be instantiated
// in multiple translation units. Another instantiation is defined
// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest
// fixture is defined in gtest-param-test_test.h
INSTANTIATE_TEST_CASE_P(Sequence2,
InstantiationInMultipleTranslaionUnitsTest,
Values(42*3, 42*4, 42*5));
#endif // GTEST_HAS_PARAM_TEST

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: vladl@google.com (Vlad Losev)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file provides classes and functions used internally
// for testing Google Test itself.
#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
#include "gtest/gtest.h"
#if GTEST_HAS_PARAM_TEST
// Test fixture for testing definition and instantiation of a test
// in separate translation units.
class ExternalInstantiationTest : public ::testing::TestWithParam<int> {
};
// Test fixture for testing instantiation of a test in multiple
// translation units.
class InstantiationInMultipleTranslaionUnitsTest
: public ::testing::TestWithParam<int> {
};
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,208 +0,0 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
#include "gtest/gtest-test-part.h"
#include "gtest/gtest.h"
using testing::Message;
using testing::Test;
using testing::TestPartResult;
using testing::TestPartResultArray;
namespace {
// Tests the TestPartResult class.
// The test fixture for testing TestPartResult.
class TestPartResultTest : public Test {
protected:
TestPartResultTest()
: r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"),
r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"),
r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {}
TestPartResult r1_, r2_, r3_;
};
TEST_F(TestPartResultTest, ConstructorWorks) {
Message message;
message << "something is terribly wrong";
message << static_cast<const char*>(testing::internal::kStackTraceMarker);
message << "some unimportant stack trace";
const TestPartResult result(TestPartResult::kNonFatalFailure,
"some_file.cc",
42,
message.GetString().c_str());
EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type());
EXPECT_STREQ("some_file.cc", result.file_name());
EXPECT_EQ(42, result.line_number());
EXPECT_STREQ(message.GetString().c_str(), result.message());
EXPECT_STREQ("something is terribly wrong", result.summary());
}
TEST_F(TestPartResultTest, ResultAccessorsWork) {
const TestPartResult success(TestPartResult::kSuccess,
"file.cc",
42,
"message");
EXPECT_TRUE(success.passed());
EXPECT_FALSE(success.failed());
EXPECT_FALSE(success.nonfatally_failed());
EXPECT_FALSE(success.fatally_failed());
const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure,
"file.cc",
42,
"message");
EXPECT_FALSE(nonfatal_failure.passed());
EXPECT_TRUE(nonfatal_failure.failed());
EXPECT_TRUE(nonfatal_failure.nonfatally_failed());
EXPECT_FALSE(nonfatal_failure.fatally_failed());
const TestPartResult fatal_failure(TestPartResult::kFatalFailure,
"file.cc",
42,
"message");
EXPECT_FALSE(fatal_failure.passed());
EXPECT_TRUE(fatal_failure.failed());
EXPECT_FALSE(fatal_failure.nonfatally_failed());
EXPECT_TRUE(fatal_failure.fatally_failed());
}
// Tests TestPartResult::type().
TEST_F(TestPartResultTest, type) {
EXPECT_EQ(TestPartResult::kSuccess, r1_.type());
EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type());
EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type());
}
// Tests TestPartResult::file_name().
TEST_F(TestPartResultTest, file_name) {
EXPECT_STREQ("foo/bar.cc", r1_.file_name());
EXPECT_STREQ(NULL, r3_.file_name());
}
// Tests TestPartResult::line_number().
TEST_F(TestPartResultTest, line_number) {
EXPECT_EQ(10, r1_.line_number());
EXPECT_EQ(-1, r2_.line_number());
}
// Tests TestPartResult::message().
TEST_F(TestPartResultTest, message) {
EXPECT_STREQ("Success!", r1_.message());
}
// Tests TestPartResult::passed().
TEST_F(TestPartResultTest, Passed) {
EXPECT_TRUE(r1_.passed());
EXPECT_FALSE(r2_.passed());
EXPECT_FALSE(r3_.passed());
}
// Tests TestPartResult::failed().
TEST_F(TestPartResultTest, Failed) {
EXPECT_FALSE(r1_.failed());
EXPECT_TRUE(r2_.failed());
EXPECT_TRUE(r3_.failed());
}
// Tests TestPartResult::fatally_failed().
TEST_F(TestPartResultTest, FatallyFailed) {
EXPECT_FALSE(r1_.fatally_failed());
EXPECT_FALSE(r2_.fatally_failed());
EXPECT_TRUE(r3_.fatally_failed());
}
// Tests TestPartResult::nonfatally_failed().
TEST_F(TestPartResultTest, NonfatallyFailed) {
EXPECT_FALSE(r1_.nonfatally_failed());
EXPECT_TRUE(r2_.nonfatally_failed());
EXPECT_FALSE(r3_.nonfatally_failed());
}
// Tests the TestPartResultArray class.
class TestPartResultArrayTest : public Test {
protected:
TestPartResultArrayTest()
: r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"),
r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {}
const TestPartResult r1_, r2_;
};
// Tests that TestPartResultArray initially has size 0.
TEST_F(TestPartResultArrayTest, InitialSizeIsZero) {
TestPartResultArray results;
EXPECT_EQ(0, results.size());
}
// Tests that TestPartResultArray contains the given TestPartResult
// after one Append() operation.
TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) {
TestPartResultArray results;
results.Append(r1_);
EXPECT_EQ(1, results.size());
EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message());
}
// Tests that TestPartResultArray contains the given TestPartResults
// after two Append() operations.
TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) {
TestPartResultArray results;
results.Append(r1_);
results.Append(r2_);
EXPECT_EQ(2, results.size());
EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message());
EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message());
}
typedef TestPartResultArrayTest TestPartResultArrayDeathTest;
// Tests that the program dies when GetTestPartResult() is called with
// an invalid index.
TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) {
TestPartResultArray results;
results.Append(r1_);
EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), "");
EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), "");
}
// TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper.
} // namespace

View File

@ -1,320 +0,0 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/internal/gtest-tuple.h"
#include <utility>
#include "gtest/gtest.h"
namespace {
using ::std::tr1::get;
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;
using ::std::tr1::tuple_element;
using ::std::tr1::tuple_size;
using ::testing::StaticAssertTypeEq;
// Tests that tuple_element<K, tuple<T0, T1, ..., TN> >::type returns TK.
TEST(tuple_element_Test, ReturnsElementType) {
StaticAssertTypeEq<int, tuple_element<0, tuple<int, char> >::type>();
StaticAssertTypeEq<int&, tuple_element<1, tuple<double, int&> >::type>();
StaticAssertTypeEq<bool, tuple_element<2, tuple<double, int, bool> >::type>();
}
// Tests that tuple_size<T>::value gives the number of fields in tuple
// type T.
TEST(tuple_size_Test, ReturnsNumberOfFields) {
EXPECT_EQ(0, +tuple_size<tuple<> >::value);
EXPECT_EQ(1, +tuple_size<tuple<void*> >::value);
EXPECT_EQ(1, +tuple_size<tuple<char> >::value);
EXPECT_EQ(1, +(tuple_size<tuple<tuple<int, double> > >::value));
EXPECT_EQ(2, +(tuple_size<tuple<int&, const char> >::value));
EXPECT_EQ(3, +(tuple_size<tuple<char*, void, const bool&> >::value));
}
// Tests comparing a tuple with itself.
TEST(ComparisonTest, ComparesWithSelf) {
const tuple<int, char, bool> a(5, 'a', false);
EXPECT_TRUE(a == a);
EXPECT_FALSE(a != a);
}
// Tests comparing two tuples with the same value.
TEST(ComparisonTest, ComparesEqualTuples) {
const tuple<int, bool> a(5, true), b(5, true);
EXPECT_TRUE(a == b);
EXPECT_FALSE(a != b);
}
// Tests comparing two different tuples that have no reference fields.
TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) {
typedef tuple<const int, char> FooTuple;
const FooTuple a(0, 'x');
const FooTuple b(1, 'a');
EXPECT_TRUE(a != b);
EXPECT_FALSE(a == b);
const FooTuple c(1, 'b');
EXPECT_TRUE(b != c);
EXPECT_FALSE(b == c);
}
// Tests comparing two different tuples that have reference fields.
TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) {
typedef tuple<int&, const char&> FooTuple;
int i = 5;
const char ch = 'a';
const FooTuple a(i, ch);
int j = 6;
const FooTuple b(j, ch);
EXPECT_TRUE(a != b);
EXPECT_FALSE(a == b);
j = 5;
const char ch2 = 'b';
const FooTuple c(j, ch2);
EXPECT_TRUE(b != c);
EXPECT_FALSE(b == c);
}
// Tests that a tuple field with a reference type is an alias of the
// variable it's supposed to reference.
TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
int n = 0;
tuple<bool, int&> t(true, n);
n = 1;
EXPECT_EQ(n, get<1>(t))
<< "Changing a underlying variable should update the reference field.";
// Makes sure that the implementation doesn't do anything funny with
// the & operator for the return type of get<>().
EXPECT_EQ(&n, &(get<1>(t)))
<< "The address of a reference field should equal the address of "
<< "the underlying variable.";
get<1>(t) = 2;
EXPECT_EQ(2, n)
<< "Changing a reference field should update the underlying variable.";
}
// Tests that tuple's default constructor default initializes each field.
// This test needs to compile without generating warnings.
TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) {
// The TR1 report requires that tuple's default constructor default
// initializes each field, even if it's a primitive type. If the
// implementation forgets to do this, this test will catch it by
// generating warnings about using uninitialized variables (assuming
// a decent compiler).
tuple<> empty;
tuple<int> a1, b1;
b1 = a1;
EXPECT_EQ(0, get<0>(b1));
tuple<int, double> a2, b2;
b2 = a2;
EXPECT_EQ(0, get<0>(b2));
EXPECT_EQ(0.0, get<1>(b2));
tuple<double, char, bool*> a3, b3;
b3 = a3;
EXPECT_EQ(0.0, get<0>(b3));
EXPECT_EQ('\0', get<1>(b3));
EXPECT_TRUE(get<2>(b3) == NULL);
tuple<int, int, int, int, int, int, int, int, int, int> a10, b10;
b10 = a10;
EXPECT_EQ(0, get<0>(b10));
EXPECT_EQ(0, get<1>(b10));
EXPECT_EQ(0, get<2>(b10));
EXPECT_EQ(0, get<3>(b10));
EXPECT_EQ(0, get<4>(b10));
EXPECT_EQ(0, get<5>(b10));
EXPECT_EQ(0, get<6>(b10));
EXPECT_EQ(0, get<7>(b10));
EXPECT_EQ(0, get<8>(b10));
EXPECT_EQ(0, get<9>(b10));
}
// Tests constructing a tuple from its fields.
TEST(TupleConstructorTest, ConstructsFromFields) {
int n = 1;
// Reference field.
tuple<int&> a(n);
EXPECT_EQ(&n, &(get<0>(a)));
// Non-reference fields.
tuple<int, char> b(5, 'a');
EXPECT_EQ(5, get<0>(b));
EXPECT_EQ('a', get<1>(b));
// Const reference field.
const int m = 2;
tuple<bool, const int&> c(true, m);
EXPECT_TRUE(get<0>(c));
EXPECT_EQ(&m, &(get<1>(c)));
}
// Tests tuple's copy constructor.
TEST(TupleConstructorTest, CopyConstructor) {
tuple<double, bool> a(0.0, true);
tuple<double, bool> b(a);
EXPECT_DOUBLE_EQ(0.0, get<0>(b));
EXPECT_TRUE(get<1>(b));
}
// Tests constructing a tuple from another tuple that has a compatible
// but different type.
TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) {
tuple<int, int, char> a(0, 1, 'a');
tuple<double, long, int> b(a);
EXPECT_DOUBLE_EQ(0.0, get<0>(b));
EXPECT_EQ(1, get<1>(b));
EXPECT_EQ('a', get<2>(b));
}
// Tests constructing a 2-tuple from an std::pair.
TEST(TupleConstructorTest, ConstructsFromPair) {
::std::pair<int, char> a(1, 'a');
tuple<int, char> b(a);
tuple<int, const char&> c(a);
}
// Tests assigning a tuple to another tuple with the same type.
TEST(TupleAssignmentTest, AssignsToSameTupleType) {
const tuple<int, long> a(5, 7L);
tuple<int, long> b;
b = a;
EXPECT_EQ(5, get<0>(b));
EXPECT_EQ(7L, get<1>(b));
}
// Tests assigning a tuple to another tuple with a different but
// compatible type.
TEST(TupleAssignmentTest, AssignsToDifferentTupleType) {
const tuple<int, long, bool> a(1, 7L, true);
tuple<long, int, bool> b;
b = a;
EXPECT_EQ(1L, get<0>(b));
EXPECT_EQ(7, get<1>(b));
EXPECT_TRUE(get<2>(b));
}
// Tests assigning an std::pair to a 2-tuple.
TEST(TupleAssignmentTest, AssignsFromPair) {
const ::std::pair<int, bool> a(5, true);
tuple<int, bool> b;
b = a;
EXPECT_EQ(5, get<0>(b));
EXPECT_TRUE(get<1>(b));
tuple<long, bool> c;
c = a;
EXPECT_EQ(5L, get<0>(c));
EXPECT_TRUE(get<1>(c));
}
// A fixture for testing big tuples.
class BigTupleTest : public testing::Test {
protected:
typedef tuple<int, int, int, int, int, int, int, int, int, int> BigTuple;
BigTupleTest() :
a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2),
b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {}
BigTuple a_, b_;
};
// Tests constructing big tuples.
TEST_F(BigTupleTest, Construction) {
BigTuple a;
BigTuple b(b_);
}
// Tests that get<N>(t) returns the N-th (0-based) field of tuple t.
TEST_F(BigTupleTest, get) {
EXPECT_EQ(1, get<0>(a_));
EXPECT_EQ(2, get<9>(a_));
// Tests that get() works on a const tuple too.
const BigTuple a(a_);
EXPECT_EQ(1, get<0>(a));
EXPECT_EQ(2, get<9>(a));
}
// Tests comparing big tuples.
TEST_F(BigTupleTest, Comparisons) {
EXPECT_TRUE(a_ == a_);
EXPECT_FALSE(a_ != a_);
EXPECT_TRUE(a_ != b_);
EXPECT_FALSE(a_ == b_);
}
TEST(MakeTupleTest, WorksForScalarTypes) {
tuple<bool, int> a;
a = make_tuple(true, 5);
EXPECT_TRUE(get<0>(a));
EXPECT_EQ(5, get<1>(a));
tuple<char, int, long> b;
b = make_tuple('a', 'b', 5);
EXPECT_EQ('a', get<0>(b));
EXPECT_EQ('b', get<1>(b));
EXPECT_EQ(5, get<2>(b));
}
TEST(MakeTupleTest, WorksForPointers) {
int a[] = { 1, 2, 3, 4 };
const char* const str = "hi";
int* const p = a;
tuple<const char*, int*> t;
t = make_tuple(str, p);
EXPECT_EQ(str, get<0>(t));
EXPECT_EQ(p, get<1>(t));
}
} // namespace

View File

@ -1,45 +0,0 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include <vector>
#include "test/gtest-typed-test_test.h"
#include "gtest/gtest.h"
#if GTEST_HAS_TYPED_TEST_P
// Tests that the same type-parameterized test case can be
// instantiated in different translation units linked together.
// (ContainerTest is also instantiated in gtest-typed-test_test.cc.)
INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest,
testing::Types<std::vector<int> >);
#endif // GTEST_HAS_TYPED_TEST_P

View File

@ -1,380 +0,0 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "test/gtest-typed-test_test.h"
#include <set>
#include <vector>
#include "gtest/gtest.h"
using testing::Test;
// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture
// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and
// type-parameterized test.
template <typename T>
class CommonTest : public Test {
// For some technical reason, SetUpTestCase() and TearDownTestCase()
// must be public.
public:
static void SetUpTestCase() {
shared_ = new T(5);
}
static void TearDownTestCase() {
delete shared_;
shared_ = NULL;
}
// This 'protected:' is optional. There's no harm in making all
// members of this fixture class template public.
protected:
// We used to use std::list here, but switched to std::vector since
// MSVC's <list> doesn't compile cleanly with /W4.
typedef std::vector<T> Vector;
typedef std::set<int> IntSet;
CommonTest() : value_(1) {}
virtual ~CommonTest() { EXPECT_EQ(3, value_); }
virtual void SetUp() {
EXPECT_EQ(1, value_);
value_++;
}
virtual void TearDown() {
EXPECT_EQ(2, value_);
value_++;
}
T value_;
static T* shared_;
};
template <typename T>
T* CommonTest<T>::shared_ = NULL;
// This #ifdef block tests typed tests.
#if GTEST_HAS_TYPED_TEST
using testing::Types;
// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor,
// and SetUp()/TearDown() work correctly in typed tests
typedef Types<char, int> TwoTypes;
TYPED_TEST_CASE(CommonTest, TwoTypes);
TYPED_TEST(CommonTest, ValuesAreCorrect) {
// Static members of the fixture class template can be visited via
// the TestFixture:: prefix.
EXPECT_EQ(5, *TestFixture::shared_);
// Typedefs in the fixture class template can be visited via the
// "typename TestFixture::" prefix.
typename TestFixture::Vector empty;
EXPECT_EQ(0U, empty.size());
typename TestFixture::IntSet empty2;
EXPECT_EQ(0U, empty2.size());
// Non-static members of the fixture class must be visited via
// 'this', as required by C++ for class templates.
EXPECT_EQ(2, this->value_);
}
// The second test makes sure shared_ is not deleted after the first
// test.
TYPED_TEST(CommonTest, ValuesAreStillCorrect) {
// Static members of the fixture class template can also be visited
// via 'this'.
ASSERT_TRUE(this->shared_ != NULL);
EXPECT_EQ(5, *this->shared_);
// TypeParam can be used to refer to the type parameter.
EXPECT_EQ(static_cast<TypeParam>(2), this->value_);
}
// Tests that multiple TYPED_TEST_CASE's can be defined in the same
// translation unit.
template <typename T>
class TypedTest1 : public Test {
};
// Verifies that the second argument of TYPED_TEST_CASE can be a
// single type.
TYPED_TEST_CASE(TypedTest1, int);
TYPED_TEST(TypedTest1, A) {}
template <typename T>
class TypedTest2 : public Test {
};
// Verifies that the second argument of TYPED_TEST_CASE can be a
// Types<...> type list.
TYPED_TEST_CASE(TypedTest2, Types<int>);
// This also verifies that tests from different typed test cases can
// share the same name.
TYPED_TEST(TypedTest2, A) {}
// Tests that a typed test case can be defined in a namespace.
namespace library1 {
template <typename T>
class NumericTest : public Test {
};
typedef Types<int, long> NumericTypes;
TYPED_TEST_CASE(NumericTest, NumericTypes);
TYPED_TEST(NumericTest, DefaultIsZero) {
EXPECT_EQ(0, TypeParam());
}
} // namespace library1
#endif // GTEST_HAS_TYPED_TEST
// This #ifdef block tests type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
using testing::Types;
using testing::internal::TypedTestCasePState;
// Tests TypedTestCasePState.
class TypedTestCasePStateTest : public Test {
protected:
virtual void SetUp() {
state_.AddTestName("foo.cc", 0, "FooTest", "A");
state_.AddTestName("foo.cc", 0, "FooTest", "B");
state_.AddTestName("foo.cc", 0, "FooTest", "C");
}
TypedTestCasePState state_;
};
TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) {
const char* tests = "A, B, C";
EXPECT_EQ(tests,
state_.VerifyRegisteredTestNames("foo.cc", 1, tests));
}
// Makes sure that the order of the tests and spaces around the names
// don't matter.
TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) {
const char* tests = "A,C, B";
EXPECT_EQ(tests,
state_.VerifyRegisteredTestNames("foo.cc", 1, tests));
}
typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest;
TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) {
EXPECT_DEATH_IF_SUPPORTED(
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"),
"foo\\.cc.1.?: Test A is listed more than once\\.");
}
TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) {
EXPECT_DEATH_IF_SUPPORTED(
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"),
"foo\\.cc.1.?: No test named D can be found in this test case\\.");
}
TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) {
EXPECT_DEATH_IF_SUPPORTED(
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"),
"foo\\.cc.1.?: You forgot to list test B\\.");
}
// Tests that defining a test for a parameterized test case generates
// a run-time error if the test case has been registered.
TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) {
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C");
EXPECT_DEATH_IF_SUPPORTED(
state_.AddTestName("foo.cc", 2, "FooTest", "D"),
"foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P"
"\\(FooTest, \\.\\.\\.\\)\\.");
}
// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor,
// and SetUp()/TearDown() work correctly in type-parameterized tests.
template <typename T>
class DerivedTest : public CommonTest<T> {
};
TYPED_TEST_CASE_P(DerivedTest);
TYPED_TEST_P(DerivedTest, ValuesAreCorrect) {
// Static members of the fixture class template can be visited via
// the TestFixture:: prefix.
EXPECT_EQ(5, *TestFixture::shared_);
// Non-static members of the fixture class must be visited via
// 'this', as required by C++ for class templates.
EXPECT_EQ(2, this->value_);
}
// The second test makes sure shared_ is not deleted after the first
// test.
TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) {
// Static members of the fixture class template can also be visited
// via 'this'.
ASSERT_TRUE(this->shared_ != NULL);
EXPECT_EQ(5, *this->shared_);
EXPECT_EQ(2, this->value_);
}
REGISTER_TYPED_TEST_CASE_P(DerivedTest,
ValuesAreCorrect, ValuesAreStillCorrect);
typedef Types<short, long> MyTwoTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes);
// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same
// translation unit.
template <typename T>
class TypedTestP1 : public Test {
};
TYPED_TEST_CASE_P(TypedTestP1);
// For testing that the code between TYPED_TEST_CASE_P() and
// TYPED_TEST_P() is not enclosed in a namespace.
typedef int IntAfterTypedTestCaseP;
TYPED_TEST_P(TypedTestP1, A) {}
TYPED_TEST_P(TypedTestP1, B) {}
// For testing that the code between TYPED_TEST_P() and
// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace.
typedef int IntBeforeRegisterTypedTestCaseP;
REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B);
template <typename T>
class TypedTestP2 : public Test {
};
TYPED_TEST_CASE_P(TypedTestP2);
// This also verifies that tests from different type-parameterized
// test cases can share the same name.
TYPED_TEST_P(TypedTestP2, A) {}
REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A);
// Verifies that the code between TYPED_TEST_CASE_P() and
// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace.
IntAfterTypedTestCaseP after = 0;
IntBeforeRegisterTypedTestCaseP before = 0;
// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P()
// can be either a single type or a Types<...> type list.
INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int);
INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types<int>);
// Tests that the same type-parameterized test case can be
// instantiated more than once in the same translation unit.
INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types<double>);
// Tests that the same type-parameterized test case can be
// instantiated in different translation units linked together.
// (ContainerTest is also instantiated in gtest-typed-test_test.cc.)
typedef Types<std::vector<double>, std::set<char> > MyContainers;
INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers);
// Tests that a type-parameterized test case can be defined and
// instantiated in a namespace.
namespace library2 {
template <typename T>
class NumericTest : public Test {
};
TYPED_TEST_CASE_P(NumericTest);
TYPED_TEST_P(NumericTest, DefaultIsZero) {
EXPECT_EQ(0, TypeParam());
}
TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) {
EXPECT_LT(TypeParam(0), TypeParam(1));
}
REGISTER_TYPED_TEST_CASE_P(NumericTest,
DefaultIsZero, ZeroIsLessThanOne);
typedef Types<int, double> NumericTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes);
static const char* GetTestName() {
return testing::UnitTest::GetInstance()->current_test_info()->name();
}
// Test the stripping of space from test names
template <typename T> class TrimmedTest : public Test { };
TYPED_TEST_CASE_P(TrimmedTest);
TYPED_TEST_P(TrimmedTest, Test1) { EXPECT_STREQ("Test1", GetTestName()); }
TYPED_TEST_P(TrimmedTest, Test2) { EXPECT_STREQ("Test2", GetTestName()); }
TYPED_TEST_P(TrimmedTest, Test3) { EXPECT_STREQ("Test3", GetTestName()); }
TYPED_TEST_P(TrimmedTest, Test4) { EXPECT_STREQ("Test4", GetTestName()); }
TYPED_TEST_P(TrimmedTest, Test5) { EXPECT_STREQ("Test5", GetTestName()); }
REGISTER_TYPED_TEST_CASE_P(
TrimmedTest,
Test1, Test2,Test3 , Test4 ,Test5 ); // NOLINT
template <typename T1, typename T2> struct MyPair {};
// Be sure to try a type with a comma in its name just in case it matters.
typedef Types<int, double, MyPair<int, int> > TrimTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, TrimmedTest, TrimTypes);
} // namespace library2
#endif // GTEST_HAS_TYPED_TEST_P
#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
// Google Test may not support type-parameterized tests with some
// compilers. If we use conditional compilation to compile out all
// code referring to the gtest_main library, MSVC linker will not link
// that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point
// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {}
#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)

View File

@ -1,66 +0,0 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
#include "gtest/gtest.h"
#if GTEST_HAS_TYPED_TEST_P
using testing::Test;
// For testing that the same type-parameterized test case can be
// instantiated in different translation units linked together.
// ContainerTest will be instantiated in both gtest-typed-test_test.cc
// and gtest-typed-test2_test.cc.
template <typename T>
class ContainerTest : public Test {
};
TYPED_TEST_CASE_P(ContainerTest);
TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) {
TypeParam container;
}
TYPED_TEST_P(ContainerTest, InitialSizeIsZero) {
TypeParam container;
EXPECT_EQ(0U, container.size());
}
REGISTER_TYPED_TEST_CASE_P(ContainerTest,
CanBeDefaultConstructed, InitialSizeIsZero);
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_

View File

@ -1,341 +0,0 @@
// Copyright 2009 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
//
// The Google C++ Testing Framework (Google Test)
//
// This file contains tests verifying correctness of data provided via
// UnitTest's public methods.
#include "gtest/gtest.h"
#include <string.h> // For strcmp.
#include <algorithm>
using ::testing::InitGoogleTest;
namespace testing {
namespace internal {
template <typename T>
struct LessByName {
bool operator()(const T* a, const T* b) {
return strcmp(a->name(), b->name()) < 0;
}
};
class UnitTestHelper {
public:
// Returns the array of pointers to all test cases sorted by the test case
// name. The caller is responsible for deleting the array.
static TestCase const** GetSortedTestCases() {
UnitTest& unit_test = *UnitTest::GetInstance();
TestCase const** const test_cases =
new const TestCase*[unit_test.total_test_case_count()];
for (int i = 0; i < unit_test.total_test_case_count(); ++i)
test_cases[i] = unit_test.GetTestCase(i);
std::sort(test_cases,
test_cases + unit_test.total_test_case_count(),
LessByName<TestCase>());
return test_cases;
}
// Returns the test case by its name. The caller doesn't own the returned
// pointer.
static const TestCase* FindTestCase(const char* name) {
UnitTest& unit_test = *UnitTest::GetInstance();
for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
const TestCase* test_case = unit_test.GetTestCase(i);
if (0 == strcmp(test_case->name(), name))
return test_case;
}
return NULL;
}
// Returns the array of pointers to all tests in a particular test case
// sorted by the test name. The caller is responsible for deleting the
// array.
static TestInfo const** GetSortedTests(const TestCase* test_case) {
TestInfo const** const tests =
new const TestInfo*[test_case->total_test_count()];
for (int i = 0; i < test_case->total_test_count(); ++i)
tests[i] = test_case->GetTestInfo(i);
std::sort(tests, tests + test_case->total_test_count(),
LessByName<TestInfo>());
return tests;
}
};
#if GTEST_HAS_TYPED_TEST
template <typename T> class TestCaseWithCommentTest : public Test {};
TYPED_TEST_CASE(TestCaseWithCommentTest, Types<int>);
TYPED_TEST(TestCaseWithCommentTest, Dummy) {}
const int kTypedTestCases = 1;
const int kTypedTests = 1;
#else
const int kTypedTestCases = 0;
const int kTypedTests = 0;
#endif // GTEST_HAS_TYPED_TEST
// We can only test the accessors that do not change value while tests run.
// Since tests can be run in any order, the values the accessors that track
// test execution (such as failed_test_count) can not be predicted.
TEST(ApiTest, UnitTestImmutableAccessorsWork) {
UnitTest* unit_test = UnitTest::GetInstance();
ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count());
EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count());
EXPECT_EQ(2, unit_test->disabled_test_count());
EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count());
EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count());
const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases();
EXPECT_STREQ("ApiTest", test_cases[0]->name());
EXPECT_STREQ("DISABLED_Test", test_cases[1]->name());
#if GTEST_HAS_TYPED_TEST
EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name());
#endif // GTEST_HAS_TYPED_TEST
delete[] test_cases;
// The following lines initiate actions to verify certain methods in
// FinalSuccessChecker::TearDown.
// Records a test property to verify TestResult::GetTestProperty().
RecordProperty("key", "value");
}
AssertionResult IsNull(const char* str) {
if (str != NULL) {
return testing::AssertionFailure() << "argument is " << str;
}
return AssertionSuccess();
}
TEST(ApiTest, TestCaseImmutableAccessorsWork) {
const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest");
ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("ApiTest", test_case->name());
EXPECT_TRUE(IsNull(test_case->type_param()));
EXPECT_TRUE(test_case->should_run());
EXPECT_EQ(1, test_case->disabled_test_count());
EXPECT_EQ(3, test_case->test_to_run_count());
ASSERT_EQ(4, test_case->total_test_count());
const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case);
EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name());
EXPECT_STREQ("ApiTest", tests[0]->test_case_name());
EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_TRUE(IsNull(tests[0]->type_param()));
EXPECT_FALSE(tests[0]->should_run());
EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
EXPECT_TRUE(IsNull(tests[1]->value_param()));
EXPECT_TRUE(IsNull(tests[1]->type_param()));
EXPECT_TRUE(tests[1]->should_run());
EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
EXPECT_TRUE(IsNull(tests[2]->value_param()));
EXPECT_TRUE(IsNull(tests[2]->type_param()));
EXPECT_TRUE(tests[2]->should_run());
EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
EXPECT_TRUE(IsNull(tests[3]->value_param()));
EXPECT_TRUE(IsNull(tests[3]->type_param()));
EXPECT_TRUE(tests[3]->should_run());
delete[] tests;
tests = NULL;
#if GTEST_HAS_TYPED_TEST
test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0");
ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name());
EXPECT_STREQ(GetTypeName<int>().c_str(), test_case->type_param());
EXPECT_TRUE(test_case->should_run());
EXPECT_EQ(0, test_case->disabled_test_count());
EXPECT_EQ(1, test_case->test_to_run_count());
ASSERT_EQ(1, test_case->total_test_count());
tests = UnitTestHelper::GetSortedTests(test_case);
EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
EXPECT_TRUE(tests[0]->should_run());
delete[] tests;
#endif // GTEST_HAS_TYPED_TEST
}
TEST(ApiTest, TestCaseDisabledAccessorsWork) {
const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test");
ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("DISABLED_Test", test_case->name());
EXPECT_TRUE(IsNull(test_case->type_param()));
EXPECT_FALSE(test_case->should_run());
EXPECT_EQ(1, test_case->disabled_test_count());
EXPECT_EQ(0, test_case->test_to_run_count());
ASSERT_EQ(1, test_case->total_test_count());
const TestInfo* const test_info = test_case->GetTestInfo(0);
EXPECT_STREQ("Dummy2", test_info->name());
EXPECT_STREQ("DISABLED_Test", test_info->test_case_name());
EXPECT_TRUE(IsNull(test_info->value_param()));
EXPECT_TRUE(IsNull(test_info->type_param()));
EXPECT_FALSE(test_info->should_run());
}
// These two tests are here to provide support for testing
// test_case_to_run_count, disabled_test_count, and test_to_run_count.
TEST(ApiTest, DISABLED_Dummy1) {}
TEST(DISABLED_Test, Dummy2) {}
class FinalSuccessChecker : public Environment {
protected:
virtual void TearDown() {
UnitTest* unit_test = UnitTest::GetInstance();
EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count());
EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count());
EXPECT_EQ(0, unit_test->failed_test_case_count());
EXPECT_EQ(0, unit_test->failed_test_count());
EXPECT_TRUE(unit_test->Passed());
EXPECT_FALSE(unit_test->Failed());
ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count());
const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases();
EXPECT_STREQ("ApiTest", test_cases[0]->name());
EXPECT_TRUE(IsNull(test_cases[0]->type_param()));
EXPECT_TRUE(test_cases[0]->should_run());
EXPECT_EQ(1, test_cases[0]->disabled_test_count());
ASSERT_EQ(4, test_cases[0]->total_test_count());
EXPECT_EQ(3, test_cases[0]->successful_test_count());
EXPECT_EQ(0, test_cases[0]->failed_test_count());
EXPECT_TRUE(test_cases[0]->Passed());
EXPECT_FALSE(test_cases[0]->Failed());
EXPECT_STREQ("DISABLED_Test", test_cases[1]->name());
EXPECT_TRUE(IsNull(test_cases[1]->type_param()));
EXPECT_FALSE(test_cases[1]->should_run());
EXPECT_EQ(1, test_cases[1]->disabled_test_count());
ASSERT_EQ(1, test_cases[1]->total_test_count());
EXPECT_EQ(0, test_cases[1]->successful_test_count());
EXPECT_EQ(0, test_cases[1]->failed_test_count());
#if GTEST_HAS_TYPED_TEST
EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name());
EXPECT_STREQ(GetTypeName<int>().c_str(), test_cases[2]->type_param());
EXPECT_TRUE(test_cases[2]->should_run());
EXPECT_EQ(0, test_cases[2]->disabled_test_count());
ASSERT_EQ(1, test_cases[2]->total_test_count());
EXPECT_EQ(1, test_cases[2]->successful_test_count());
EXPECT_EQ(0, test_cases[2]->failed_test_count());
EXPECT_TRUE(test_cases[2]->Passed());
EXPECT_FALSE(test_cases[2]->Failed());
#endif // GTEST_HAS_TYPED_TEST
const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest");
const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case);
EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name());
EXPECT_STREQ("ApiTest", tests[0]->test_case_name());
EXPECT_FALSE(tests[0]->should_run());
EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
EXPECT_TRUE(IsNull(tests[1]->value_param()));
EXPECT_TRUE(IsNull(tests[1]->type_param()));
EXPECT_TRUE(tests[1]->should_run());
EXPECT_TRUE(tests[1]->result()->Passed());
EXPECT_EQ(0, tests[1]->result()->test_property_count());
EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
EXPECT_TRUE(IsNull(tests[2]->value_param()));
EXPECT_TRUE(IsNull(tests[2]->type_param()));
EXPECT_TRUE(tests[2]->should_run());
EXPECT_TRUE(tests[2]->result()->Passed());
EXPECT_EQ(0, tests[2]->result()->test_property_count());
EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
EXPECT_TRUE(IsNull(tests[3]->value_param()));
EXPECT_TRUE(IsNull(tests[3]->type_param()));
EXPECT_TRUE(tests[3]->should_run());
EXPECT_TRUE(tests[3]->result()->Passed());
EXPECT_EQ(1, tests[3]->result()->test_property_count());
const TestProperty& property = tests[3]->result()->GetTestProperty(0);
EXPECT_STREQ("key", property.key());
EXPECT_STREQ("value", property.value());
delete[] tests;
#if GTEST_HAS_TYPED_TEST
test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0");
tests = UnitTestHelper::GetSortedTests(test_case);
EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
EXPECT_TRUE(tests[0]->should_run());
EXPECT_TRUE(tests[0]->result()->Passed());
EXPECT_EQ(0, tests[0]->result()->test_property_count());
delete[] tests;
#endif // GTEST_HAS_TYPED_TEST
delete[] test_cases;
}
};
} // namespace internal
} // namespace testing
int main(int argc, char **argv) {
InitGoogleTest(&argc, argv);
AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker());
return RUN_ALL_TESTS();
}

View File

@ -1,47 +0,0 @@
// Copyright 2009, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Tests for Google C++ Testing Framework (Google Test)
//
// Sometimes it's desirable to build most of Google Test's own tests
// by compiling a single file. This file serves this purpose.
#include "test/gtest-filepath_test.cc"
#include "test/gtest-linked_ptr_test.cc"
#include "test/gtest-message_test.cc"
#include "test/gtest-options_test.cc"
#include "test/gtest-port_test.cc"
#include "test/gtest_pred_impl_unittest.cc"
#include "test/gtest_prod_test.cc"
#include "test/gtest-test-part_test.cc"
#include "test/gtest-typed-test_test.cc"
#include "test/gtest-typed-test2_test.cc"
#include "test/gtest_unittest.cc"
#include "test/production.cc"

View File

@ -1,212 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2006, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for Google Test's break-on-failure mode.
A user can ask Google Test to seg-fault when an assertion fails, using
either the GTEST_BREAK_ON_FAILURE environment variable or the
--gtest_break_on_failure flag. This script tests such functionality
by invoking gtest_break_on_failure_unittest_ (a program written with
Google Test) with different environments and command line flags.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import sys
# Constants.
IS_WINDOWS = os.name == 'nt'
# The environment variable for enabling/disabling the break-on-failure mode.
BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE'
# The command line flag for enabling/disabling the break-on-failure mode.
BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure'
# The environment variable for enabling/disabling the throw-on-failure mode.
THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE'
# The environment variable for enabling/disabling the catch-exceptions mode.
CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS'
# Path to the gtest_break_on_failure_unittest_ program.
EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_break_on_failure_unittest_')
environ = gtest_test_utils.environ
SetEnvVar = gtest_test_utils.SetEnvVar
# Tests in this file run a Google-Test-based test program and expect it
# to terminate prematurely. Therefore they are incompatible with
# the premature-exit-file protocol by design. Unset the
# premature-exit filepath to prevent Google Test from creating
# the file.
SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None)
def Run(command):
"""Runs a command; returns 1 if it was killed by a signal, or 0 otherwise."""
p = gtest_test_utils.Subprocess(command, env=environ)
if p.terminated_by_signal:
return 1
else:
return 0
# The tests.
class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase):
"""Tests using the GTEST_BREAK_ON_FAILURE environment variable or
the --gtest_break_on_failure flag to turn assertion failures into
segmentation faults.
"""
def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault):
"""Runs gtest_break_on_failure_unittest_ and verifies that it does
(or does not) have a seg-fault.
Args:
env_var_value: value of the GTEST_BREAK_ON_FAILURE environment
variable; None if the variable should be unset.
flag_value: value of the --gtest_break_on_failure flag;
None if the flag should not be present.
expect_seg_fault: 1 if the program is expected to generate a seg-fault;
0 otherwise.
"""
SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value)
if env_var_value is None:
env_var_value_msg = ' is not set'
else:
env_var_value_msg = '=' + env_var_value
if flag_value is None:
flag = ''
elif flag_value == '0':
flag = '--%s=0' % BREAK_ON_FAILURE_FLAG
else:
flag = '--%s' % BREAK_ON_FAILURE_FLAG
command = [EXE_PATH]
if flag:
command.append(flag)
if expect_seg_fault:
should_or_not = 'should'
else:
should_or_not = 'should not'
has_seg_fault = Run(command)
SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None)
msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' %
(BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command),
should_or_not))
self.assert_(has_seg_fault == expect_seg_fault, msg)
def testDefaultBehavior(self):
"""Tests the behavior of the default mode."""
self.RunAndVerify(env_var_value=None,
flag_value=None,
expect_seg_fault=0)
def testEnvVar(self):
"""Tests using the GTEST_BREAK_ON_FAILURE environment variable."""
self.RunAndVerify(env_var_value='0',
flag_value=None,
expect_seg_fault=0)
self.RunAndVerify(env_var_value='1',
flag_value=None,
expect_seg_fault=1)
def testFlag(self):
"""Tests using the --gtest_break_on_failure flag."""
self.RunAndVerify(env_var_value=None,
flag_value='0',
expect_seg_fault=0)
self.RunAndVerify(env_var_value=None,
flag_value='1',
expect_seg_fault=1)
def testFlagOverridesEnvVar(self):
"""Tests that the flag overrides the environment variable."""
self.RunAndVerify(env_var_value='0',
flag_value='0',
expect_seg_fault=0)
self.RunAndVerify(env_var_value='0',
flag_value='1',
expect_seg_fault=1)
self.RunAndVerify(env_var_value='1',
flag_value='0',
expect_seg_fault=0)
self.RunAndVerify(env_var_value='1',
flag_value='1',
expect_seg_fault=1)
def testBreakOnFailureOverridesThrowOnFailure(self):
"""Tests that gtest_break_on_failure overrides gtest_throw_on_failure."""
SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1')
try:
self.RunAndVerify(env_var_value=None,
flag_value='1',
expect_seg_fault=1)
finally:
SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None)
if IS_WINDOWS:
def testCatchExceptionsDoesNotInterfere(self):
"""Tests that gtest_catch_exceptions doesn't interfere."""
SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1')
try:
self.RunAndVerify(env_var_value='1',
flag_value='1',
expect_seg_fault=1)
finally:
SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None)
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,88 +0,0 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Unit test for Google Test's break-on-failure mode.
//
// A user can ask Google Test to seg-fault when an assertion fails, using
// either the GTEST_BREAK_ON_FAILURE environment variable or the
// --gtest_break_on_failure flag. This file is used for testing such
// functionality.
//
// This program will be invoked from a Python unit test. It is
// expected to fail. Don't run it directly.
#include "gtest/gtest.h"
#if GTEST_OS_WINDOWS
# include <windows.h>
# include <stdlib.h>
#endif
namespace {
// A test that's expected to fail.
TEST(Foo, Bar) {
EXPECT_EQ(2, 3);
}
#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE
// On Windows Mobile global exception handlers are not supported.
LONG WINAPI ExitWithExceptionCode(
struct _EXCEPTION_POINTERS* exception_pointers) {
exit(exception_pointers->ExceptionRecord->ExceptionCode);
}
#endif
} // namespace
int main(int argc, char **argv) {
#if GTEST_OS_WINDOWS
// Suppresses display of the Windows error dialog upon encountering
// a general protection fault (segment violation).
SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS);
# if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE
// The default unhandled exception filter does not always exit
// with the exception code as exit code - for example it exits with
// 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT
// if the application is compiled in debug mode. Thus we use our own
// filter which always exits with the exception code for unhandled
// exceptions.
SetUnhandledExceptionFilter(ExitWithExceptionCode);
# endif
#endif
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -1,237 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2010 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tests Google Test's exception catching behavior.
This script invokes gtest_catch_exceptions_test_ and
gtest_catch_exceptions_ex_test_ (programs written with
Google Test) and verifies their output.
"""
__author__ = 'vladl@google.com (Vlad Losev)'
import os
import gtest_test_utils
# Constants.
FLAG_PREFIX = '--gtest_'
LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0'
FILTER_FLAG = FLAG_PREFIX + 'filter'
# Path to the gtest_catch_exceptions_ex_test_ binary, compiled with
# exceptions enabled.
EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_catch_exceptions_ex_test_')
# Path to the gtest_catch_exceptions_test_ binary, compiled with
# exceptions disabled.
EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_catch_exceptions_no_ex_test_')
environ = gtest_test_utils.environ
SetEnvVar = gtest_test_utils.SetEnvVar
# Tests in this file run a Google-Test-based test program and expect it
# to terminate prematurely. Therefore they are incompatible with
# the premature-exit-file protocol by design. Unset the
# premature-exit filepath to prevent Google Test from creating
# the file.
SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None)
TEST_LIST = gtest_test_utils.Subprocess(
[EXE_PATH, LIST_TESTS_FLAG], env=environ).output
SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST
if SUPPORTS_SEH_EXCEPTIONS:
BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output
EX_BINARY_OUTPUT = gtest_test_utils.Subprocess(
[EX_EXE_PATH], env=environ).output
# The tests.
if SUPPORTS_SEH_EXCEPTIONS:
# pylint:disable-msg=C6302
class CatchSehExceptionsTest(gtest_test_utils.TestCase):
"""Tests exception-catching behavior."""
def TestSehExceptions(self, test_output):
self.assert_('SEH exception with code 0x2a thrown '
'in the test fixture\'s constructor'
in test_output)
self.assert_('SEH exception with code 0x2a thrown '
'in the test fixture\'s destructor'
in test_output)
self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()'
in test_output)
self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()'
in test_output)
self.assert_('SEH exception with code 0x2a thrown in SetUp()'
in test_output)
self.assert_('SEH exception with code 0x2a thrown in TearDown()'
in test_output)
self.assert_('SEH exception with code 0x2a thrown in the test body'
in test_output)
def testCatchesSehExceptionsWithCxxExceptionsEnabled(self):
self.TestSehExceptions(EX_BINARY_OUTPUT)
def testCatchesSehExceptionsWithCxxExceptionsDisabled(self):
self.TestSehExceptions(BINARY_OUTPUT)
class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
"""Tests C++ exception-catching behavior.
Tests in this test case verify that:
* C++ exceptions are caught and logged as C++ (not SEH) exceptions
* Exception thrown affect the remainder of the test work flow in the
expected manner.
"""
def testCatchesCxxExceptionsInFixtureConstructor(self):
self.assert_('C++ exception with description '
'"Standard C++ exception" thrown '
'in the test fixture\'s constructor'
in EX_BINARY_OUTPUT)
self.assert_('unexpected' not in EX_BINARY_OUTPUT,
'This failure belongs in this test only if '
'"CxxExceptionInConstructorTest" (no quotes) '
'appears on the same line as words "called unexpectedly"')
if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in
EX_BINARY_OUTPUT):
def testCatchesCxxExceptionsInFixtureDestructor(self):
self.assert_('C++ exception with description '
'"Standard C++ exception" thrown '
'in the test fixture\'s destructor'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() '
'called as expected.'
in EX_BINARY_OUTPUT)
def testCatchesCxxExceptionsInSetUpTestCase(self):
self.assert_('C++ exception with description "Standard C++ exception"'
' thrown in SetUpTestCase()'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTestCaseTest constructor '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTestCaseTest destructor '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTestCaseTest test body '
'called as expected.'
in EX_BINARY_OUTPUT)
def testCatchesCxxExceptionsInTearDownTestCase(self):
self.assert_('C++ exception with description "Standard C++ exception"'
' thrown in TearDownTestCase()'
in EX_BINARY_OUTPUT)
def testCatchesCxxExceptionsInSetUp(self):
self.assert_('C++ exception with description "Standard C++ exception"'
' thrown in SetUp()'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTest destructor '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInSetUpTest::TearDown() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('unexpected' not in EX_BINARY_OUTPUT,
'This failure belongs in this test only if '
'"CxxExceptionInSetUpTest" (no quotes) '
'appears on the same line as words "called unexpectedly"')
def testCatchesCxxExceptionsInTearDown(self):
self.assert_('C++ exception with description "Standard C++ exception"'
' thrown in TearDown()'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInTearDownTest destructor '
'called as expected.'
in EX_BINARY_OUTPUT)
def testCatchesCxxExceptionsInTestBody(self):
self.assert_('C++ exception with description "Standard C++ exception"'
' thrown in the test body'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInTestBodyTest destructor '
'called as expected.'
in EX_BINARY_OUTPUT)
self.assert_('CxxExceptionInTestBodyTest::TearDown() '
'called as expected.'
in EX_BINARY_OUTPUT)
def testCatchesNonStdCxxExceptions(self):
self.assert_('Unknown C++ exception thrown in the test body'
in EX_BINARY_OUTPUT)
def testUnhandledCxxExceptionsAbortTheProgram(self):
# Filters out SEH exception tests on Windows. Unhandled SEH exceptions
# cause tests to show pop-up windows there.
FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*'
# By default, Google Test doesn't catch the exceptions.
uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess(
[EX_EXE_PATH,
NO_CATCH_EXCEPTIONS_FLAG,
FITLER_OUT_SEH_TESTS_FLAG],
env=environ).output
self.assert_('Unhandled C++ exception terminating the program'
in uncaught_exceptions_ex_binary_output)
self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output)
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,311 +0,0 @@
// Copyright 2010, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
//
// Tests for Google Test itself. Tests in this file throw C++ or SEH
// exceptions, and the output is verified by gtest_catch_exceptions_test.py.
#include "gtest/gtest.h"
#include <stdio.h> // NOLINT
#include <stdlib.h> // For exit().
#if GTEST_HAS_SEH
# include <windows.h>
#endif
#if GTEST_HAS_EXCEPTIONS
# include <exception> // For set_terminate().
# include <stdexcept>
#endif
using testing::Test;
#if GTEST_HAS_SEH
class SehExceptionInConstructorTest : public Test {
public:
SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); }
};
TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {}
class SehExceptionInDestructorTest : public Test {
public:
~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); }
};
TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {}
class SehExceptionInSetUpTestCaseTest : public Test {
public:
static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); }
};
TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {}
class SehExceptionInTearDownTestCaseTest : public Test {
public:
static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); }
};
TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {}
class SehExceptionInSetUpTest : public Test {
protected:
virtual void SetUp() { RaiseException(42, 0, 0, NULL); }
};
TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {}
class SehExceptionInTearDownTest : public Test {
protected:
virtual void TearDown() { RaiseException(42, 0, 0, NULL); }
};
TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {}
TEST(SehExceptionTest, ThrowsSehException) {
RaiseException(42, 0, 0, NULL);
}
#endif // GTEST_HAS_SEH
#if GTEST_HAS_EXCEPTIONS
class CxxExceptionInConstructorTest : public Test {
public:
CxxExceptionInConstructorTest() {
// Without this macro VC++ complains about unreachable code at the end of
// the constructor.
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
throw std::runtime_error("Standard C++ exception"));
}
static void TearDownTestCase() {
printf("%s",
"CxxExceptionInConstructorTest::TearDownTestCase() "
"called as expected.\n");
}
protected:
~CxxExceptionInConstructorTest() {
ADD_FAILURE() << "CxxExceptionInConstructorTest destructor "
<< "called unexpectedly.";
}
virtual void SetUp() {
ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() "
<< "called unexpectedly.";
}
virtual void TearDown() {
ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() "
<< "called unexpectedly.";
}
};
TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) {
ADD_FAILURE() << "CxxExceptionInConstructorTest test body "
<< "called unexpectedly.";
}
// Exceptions in destructors are not supported in C++11.
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
class CxxExceptionInDestructorTest : public Test {
public:
static void TearDownTestCase() {
printf("%s",
"CxxExceptionInDestructorTest::TearDownTestCase() "
"called as expected.\n");
}
protected:
~CxxExceptionInDestructorTest() {
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
throw std::runtime_error("Standard C++ exception"));
}
};
TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {}
#endif // C++11 mode
class CxxExceptionInSetUpTestCaseTest : public Test {
public:
CxxExceptionInSetUpTestCaseTest() {
printf("%s",
"CxxExceptionInSetUpTestCaseTest constructor "
"called as expected.\n");
}
static void SetUpTestCase() {
throw std::runtime_error("Standard C++ exception");
}
static void TearDownTestCase() {
printf("%s",
"CxxExceptionInSetUpTestCaseTest::TearDownTestCase() "
"called as expected.\n");
}
protected:
~CxxExceptionInSetUpTestCaseTest() {
printf("%s",
"CxxExceptionInSetUpTestCaseTest destructor "
"called as expected.\n");
}
virtual void SetUp() {
printf("%s",
"CxxExceptionInSetUpTestCaseTest::SetUp() "
"called as expected.\n");
}
virtual void TearDown() {
printf("%s",
"CxxExceptionInSetUpTestCaseTest::TearDown() "
"called as expected.\n");
}
};
TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {
printf("%s",
"CxxExceptionInSetUpTestCaseTest test body "
"called as expected.\n");
}
class CxxExceptionInTearDownTestCaseTest : public Test {
public:
static void TearDownTestCase() {
throw std::runtime_error("Standard C++ exception");
}
};
TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {}
class CxxExceptionInSetUpTest : public Test {
public:
static void TearDownTestCase() {
printf("%s",
"CxxExceptionInSetUpTest::TearDownTestCase() "
"called as expected.\n");
}
protected:
~CxxExceptionInSetUpTest() {
printf("%s",
"CxxExceptionInSetUpTest destructor "
"called as expected.\n");
}
virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); }
virtual void TearDown() {
printf("%s",
"CxxExceptionInSetUpTest::TearDown() "
"called as expected.\n");
}
};
TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) {
ADD_FAILURE() << "CxxExceptionInSetUpTest test body "
<< "called unexpectedly.";
}
class CxxExceptionInTearDownTest : public Test {
public:
static void TearDownTestCase() {
printf("%s",
"CxxExceptionInTearDownTest::TearDownTestCase() "
"called as expected.\n");
}
protected:
~CxxExceptionInTearDownTest() {
printf("%s",
"CxxExceptionInTearDownTest destructor "
"called as expected.\n");
}
virtual void TearDown() {
throw std::runtime_error("Standard C++ exception");
}
};
TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {}
class CxxExceptionInTestBodyTest : public Test {
public:
static void TearDownTestCase() {
printf("%s",
"CxxExceptionInTestBodyTest::TearDownTestCase() "
"called as expected.\n");
}
protected:
~CxxExceptionInTestBodyTest() {
printf("%s",
"CxxExceptionInTestBodyTest destructor "
"called as expected.\n");
}
virtual void TearDown() {
printf("%s",
"CxxExceptionInTestBodyTest::TearDown() "
"called as expected.\n");
}
};
TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) {
throw std::runtime_error("Standard C++ exception");
}
TEST(CxxExceptionTest, ThrowsNonStdCxxException) {
throw "C-string";
}
// This terminate handler aborts the program using exit() rather than abort().
// This avoids showing pop-ups on Windows systems and core dumps on Unix-like
// ones.
void TerminateHandler() {
fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program.");
fflush(NULL);
exit(3);
}
#endif // GTEST_HAS_EXCEPTIONS
int main(int argc, char** argv) {
#if GTEST_HAS_EXCEPTIONS
std::set_terminate(&TerminateHandler);
#endif
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -1,130 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Verifies that Google Test correctly determines whether to use colors."""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import gtest_test_utils
IS_WINDOWS = os.name = 'nt'
COLOR_ENV_VAR = 'GTEST_COLOR'
COLOR_FLAG = 'gtest_color'
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_')
def SetEnvVar(env_var, value):
"""Sets the env variable to 'value'; unsets it when 'value' is None."""
if value is not None:
os.environ[env_var] = value
elif env_var in os.environ:
del os.environ[env_var]
def UsesColor(term, color_env_var, color_flag):
"""Runs gtest_color_test_ and returns its exit code."""
SetEnvVar('TERM', term)
SetEnvVar(COLOR_ENV_VAR, color_env_var)
if color_flag is None:
args = []
else:
args = ['--%s=%s' % (COLOR_FLAG, color_flag)]
p = gtest_test_utils.Subprocess([COMMAND] + args)
return not p.exited or p.exit_code
class GTestColorTest(gtest_test_utils.TestCase):
def testNoEnvVarNoFlag(self):
"""Tests the case when there's neither GTEST_COLOR nor --gtest_color."""
if not IS_WINDOWS:
self.assert_(not UsesColor('dumb', None, None))
self.assert_(not UsesColor('emacs', None, None))
self.assert_(not UsesColor('xterm-mono', None, None))
self.assert_(not UsesColor('unknown', None, None))
self.assert_(not UsesColor(None, None, None))
self.assert_(UsesColor('linux', None, None))
self.assert_(UsesColor('cygwin', None, None))
self.assert_(UsesColor('xterm', None, None))
self.assert_(UsesColor('xterm-color', None, None))
self.assert_(UsesColor('xterm-256color', None, None))
def testFlagOnly(self):
"""Tests the case when there's --gtest_color but not GTEST_COLOR."""
self.assert_(not UsesColor('dumb', None, 'no'))
self.assert_(not UsesColor('xterm-color', None, 'no'))
if not IS_WINDOWS:
self.assert_(not UsesColor('emacs', None, 'auto'))
self.assert_(UsesColor('xterm', None, 'auto'))
self.assert_(UsesColor('dumb', None, 'yes'))
self.assert_(UsesColor('xterm', None, 'yes'))
def testEnvVarOnly(self):
"""Tests the case when there's GTEST_COLOR but not --gtest_color."""
self.assert_(not UsesColor('dumb', 'no', None))
self.assert_(not UsesColor('xterm-color', 'no', None))
if not IS_WINDOWS:
self.assert_(not UsesColor('dumb', 'auto', None))
self.assert_(UsesColor('xterm-color', 'auto', None))
self.assert_(UsesColor('dumb', 'yes', None))
self.assert_(UsesColor('xterm-color', 'yes', None))
def testEnvVarAndFlag(self):
"""Tests the case when there are both GTEST_COLOR and --gtest_color."""
self.assert_(not UsesColor('xterm-color', 'no', 'no'))
self.assert_(UsesColor('dumb', 'no', 'yes'))
self.assert_(UsesColor('xterm-color', 'no', 'auto'))
def testAliasesOfYesAndNo(self):
"""Tests using aliases in specifying --gtest_color."""
self.assert_(UsesColor('dumb', None, 'true'))
self.assert_(UsesColor('dumb', None, 'YES'))
self.assert_(UsesColor('dumb', None, 'T'))
self.assert_(UsesColor('dumb', None, '1'))
self.assert_(not UsesColor('xterm', None, 'f'))
self.assert_(not UsesColor('xterm', None, 'false'))
self.assert_(not UsesColor('xterm', None, '0'))
self.assert_(not UsesColor('xterm', None, 'unknown'))
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,71 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// A helper program for testing how Google Test determines whether to use
// colors in the output. It prints "YES" and returns 1 if Google Test
// decides to use colors, and prints "NO" and returns 0 otherwise.
#include <stdio.h>
#include "gtest/gtest.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// his code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
using testing::internal::ShouldUseColor;
// The purpose of this is to ensure that the UnitTest singleton is
// created before main() is entered, and thus that ShouldUseColor()
// works the same way as in a real Google-Test-based test. We don't actual
// run the TEST itself.
TEST(GTestColorTest, Dummy) {
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
if (ShouldUseColor(true)) {
// Google Test decides to use colors in the output (assuming it
// goes to a TTY).
printf("YES\n");
return 1;
} else {
// Google Test decides not to use colors in the output.
printf("NO\n");
return 0;
}
}

View File

@ -1,117 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Verifies that Google Test correctly parses environment variables."""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import gtest_test_utils
IS_WINDOWS = os.name == 'nt'
IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
environ = os.environ.copy()
def AssertEq(expected, actual):
if expected != actual:
print('Expected: %s' % (expected,))
print(' Actual: %s' % (actual,))
raise AssertionError
def SetEnvVar(env_var, value):
"""Sets the env variable to 'value'; unsets it when 'value' is None."""
if value is not None:
environ[env_var] = value
elif env_var in environ:
del environ[env_var]
def GetFlag(flag):
"""Runs gtest_env_var_test_ and returns its output."""
args = [COMMAND]
if flag is not None:
args += [flag]
return gtest_test_utils.Subprocess(args, env=environ).output
def TestFlag(flag, test_val, default_val):
"""Verifies that the given flag is affected by the corresponding env var."""
env_var = 'GTEST_' + flag.upper()
SetEnvVar(env_var, test_val)
AssertEq(test_val, GetFlag(flag))
SetEnvVar(env_var, None)
AssertEq(default_val, GetFlag(flag))
class GTestEnvVarTest(gtest_test_utils.TestCase):
def testEnvVarAffectsFlag(self):
"""Tests that environment variable should affect the corresponding flag."""
TestFlag('break_on_failure', '1', '0')
TestFlag('color', 'yes', 'auto')
TestFlag('filter', 'FooTest.Bar', '*')
SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test
TestFlag('output', 'xml:tmp/foo.xml', '')
TestFlag('print_time', '0', '1')
TestFlag('repeat', '999', '1')
TestFlag('throw_on_failure', '1', '0')
TestFlag('death_test_style', 'threadsafe', 'fast')
TestFlag('catch_exceptions', '0', '1')
if IS_LINUX:
TestFlag('death_test_use_fork', '1', '0')
TestFlag('stack_trace_depth', '0', '100')
def testXmlOutputFile(self):
"""Tests that $XML_OUTPUT_FILE affects the output flag."""
SetEnvVar('GTEST_OUTPUT', None)
SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml')
AssertEq('xml:tmp/bar.xml', GetFlag('output'))
def testXmlOutputFileOverride(self):
"""Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT"""
SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml')
SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml')
AssertEq('xml:tmp/foo.xml', GetFlag('output'))
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,126 +0,0 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// A helper program for testing that Google Test parses the environment
// variables correctly.
#include "gtest/gtest.h"
#include <iostream>
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
using ::std::cout;
namespace testing {
// The purpose of this is to make the test more realistic by ensuring
// that the UnitTest singleton is created before main() is entered.
// We don't actual run the TEST itself.
TEST(GTestEnvVarTest, Dummy) {
}
void PrintFlag(const char* flag) {
if (strcmp(flag, "break_on_failure") == 0) {
cout << GTEST_FLAG(break_on_failure);
return;
}
if (strcmp(flag, "catch_exceptions") == 0) {
cout << GTEST_FLAG(catch_exceptions);
return;
}
if (strcmp(flag, "color") == 0) {
cout << GTEST_FLAG(color);
return;
}
if (strcmp(flag, "death_test_style") == 0) {
cout << GTEST_FLAG(death_test_style);
return;
}
if (strcmp(flag, "death_test_use_fork") == 0) {
cout << GTEST_FLAG(death_test_use_fork);
return;
}
if (strcmp(flag, "filter") == 0) {
cout << GTEST_FLAG(filter);
return;
}
if (strcmp(flag, "output") == 0) {
cout << GTEST_FLAG(output);
return;
}
if (strcmp(flag, "print_time") == 0) {
cout << GTEST_FLAG(print_time);
return;
}
if (strcmp(flag, "repeat") == 0) {
cout << GTEST_FLAG(repeat);
return;
}
if (strcmp(flag, "stack_trace_depth") == 0) {
cout << GTEST_FLAG(stack_trace_depth);
return;
}
if (strcmp(flag, "throw_on_failure") == 0) {
cout << GTEST_FLAG(throw_on_failure);
return;
}
cout << "Invalid flag name " << flag
<< ". Valid names are break_on_failure, color, filter, etc.\n";
exit(1);
}
} // namespace testing
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
if (argc != 2) {
cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n";
return 1;
}
testing::PrintFlag(argv[1]);
return 0;
}

View File

@ -1,192 +0,0 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Tests using global test environments.
#include <stdlib.h>
#include <stdio.h>
#include "gtest/gtest.h"
#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include.
#include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing {
GTEST_DECLARE_string_(filter);
}
namespace {
enum FailureType {
NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE
};
// For testing using global test environments.
class MyEnvironment : public testing::Environment {
public:
MyEnvironment() { Reset(); }
// Depending on the value of failure_in_set_up_, SetUp() will
// generate a non-fatal failure, generate a fatal failure, or
// succeed.
virtual void SetUp() {
set_up_was_run_ = true;
switch (failure_in_set_up_) {
case NON_FATAL_FAILURE:
ADD_FAILURE() << "Expected non-fatal failure in global set-up.";
break;
case FATAL_FAILURE:
FAIL() << "Expected fatal failure in global set-up.";
break;
default:
break;
}
}
// Generates a non-fatal failure.
virtual void TearDown() {
tear_down_was_run_ = true;
ADD_FAILURE() << "Expected non-fatal failure in global tear-down.";
}
// Resets the state of the environment s.t. it can be reused.
void Reset() {
failure_in_set_up_ = NO_FAILURE;
set_up_was_run_ = false;
tear_down_was_run_ = false;
}
// We call this function to set the type of failure SetUp() should
// generate.
void set_failure_in_set_up(FailureType type) {
failure_in_set_up_ = type;
}
// Was SetUp() run?
bool set_up_was_run() const { return set_up_was_run_; }
// Was TearDown() run?
bool tear_down_was_run() const { return tear_down_was_run_; }
private:
FailureType failure_in_set_up_;
bool set_up_was_run_;
bool tear_down_was_run_;
};
// Was the TEST run?
bool test_was_run;
// The sole purpose of this TEST is to enable us to check whether it
// was run.
TEST(FooTest, Bar) {
test_was_run = true;
}
// Prints the message and aborts the program if condition is false.
void Check(bool condition, const char* msg) {
if (!condition) {
printf("FAILED: %s\n", msg);
testing::internal::posix::Abort();
}
}
// Runs the tests. Return true iff successful.
//
// The 'failure' parameter specifies the type of failure that should
// be generated by the global set-up.
int RunAllTests(MyEnvironment* env, FailureType failure) {
env->Reset();
env->set_failure_in_set_up(failure);
test_was_run = false;
testing::internal::GetUnitTestImpl()->ClearAdHocTestResult();
return RUN_ALL_TESTS();
}
} // namespace
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
// Registers a global test environment, and verifies that the
// registration function returns its argument.
MyEnvironment* const env = new MyEnvironment;
Check(testing::AddGlobalTestEnvironment(env) == env,
"AddGlobalTestEnvironment() should return its argument.");
// Verifies that RUN_ALL_TESTS() runs the tests when the global
// set-up is successful.
Check(RunAllTests(env, NO_FAILURE) != 0,
"RUN_ALL_TESTS() should return non-zero, as the global tear-down "
"should generate a failure.");
Check(test_was_run,
"The tests should run, as the global set-up should generate no "
"failure");
Check(env->tear_down_was_run(),
"The global tear-down should run, as the global set-up was run.");
// Verifies that RUN_ALL_TESTS() runs the tests when the global
// set-up generates no fatal failure.
Check(RunAllTests(env, NON_FATAL_FAILURE) != 0,
"RUN_ALL_TESTS() should return non-zero, as both the global set-up "
"and the global tear-down should generate a non-fatal failure.");
Check(test_was_run,
"The tests should run, as the global set-up should generate no "
"fatal failure.");
Check(env->tear_down_was_run(),
"The global tear-down should run, as the global set-up was run.");
// Verifies that RUN_ALL_TESTS() runs no test when the global set-up
// generates a fatal failure.
Check(RunAllTests(env, FATAL_FAILURE) != 0,
"RUN_ALL_TESTS() should return non-zero, as the global set-up "
"should generate a fatal failure.");
Check(!test_was_run,
"The tests should not run, as the global set-up should generate "
"a fatal failure.");
Check(env->tear_down_was_run(),
"The global tear-down should run, as the global set-up was run.");
// Verifies that RUN_ALL_TESTS() doesn't do global set-up or
// tear-down when there is no test to run.
testing::GTEST_FLAG(filter) = "-*";
Check(RunAllTests(env, NO_FAILURE) == 0,
"RUN_ALL_TESTS() should return zero, as there is no test to run.");
Check(!env->set_up_was_run(),
"The global set-up should not run, as there is no test to run.");
Check(!env->tear_down_was_run(),
"The global tear-down should not run, "
"as the global set-up was not run.");
printf("PASS\n");
return 0;
}

View File

@ -1,636 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2005 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for Google Test test filters.
A user can specify which test(s) in a Google Test program to run via either
the GTEST_FILTER environment variable or the --gtest_filter flag.
This script tests such functionality by invoking
gtest_filter_unittest_ (a program written with Google Test) with different
environments and command line flags.
Note that test sharding may also influence which tests are filtered. Therefore,
we test that here also.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
try:
from sets import Set as set # For Python 2.3 compatibility
except ImportError:
pass
import sys
import gtest_test_utils
# Constants.
# Checks if this platform can pass empty environment variables to child
# processes. We set an env variable to an empty string and invoke a python
# script in a subprocess to print whether the variable is STILL in
# os.environ. We then use 'eval' to parse the child's output so that an
# exception is thrown if the input is anything other than 'True' nor 'False'.
os.environ['EMPTY_VAR'] = ''
child = gtest_test_utils.Subprocess(
[sys.executable, '-c', 'import os; print(\'EMPTY_VAR\' in os.environ)'])
CAN_PASS_EMPTY_ENV = eval(child.output)
# Check if this platform can unset environment variables in child processes.
# We set an env variable to a non-empty string, unset it, and invoke
# a python script in a subprocess to print whether the variable
# is NO LONGER in os.environ.
# We use 'eval' to parse the child's output so that an exception
# is thrown if the input is neither 'True' nor 'False'.
os.environ['UNSET_VAR'] = 'X'
del os.environ['UNSET_VAR']
child = gtest_test_utils.Subprocess(
[sys.executable, '-c', 'import os; print(\'UNSET_VAR\' not in os.environ)'])
CAN_UNSET_ENV = eval(child.output)
# Checks if we should test with an empty filter. This doesn't
# make sense on platforms that cannot pass empty env variables (Win32)
# and on platforms that cannot unset variables (since we cannot tell
# the difference between "" and NULL -- Borland and Solaris < 5.10)
CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV)
# The environment variable for specifying the test filters.
FILTER_ENV_VAR = 'GTEST_FILTER'
# The environment variables for test sharding.
TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
# The command line flag for specifying the test filters.
FILTER_FLAG = 'gtest_filter'
# The command line flag for including disabled tests.
ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
# Command to run the gtest_filter_unittest_ program.
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
# Regex for determining whether parameterized tests are enabled in the binary.
PARAM_TEST_REGEX = re.compile(r'/ParamTest')
# Regex for parsing test case names from Google Test's output.
TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)')
# Regex for parsing test names from Google Test's output.
TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)')
# The command line flag to tell Google Test to output the list of tests it
# will run.
LIST_TESTS_FLAG = '--gtest_list_tests'
# Indicates whether Google Test supports death tests.
SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess(
[COMMAND, LIST_TESTS_FLAG]).output
# Full names of all tests in gtest_filter_unittests_.
PARAM_TESTS = [
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestX/1',
'SeqP/ParamTest.TestY/0',
'SeqP/ParamTest.TestY/1',
'SeqQ/ParamTest.TestX/0',
'SeqQ/ParamTest.TestX/1',
'SeqQ/ParamTest.TestY/0',
'SeqQ/ParamTest.TestY/1',
]
DISABLED_TESTS = [
'BarTest.DISABLED_TestFour',
'BarTest.DISABLED_TestFive',
'BazTest.DISABLED_TestC',
'DISABLED_FoobarTest.Test1',
'DISABLED_FoobarTest.DISABLED_Test2',
'DISABLED_FoobarbazTest.TestA',
]
if SUPPORTS_DEATH_TESTS:
DEATH_TESTS = [
'HasDeathTest.Test1',
'HasDeathTest.Test2',
]
else:
DEATH_TESTS = []
# All the non-disabled tests.
ACTIVE_TESTS = [
'FooTest.Abc',
'FooTest.Xyz',
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
'BazTest.TestOne',
'BazTest.TestA',
'BazTest.TestB',
] + DEATH_TESTS + PARAM_TESTS
param_tests_present = None
# Utilities.
environ = os.environ.copy()
def SetEnvVar(env_var, value):
"""Sets the env variable to 'value'; unsets it when 'value' is None."""
if value is not None:
environ[env_var] = value
elif env_var in environ:
del environ[env_var]
def RunAndReturnOutput(args = None):
"""Runs the test program and returns its output."""
return gtest_test_utils.Subprocess([COMMAND] + (args or []),
env=environ).output
def RunAndExtractTestList(args = None):
"""Runs the test program and returns its exit code and a list of tests run."""
p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ)
tests_run = []
test_case = ''
test = ''
for line in p.output.split('\n'):
match = TEST_CASE_REGEX.match(line)
if match is not None:
test_case = match.group(1)
else:
match = TEST_REGEX.match(line)
if match is not None:
test = match.group(1)
tests_run.append(test_case + '.' + test)
return (tests_run, p.exit_code)
def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs):
"""Runs the given function and arguments in a modified environment."""
try:
original_env = environ.copy()
environ.update(extra_env)
return function(*args, **kwargs)
finally:
environ.clear()
environ.update(original_env)
def RunWithSharding(total_shards, shard_index, command):
"""Runs a test program shard and returns exit code and a list of tests run."""
extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index),
TOTAL_SHARDS_ENV_VAR: str(total_shards)}
return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command)
# The unit test.
class GTestFilterUnitTest(gtest_test_utils.TestCase):
"""Tests the env variable or the command line flag to filter tests."""
# Utilities.
def AssertSetEqual(self, lhs, rhs):
"""Asserts that two sets are equal."""
for elem in lhs:
self.assert_(elem in rhs, '%s in %s' % (elem, rhs))
for elem in rhs:
self.assert_(elem in lhs, '%s in %s' % (elem, lhs))
def AssertPartitionIsValid(self, set_var, list_of_sets):
"""Asserts that list_of_sets is a valid partition of set_var."""
full_partition = []
for slice_var in list_of_sets:
full_partition.extend(slice_var)
self.assertEqual(len(set_var), len(full_partition))
self.assertEqual(set(set_var), set(full_partition))
def AdjustForParameterizedTests(self, tests_to_run):
"""Adjust tests_to_run in case value parameterized tests are disabled."""
global param_tests_present
if not param_tests_present:
return list(set(tests_to_run) - set(PARAM_TESTS))
else:
return tests_to_run
def RunAndVerify(self, gtest_filter, tests_to_run):
"""Checks that the binary runs correct set of tests for a given filter."""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# First, tests using the environment variable.
# Windows removes empty variables from the environment when passing it
# to a new process. This means it is impossible to pass an empty filter
# into a process using the environment variable. However, we can still
# test the case when the variable is not supplied (i.e., gtest_filter is
# None).
# pylint: disable-msg=C6403
if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
SetEnvVar(FILTER_ENV_VAR, gtest_filter)
tests_run = RunAndExtractTestList()[0]
SetEnvVar(FILTER_ENV_VAR, None)
self.AssertSetEqual(tests_run, tests_to_run)
# pylint: enable-msg=C6403
# Next, tests using the command line flag.
if gtest_filter is None:
args = []
else:
args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)]
tests_run = RunAndExtractTestList(args)[0]
self.AssertSetEqual(tests_run, tests_to_run)
def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run,
args=None, check_exit_0=False):
"""Checks that binary runs correct tests for the given filter and shard.
Runs all shards of gtest_filter_unittest_ with the given filter, and
verifies that the right set of tests were run. The union of tests run
on each shard should be identical to tests_to_run, without duplicates.
Args:
gtest_filter: A filter to apply to the tests.
total_shards: A total number of shards to split test run into.
tests_to_run: A set of tests expected to run.
args : Arguments to pass to the to the test binary.
check_exit_0: When set to a true value, make sure that all shards
return 0.
"""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Windows removes empty variables from the environment when passing it
# to a new process. This means it is impossible to pass an empty filter
# into a process using the environment variable. However, we can still
# test the case when the variable is not supplied (i.e., gtest_filter is
# None).
# pylint: disable-msg=C6403
if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
SetEnvVar(FILTER_ENV_VAR, gtest_filter)
partition = []
for i in range(0, total_shards):
(tests_run, exit_code) = RunWithSharding(total_shards, i, args)
if check_exit_0:
self.assertEqual(0, exit_code)
partition.append(tests_run)
self.AssertPartitionIsValid(tests_to_run, partition)
SetEnvVar(FILTER_ENV_VAR, None)
# pylint: enable-msg=C6403
def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run):
"""Checks that the binary runs correct set of tests for the given filter.
Runs gtest_filter_unittest_ with the given filter, and enables
disabled tests. Verifies that the right set of tests were run.
Args:
gtest_filter: A filter to apply to the tests.
tests_to_run: A set of tests expected to run.
"""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Construct the command line.
args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG]
if gtest_filter is not None:
args.append('--%s=%s' % (FILTER_FLAG, gtest_filter))
tests_run = RunAndExtractTestList(args)[0]
self.AssertSetEqual(tests_run, tests_to_run)
def setUp(self):
"""Sets up test case.
Determines whether value-parameterized tests are enabled in the binary and
sets the flags accordingly.
"""
global param_tests_present
if param_tests_present is None:
param_tests_present = PARAM_TEST_REGEX.search(
RunAndReturnOutput()) is not None
def testDefaultBehavior(self):
"""Tests the behavior of not specifying the filter."""
self.RunAndVerify(None, ACTIVE_TESTS)
def testDefaultBehaviorWithShards(self):
"""Tests the behavior without the filter, with sharding enabled."""
self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS)
def testEmptyFilter(self):
"""Tests an empty filter."""
self.RunAndVerify('', [])
self.RunAndVerifyWithSharding('', 1, [])
self.RunAndVerifyWithSharding('', 2, [])
def testBadFilter(self):
"""Tests a filter that matches nothing."""
self.RunAndVerify('BadFilter', [])
self.RunAndVerifyAllowingDisabled('BadFilter', [])
def testFullName(self):
"""Tests filtering by full name."""
self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz'])
self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz'])
self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz'])
def testUniversalFilters(self):
"""Tests filters that match everything."""
self.RunAndVerify('*', ACTIVE_TESTS)
self.RunAndVerify('*.*', ACTIVE_TESTS)
self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS)
self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS)
self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS)
def testFilterByTestCase(self):
"""Tests filtering by test case name."""
self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz'])
BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB']
self.RunAndVerify('BazTest.*', BAZ_TESTS)
self.RunAndVerifyAllowingDisabled('BazTest.*',
BAZ_TESTS + ['BazTest.DISABLED_TestC'])
def testFilterByTest(self):
"""Tests filtering by test name."""
self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne'])
def testFilterDisabledTests(self):
"""Select only the disabled tests to run."""
self.RunAndVerify('DISABLED_FoobarTest.Test1', [])
self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1',
['DISABLED_FoobarTest.Test1'])
self.RunAndVerify('*DISABLED_*', [])
self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS)
self.RunAndVerify('*.DISABLED_*', [])
self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [
'BarTest.DISABLED_TestFour',
'BarTest.DISABLED_TestFive',
'BazTest.DISABLED_TestC',
'DISABLED_FoobarTest.DISABLED_Test2',
])
self.RunAndVerify('DISABLED_*', [])
self.RunAndVerifyAllowingDisabled('DISABLED_*', [
'DISABLED_FoobarTest.Test1',
'DISABLED_FoobarTest.DISABLED_Test2',
'DISABLED_FoobarbazTest.TestA',
])
def testWildcardInTestCaseName(self):
"""Tests using wildcard in the test case name."""
self.RunAndVerify('*a*.*', [
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
'BazTest.TestOne',
'BazTest.TestA',
'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS)
def testWildcardInTestName(self):
"""Tests using wildcard in the test name."""
self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA'])
def testFilterWithoutDot(self):
"""Tests a filter that has no '.' in it."""
self.RunAndVerify('*z*', [
'FooTest.Xyz',
'BazTest.TestOne',
'BazTest.TestA',
'BazTest.TestB',
])
def testTwoPatterns(self):
"""Tests filters that consist of two patterns."""
self.RunAndVerify('Foo*.*:*A*', [
'FooTest.Abc',
'FooTest.Xyz',
'BazTest.TestA',
])
# An empty pattern + a non-empty one
self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA'])
def testThreePatterns(self):
"""Tests filters that consist of three patterns."""
self.RunAndVerify('*oo*:*A*:*One', [
'FooTest.Abc',
'FooTest.Xyz',
'BarTest.TestOne',
'BazTest.TestOne',
'BazTest.TestA',
])
# The 2nd pattern is empty.
self.RunAndVerify('*oo*::*One', [
'FooTest.Abc',
'FooTest.Xyz',
'BarTest.TestOne',
'BazTest.TestOne',
])
# The last 2 patterns are empty.
self.RunAndVerify('*oo*::', [
'FooTest.Abc',
'FooTest.Xyz',
])
def testNegativeFilters(self):
self.RunAndVerify('*-BazTest.TestOne', [
'FooTest.Abc',
'FooTest.Xyz',
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
'BazTest.TestA',
'BazTest.TestB',
] + DEATH_TESTS + PARAM_TESTS)
self.RunAndVerify('*-FooTest.Abc:BazTest.*', [
'FooTest.Xyz',
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
] + DEATH_TESTS + PARAM_TESTS)
self.RunAndVerify('BarTest.*-BarTest.TestOne', [
'BarTest.TestTwo',
'BarTest.TestThree',
])
# Tests without leading '*'.
self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [
'BarTest.TestOne',
'BarTest.TestTwo',
'BarTest.TestThree',
] + DEATH_TESTS + PARAM_TESTS)
# Value parameterized tests.
self.RunAndVerify('*/*', PARAM_TESTS)
# Value parameterized tests filtering by the sequence name.
self.RunAndVerify('SeqP/*', [
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestX/1',
'SeqP/ParamTest.TestY/0',
'SeqP/ParamTest.TestY/1',
])
# Value parameterized tests filtering by the test name.
self.RunAndVerify('*/0', [
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestY/0',
'SeqQ/ParamTest.TestX/0',
'SeqQ/ParamTest.TestY/0',
])
def testFlagOverridesEnvVar(self):
"""Tests that the filter flag overrides the filtering env. variable."""
SetEnvVar(FILTER_ENV_VAR, 'Foo*')
args = ['--%s=%s' % (FILTER_FLAG, '*One')]
tests_run = RunAndExtractTestList(args)[0]
SetEnvVar(FILTER_ENV_VAR, None)
self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne'])
def testShardStatusFileIsCreated(self):
"""Tests that the shard file is created if specified in the environment."""
shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
'shard_status_file')
self.assert_(not os.path.exists(shard_status_file))
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
try:
InvokeWithModifiedEnv(extra_env, RunAndReturnOutput)
finally:
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
def testShardStatusFileIsCreatedWithListTests(self):
"""Tests that the shard file is created with the "list_tests" flag."""
shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
'shard_status_file2')
self.assert_(not os.path.exists(shard_status_file))
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
try:
output = InvokeWithModifiedEnv(extra_env,
RunAndReturnOutput,
[LIST_TESTS_FLAG])
finally:
# This assertion ensures that Google Test enumerated the tests as
# opposed to running them.
self.assert_('[==========]' not in output,
'Unexpected output during test enumeration.\n'
'Please ensure that LIST_TESTS_FLAG is assigned the\n'
'correct flag value for listing Google Test tests.')
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
if SUPPORTS_DEATH_TESTS:
def testShardingWorksWithDeathTests(self):
"""Tests integration with death tests and sharding."""
gtest_filter = 'HasDeathTest.*:SeqP/*'
expected_tests = [
'HasDeathTest.Test1',
'HasDeathTest.Test2',
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestX/1',
'SeqP/ParamTest.TestY/0',
'SeqP/ParamTest.TestY/1',
]
for flag in ['--gtest_death_test_style=threadsafe',
'--gtest_death_test_style=fast']:
self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests,
check_exit_0=True, args=[flag])
self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests,
check_exit_0=True, args=[flag])
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,140 +0,0 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Unit test for Google Test test filters.
//
// A user can specify which test(s) in a Google Test program to run via
// either the GTEST_FILTER environment variable or the --gtest_filter
// flag. This is used for testing such functionality.
//
// The program will be invoked from a Python unit test. Don't run it
// directly.
#include "gtest/gtest.h"
namespace {
// Test case FooTest.
class FooTest : public testing::Test {
};
TEST_F(FooTest, Abc) {
}
TEST_F(FooTest, Xyz) {
FAIL() << "Expected failure.";
}
// Test case BarTest.
TEST(BarTest, TestOne) {
}
TEST(BarTest, TestTwo) {
}
TEST(BarTest, TestThree) {
}
TEST(BarTest, DISABLED_TestFour) {
FAIL() << "Expected failure.";
}
TEST(BarTest, DISABLED_TestFive) {
FAIL() << "Expected failure.";
}
// Test case BazTest.
TEST(BazTest, TestOne) {
FAIL() << "Expected failure.";
}
TEST(BazTest, TestA) {
}
TEST(BazTest, TestB) {
}
TEST(BazTest, DISABLED_TestC) {
FAIL() << "Expected failure.";
}
// Test case HasDeathTest
TEST(HasDeathTest, Test1) {
EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*");
}
// We need at least two death tests to make sure that the all death tests
// aren't on the first shard.
TEST(HasDeathTest, Test2) {
EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*");
}
// Test case FoobarTest
TEST(DISABLED_FoobarTest, Test1) {
FAIL() << "Expected failure.";
}
TEST(DISABLED_FoobarTest, DISABLED_Test2) {
FAIL() << "Expected failure.";
}
// Test case FoobarbazTest
TEST(DISABLED_FoobarbazTest, TestA) {
FAIL() << "Expected failure.";
}
#if GTEST_HAS_PARAM_TEST
class ParamTest : public testing::TestWithParam<int> {
};
TEST_P(ParamTest, TestX) {
}
TEST_P(ParamTest, TestY) {
}
INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2));
INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6));
#endif // GTEST_HAS_PARAM_TEST
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -1,172 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2009, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tests the --help flag of Google C++ Testing Framework.
SYNOPSIS
gtest_help_test.py --build_dir=BUILD/DIR
# where BUILD/DIR contains the built gtest_help_test_ file.
gtest_help_test.py
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import gtest_test_utils
IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
IS_WINDOWS = os.name == 'nt'
PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
FLAG_PREFIX = '--gtest_'
DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to'
UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing'
LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG),
re.sub('^--', '/', LIST_TESTS_FLAG),
re.sub('_', '-', LIST_TESTS_FLAG)]
INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess(
[PROGRAM_PATH, LIST_TESTS_FLAG]).output
# The help message must match this regex.
HELP_REGEX = re.compile(
FLAG_PREFIX + r'list_tests.*' +
FLAG_PREFIX + r'filter=.*' +
FLAG_PREFIX + r'also_run_disabled_tests.*' +
FLAG_PREFIX + r'repeat=.*' +
FLAG_PREFIX + r'shuffle.*' +
FLAG_PREFIX + r'random_seed=.*' +
FLAG_PREFIX + r'color=.*' +
FLAG_PREFIX + r'print_time.*' +
FLAG_PREFIX + r'output=.*' +
FLAG_PREFIX + r'break_on_failure.*' +
FLAG_PREFIX + r'throw_on_failure.*' +
FLAG_PREFIX + r'catch_exceptions=0.*',
re.DOTALL)
def RunWithFlag(flag):
"""Runs gtest_help_test_ with the given flag.
Returns:
the exit code and the text output as a tuple.
Args:
flag: the command-line flag to pass to gtest_help_test_, or None.
"""
if flag is None:
command = [PROGRAM_PATH]
else:
command = [PROGRAM_PATH, flag]
child = gtest_test_utils.Subprocess(command)
return child.exit_code, child.output
class GTestHelpTest(gtest_test_utils.TestCase):
"""Tests the --help flag and its equivalent forms."""
def TestHelpFlag(self, flag):
"""Verifies correct behavior when help flag is specified.
The right message must be printed and the tests must
skipped when the given flag is specified.
Args:
flag: A flag to pass to the binary or None.
"""
exit_code, output = RunWithFlag(flag)
self.assertEquals(0, exit_code)
self.assert_(HELP_REGEX.search(output), output)
if IS_LINUX:
self.assert_(STREAM_RESULT_TO_FLAG in output, output)
else:
self.assert_(STREAM_RESULT_TO_FLAG not in output, output)
if SUPPORTS_DEATH_TESTS and not IS_WINDOWS:
self.assert_(DEATH_TEST_STYLE_FLAG in output, output)
else:
self.assert_(DEATH_TEST_STYLE_FLAG not in output, output)
def TestNonHelpFlag(self, flag):
"""Verifies correct behavior when no help flag is specified.
Verifies that when no help flag is specified, the tests are run
and the help message is not printed.
Args:
flag: A flag to pass to the binary or None.
"""
exit_code, output = RunWithFlag(flag)
self.assert_(exit_code != 0)
self.assert_(not HELP_REGEX.search(output), output)
def testPrintsHelpWithFullFlag(self):
self.TestHelpFlag('--help')
def testPrintsHelpWithShortFlag(self):
self.TestHelpFlag('-h')
def testPrintsHelpWithQuestionFlag(self):
self.TestHelpFlag('-?')
def testPrintsHelpWithWindowsStyleQuestionFlag(self):
self.TestHelpFlag('/?')
def testPrintsHelpWithUnrecognizedGoogleTestFlag(self):
self.TestHelpFlag(UNKNOWN_FLAG)
def testPrintsHelpWithIncorrectFlagStyle(self):
for incorrect_flag in INCORRECT_FLAG_VARIANTS:
self.TestHelpFlag(incorrect_flag)
def testRunsTestsWithoutHelpFlag(self):
"""Verifies that when no help flag is specified, the tests are run
and the help message is not printed."""
self.TestNonHelpFlag(None)
def testRunsTestsWithGtestInternalFlag(self):
"""Verifies that the tests are run and no help message is printed when
a flag starting with Google Test prefix and 'internal_' is supplied."""
self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING)
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,46 +0,0 @@
// Copyright 2009, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This program is meant to be run by gtest_help_test.py. Do not run
// it directly.
#include "gtest/gtest.h"
// When a help flag is specified, this program should skip the tests
// and exit with 0; otherwise the following test will be executed,
// causing this program to exit with a non-zero code.
TEST(HelpFlagTest, ShouldNotBeRun) {
ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified.";
}
#if GTEST_HAS_DEATH_TEST
TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {}
#endif

View File

@ -1,207 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2006, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for Google Test's --gtest_list_tests flag.
A user can ask Google Test to list all tests by specifying the
--gtest_list_tests flag. This script tests such functionality
by invoking gtest_list_tests_unittest_ (a program written with
Google Test) the command line flags.
"""
__author__ = 'phanna@google.com (Patrick Hanna)'
import gtest_test_utils
import re
# Constants.
# The command line flag for enabling/disabling listing all tests.
LIST_TESTS_FLAG = 'gtest_list_tests'
# Path to the gtest_list_tests_unittest_ program.
EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_')
# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests
EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\.
Test1
Foo\.
Bar1
Bar2
DISABLED_Bar3
Abc\.
Xyz
Def
FooBar\.
Baz
FooTest\.
Test1
DISABLED_Test2
Test3
TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TestA
TestB
TypedTest/1\. # TypeParam = int\s*\*( __ptr64)?
TestA
TestB
TypedTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TestA
TestB
My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TestA
TestB
My/TypeParamTest/1\. # TypeParam = int\s*\*( __ptr64)?
TestA
TestB
My/TypeParamTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TestA
TestB
MyInstantiation/ValueParamTest\.
TestA/0 # GetParam\(\) = one line
TestA/1 # GetParam\(\) = two\\nlines
TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
TestB/0 # GetParam\(\) = one line
TestB/1 # GetParam\(\) = two\\nlines
TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
""")
# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests and --gtest_filter=Foo*.
EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\.
Test1
Foo\.
Bar1
Bar2
DISABLED_Bar3
FooBar\.
Baz
FooTest\.
Test1
DISABLED_Test2
Test3
""")
# Utilities.
def Run(args):
"""Runs gtest_list_tests_unittest_ and returns the list of tests printed."""
return gtest_test_utils.Subprocess([EXE_PATH] + args,
capture_stderr=False).output
# The unit test.
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests."""
def RunAndVerify(self, flag_value, expected_output_re, other_flag):
"""Runs gtest_list_tests_unittest_ and verifies that it prints
the correct tests.
Args:
flag_value: value of the --gtest_list_tests flag;
None if the flag should not be present.
expected_output_re: regular expression that matches the expected
output after running command;
other_flag: a different flag to be passed to command
along with gtest_list_tests;
None if the flag should not be present.
"""
if flag_value is None:
flag = ''
flag_expression = 'not set'
elif flag_value == '0':
flag = '--%s=0' % LIST_TESTS_FLAG
flag_expression = '0'
else:
flag = '--%s' % LIST_TESTS_FLAG
flag_expression = '1'
args = [flag]
if other_flag is not None:
args += [other_flag]
output = Run(args)
if expected_output_re:
self.assert_(
expected_output_re.match(output),
('when %s is %s, the output of "%s" is "%s",\n'
'which does not match regex "%s"' %
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output,
expected_output_re.pattern)))
else:
self.assert_(
not EXPECTED_OUTPUT_NO_FILTER_RE.match(output),
('when %s is %s, the output of "%s" is "%s"'%
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)))
def testDefaultBehavior(self):
"""Tests the behavior of the default mode."""
self.RunAndVerify(flag_value=None,
expected_output_re=None,
other_flag=None)
def testFlag(self):
"""Tests using the --gtest_list_tests flag."""
self.RunAndVerify(flag_value='0',
expected_output_re=None,
other_flag=None)
self.RunAndVerify(flag_value='1',
expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag=None)
def testOverrideNonFilterFlags(self):
"""Tests that --gtest_list_tests overrides the non-filter flags."""
self.RunAndVerify(flag_value='1',
expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag='--gtest_break_on_failure')
def testWithFilterFlags(self):
"""Tests that --gtest_list_tests takes into account the
--gtest_filter flag."""
self.RunAndVerify(flag_value='1',
expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE,
other_flag='--gtest_filter=Foo*')
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,157 +0,0 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: phanna@google.com (Patrick Hanna)
// Unit test for Google Test's --gtest_list_tests flag.
//
// A user can ask Google Test to list all tests that will run
// so that when using a filter, a user will know what
// tests to look for. The tests will not be run after listing.
//
// This program will be invoked from a Python unit test.
// Don't run it directly.
#include "gtest/gtest.h"
// Several different test cases and tests that will be listed.
TEST(Foo, Bar1) {
}
TEST(Foo, Bar2) {
}
TEST(Foo, DISABLED_Bar3) {
}
TEST(Abc, Xyz) {
}
TEST(Abc, Def) {
}
TEST(FooBar, Baz) {
}
class FooTest : public testing::Test {
};
TEST_F(FooTest, Test1) {
}
TEST_F(FooTest, DISABLED_Test2) {
}
TEST_F(FooTest, Test3) {
}
TEST(FooDeathTest, Test1) {
}
// A group of value-parameterized tests.
class MyType {
public:
explicit MyType(const std::string& a_value) : value_(a_value) {}
const std::string& value() const { return value_; }
private:
std::string value_;
};
// Teaches Google Test how to print a MyType.
void PrintTo(const MyType& x, std::ostream* os) {
*os << x.value();
}
class ValueParamTest : public testing::TestWithParam<MyType> {
};
TEST_P(ValueParamTest, TestA) {
}
TEST_P(ValueParamTest, TestB) {
}
INSTANTIATE_TEST_CASE_P(
MyInstantiation, ValueParamTest,
testing::Values(MyType("one line"),
MyType("two\nlines"),
MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT
// A group of typed tests.
// A deliberately long type name for testing the line-truncating
// behavior when printing a type parameter.
class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT
};
template <typename T>
class TypedTest : public testing::Test {
};
template <typename T, int kSize>
class MyArray {
};
typedef testing::Types<VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName, // NOLINT
int*, MyArray<bool, 42> > MyTypes;
TYPED_TEST_CASE(TypedTest, MyTypes);
TYPED_TEST(TypedTest, TestA) {
}
TYPED_TEST(TypedTest, TestB) {
}
// A group of type-parameterized tests.
template <typename T>
class TypeParamTest : public testing::Test {
};
TYPED_TEST_CASE_P(TypeParamTest);
TYPED_TEST_P(TypeParamTest, TestA) {
}
TYPED_TEST_P(TypeParamTest, TestB) {
}
REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB);
INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes);
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Some files were not shown because too many files have changed in this diff Show More