ThirdParty: Update included gtest

This commit is contained in:
Paul Hollinsky
2022-02-25 01:14:57 -05:00
parent e52073c518
commit bb49ce039e
227 changed files with 25454 additions and 28563 deletions
+11 -16
View File
@@ -53,7 +53,7 @@ else()
cmake_policy(SET CMP0048 NEW)
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
endif()
cmake_minimum_required(VERSION 2.6.4)
cmake_minimum_required(VERSION 2.8.12)
if (POLICY CMP0063) # Visibility
cmake_policy(SET CMP0063 NEW)
@@ -92,10 +92,13 @@ include(cmake/internal_utils.cmake)
config_compiler_and_linker() # Defined in internal_utils.cmake.
# Needed to set the namespace for both the export targets and the
# alias libraries
set(cmake_package_name GTest CACHE INTERNAL "")
# Create the CMake package file descriptors.
if (INSTALL_GTEST)
include(CMakePackageConfigHelpers)
set(cmake_package_name GTest)
set(targets_export_name ${cmake_package_name}Targets CACHE INTERNAL "")
set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated" CACHE INTERNAL "")
set(cmake_files_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${cmake_package_name}")
@@ -126,7 +129,9 @@ include_directories(${gtest_build_include_dirs})
# are used for other targets, to ensure that gtest can be compiled by a user
# aggressive about warnings.
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)
set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
# If the CMake version supports it, attach header directory information
# to the targets for when we are part of a parent build (ie being pulled
# in via add_subdirectory() rather than being a standalone build).
@@ -182,20 +187,6 @@ if (gtest_build_tests)
# 'make test' or ctest.
enable_testing()
if (WIN32)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/RunTest.ps1"
CONTENT
"$project_bin = \"${CMAKE_BINARY_DIR}/bin/$<CONFIG>\"
$env:Path = \"$project_bin;$env:Path\"
& $args")
elseif (MINGW)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1"
CONTENT
"$project_bin = (cygpath --windows ${CMAKE_BINARY_DIR}/bin)
$env:Path = \"$project_bin;$env:Path\"
& $args")
endif()
############################################################
# C++ tests built with standard compiler flags.
@@ -266,6 +257,7 @@ $env:Path = \"$project_bin;$env:Path\"
cxx_executable(googletest-break-on-failure-unittest_ test gtest)
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.
@@ -317,6 +309,9 @@ $env:Path = \"$project_bin;$env:Path\"
cxx_executable(googletest-uninitialized-test_ test gtest)
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_outfile2_test_ test gtest_main)
py_test(gtest_xml_outfiles_test)
-37
View File
@@ -1,37 +0,0 @@
# This file contains a list of people who've made non-trivial
# contribution to the Google C++ Testing Framework project. People
# who commit code to the project are encouraged to add their names
# here. Please keep the list sorted by first names.
Ajay Joshi <jaj@google.com>
Balázs Dán <balazs.dan@gmail.com>
Bharat Mediratta <bharat@menalto.com>
Chandler Carruth <chandlerc@google.com>
Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com>
Eric Roman <eroman@chromium.org>
Hady Zalek <hady.zalek@gmail.com>
Jeffrey Yasskin <jyasskin@google.com>
Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com>
Keith Ray <keith.ray@gmail.com>
Kenton Varda <kenton@google.com>
Manuel Klimek <klimek@google.com>
Markus Heule <markus.heule@gmail.com>
Mika Raento <mikie@iki.fi>
Miklós Fazekas <mfazekas@szemafor.com>
Pasi Valminen <pasi.valminen@gmail.com>
Patrick Hanna <phanna@google.com>
Patrick Riley <pfr@google.com>
Peter Kaminski <piotrk@google.com>
Preston Jackson <preston.a.jackson@gmail.com>
Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
Russ Cox <rsc@google.com>
Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com>
Tracy Bialik <tracy@pentad.com>
Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com>
Zhanyong Wan <wan@google.com>
-28
View File
@@ -1,28 +0,0 @@
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+75 -104
View File
@@ -2,39 +2,51 @@
#### Setup
To build Google Test and your tests that use it, you need to tell your build
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.
### Build with CMake
Google Test comes with a CMake build script (
[CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt))
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/>.
CMake works by generating native makefiles or build projects that can be used in
the compiler environment of your choice. You can either build Google Test as a
the compiler environment of your choice. You can either build GoogleTest as a
standalone project or it can be incorporated into an existing CMake build for
another project.
#### Standalone CMake Project
When building Google Test as a standalone project, 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
When building GoogleTest as a standalone project, the typical workflow starts
with
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
```
git clone https://github.com/google/googletest.git -b release-1.10.0
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.
```
The above command also includes GoogleMock by default. And so, if you want to
build only GoogleTest, you should replace the last command with
```
cmake .. -DBUILD_GMOCK=OFF
```
If you are on a \*nix system, you should now see a Makefile in the current
directory. Just type 'make' to build gtest.
directory. Just type `make` to build GoogleTest. And then you can simply install
GoogleTest if you are a system administrator.
```
make
sudo make install # Install in /usr/local/ by default
```
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
@@ -44,13 +56,19 @@ On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated.
#### Incorporating Into An Existing CMake Project
If you want to use gtest in a project which already uses CMake, then a more
robust and flexible approach is to build gtest as part of that project directly.
This is done by making the GoogleTest source code available to the main build
and adding it using CMake's `add_subdirectory()` command. This has the
significant advantage that the same compiler and linker settings are used
between gtest and the rest of your project, so issues associated with using
incompatible libraries (eg debug/release), etc. are avoided. This is
If you want to use GoogleTest in a project which already uses CMake, the easiest
way is to get installed libraries and headers.
* 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`.
And a more robust and flexible approach is to build GoogleTest as part of that
project directly. This is done by making the GoogleTest source code available to
the main build and adding it using CMake's `add_subdirectory()` command. This
has the significant advantage that the same compiler and linker settings are
used between GoogleTest and the rest of your project, so issues associated with
using incompatible libraries (eg debug/release), etc. are avoided. This is
particularly useful on Windows. Making GoogleTest's source code available to the
main build can be done a few different ways:
@@ -64,68 +82,23 @@ main build can be done a few different ways:
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
is just a little more complex, but doesn't have the limitations of the other
methods.
approach doesn't have the limitations of the other methods.
The last of the above methods is implemented with a small piece of CMake code in
a separate file (e.g. `CMakeLists.txt.in`) which is copied to the build area and
then invoked as a sub-build _during the CMake stage_. That directory is then
pulled into the main build with `add_subdirectory()`. For example:
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.
New file `CMakeLists.txt.in`:
Just add to your `CMakeLists.txt`:
```cmake
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
include(FetchContent)
FetchContent_Declare(
googletest
# Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
```
Existing build's `CMakeLists.txt`:
```cmake
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# The gtest/gtest_main targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories("${gtest_SOURCE_DIR}/include")
endif()
FetchContent_MakeAvailable(googletest)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable(example example.cpp)
@@ -133,20 +106,18 @@ target_link_libraries(example gtest_main)
add_test(NAME example_test COMMAND example)
```
Note that this approach requires CMake 2.8.2 or later due to its use of the
`ExternalProject_Add()` command. The above technique is discussed in more detail
in [this separate article](http://crascit.com/2015/07/25/cmake-gtest/) which
also contains a link to a fully generalized implementation of the technique.
Note that this approach requires CMake 3.14 or later due to its use of the
`FetchContent_MakeAvailable()` command.
##### Visual Studio Dynamic vs Static Runtimes
By default, new Visual Studio projects link the C runtimes dynamically but
Google Test links them statically. This will generate an error that looks
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
Google Test already has a CMake option for this: `gtest_force_shared_crt`
GoogleTest already has a CMake option for this: `gtest_force_shared_crt`
Enabling this option will make gtest link the runtimes dynamically too, and
match the project in which it is included.
@@ -154,17 +125,17 @@ match the project in which it is included.
#### C++ Standard Version
An environment that supports C++11 is required in order to successfully build
Google Test. One way to ensure this is to specify the standard in the top-level
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 Google Test for validation,
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.
### Tweaking Google Test
### Tweaking GoogleTest
Google Test can be used in diverse environments. The default configuration may
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 Google Test by defining control macros on the compiler
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.
@@ -173,12 +144,12 @@ We list the most frequently used macros below. For a complete list, see file
### 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.).
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.).
If Google Test doesn't correctly detect whether pthread is available in your
If GoogleTest doesn't correctly detect whether pthread is available in your
environment, you can force it with
-DGTEST_HAS_PTHREAD=1
@@ -187,16 +158,16 @@ or
-DGTEST_HAS_PTHREAD=0
When Google Test uses pthread, you may need to add flags to your compiler and/or
When GoogleTest uses pthread, you may need to add flags to your compiler and/or
linker to select the pthread library, or you'll get link errors. If you use the
CMake script or the deprecated Autotools script, this is taken care of for you.
If you use your own build script, you'll need to read your compiler and linker's
manual to figure out what flags to add.
CMake script, this is taken care of for you. If you use your own build script,
you'll need to read your compiler and linker's manual to figure out what flags
to add.
### As a Shared Library (DLL)
Google Test is compact, so most users can build and link it as a static library
for the simplicity. You can choose to use Google Test as a shared library (known
GoogleTest is compact, so most users can build and link it as a static library
for the simplicity. You can choose to use GoogleTest as a shared library (known
as a DLL on Windows) if you prefer.
To compile *gtest* as a shared library, add
@@ -216,22 +187,22 @@ Note: while the above steps aren't technically necessary today when using some
compilers (e.g. GCC), they may become necessary in the future, if we decide to
improve the speed of loading the library (see
<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are recommended
to always add the above flags when using Google Test as a shared library.
Otherwise a future release of Google Test may break your build script.
to always add the above flags when using GoogleTest as a shared library.
Otherwise a future release of GoogleTest may break your build script.
### Avoiding Macro Name Clashes
In C++, macros don't obey namespaces. Therefore two libraries that both define a
macro of the same name will clash if you `#include` both definitions. In case a
Google Test macro clashes with another library, you can force Google Test to
GoogleTest macro clashes with another library, you can force GoogleTest to
rename its macro to avoid the conflict.
Specifically, if both Google Test and some other code define macro FOO, you can
Specifically, if both GoogleTest and some other code define macro FOO, you can
add
-DGTEST_DONT_DEFINE_FOO=1
to the compiler flags to tell Google Test to change the macro's name from `FOO`
to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, or `TEST`. For
example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
+3 -4
View File
@@ -1,10 +1,9 @@
prefix=${pcfiledir}/../..
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
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@ @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
@@ -1,11 +1,10 @@
prefix=${pcfiledir}/../..
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
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
Requires: gtest = @PROJECT_VERSION@
Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@
Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
@@ -72,7 +72,7 @@ macro(config_compiler_and_linker)
if (MSVC)
# Newlines inside flags variables break CMake's NMake generator.
# 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")
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_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
@@ -81,6 +81,8 @@ macro(config_compiler_and_linker)
# 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")
@@ -148,6 +150,7 @@ function(cxx_library_with_type name type cxx_flags)
# type can be either STATIC or SHARED to denote a static or shared library.
# ARGN refers to additional arguments after 'cxx_flags'.
add_library(${name} ${type} ${ARGN})
add_library(${cmake_package_name}::${name} ALIAS ${name})
set_target_properties(${name}
PROPERTIES
COMPILE_FLAGS "${cxx_flags}")
@@ -188,6 +191,10 @@ function(cxx_library_with_type name type cxx_flags)
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()
endfunction()
########################################################################
@@ -240,7 +247,13 @@ function(cxx_executable name dir libs)
endfunction()
# 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...)
#
@@ -248,13 +261,7 @@ find_package(PythonInterp)
# from the given source files with the given compiler flags.
function(cxx_test_with_flags name cxx_flags libs)
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
if (WIN32 OR MINGW)
add_test(NAME ${name}
COMMAND "powershell" "-Command" "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/RunTest.ps1" "$<TARGET_FILE:${name}>")
else()
add_test(NAME ${name}
COMMAND "$<TARGET_FILE:${name}>")
endif()
add_test(NAME ${name} COMMAND "$<TARGET_FILE:${name}>")
endfunction()
# cxx_test(name libs srcs...)
@@ -278,45 +285,24 @@ function(py_test name)
# 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.
if (WIN32 OR MINGW)
add_test(NAME ${name}
COMMAND powershell -Command ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/RunTest.ps1
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG> ${ARGN})
else()
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG> ${ARGN})
endif()
else (CMAKE_CONFIGURATION_TYPES)
# Single-configuration build generators like Makefile generators
# don't have subdirs below CMAKE_CURRENT_BINARY_DIR.
if (WIN32 OR MINGW)
add_test(NAME ${name}
COMMAND powershell -Command ${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN})
else()
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN})
endif()
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
# only at ctest runtime (by calling ctest -c <Configuration>), so
# we have to escape $ to delay variable substitution here.
if (WIN32 OR MINGW)
add_test(NAME ${name}
COMMAND powershell -Command ${CMAKE_CURRENT_BINARY_DIR}/RunTest.ps1
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN})
else()
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN})
endif()
add_test(NAME ${name}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN})
endif()
endif(PYTHONINTERP_FOUND)
endfunction()
@@ -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.
File diff suppressed because it is too large Load Diff
-753
View File
@@ -1,753 +0,0 @@
# Googletest FAQ
<!-- GOOGLETEST_CM0013 DO NOT DELETE -->
## Why should test suite names and test names not contain underscore?
Underscore (`_`) is special, as C++ reserves the following to be used by the
compiler and the standard library:
1. any identifier that starts with an `_` followed by an upper-case letter, and
1. any identifier that contains two consecutive underscores (i.e. `__`)
*anywhere* in its name.
User code is *prohibited* from using such identifiers.
Now let's look at what this means for `TEST` and `TEST_F`.
Currently `TEST(TestSuiteName, TestName)` generates a class named
`TestSuiteName_TestName_Test`. What happens if `TestSuiteName` or `TestName`
contains `_`?
1. If `TestSuiteName` starts with an `_` followed by an upper-case letter (say,
`_Foo`), we end up with `_Foo_TestName_Test`, which is reserved and thus
invalid.
1. If `TestSuiteName` ends with an `_` (say, `Foo_`), we get
`Foo__TestName_Test`, which is invalid.
1. If `TestName` starts with an `_` (say, `_Bar`), we get
`TestSuiteName__Bar_Test`, which is invalid.
1. If `TestName` ends with an `_` (say, `Bar_`), we get
`TestSuiteName_Bar__Test`, which is invalid.
So clearly `TestSuiteName` and `TestName` cannot start or end with `_`
(Actually, `TestSuiteName` can start with `_` -- as long as the `_` isn't
followed by an upper-case letter. But that's getting complicated. So for
simplicity we just say that it cannot start with `_`.).
It may seem fine for `TestSuiteName` and `TestName` to contain `_` in the
middle. However, consider this:
```c++
TEST(Time, Flies_Like_An_Arrow) { ... }
TEST(Time_Flies, Like_An_Arrow) { ... }
```
Now, the two `TEST`s will both generate the same class
(`Time_Flies_Like_An_Arrow_Test`). That's not good.
So for simplicity, we just ask the users to avoid `_` in `TestSuiteName` and
`TestName`. The rule is more constraining than necessary, but it's simple and
easy to remember. It also gives googletest some wiggle room in case its
implementation needs to change in the future.
If you violate the rule, there may not be immediate consequences, but your test
may (just may) break with a new compiler (or a new version of the compiler you
are using) or with a new version of googletest. Therefore it's best to follow
the rule.
## Why does googletest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`?
First of all you can use `EXPECT_NE(nullptr, ptr)` and `ASSERT_NE(nullptr,
ptr)`. This is the preferred syntax in the style guide because nullptr does not
have the type problems that NULL does. Which is why NULL does not work.
Due to some peculiarity of C++, it requires some non-trivial template meta
programming tricks to support using `NULL` as an argument of the `EXPECT_XX()`
and `ASSERT_XX()` macros. Therefore we only do it where it's most needed
(otherwise we make the implementation of googletest harder to maintain and more
error-prone than necessary).
The `EXPECT_EQ()` macro takes the *expected* value as its first argument and the
*actual* value as the second. It's reasonable that someone wants to write
`EXPECT_EQ(NULL, some_expression)`, and this indeed was requested several times.
Therefore we implemented it.
The need for `EXPECT_NE(NULL, ptr)` isn't nearly as strong. When the assertion
fails, you already know that `ptr` must be `NULL`, so it doesn't add any
information to print `ptr` in this case. That means `EXPECT_TRUE(ptr != NULL)`
works just as well.
If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'll have to
support `EXPECT_NE(ptr, NULL)` as well, as unlike `EXPECT_EQ`, we don't have a
convention on the order of the two arguments for `EXPECT_NE`. This means using
the template meta programming tricks twice in the implementation, making it even
harder to understand and maintain. We believe the benefit doesn't justify the
cost.
Finally, with the growth of the gMock matcher library, we are encouraging people
to use the unified `EXPECT_THAT(value, matcher)` syntax more often in tests. One
significant advantage of the matcher approach is that matchers can be easily
combined to form new matchers, while the `EXPECT_NE`, etc, macros cannot be
easily combined. Therefore we want to invest more in the matchers than in the
`EXPECT_XX()` macros.
## I need to test that different implementations of an interface satisfy some common requirements. Should I use typed tests or value-parameterized tests?
For testing various implementations of the same interface, either typed tests or
value-parameterized tests can get it done. It's really up to you the user to
decide which is more convenient for you, depending on your particular case. Some
rough guidelines:
* Typed tests can be easier to write if instances of the different
implementations can be created the same way, modulo the type. For example,
if all these implementations have a public default constructor (such that
you can write `new TypeParam`), or if their factory functions have the same
form (e.g. `CreateInstance<TypeParam>()`).
* Value-parameterized tests can be easier to write if you need different code
patterns to create different implementations' instances, e.g. `new Foo` vs
`new Bar(5)`. To accommodate for the differences, you can write factory
function wrappers and pass these function pointers to the tests as their
parameters.
* When a typed test fails, the default output includes the name of the type,
which can help you quickly identify which implementation is wrong.
Value-parameterized tests only show the number of the failed iteration by
default. You will need to define a function that returns the iteration name
and pass it as the third parameter to INSTANTIATE_TEST_SUITE_P to have more
useful output.
* When using typed tests, you need to make sure you are testing against the
interface type, not the concrete types (in other words, you want to make
sure `implicit_cast<MyInterface*>(my_concrete_impl)` works, not just that
`my_concrete_impl` works). It's less likely to make mistakes in this area
when using value-parameterized tests.
I hope I didn't confuse you more. :-) If you don't mind, I'd suggest you to give
both approaches a try. Practice is a much better way to grasp the subtle
differences between the two tools. Once you have some concrete experience, you
can much more easily decide which one to use the next time.
## I got some run-time errors about invalid proto descriptors when using `ProtocolMessageEquals`. Help!
**Note:** `ProtocolMessageEquals` and `ProtocolMessageEquiv` are *deprecated*
now. Please use `EqualsProto`, etc instead.
`ProtocolMessageEquals` and `ProtocolMessageEquiv` were redefined recently and
are now less tolerant of invalid protocol buffer definitions. In particular, if
you have a `foo.proto` that doesn't fully qualify the type of a protocol message
it references (e.g. `message<Bar>` where it should be `message<blah.Bar>`), you
will now get run-time errors like:
```
... descriptor.cc:...] Invalid proto descriptor for file "path/to/foo.proto":
... descriptor.cc:...] blah.MyMessage.my_field: ".Bar" is not defined.
```
If you see this, your `.proto` file is broken and needs to be fixed by making
the types fully qualified. The new definition of `ProtocolMessageEquals` and
`ProtocolMessageEquiv` just happen to reveal your bug.
## My death test modifies some state, but the change seems lost after the death test finishes. Why?
Death tests (`EXPECT_DEATH`, etc) are executed in a sub-process s.t. the
expected crash won't kill the test program (i.e. the parent process). As a
result, any in-memory side effects they incur are observable in their respective
sub-processes, but not in the parent process. You can think of them as running
in a parallel universe, more or less.
In particular, if you use mocking and the death test statement invokes some mock
methods, the parent process will think the calls have never occurred. Therefore,
you may want to move your `EXPECT_CALL` statements inside the `EXPECT_DEATH`
macro.
## EXPECT_EQ(htonl(blah), blah_blah) generates weird compiler errors in opt mode. Is this a googletest bug?
Actually, the bug is in `htonl()`.
According to `'man htonl'`, `htonl()` is a *function*, which means it's valid to
use `htonl` as a function pointer. However, in opt mode `htonl()` is defined as
a *macro*, which breaks this usage.
Worse, the macro definition of `htonl()` uses a `gcc` extension and is *not*
standard C++. That hacky implementation has some ad hoc limitations. In
particular, it prevents you from writing `Foo<sizeof(htonl(x))>()`, where `Foo`
is a template that has an integral argument.
The implementation of `EXPECT_EQ(a, b)` uses `sizeof(... a ...)` inside a
template argument, and thus doesn't compile in opt mode when `a` contains a call
to `htonl()`. It is difficult to make `EXPECT_EQ` bypass the `htonl()` bug, as
the solution must work with different compilers on various platforms.
`htonl()` has some other problems as described in `//util/endian/endian.h`,
which defines `ghtonl()` to replace it. `ghtonl()` does the same thing `htonl()`
does, only without its problems. We suggest you to use `ghtonl()` instead of
`htonl()`, both in your tests and production code.
`//util/endian/endian.h` also defines `ghtons()`, which solves similar problems
in `htons()`.
Don't forget to add `//util/endian` to the list of dependencies in the `BUILD`
file wherever `ghtonl()` and `ghtons()` are used. The library consists of a
single header file and will not bloat your binary.
## The compiler complains about "undefined references" to some static const member variables, but I did define them in the class body. What's wrong?
If your class has a static data member:
```c++
// foo.h
class Foo {
...
static const int kBar = 100;
};
```
You also need to define it *outside* of the class body in `foo.cc`:
```c++
const int Foo::kBar; // No initializer here.
```
Otherwise your code is **invalid C++**, and may break in unexpected ways. In
particular, using it in googletest comparison assertions (`EXPECT_EQ`, etc) will
generate an "undefined reference" linker error. The fact that "it used to work"
doesn't mean it's valid. It just means that you were lucky. :-)
## Can I derive a test fixture from another?
Yes.
Each test fixture has a corresponding and same named test suite. This means only
one test suite can use a particular fixture. Sometimes, however, multiple test
cases may want to use the same or slightly different fixtures. For example, you
may want to make sure that all of a GUI library's test suites don't leak
important system resources like fonts and brushes.
In googletest, you share a fixture among test suites by putting the shared logic
in a base test fixture, then deriving from that base a separate fixture for each
test suite that wants to use this common logic. You then use `TEST_F()` to write
tests using each derived fixture.
Typically, your code looks like this:
```c++
// Defines a base test fixture.
class BaseTest : public ::testing::Test {
protected:
...
};
// Derives a fixture FooTest from BaseTest.
class FooTest : public BaseTest {
protected:
void SetUp() override {
BaseTest::SetUp(); // Sets up the base fixture first.
... additional set-up work ...
}
void TearDown() override {
... clean-up work for FooTest ...
BaseTest::TearDown(); // Remember to tear down the base fixture
// after cleaning up FooTest!
}
... functions and variables for FooTest ...
};
// Tests that use the fixture FooTest.
TEST_F(FooTest, Bar) { ... }
TEST_F(FooTest, Baz) { ... }
... additional fixtures derived from BaseTest ...
```
If necessary, you can continue to derive test fixtures from a derived fixture.
googletest has no limit on how deep the hierarchy can be.
For a complete example using derived test fixtures, see
[googletest sample](https://github.com/google/googletest/blob/master/googletest/samples/sample5_unittest.cc)
## My compiler complains "void value not ignored as it ought to be." What does this mean?
You're probably using an `ASSERT_*()` in a function that doesn't return `void`.
`ASSERT_*()` can only be used in `void` functions, due to exceptions being
disabled by our build system. Please see more details
[here](advanced.md#assertion-placement).
## My death test hangs (or seg-faults). How do I fix it?
In googletest, death tests are run in a child process and the way they work is
delicate. To write death tests you really need to understand how they work.
Please make sure you have read [this](advanced.md#how-it-works).
In particular, death tests don't like having multiple threads in the parent
process. So the first thing you can try is to eliminate creating threads outside
of `EXPECT_DEATH()`. For example, you may want to use mocks or fake objects
instead of real ones in your tests.
Sometimes this is impossible as some library you must use may be creating
threads before `main()` is even reached. In this case, you can try to minimize
the chance of conflicts by either moving as many activities as possible inside
`EXPECT_DEATH()` (in the extreme case, you want to move everything inside), or
leaving as few things as possible in it. Also, you can try to set the death test
style to `"threadsafe"`, which is safer but slower, and see if it helps.
If you go with thread-safe death tests, remember that they rerun the test
program from the beginning in the child process. Therefore make sure your
program can run side-by-side with itself and is deterministic.
In the end, this boils down to good concurrent programming. You have to make
sure that there is no race conditions or dead locks in your program. No silver
bullet - sorry!
## Should I use the constructor/destructor of the test fixture or SetUp()/TearDown()?
The first thing to remember is that googletest does **not** reuse the same test
fixture object across multiple tests. For each `TEST_F`, googletest will create
a **fresh** test fixture object, immediately call `SetUp()`, run the test body,
call `TearDown()`, and then delete the test fixture object.
When you need to write per-test set-up and tear-down logic, you have the choice
between using the test fixture constructor/destructor or `SetUp()/TearDown()`.
The former is usually preferred, as it has the following benefits:
* By initializing a member variable in the constructor, we have the option to
make it `const`, which helps prevent accidental changes to its value and
makes the tests more obviously correct.
* In case we need to subclass the test fixture class, the subclass'
constructor is guaranteed to call the base class' constructor *first*, and
the subclass' destructor is guaranteed to call the base class' destructor
*afterward*. With `SetUp()/TearDown()`, a subclass may make the mistake of
forgetting to call the base class' `SetUp()/TearDown()` or call them at the
wrong time.
You may still want to use `SetUp()/TearDown()` in the following cases:
* C++ does not allow virtual function calls in constructors and destructors.
You can call a method declared as virtual, but it will not use dynamic
dispatch, it will use the definition from the class the constructor of which
is currently executing. This is because calling a virtual method before the
derived class constructor has a chance to run is very dangerous - the
virtual method might operate on uninitialized data. Therefore, if you need
to call a method that will be overridden in a derived class, you have to use
`SetUp()/TearDown()`.
* In the body of a constructor (or destructor), it's not possible to use the
`ASSERT_xx` macros. Therefore, if the set-up operation could cause a fatal
test failure that should prevent the test from running, it's necessary to
use `abort` <!-- GOOGLETEST_CM0014 DO NOT DELETE --> and abort the whole test executable,
or to use `SetUp()` instead of a constructor.
* If the tear-down operation could throw an exception, you must use
`TearDown()` as opposed to the destructor, as throwing in a destructor leads
to undefined behavior and usually will kill your program right away. Note
that many standard libraries (like STL) may throw when exceptions are
enabled in the compiler. Therefore you should prefer `TearDown()` if you
want to write portable tests that work with or without exceptions.
* The googletest team is considering making the assertion macros throw on
platforms where exceptions are enabled (e.g. Windows, Mac OS, and Linux
client-side), which will eliminate the need for the user to propagate
failures from a subroutine to its caller. Therefore, you shouldn't use
googletest assertions in a destructor if your code could run on such a
platform.
## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it?
If the predicate function you use in `ASSERT_PRED*` or `EXPECT_PRED*` is
overloaded or a template, the compiler will have trouble figuring out which
overloaded version it should use. `ASSERT_PRED_FORMAT*` and
`EXPECT_PRED_FORMAT*` don't have this problem.
If you see this error, you might want to switch to
`(ASSERT|EXPECT)_PRED_FORMAT*`, which will also give you a better failure
message. If, however, that is not an option, you can resolve the problem by
explicitly telling the compiler which version to pick.
For example, suppose you have
```c++
bool IsPositive(int n) {
return n > 0;
}
bool IsPositive(double x) {
return x > 0;
}
```
you will get a compiler error if you write
```c++
EXPECT_PRED1(IsPositive, 5);
```
However, this will work:
```c++
EXPECT_PRED1(static_cast<bool (*)(int)>(IsPositive), 5);
```
(The stuff inside the angled brackets for the `static_cast` operator is the type
of the function pointer for the `int`-version of `IsPositive()`.)
As another example, when you have a template function
```c++
template <typename T>
bool IsNegative(T x) {
return x < 0;
}
```
you can use it in a predicate assertion like this:
```c++
ASSERT_PRED1(IsNegative<int>, -5);
```
Things are more interesting if your template has more than one parameters. The
following won't compile:
```c++
ASSERT_PRED2(GreaterThan<int, int>, 5, 0);
```
as the C++ pre-processor thinks you are giving `ASSERT_PRED2` 4 arguments, which
is one more than expected. The workaround is to wrap the predicate function in
parentheses:
```c++
ASSERT_PRED2((GreaterThan<int, int>), 5, 0);
```
## My compiler complains about "ignoring return value" when I call RUN_ALL_TESTS(). Why?
Some people had been ignoring the return value of `RUN_ALL_TESTS()`. That is,
instead of
```c++
return RUN_ALL_TESTS();
```
they write
```c++
RUN_ALL_TESTS();
```
This is **wrong and dangerous**. The testing services needs to see the return
value of `RUN_ALL_TESTS()` in order to determine if a test has passed. If your
`main()` function ignores it, your test will be considered successful even if it
has a googletest assertion failure. Very bad.
We have decided to fix this (thanks to Michael Chastain for the idea). Now, your
code will no longer be able to ignore `RUN_ALL_TESTS()` when compiled with
`gcc`. If you do so, you'll get a compiler error.
If you see the compiler complaining about you ignoring the return value of
`RUN_ALL_TESTS()`, the fix is simple: just make sure its value is used as the
return value of `main()`.
But how could we introduce a change that breaks existing tests? Well, in this
case, the code was already broken in the first place, so we didn't break it. :-)
## My compiler complains that a constructor (or destructor) cannot return a value. What's going on?
Due to a peculiarity of C++, in order to support the syntax for streaming
messages to an `ASSERT_*`, e.g.
```c++
ASSERT_EQ(1, Foo()) << "blah blah" << foo;
```
we had to give up using `ASSERT*` and `FAIL*` (but not `EXPECT*` and
`ADD_FAILURE*`) in constructors and destructors. The workaround is to move the
content of your constructor/destructor to a private void member function, or
switch to `EXPECT_*()` if that works. This
[section](advanced.md#assertion-placement) in the user's guide explains it.
## My SetUp() function is not called. Why?
C++ is case-sensitive. Did you spell it as `Setup()`?
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
wonder why it's never called.
## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
You don't have to. Instead of
```c++
class FooTest : public BaseTest {};
TEST_F(FooTest, Abc) { ... }
TEST_F(FooTest, Def) { ... }
class BarTest : public BaseTest {};
TEST_F(BarTest, Abc) { ... }
TEST_F(BarTest, Def) { ... }
```
you can simply `typedef` the test fixtures:
```c++
typedef BaseTest FooTest;
TEST_F(FooTest, Abc) { ... }
TEST_F(FooTest, Def) { ... }
typedef BaseTest BarTest;
TEST_F(BarTest, Abc) { ... }
TEST_F(BarTest, Def) { ... }
```
## googletest output is buried in a whole bunch of LOG messages. What do I do?
The googletest output is meant to be a concise and human-friendly report. If
your test generates textual output itself, it will mix with the googletest
output, making it hard to read. However, there is an easy solution to this
problem.
Since `LOG` messages go to stderr, we decided to let googletest output go to
stdout. This way, you can easily separate the two using redirection. For
example:
```shell
$ ./my_test > gtest_output.txt
```
## Why should I prefer test fixtures over global variables?
There are several good reasons:
1. It's likely your test needs to change the states of its global variables.
This makes it difficult to keep side effects from escaping one test and
contaminating others, making debugging difficult. By using fixtures, each
test has a fresh set of variables that's different (but with the same
names). Thus, tests are kept independent of each other.
1. Global variables pollute the global namespace.
1. Test fixtures can be reused via subclassing, which cannot be done easily
with global variables. This is useful if many test suites have something in
common.
## What can the statement argument in ASSERT_DEATH() be?
`ASSERT_DEATH(*statement*, *regex*)` (or any death assertion macro) can be used
wherever `*statement*` is valid. So basically `*statement*` can be any C++
statement that makes sense in the current context. In particular, it can
reference global and/or local variables, and can be:
* a simple function call (often the case),
* a complex expression, or
* a compound statement.
Some examples are shown here:
```c++
// A death test can be a simple function call.
TEST(MyDeathTest, FunctionCall) {
ASSERT_DEATH(Xyz(5), "Xyz failed");
}
// Or a complex expression that references variables and functions.
TEST(MyDeathTest, ComplexExpression) {
const bool c = Condition();
ASSERT_DEATH((c ? Func1(0) : object2.Method("test")),
"(Func1|Method) failed");
}
// Death assertions can be used any where in a function. In
// particular, they can be inside a loop.
TEST(MyDeathTest, InsideLoop) {
// Verifies that Foo(0), Foo(1), ..., and Foo(4) all die.
for (int i = 0; i < 5; i++) {
EXPECT_DEATH_M(Foo(i), "Foo has \\d+ errors",
::testing::Message() << "where i is " << i);
}
}
// A death assertion can contain a compound statement.
TEST(MyDeathTest, CompoundStatement) {
// Verifies that at lease one of Bar(0), Bar(1), ..., and
// Bar(4) dies.
ASSERT_DEATH({
for (int i = 0; i < 5; i++) {
Bar(i);
}
},
"Bar has \\d+ errors");
}
```
gtest-death-test_test.cc contains more examples if you are interested.
## I have a fixture class `FooTest`, but `TEST_F(FooTest, Bar)` gives me error ``"no matching function for call to `FooTest::FooTest()'"``. Why?
Googletest needs to be able to create objects of your test fixture class, so it
must have a default constructor. Normally the compiler will define one for you.
However, there are cases where you have to define your own:
* If you explicitly declare a non-default constructor for class `FooTest`
(`DISALLOW_EVIL_CONSTRUCTORS()` does this), then you need to define a
default constructor, even if it would be empty.
* If `FooTest` has a const non-static data member, then you have to define the
default constructor *and* initialize the const member in the initializer
list of the constructor. (Early versions of `gcc` doesn't force you to
initialize the const member. It's a bug that has been fixed in `gcc 4`.)
## Why does ASSERT_DEATH complain about previous threads that were already joined?
With the Linux pthread library, there is no turning back once you cross the line
from single thread to multiple threads. The first time you create a thread, a
manager thread is created in addition, so you get 3, not 2, threads. Later when
the thread you create joins the main thread, the thread count decrements by 1,
but the manager thread will never be killed, so you still have 2 threads, which
means you cannot safely run a death test.
The new NPTL thread library doesn't suffer from this problem, as it doesn't
create a manager thread. However, if you don't control which machine your test
runs on, you shouldn't depend on this.
## Why does googletest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH?
googletest does not interleave tests from different test suites. That is, it
runs all tests in one test suite first, and then runs all tests in the next test
suite, and so on. googletest does this because it needs to set up a test suite
before the first test in it is run, and tear it down afterwords. Splitting up
the test case would require multiple set-up and tear-down processes, which is
inefficient and makes the semantics unclean.
If we were to determine the order of tests based on test name instead of test
case name, then we would have a problem with the following situation:
```c++
TEST_F(FooTest, AbcDeathTest) { ... }
TEST_F(FooTest, Uvw) { ... }
TEST_F(BarTest, DefDeathTest) { ... }
TEST_F(BarTest, Xyz) { ... }
```
Since `FooTest.AbcDeathTest` needs to run before `BarTest.Xyz`, and we don't
interleave tests from different test suites, we need to run all tests in the
`FooTest` case before running any test in the `BarTest` case. This contradicts
with the requirement to run `BarTest.DefDeathTest` before `FooTest.Uvw`.
## But I don't like calling my entire test suite \*DeathTest when it contains both death tests and non-death tests. What do I do?
You don't have to, but if you like, you may split up the test suite into
`FooTest` and `FooDeathTest`, where the names make it clear that they are
related:
```c++
class FooTest : public ::testing::Test { ... };
TEST_F(FooTest, Abc) { ... }
TEST_F(FooTest, Def) { ... }
using FooDeathTest = FooTest;
TEST_F(FooDeathTest, Uvw) { ... EXPECT_DEATH(...) ... }
TEST_F(FooDeathTest, Xyz) { ... ASSERT_DEATH(...) ... }
```
## googletest prints the LOG messages in a death test's child process only when the test fails. How can I see the LOG messages when the death test succeeds?
Printing the LOG messages generated by the statement inside `EXPECT_DEATH()`
makes it harder to search for real problems in the parent's log. Therefore,
googletest only prints them when the death test has failed.
If you really need to see such LOG messages, a workaround is to temporarily
break the death test (e.g. by changing the regex pattern it is expected to
match). Admittedly, this is a hack. We'll consider a more permanent solution
after the fork-and-exec-style death tests are implemented.
## The compiler complains about "no match for 'operator<<'" when I use an assertion. What gives?
If you use a user-defined type `FooType` in an assertion, you must make sure
there is an `std::ostream& operator<<(std::ostream&, const FooType&)` function
defined such that we can print a value of `FooType`.
In addition, if `FooType` is declared in a name space, the `<<` operator also
needs to be defined in the *same* name space. See https://abseil.io/tips/49 for details.
## How do I suppress the memory leak messages on Windows?
Since the statically initialized googletest singleton requires allocations on
the heap, the Visual C++ memory leak detector will report memory leaks at the
end of the program run. The easiest way to avoid this is to use the
`_CrtMemCheckpoint` and `_CrtMemDumpAllObjectsSince` calls to not report any
statically initialized heap objects. See MSDN for more details and additional
heap check/debug routines.
## How can my code detect if it is running in a test?
If you write code that sniffs whether it's running in a test and does different
things accordingly, you are leaking test-only logic into production code and
there is no easy way to ensure that the test-only code paths aren't run by
mistake in production. Such cleverness also leads to
[Heisenbugs](https://en.wikipedia.org/wiki/Heisenbug). Therefore we strongly
advise against the practice, and googletest doesn't provide a way to do it.
In general, the recommended way to cause the code to behave differently under
test is [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection). You can inject
different functionality from the test and from the production code. Since your
production code doesn't link in the for-test logic at all (the
[`testonly`](https://docs.bazel.build/versions/master/be/common-definitions.html#common.testonly) attribute for BUILD targets helps to ensure
that), there is no danger in accidentally running it.
However, if you *really*, *really*, *really* have no choice, and if you follow
the rule of ending your test program names with `_test`, you can use the
*horrible* hack of sniffing your executable name (`argv[0]` in `main()`) to know
whether the code is under test.
## How do I temporarily disable a test?
If you have a broken test that you cannot fix right away, you can add the
DISABLED_ prefix to its name. This will exclude it from execution. This is
better than commenting out the code or using #if 0, as disabled tests are still
compiled (and thus won't rot).
To include disabled tests in test execution, just invoke the test program with
the --gtest_also_run_disabled_tests flag.
## Is it OK if I have two separate `TEST(Foo, Bar)` test methods defined in different namespaces?
Yes.
The rule is **all test methods in the same test suite must use the same fixture
class.** This means that the following is **allowed** because both tests use the
same fixture class (`::testing::Test`).
```c++
namespace foo {
TEST(CoolTest, DoSomething) {
SUCCEED();
}
} // namespace foo
namespace bar {
TEST(CoolTest, DoSomething) {
SUCCEED();
}
} // namespace bar
```
However, the following code is **not allowed** and will produce a runtime error
from googletest because the test methods are using different test fixture
classes with the same test suite name.
```c++
namespace foo {
class CoolTest : public ::testing::Test {}; // Fixture foo::CoolTest
TEST_F(CoolTest, DoSomething) {
SUCCEED();
}
} // namespace foo
namespace bar {
class CoolTest : public ::testing::Test {}; // Fixture: bar::CoolTest
TEST_F(CoolTest, DoSomething) {
SUCCEED();
}
} // namespace bar
```
@@ -1,146 +0,0 @@
## Using GoogleTest from various build systems ##
GoogleTest comes with pkg-config files that can be used to determine all
necessary flags for compiling and linking to GoogleTest (and GoogleMock).
Pkg-config is a standardised plain-text format containing
* the includedir (-I) path
* necessary macro (-D) definitions
* further required flags (-pthread)
* the library (-L) path
* the library (-l) to link to
All current build systems support pkg-config in one way or another. For
all examples here we assume you want to compile the sample
`samples/sample3_unittest.cc`.
### CMake ###
Using `pkg-config` in CMake is fairly easy:
``` cmake
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0048 NEW)
project(my_gtest_pkgconfig VERSION 0.0.1 LANGUAGES CXX)
find_package(PkgConfig)
pkg_search_module(GTEST REQUIRED gtest_main)
add_executable(testapp samples/sample3_unittest.cc)
target_link_libraries(testapp ${GTEST_LDFLAGS})
target_compile_options(testapp PUBLIC ${GTEST_CFLAGS})
include(CTest)
add_test(first_and_only_test testapp)
```
It is generally recommended that you use `target_compile_options` + `_CFLAGS`
over `target_include_directories` + `_INCLUDE_DIRS` as the former includes not
just -I flags (GoogleTest might require a macro indicating to internal headers
that all libraries have been compiled with threading enabled. In addition,
GoogleTest might also require `-pthread` in the compiling step, and as such
splitting the pkg-config `Cflags` variable into include dirs and macros for
`target_compile_definitions()` might still miss this). The same recommendation
goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which
happens to discard `-L` flags and `-pthread`.
### Autotools ###
Finding GoogleTest in Autoconf and using it from Automake is also fairly easy:
In your `configure.ac`:
```
AC_PREREQ([2.69])
AC_INIT([my_gtest_pkgconfig], [0.0.1])
AC_CONFIG_SRCDIR([samples/sample3_unittest.cc])
AC_PROG_CXX
PKG_CHECK_MODULES([GTEST], [gtest_main])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
```
and in your `Makefile.am`:
```
check_PROGRAMS = testapp
TESTS = $(check_PROGRAMS)
testapp_SOURCES = samples/sample3_unittest.cc
testapp_CXXFLAGS = $(GTEST_CFLAGS)
testapp_LDADD = $(GTEST_LIBS)
```
### Meson ###
Meson natively uses pkgconfig to query dependencies:
```
project('my_gtest_pkgconfig', 'cpp', version : '0.0.1')
gtest_dep = dependency('gtest_main')
testapp = executable(
'testapp',
files(['samples/sample3_unittest.cc']),
dependencies : gtest_dep,
install : false)
test('first_and_only_test', testapp)
```
### Plain Makefiles ###
Since `pkg-config` is a small Unix command-line utility, it can be used
in handwritten `Makefile`s too:
``` Makefile
GTEST_CFLAGS = `pkg-config --cflags gtest_main`
GTEST_LIBS = `pkg-config --libs gtest_main`
.PHONY: tests all
tests: all
./testapp
all: testapp
testapp: testapp.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@ $(GTEST_LIBS)
testapp.o: samples/sample3_unittest.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -c -o $@ $(GTEST_CFLAGS)
```
### Help! pkg-config can't find GoogleTest! ###
Let's say you have a `CMakeLists.txt` along the lines of the one in this
tutorial and you try to run `cmake`. It is very possible that you get a
failure along the lines of:
```
-- Checking for one of the modules 'gtest_main'
CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):
None of the required 'gtest_main' found
```
These failures are common if you installed GoogleTest yourself and have not
sourced it from a distro or other package manager. If so, you need to tell
pkg-config where it can find the `.pc` files containing the information.
Say you installed GoogleTest to `/usr/local`, then it might be that the
`.pc` files are installed under `/usr/local/lib64/pkgconfig`. If you set
```
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
```
pkg-config will also try to look in `PKG_CONFIG_PATH` to find `gtest_main.pc`.
-565
View File
@@ -1,565 +0,0 @@
# Googletest Primer
## Introduction: Why googletest?
*googletest* helps you write better C++ tests.
googletest is a testing framework developed by the Testing Technology team with
Google's specific requirements and constraints in mind. No matter whether you
work on Linux, Windows, or a Mac, if you write C++ code, googletest can help
you. And it supports *any* kind of tests, not just unit tests.
So what makes a good test, and how does googletest fit in? We believe:
1. Tests should be *independent* and *repeatable*. It's a pain to debug a test
that succeeds or fails as a result of other tests. googletest isolates the
tests by running each of them on a different object. When a test fails,
googletest allows you to run it in isolation for quick debugging.
1. Tests should be well *organized* and reflect the structure of the tested
code. googletest groups related tests into test suites that can share data
and subroutines. This common pattern is easy to recognize and makes tests
easy to maintain. Such consistency is especially helpful when people switch
projects and start to work on a new code base.
1. Tests should be *portable* and *reusable*. Google has a lot of code that is
platform-neutral, its tests should also be platform-neutral. googletest
works on different OSes, with different compilers, with or without
exceptions, so googletest tests can work with a variety of configurations.
1. When tests fail, they should provide as much *information* about the problem
as possible. googletest doesn't stop at the first test failure. Instead, it
only stops the current test and continues with the next. You can also set up
tests that report non-fatal failures after which the current test continues.
Thus, you can detect and fix multiple bugs in a single run-edit-compile
cycle.
1. The testing framework should liberate test writers from housekeeping chores
and let them focus on the test *content*. googletest automatically keeps
track of all tests defined, and doesn't require the user to enumerate them
in order to run them.
1. Tests should be *fast*. With googletest, you can reuse shared resources
across tests and pay for the set-up/tear-down only once, without making
tests depend on each other.
Since googletest is based on the popular xUnit architecture, you'll feel right
at home if you've used JUnit or PyUnit before. If not, it will take you about 10
minutes to learn the basics and get started. So let's go!
## Beware of the nomenclature
_Note:_ There might be some confusion of idea due to different
definitions of the terms _Test_, _Test Case_ and _Test Suite_, so beware
of misunderstanding these.
Historically, googletest started to use the term _Test Case_ for grouping
related tests, whereas current publications including the International Software
Testing Qualifications Board ([ISTQB](http://www.istqb.org/)) and various
textbooks on Software Quality use the term _[Test
Suite](http://glossary.istqb.org/search/test%20suite)_ for this.
The related term _Test_, as it is used in the googletest, is corresponding to
the term _[Test Case](http://glossary.istqb.org/search/test%20case)_ of ISTQB
and others.
The term _Test_ is commonly of broad enough sense, including ISTQB's definition
of _Test Case_, so it's not much of a problem here. But the term _Test Case_ as
was used in Google Test is of contradictory sense and thus confusing.
googletest recently started replacing the term _Test Case_ by _Test Suite_ The
preferred API is TestSuite*. The older TestCase* API is being slowly deprecated
and refactored away
So please be aware of the different definitions of the terms:
Meaning | googletest Term | [ISTQB](http://www.istqb.org/) Term
:----------------------------------------------------------------------------------- | :---------------------- | :----------------------------------
Exercise a particular program path with specific input values and verify the results | [TEST()](#simple-tests) | [Test Case](http://glossary.istqb.org/search/test%20case)
## Basic Concepts
When using googletest, you start by writing *assertions*, which are statements
that check whether a condition is true. An assertion's result can be *success*,
*nonfatal failure*, or *fatal failure*. If a fatal failure occurs, it aborts the
current function; otherwise the program continues normally.
*Tests* use assertions to verify the tested code's behavior. If a test crashes
or has a failed assertion, then it *fails*; otherwise it *succeeds*.
A *test suite* contains one or many tests. You should group your tests into test
suites that reflect the structure of the tested code. When multiple tests in a
test suite need to share common objects and subroutines, you can put them into a
*test fixture* class.
A *test program* can contain multiple test suites.
We'll now explain how to write a test program, starting at the individual
assertion level and building up to tests and test suites.
## Assertions
googletest assertions are macros that resemble function calls. You test a class
or function by making assertions about its behavior. When an assertion fails,
googletest prints the assertion's source file and line number location, along
with a failure message. You may also supply a custom failure message which will
be appended to googletest's message.
The assertions come in pairs that test the same thing but have different effects
on the current function. `ASSERT_*` versions generate fatal failures when they
fail, and **abort the current function**. `EXPECT_*` versions generate nonfatal
failures, which don't abort the current function. Usually `EXPECT_*` are
preferred, as they allow more than one failure to be reported in a test.
However, you should use `ASSERT_*` if it doesn't make sense to continue when the
assertion in question fails.
Since a failed `ASSERT_*` returns from the current function immediately,
possibly skipping clean-up code that comes after it, it may cause a space leak.
Depending on the nature of the leak, it may or may not be worth fixing - so keep
this in mind if you get a heap checker error in addition to assertion errors.
To provide a custom failure message, simply stream it into the macro using the
`<<` operator, or a sequence of such operators. An example:
```c++
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
for (int i = 0; i < x.size(); ++i) {
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}
```
Anything that can be streamed to an `ostream` can be streamed to an assertion
macro--in particular, C strings and `string` objects. If a wide string
(`wchar_t*`, `TCHAR*` in `UNICODE` mode on Windows, or `std::wstring`) is
streamed to an assertion, it will be translated to UTF-8 when printed.
### Basic Assertions
These assertions do basic true/false condition testing.
Fatal assertion | Nonfatal assertion | Verifies
-------------------------- | -------------------------- | --------------------
`ASSERT_TRUE(condition);` | `EXPECT_TRUE(condition);` | `condition` is true
`ASSERT_FALSE(condition);` | `EXPECT_FALSE(condition);` | `condition` is false
Remember, when they fail, `ASSERT_*` yields a fatal failure and returns from the
current function, while `EXPECT_*` yields a nonfatal failure, allowing the
function to continue running. In either case, an assertion failure means its
containing test fails.
**Availability**: Linux, Windows, Mac.
### Binary Comparison
This section describes assertions that compare two values.
Fatal assertion | Nonfatal assertion | Verifies
------------------------ | ------------------------ | --------------
`ASSERT_EQ(val1, val2);` | `EXPECT_EQ(val1, val2);` | `val1 == val2`
`ASSERT_NE(val1, val2);` | `EXPECT_NE(val1, val2);` | `val1 != val2`
`ASSERT_LT(val1, val2);` | `EXPECT_LT(val1, val2);` | `val1 < val2`
`ASSERT_LE(val1, val2);` | `EXPECT_LE(val1, val2);` | `val1 <= val2`
`ASSERT_GT(val1, val2);` | `EXPECT_GT(val1, val2);` | `val1 > val2`
`ASSERT_GE(val1, val2);` | `EXPECT_GE(val1, val2);` | `val1 >= val2`
Value arguments must be comparable by the assertion's comparison operator or
you'll get a compiler error. We used to require the arguments to support the
`<<` operator for streaming to an `ostream`, but it's no longer necessary. If
`<<` is supported, it will be called to print the arguments when the assertion
fails; otherwise googletest will attempt to print them in the best way it can.
For more details and how to customize the printing of the arguments, see
[documentation](https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#teaching-gmock-how-to-print-your-values)
These assertions can work with a user-defined type, but only if you define the
corresponding comparison operator (e.g. `==`, `<`, etc). Since this is
discouraged by the Google [C++ Style
Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading),
you may need to use `ASSERT_TRUE()` or `EXPECT_TRUE()` to assert the equality of
two objects of a user-defined type.
However, when possible, `ASSERT_EQ(actual, expected)` is preferred to
`ASSERT_TRUE(actual == expected)`, since it tells you `actual` and `expected`'s
values on failure.
Arguments are always evaluated exactly once. Therefore, it's OK for the
arguments to have side effects. However, as with any ordinary C/C++ function,
the arguments' evaluation order is undefined (i.e. the compiler is free to
choose any order) and your code should not depend on any particular argument
evaluation order.
`ASSERT_EQ()` does pointer equality on pointers. If used on two C strings, it
tests if they are in the same memory location, not if they have the same value.
Therefore, if you want to compare C strings (e.g. `const char*`) by value, use
`ASSERT_STREQ()`, which will be described later on. In particular, to assert
that a C string is `NULL`, use `ASSERT_STREQ(c_string, NULL)`. Consider using
`ASSERT_EQ(c_string, nullptr)` if c++11 is supported. To compare two `string`
objects, you should use `ASSERT_EQ`.
When doing pointer comparisons use `*_EQ(ptr, nullptr)` and `*_NE(ptr, nullptr)`
instead of `*_EQ(ptr, NULL)` and `*_NE(ptr, NULL)`. This is because `nullptr` is
typed while `NULL` is not. See [FAQ](faq.md)for more details.
If you're working with floating point numbers, you may want to use the floating
point variations of some of these macros in order to avoid problems caused by
rounding. See [Advanced googletest Topics](advanced.md) for details.
Macros in this section work with both narrow and wide string objects (`string`
and `wstring`).
**Availability**: Linux, Windows, Mac.
**Historical note**: Before February 2016 `*_EQ` had a convention of calling it
as `ASSERT_EQ(expected, actual)`, so lots of existing code uses this order. Now
`*_EQ` treats both parameters in the same way.
### String Comparison
The assertions in this group compare two **C strings**. If you want to compare
two `string` objects, use `EXPECT_EQ`, `EXPECT_NE`, and etc instead.
| Fatal assertion | Nonfatal assertion | Verifies |
| ----------------------- | ----------------------- | ---------------------- |
| `ASSERT_STREQ(str1, | `EXPECT_STREQ(str1, | the two C strings have |
: str2);` : str2);` : the same content :
| `ASSERT_STRNE(str1, | `EXPECT_STRNE(str1, | the two C strings have |
: str2);` : str2);` : different contents :
| `ASSERT_STRCASEEQ(str1, | `EXPECT_STRCASEEQ(str1, | the two C strings have |
: str2);` : str2);` : the same content, :
: : : ignoring case :
| `ASSERT_STRCASENE(str1, | `EXPECT_STRCASENE(str1, | the two C strings have |
: str2);` : str2);` : different contents, :
: : : ignoring case :
Note that "CASE" in an assertion name means that case is ignored. A `NULL`
pointer and an empty string are considered *different*.
`*STREQ*` and `*STRNE*` also accept wide C strings (`wchar_t*`). If a comparison
of two wide strings fails, their values will be printed as UTF-8 narrow strings.
**Availability**: Linux, Windows, Mac.
**See also**: For more string comparison tricks (substring, prefix, suffix, and
regular expression matching, for example), see
[this](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md)
in the Advanced googletest Guide.
## Simple Tests
To create a test:
1. Use the `TEST()` macro to define and name a test function, These are
ordinary C++ functions that don't return a value.
1. In this function, along with any valid C++ statements you want to include,
use the various googletest assertions to check values.
1. The test's result is determined by the assertions; if any assertion in the
test fails (either fatally or non-fatally), or if the test crashes, the
entire test fails. Otherwise, it succeeds.
```c++
TEST(TestSuiteName, TestName) {
... test body ...
}
```
`TEST()` arguments go from general to specific. The *first* argument is the name
of the test suite, and the *second* argument is the test's name within the test
case. Both names must be valid C++ identifiers, and they should not contain
underscore (`_`). A test's *full name* consists of its containing test suite and
its individual name. Tests from different test suites can have the same
individual name.
For example, let's take a simple integer function:
```c++
int Factorial(int n); // Returns the factorial of n
```
A test suite for this function might look like:
```c++
// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
EXPECT_EQ(Factorial(0), 1);
}
// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(Factorial(1), 1);
EXPECT_EQ(Factorial(2), 2);
EXPECT_EQ(Factorial(3), 6);
EXPECT_EQ(Factorial(8), 40320);
}
```
googletest groups the test results by test suites, so logically-related tests
should be in the same test suite; in other words, the first argument to their
`TEST()` should be the same. In the above example, we have two tests,
`HandlesZeroInput` and `HandlesPositiveInput`, that belong to the same test
suite `FactorialTest`.
When naming your test suites and tests, you should follow the same convention as
for
[naming functions and classes](https://google.github.io/styleguide/cppguide.html#Function_Names).
**Availability**: Linux, Windows, Mac.
## Test Fixtures: Using the Same Data Configuration for Multiple Tests
If you find yourself writing two or more tests that operate on similar data, you
can use a *test fixture*. It allows you to reuse the same configuration of
objects for several different tests.
To create a fixture:
1. Derive a class from `::testing::Test` . Start its body with `protected:` as
we'll want to access fixture members from sub-classes.
1. Inside the class, declare any objects you plan to use.
1. If necessary, write a default constructor or `SetUp()` function to prepare
the objects for each test. A common mistake is to spell `SetUp()` as
**`Setup()`** with a small `u` - Use `override` in C++11 to make sure you
spelled it correctly
1. If necessary, write a destructor or `TearDown()` function to release any
resources you allocated in `SetUp()` . To learn when you should use the
constructor/destructor and when you should use `SetUp()/TearDown()`, read
the [FAQ](faq.md).
1. If needed, define subroutines for your tests to share.
When using a fixture, use `TEST_F()` instead of `TEST()` as it allows you to
access objects and subroutines in the test fixture:
```c++
TEST_F(TestFixtureName, TestName) {
... test body ...
}
```
Like `TEST()`, the first argument is the test suite name, but for `TEST_F()`
this must be the name of the test fixture class. You've probably guessed: `_F`
is for fixture.
Unfortunately, the C++ macro system does not allow us to create a single macro
that can handle both types of tests. Using the wrong macro causes a compiler
error.
Also, you must first define a test fixture class before using it in a
`TEST_F()`, or you'll get the compiler error "`virtual outside class
declaration`".
For each test defined with `TEST_F()` , googletest will create a *fresh* test
fixture at runtime, immediately initialize it via `SetUp()` , run the test,
clean up by calling `TearDown()` , and then delete the test fixture. Note that
different tests in the same test suite have different test fixture objects, and
googletest always deletes a test fixture before it creates the next one.
googletest does **not** reuse the same test fixture for multiple tests. Any
changes one test makes to the fixture do not affect other tests.
As an example, let's write tests for a FIFO queue class named `Queue`, which has
the following interface:
```c++
template <typename E> // E is the element type.
class Queue {
public:
Queue();
void Enqueue(const E& element);
E* Dequeue(); // Returns NULL if the queue is empty.
size_t size() const;
...
};
```
First, define a fixture class. By convention, you should give it the name
`FooTest` where `Foo` is the class being tested.
```c++
class QueueTest : public ::testing::Test {
protected:
void SetUp() override {
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// void TearDown() override {}
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
```
In this case, `TearDown()` is not needed since we don't have to clean up after
each test, other than what's already done by the destructor.
Now we'll write tests using `TEST_F()` and this fixture.
```c++
TEST_F(QueueTest, IsEmptyInitially) {
EXPECT_EQ(q0_.size(), 0);
}
TEST_F(QueueTest, DequeueWorks) {
int* n = q0_.Dequeue();
EXPECT_EQ(n, nullptr);
n = q1_.Dequeue();
ASSERT_NE(n, nullptr);
EXPECT_EQ(*n, 1);
EXPECT_EQ(q1_.size(), 0);
delete n;
n = q2_.Dequeue();
ASSERT_NE(n, nullptr);
EXPECT_EQ(*n, 2);
EXPECT_EQ(q2_.size(), 1);
delete n;
}
```
The above uses both `ASSERT_*` and `EXPECT_*` assertions. The rule of thumb is
to use `EXPECT_*` when you want the test to continue to reveal more errors after
the assertion failure, and use `ASSERT_*` when continuing after failure doesn't
make sense. For example, the second assertion in the `Dequeue` test is
`ASSERT_NE(nullptr, n)`, as we need to dereference the pointer `n` later, which
would lead to a segfault when `n` is `NULL`.
When these tests run, the following happens:
1. googletest constructs a `QueueTest` object (let's call it `t1` ).
1. `t1.SetUp()` initializes `t1` .
1. The first test ( `IsEmptyInitially` ) runs on `t1` .
1. `t1.TearDown()` cleans up after the test finishes.
1. `t1` is destructed.
1. The above steps are repeated on another `QueueTest` object, this time
running the `DequeueWorks` test.
**Availability**: Linux, Windows, Mac.
## Invoking the Tests
`TEST()` and `TEST_F()` implicitly register their tests with googletest. So,
unlike with many other C++ testing frameworks, you don't have to re-list all
your defined tests in order to run them.
After defining your tests, you can run them with `RUN_ALL_TESTS()` , which
returns `0` if all the tests are successful, or `1` otherwise. Note that
`RUN_ALL_TESTS()` runs *all tests* in your link unit -- they can be from
different test suites, or even different source files.
When invoked, the `RUN_ALL_TESTS()` macro:
* Saves the state of all googletest flags
* Creates a test fixture object for the first test.
* Initializes it via `SetUp()`.
* Runs the test on the fixture object.
* Cleans up the fixture via `TearDown()`.
* Deletes the fixture.
* Restores the state of all all googletest flags
* Repeats the above steps for the next test, until all tests have run.
If a fatal failure happens the subsequent steps will be skipped.
> IMPORTANT: You must **not** ignore the return value of `RUN_ALL_TESTS()`, or
> you will get a compiler error. The rationale for this design is that the
> automated testing service determines whether a test has passed based on its
> exit code, not on its stdout/stderr output; thus your `main()` function must
> return the value of `RUN_ALL_TESTS()`.
>
> Also, you should call `RUN_ALL_TESTS()` only **once**. Calling it more than
> once conflicts with some advanced googletest features (e.g. thread-safe
> [death tests](advanced.md#death-tests)) and thus is not supported.
**Availability**: Linux, Windows, Mac.
## Writing the main() Function
Write your own main() function, which should return the value of
`RUN_ALL_TESTS()`
You can start from this boilerplate:
```c++
#include "this/package/foo.h"
#include "gtest/gtest.h"
namespace {
// The fixture for testing class Foo.
class FooTest : public ::testing::Test {
protected:
// You can remove any or all of the following functions if its body
// is empty.
FooTest() {
// You can do set-up work for each test here.
}
~FooTest() override {
// You can do clean-up work that doesn't throw exceptions here.
}
// If the constructor and destructor are not enough for setting up
// and cleaning up each test, you can define the following methods:
void SetUp() override {
// Code here will be called immediately after the constructor (right
// before each test).
}
void TearDown() override {
// Code here will be called immediately after each test (right
// before the destructor).
}
// Objects declared here can be used by all tests in the test suite for Foo.
};
// Tests that the Foo::Bar() method does Abc.
TEST_F(FooTest, MethodBarDoesAbc) {
const std::string input_filepath = "this/package/testdata/myinputfile.dat";
const std::string output_filepath = "this/package/testdata/myoutputfile.dat";
Foo f;
EXPECT_EQ(f.Bar(input_filepath, output_filepath), 0);
}
// Tests that Foo does Xyz.
TEST_F(FooTest, DoesXyz) {
// Exercises the Xyz feature of Foo.
}
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
```
The `::testing::InitGoogleTest()` function parses the command line for
googletest flags, and removes all recognized flags. This allows the user to
control a test program's behavior via various flags, which we'll cover in
[AdvancedGuide](advanced.md). You **must** call this function before calling
`RUN_ALL_TESTS()`, or the flags won't be properly initialized.
On Windows, `InitGoogleTest()` also works with wide strings, so it can be used
in programs compiled in `UNICODE` mode as well.
But maybe you think that writing all those main() functions is too much work? We
agree with you completely and that's why Google Test provides a basic
implementation of main(). If it fits your needs, then just link your test with
gtest\_main library and you are good to go.
NOTE: `ParseGUnitFlags()` is deprecated in favor of `InitGoogleTest()`.
## Known Limitations
* Google Test is designed to be thread-safe. The implementation is thread-safe
on systems where the `pthreads` library is available. It is currently
_unsafe_ to use Google Test assertions from two threads concurrently on
other systems (e.g. Windows). In most tests this is not an issue as usually
the assertions are done in the main thread. If you want to help, you can
volunteer to implement the necessary synchronization primitives in
`gtest-port.h` for your platform.
@@ -1,177 +0,0 @@
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
# The Problem #
Template and macro libraries often need to define many classes,
functions, or macros that vary only (or almost only) in the number of
arguments they take. It's a lot of repetitive, mechanical, and
error-prone work.
Variadic templates and variadic macros can alleviate the problem.
However, while both are being considered by the C++ committee, neither
is in the standard yet or widely supported by compilers. Thus they
are often not a good choice, especially when your code needs to be
portable. And their capabilities are still limited.
As a result, authors of such libraries often have to write scripts to
generate their implementation. However, our experience is that it's
tedious to write such scripts, which tend to reflect the structure of
the generated code poorly and are often hard to read and edit. For
example, a small change needed in the generated code may require some
non-intuitive, non-trivial changes in the script. This is especially
painful when experimenting with the code.
# Our Solution #
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
Programming, or Practical Utility for Meta Programming, whichever you
prefer) is a simple meta-programming tool for C++. The idea is that a
programmer writes a `foo.pump` file which contains C++ code plus meta
code that manipulates the C++ code. The meta code can handle
iterations over a range, nested iterations, local meta variable
definitions, simple arithmetic, and conditional expressions. You can
view it as a small Domain-Specific Language. The meta language is
designed to be non-intrusive (s.t. it won't confuse Emacs' C++ mode,
for example) and concise, making Pump code intuitive and easy to
maintain.
## Highlights ##
* The implementation is in a single Python script and thus ultra portable: no build or installation is needed and it works cross platforms.
* Pump tries to be smart with respect to [Google's style guide](https://github.com/google/styleguide): it breaks long lines (easy to have when they are generated) at acceptable places to fit within 80 columns and indent the continuation lines correctly.
* The format is human-readable and more concise than XML.
* The format works relatively well with Emacs' C++ mode.
## Examples ##
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are meta brackets, and `$$` starts a meta comment that ends with the line):
```
$var n = 3 $$ Defines a meta variable n.
$range i 0..n $$ Declares the range of meta iterator i (inclusive).
$for i [[
$$ Meta loop.
// Foo$i does blah for $i-ary predicates.
$range j 1..i
template <size_t N $for j [[, typename A$j]]>
class Foo$i {
$if i == 0 [[
blah a;
]] $elif i <= 2 [[
blah b;
]] $else [[
blah c;
]]
};
]]
```
will be translated by the Pump compiler to:
``` cpp
// Foo0 does blah for 0-ary predicates.
template <size_t N>
class Foo0 {
blah a;
};
// Foo1 does blah for 1-ary predicates.
template <size_t N, typename A1>
class Foo1 {
blah b;
};
// Foo2 does blah for 2-ary predicates.
template <size_t N, typename A1, typename A2>
class Foo2 {
blah b;
};
// Foo3 does blah for 3-ary predicates.
template <size_t N, typename A1, typename A2, typename A3>
class Foo3 {
blah c;
};
```
In another example,
```
$range i 1..n
Func($for i + [[a$i]]);
$$ The text between i and [[ is the separator between iterations.
```
will generate one of the following lines (without the comments), depending on the value of `n`:
``` cpp
Func(); // If n is 0.
Func(a1); // If n is 1.
Func(a1 + a2); // If n is 2.
Func(a1 + a2 + a3); // If n is 3.
// And so on...
```
## Constructs ##
We support the following meta programming constructs:
| `$var id = exp` | Defines a named constant value. `$id` is valid util the end of the current meta lexical block. |
|:----------------|:-----------------------------------------------------------------------------------------------|
| `$range id exp..exp` | Sets the range of an iteration variable, which can be reused in multiple loops later. |
| `$for id sep [[ code ]]` | Iteration. The range of `id` must have been defined earlier. `$id` is valid in `code`. |
| `$($)` | Generates a single `$` character. |
| `$id` | Value of the named constant or iteration variable. |
| `$(exp)` | Value of the expression. |
| `$if exp [[ code ]] else_branch` | Conditional. |
| `[[ code ]]` | Meta lexical block. |
| `cpp_code` | Raw C++ code. |
| `$$ comment` | Meta comment. |
**Note:** To give the user some freedom in formatting the Pump source
code, Pump ignores a new-line character if it's right after `$for foo`
or next to `[[` or `]]`. Without this rule you'll often be forced to write
very long lines to get the desired output. Therefore sometimes you may
need to insert an extra new-line in such places for a new-line to show
up in your output.
## Grammar ##
``` ebnf
code ::= atomic_code*
atomic_code ::= $var id = exp
| $var id = [[ code ]]
| $range id exp..exp
| $for id sep [[ code ]]
| $($)
| $id
| $(exp)
| $if exp [[ code ]] else_branch
| [[ code ]]
| cpp_code
sep ::= cpp_code | empty_string
else_branch ::= $else [[ code ]]
| $elif exp [[ code ]] else_branch
| empty_string
exp ::= simple_expression_in_Python_syntax
```
## Code ##
You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). It is still
very unpolished and lacks automated tests, although it has been
successfully used many times. If you find a chance to use it in your
project, please let us know what you think! We also welcome help on
improving Pump.
## Real Examples ##
You can find real-world applications of Pump in [Google Test](https://github.com/google/googletest/tree/master/googletest) and [Google Mock](https://github.com/google/googletest/tree/master/googlemock). The source file `foo.h.pump` generates `foo.h`.
## Tips ##
* If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1.
* To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line.
@@ -1,22 +0,0 @@
# Googletest Samples
If you're like us, you'd like to look at [googletest
samples.](https://github.com/google/googletest/tree/master/googletest/samples)
The sample directory has a number of well-commented samples showing how to use a
variety of googletest features.
* Sample #1 shows the basic steps of using googletest to test C++ functions.
* Sample #2 shows a more complex unit test for a class with multiple member
functions.
* Sample #3 uses a test fixture.
* Sample #4 teaches you how to use googletest and `googletest.h` together to
get the best of both libraries.
* Sample #5 puts shared testing logic in a base test fixture, and reuses it in
derived fixtures.
* Sample #6 demonstrates type-parameterized tests.
* Sample #7 teaches the basics of value-parameterized tests.
* Sample #8 shows using `Combine()` in value-parameterized tests.
* Sample #9 shows use of the listener API to modify Google Test's console
output and the use of its reflection API to inspect test results.
* Sample #10 shows use of the listener API to implement a primitive memory
leak checker.
@@ -35,8 +35,8 @@
// directly.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h"
@@ -97,6 +97,10 @@ GTEST_API_ bool InDeathTestChild();
//
// 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:
//
// GOOGLETEST_CM0005 DO NOT DELETE
@@ -162,27 +166,27 @@ GTEST_API_ bool InDeathTestChild();
// directory in PATH.
//
// Asserts that a given statement causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output
// that matches regex.
# define ASSERT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
// Asserts that a given `statement` causes the program to exit, with an
// integer exit status that satisfies `predicate`, and emitting error output
// that matches `matcher`.
# define ASSERT_EXIT(statement, predicate, matcher) \
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 suite, if any:
# define EXPECT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
# define EXPECT_EXIT(statement, predicate, matcher) \
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
// signal, and emitting error output that matches regex.
# define ASSERT_DEATH(statement, regex) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// signal, and emitting error output that matches `matcher`.
# define ASSERT_DEATH(statement, matcher) \
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 suite, if any:
# define EXPECT_DEATH(statement, regex) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
# define EXPECT_DEATH(statement, matcher) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
@@ -190,11 +194,10 @@ GTEST_API_ bool InDeathTestChild();
class GTEST_API_ ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
ExitedWithCode(const ExitedWithCode&) = default;
void operator=(const ExitedWithCode& other) = delete;
bool operator()(int exit_status) const;
private:
// No implementation - assignment is unsupported.
void operator=(const ExitedWithCode& other);
const int exit_code_;
};
@@ -276,20 +279,20 @@ class GTEST_API_ KilledBySignal {
// 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. 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.
// 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 iff EXPECT_DEATH compiles with it.
// 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
@@ -340,4 +343,4 @@ class GTEST_API_ KilledBySignal {
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
@@ -32,16 +32,14 @@
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.
// IWYU pragma: private, include "testing/base/public/gunit.h"
// IWYU pragma: friend third_party/googletest/googlemock/.*
// IWYU pragma: friend third_party/googletest/googletest/.*
#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#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"
@@ -62,20 +60,16 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
namespace testing {
// To implement a matcher Foo for type T, define:
// 1. a class FooMatcherImpl that implements the
// MatcherInterface<T> interface, and
// 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
// FooMatcherImpl*.
//
// The two-level delegation design makes it possible to allow a user
// to write "v" instead of "Eq(v)" where a Matcher is expected, which
// is impossible if we pass matchers by pointers. It also eases
// ownership management as Matcher objects can now be copied like
// plain values.
// FooMatcherMatcher.
// MatchResultListener is an abstract class. Its << operator can be
// used by a matcher to explain why a value matches or doesn't match.
//
class MatchResultListener {
public:
// Creates a listener object with the given underlying ostream. The
@@ -95,8 +89,8 @@ class MatchResultListener {
// Returns the underlying ostream.
::std::ostream* stream() { return stream_; }
// Returns true iff the listener is interested in an explanation of
// the match result. A matcher's MatchAndExplain() method can use
// 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; }
@@ -112,7 +106,7 @@ inline MatchResultListener::~MatchResultListener() {
// An instance of a subclass of this knows how to describe itself as a
// matcher.
class MatcherDescriberInterface {
class GTEST_API_ MatcherDescriberInterface {
public:
virtual ~MatcherDescriberInterface() {}
@@ -140,8 +134,8 @@ class MatcherDescriberInterface {
template <typename T>
class MatcherInterface : public MatcherDescriberInterface {
public:
// Returns true iff the matcher matches x; also explains the match
// result to 'listener' if necessary (see the next paragraph), in
// 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
@@ -180,31 +174,6 @@ class MatcherInterface : public MatcherDescriberInterface {
namespace internal {
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
template <typename T>
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
public:
explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
: impl_(impl) {}
~MatcherInterfaceAdapter() override { delete impl_; }
void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); }
void DescribeNegationTo(::std::ostream* os) const override {
impl_->DescribeNegationTo(os);
}
bool MatchAndExplain(const T& x,
MatchResultListener* listener) const override {
return impl_->MatchAndExplain(x, listener);
}
private:
const MatcherInterface<T>* const impl_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
};
struct AnyEq {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a == b; }
@@ -251,30 +220,53 @@ class StreamMatchResultListener : public MatchResultListener {
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 {
class MatcherBase : private MatcherDescriberInterface {
public:
// Returns true iff the matcher matches x; also explains the match
// result to 'listener'.
// 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 {
return impl_->MatchAndExplain(x, listener);
GTEST_CHECK_(vtable_ != nullptr);
return vtable_->match_and_explain(*this, x, listener);
}
// Returns true iff this matcher matches x.
// 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 { impl_->DescribeTo(os); }
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 {
impl_->DescribeNegationTo(os);
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.
@@ -287,31 +279,194 @@ class MatcherBase {
// of the describer, which is only guaranteed to be alive when
// this matcher object is alive.
const MatcherDescriberInterface* GetDescriber() const {
return impl_.get();
if (vtable_ == nullptr) return nullptr;
return vtable_->get_describer(*this);
}
protected:
MatcherBase() {}
MatcherBase() : vtable_(nullptr) {}
// Constructs a matcher from its implementation.
explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {}
template <typename U>
explicit MatcherBase(
const MatcherInterface<U>* impl,
typename internal::EnableIf<
!internal::IsSame<U, const U&>::value>::type* = nullptr)
: impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
explicit MatcherBase(const MatcherInterface<U>* impl) {
Init(impl);
}
MatcherBase(const MatcherBase&) = default;
MatcherBase& operator=(const MatcherBase&) = default;
MatcherBase(MatcherBase&&) = default;
MatcherBase& operator=(MatcherBase&&) = default;
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
MatcherBase(M&& m) { // NOLINT
Init(std::forward<M>(m));
}
virtual ~MatcherBase() {}
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:
std::shared_ptr<const MatcherInterface<const T&>> impl_;
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
@@ -333,11 +488,16 @@ class Matcher : public internal::MatcherBase<T> {
: internal::MatcherBase<T>(impl) {}
template <typename U>
explicit Matcher(const MatcherInterface<U>* impl,
typename internal::EnableIf<
!internal::IsSame<U, const U&>::value>::type* = nullptr)
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
@@ -355,6 +515,11 @@ class GTEST_API_ Matcher<const std::string&>
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
@@ -374,6 +539,11 @@ class GTEST_API_ Matcher<std::string>
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
@@ -382,18 +552,24 @@ class GTEST_API_ Matcher<std::string>
Matcher(const char* s); // NOLINT
};
#if GTEST_HAS_ABSL
#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 absl::string_view&>
: public internal::MatcherBase<const absl::string_view&> {
class GTEST_API_ Matcher<const internal::StringView&>
: public internal::MatcherBase<const internal::StringView&> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
: internal::MatcherBase<const absl::string_view&>(impl) {}
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.
@@ -402,20 +578,25 @@ class GTEST_API_ Matcher<const absl::string_view&>
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views directly.
Matcher(absl::string_view 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<absl::string_view>
: public internal::MatcherBase<absl::string_view> {
class GTEST_API_ Matcher<internal::StringView>
: public internal::MatcherBase<internal::StringView> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
: internal::MatcherBase<absl::string_view>(impl) {}
explicit Matcher(const MatcherInterface<absl::string_view>* impl)
: internal::MatcherBase<absl::string_view>(impl) {}
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.
@@ -424,10 +605,10 @@ class GTEST_API_ Matcher<absl::string_view>
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views directly.
Matcher(absl::string_view s); // NOLINT
// Allows the user to pass absl::string_views or std::string_views directly.
Matcher(internal::StringView s); // NOLINT
};
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Prints a matcher in a human-readable format.
template <typename T>
@@ -472,13 +653,13 @@ class PolymorphicMatcher {
public:
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); }
void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
virtual void DescribeNegationTo(::std::ostream* os) const {
void DescribeNegationTo(::std::ostream* os) const override {
impl_.DescribeNegationTo(os);
}
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
bool MatchAndExplain(T x, MatchResultListener* listener) const override {
return impl_.MatchAndExplain(x, listener);
}
@@ -527,37 +708,32 @@ 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>
operator Matcher<Lhs>() const {
return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
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; }
static const T& Unwrap(const T& v) {
return v;
}
template <typename T>
static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
static const T& Unwrap(std::reference_wrapper<T> v) {
return v;
}
template <typename Lhs, typename = Rhs>
class Impl : public MatcherInterface<Lhs> {
public:
explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
bool MatchAndExplain(Lhs lhs,
MatchResultListener* /* listener */) const override {
return Op()(lhs, Unwrap(rhs_));
}
void DescribeTo(::std::ostream* os) const override {
*os << D::Desc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << D::NegatedDesc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
private:
Rhs rhs_;
};
Rhs rhs_;
};
@@ -610,6 +786,10 @@ class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
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.
@@ -618,12 +798,12 @@ class MatchesRegexMatcher {
MatchesRegexMatcher(const RE* regex, bool full_match)
: regex_(regex), full_match_(full_match) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
#if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const {
return MatchAndExplain(std::string(s), listener);
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly:
// const char*
@@ -670,9 +850,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const internal::RE* regex) {
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
}
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const std::string& regex) {
return MatchesRegex(new internal::RE(regex));
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'.
@@ -681,9 +862,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const internal::RE* regex) {
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
}
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const std::string& regex) {
return ContainsRegex(new internal::RE(regex));
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.
@@ -745,4 +927,4 @@ inline internal::NeMatcher<Rhs> Ne(Rhs x) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
#endif // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
@@ -44,11 +44,12 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits>
#include <memory>
#include <sstream>
#include "gtest/internal/gtest-port.h"
@@ -215,4 +216,4 @@ std::string StreamableToString(const T& streamable) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
@@ -30,12 +30,9 @@
// Macros and functions for implementing parameterized tests
// in Google C++ Testing and Mocking Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
@@ -174,6 +171,7 @@ TEST_P(DerivedTest, DoesBlah) {
#endif // 0
#include <iterator>
#include <utility>
#include "gtest/internal/gtest-internal.h"
@@ -292,10 +290,9 @@ internal::ParamGenerator<T> Range(T start, T end) {
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
typename std::iterator_traits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end) {
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
::value_type ParamType;
typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
@@ -371,8 +368,6 @@ inline internal::ParamGenerator<bool> Bool() {
// std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to 10 arguments.
//
// Example:
//
// This will instantiate tests in test suite AnimalTest each one with
@@ -416,19 +411,20 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
: public test_suite_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
virtual void TestBody(); \
void TestBody() override; \
\
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \
#test_suite_name, \
GTEST_STRINGIFY_(test_suite_name), \
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
->AddTestPattern( \
GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \
new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
test_suite_name, test_name)>()); \
test_suite_name, test_name)>(), \
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
return 0; \
} \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
@@ -483,13 +479,21 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \
#test_suite_name, \
GTEST_STRINGIFY_(test_suite_name), \
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
->AddTestSuiteInstantiation( \
#prefix, &gtest_##prefix##test_suite_name##_EvalGenerator_, \
GTEST_STRINGIFY_(prefix), \
&gtest_##prefix##test_suite_name##_EvalGenerator_, \
&gtest_##prefix##test_suite_name##_EvalGenerateName_, \
__FILE__, __LINE__)
// Allow Marking a Parameterized test class as not needing to be instantiated.
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
namespace gtest_do_not_use_outside_namespace_scope {} \
static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \
GTEST_STRINGIFY_(T))
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define INSTANTIATE_TEST_CASE_P \
@@ -500,4 +504,4 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
@@ -97,10 +97,11 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <functional>
#include <memory>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
@@ -108,64 +109,124 @@
#include <type_traits>
#include <utility>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_ABSL
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#endif // GTEST_HAS_ABSL
namespace testing {
// Definitions in the 'internal' and 'internal2' name spaces are
// subject to change without notice. DO NOT USE THEM IN USER CODE!
namespace internal2 {
// Definitions in the internal* namespaces are subject to change without notice.
// DO NOT USE THEM IN USER CODE!
namespace internal {
// Prints the given number of bytes in the given object to the given
// ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count,
::std::ostream* os);
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
// For selecting which printer to use when a given type has neither <<
// nor PrintTo().
enum TypeKind {
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
#if GTEST_HAS_ABSL
kConvertibleToStringView, // a type implicitly convertible to
// absl::string_view
#endif
kOtherType // anything else
};
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
struct ContainerPrinter {
template <typename T,
typename = typename std::enable_if<
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value>::type>
static void PrintValue(const T& container, std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
size_t count = 0;
for (auto&& elem : container) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(elem, os) here as PrintTo() doesn't
// handle `elem` being a native array.
internal::UniversalPrint(elem, os);
++count;
}
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
// by the universal printer to print a value of type T when neither
// operator<< nor PrintTo() is defined for T, where kTypeKind is the
// "kind" of T as defined by enum TypeKind.
template <typename T, TypeKind kTypeKind>
class TypeWithoutFormatter {
public:
// This default version is called when kTypeKind is kOtherType.
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
if (count > 0) {
*os << ' ';
}
*os << '}';
}
};
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
const size_t kProtobufOneLinerMaxLength = 50;
// Used to print a pointer that is neither a char pointer nor a member
// pointer, when the user doesn't define PrintTo() for it. (A member
// variable pointer or member function pointer doesn't really point to
// a location in the address space. Their representation is
// implementation-defined. Therefore they will be printed as raw
// bytes.)
struct FunctionPointerPrinter {
template <typename T, typename = typename std::enable_if<
std::is_function<T>::value>::type>
static void PrintValue(T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
}
}
};
template <typename T>
class TypeWithoutFormatter<T, kProtobuf> {
public:
struct PointerPrinter {
template <typename T>
static void PrintValue(T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is not a function type. We just call << to print p,
// relying on ADL to pick up user-defined << for their pointer
// types, if any.
*os << p;
}
}
};
namespace internal_stream_operator_without_lexical_name_lookup {
// The presence of an operator<< here will terminate lexical scope lookup
// straight away (even though it cannot be a match because of its argument
// types). Thus, the two operator<< calls in StreamPrinter will find only ADL
// candidates.
struct LookupBlocker {};
void operator<<(LookupBlocker, LookupBlocker);
struct StreamPrinter {
template <typename T,
// Don't accept member pointers here. We'd print them via implicit
// conversion to bool, which isn't useful.
typename = typename std::enable_if<
!std::is_member_pointer<T>::value>::type,
// Only accept types for which we can find a streaming operator via
// ADL (possibly involving implicit conversions).
typename = decltype(std::declval<std::ostream&>()
<< std::declval<const T&>())>
static void PrintValue(const T& value, ::std::ostream* os) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
}
};
} // namespace internal_stream_operator_without_lexical_name_lookup
struct ProtobufPrinter {
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
static const size_t kProtobufOneLinerMaxLength = 50;
template <typename T,
typename = typename std::enable_if<
internal::HasDebugStringAndShortDebugString<T>::value>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
std::string pretty_str = value.ShortDebugString();
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
@@ -175,9 +236,7 @@ class TypeWithoutFormatter<T, kProtobuf> {
}
};
template <typename T>
class TypeWithoutFormatter<T, kConvertibleToInteger> {
public:
struct ConvertibleToIntegerPrinter {
// Since T has no << operator or PrintTo() but can be implicitly
// converted to BiggestInt, we print it as a BiggestInt.
//
@@ -185,113 +244,74 @@ class TypeWithoutFormatter<T, kConvertibleToInteger> {
// case printing it as an integer is the desired behavior. In case
// T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer.
static void PrintValue(const T& value, ::std::ostream* os) {
const internal::BiggestInt kBigInt = value;
*os << kBigInt;
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
*os << value;
}
};
#if GTEST_HAS_ABSL
template <typename T>
class TypeWithoutFormatter<T, kConvertibleToStringView> {
public:
// Since T has neither operator<< nor PrintTo() but can be implicitly
// converted to absl::string_view, we print it as a absl::string_view.
//
// Note: the implementation is further below, as it depends on
// internal::PrintTo symbol which is defined later in the file.
static void PrintValue(const T& value, ::std::ostream* os);
struct ConvertibleToStringViewPrinter {
#if GTEST_INTERNAL_HAS_STRING_VIEW
static void PrintValue(internal::StringView value, ::std::ostream* os) {
internal::UniversalPrint(value, os);
}
#endif
};
#endif
// Prints the given value to the given ostream. If the value is a
// protocol message, its debug string is printed; if it's an enum or
// of a type implicitly convertible to BiggestInt, it's printed as an
// integer; otherwise the bytes in the value are printed. This is
// what UniversalPrinter<T>::Print() does when it knows nothing about
// type T and T has neither << operator nor PrintTo().
//
// A user can override this behavior for a class type Foo by defining
// a << operator in the namespace where Foo is defined.
//
// We put this operator in namespace 'internal2' instead of 'internal'
// to simplify the implementation, as much code in 'internal' needs to
// use << in STL, which would conflict with our own << were it defined
// in 'internal'.
//
// Note that this operator<< takes a generic std::basic_ostream<Char,
// CharTraits> type instead of the more restricted std::ostream. If
// we define it to take an std::ostream instead, we'll get an
// "ambiguous overloads" compiler error when trying to print a type
// Foo that supports streaming to std::basic_ostream<Char,
// CharTraits>, as the compiler cannot tell whether
// operator<<(std::ostream&, const T&) or
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
// specific.
template <typename Char, typename CharTraits, typename T>
::std::basic_ostream<Char, CharTraits>& operator<<(
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
? kProtobuf
: std::is_convertible<
const T&, internal::BiggestInt>::value
? kConvertibleToInteger
:
#if GTEST_HAS_ABSL
std::is_convertible<
const T&, absl::string_view>::value
? kConvertibleToStringView
:
#endif
kOtherType)>::PrintValue(x, &os);
return os;
}
} // namespace internal2
} // namespace testing
// Prints the given number of bytes in the given object to the given
// ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count,
::std::ostream* os);
struct RawBytesPrinter {
// SFINAE on `sizeof` to make sure we have a complete type.
template <typename T, size_t = sizeof(T)>
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
// Load bearing cast to void* to support iOS
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
}
};
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
// magic needed for implementing UniversalPrinter won't work.
namespace testing_internal {
struct FallbackPrinter {
template <typename T>
static void PrintValue(const T&, ::std::ostream* os) {
*os << "(incomplete type)";
}
};
// Used to print a value that is not an STL-style container when the
// user doesn't define PrintTo() for it.
// Try every printer in order and return the first one that works.
template <typename T, typename E, typename Printer, typename... Printers>
struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
template <typename T, typename Printer, typename... Printers>
struct FindFirstPrinter<
T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
Printer, Printers...> {
using type = Printer;
};
// Select the best printer in the following order:
// - Print containers (they have begin/end/etc).
// - Print function pointers.
// - Print object pointers.
// - Use the stream operator, if available.
// - Print protocol buffers.
// - Print types convertible to BiggestInt.
// - Print types convertible to StringView, if available.
// - Fallback to printing the raw bytes of the object.
template <typename T>
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
// With the following statement, during unqualified name lookup,
// testing::internal2::operator<< appears as if it was declared in
// the nearest enclosing namespace that contains both
// ::testing_internal and ::testing::internal2, i.e. the global
// namespace. For more details, refer to the C++ Standard section
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
// testing::internal2::operator<< in case T doesn't come with a <<
// operator.
//
// We cannot write 'using ::testing::internal2::operator<<;', which
// gcc 3.3 fails to compile due to a compiler bug.
using namespace ::testing::internal2; // NOLINT
// Assuming T is defined in namespace foo, in the next statement,
// the compiler will consider all of:
//
// 1. foo::operator<< (thanks to Koenig look-up),
// 2. ::operator<< (as the current namespace is enclosed in ::),
// 3. testing::internal2::operator<< (thanks to the using statement above).
//
// The operator<< whose type matches T best will be picked.
//
// We deliberately allow #2 to be a candidate, as sometimes it's
// impossible to define #1 (e.g. when foo is ::std, defining
// anything in it is undefined behavior unless you are a compiler
// vendor.).
*os << value;
void PrintWithFallback(const T& value, ::std::ostream* os) {
using Printer = typename FindFirstPrinter<
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
ProtobufPrinter, ConvertibleToIntegerPrinter,
ConvertibleToStringViewPrinter, RawBytesPrinter, FallbackPrinter>::type;
Printer::PrintValue(value, os);
}
} // namespace testing_internal
namespace testing {
namespace internal {
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
// value of type ToPrint that is an operand of a comparison assertion
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
@@ -340,6 +360,14 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
#ifdef __cpp_char8_t
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
#endif
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
@@ -357,6 +385,14 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
#ifdef __cpp_char8_t
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
#endif
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);
#if GTEST_HAS_STD_WSTRING
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
@@ -389,85 +425,6 @@ std::string FormatForComparisonFailureMessage(
template <typename T>
class UniversalPrinter;
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
enum DefaultPrinterType {
kPrintContainer,
kPrintPointer,
kPrintFunctionPointer,
kPrintOther,
};
template <DefaultPrinterType type> struct WrapPrinterType {};
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
template <typename C>
void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */,
const C& container, ::std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
size_t count = 0;
for (typename C::const_iterator it = container.begin();
it != container.end(); ++it, ++count) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
// handle *it being a native array.
internal::UniversalPrint(*it, os);
}
if (count > 0) {
*os << ' ';
}
*os << '}';
}
// Used to print a pointer that is neither a char pointer nor a member
// pointer, when the user doesn't define PrintTo() for it. (A member
// variable pointer or member function pointer doesn't really point to
// a location in the address space. Their representation is
// implementation-defined. Therefore they will be printed as raw
// bytes.)
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is not a function type. We just call << to print p,
// relying on ADL to pick up user-defined << for their pointer
// types, if any.
*os << p;
}
}
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
}
}
// Used to print a non-container, non-pointer value when the user
// doesn't define PrintTo() for it.
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
const T& value, ::std::ostream* os) {
::testing_internal::DefaultPrintNonContainerTo(value, os);
}
// Prints the given value using the << operator if it has one;
// otherwise prints the bytes in it. This is what
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
@@ -481,36 +438,7 @@ void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
// wants).
template <typename T>
void PrintTo(const T& value, ::std::ostream* os) {
// DefaultPrintTo() is overloaded. The type of its first argument
// determines which version will be picked.
//
// Note that we check for container types here, prior to we check
// for protocol message types in our operator<<. The rationale is:
//
// For protocol messages, we want to give people a chance to
// override Google Mock's format by defining a PrintTo() or
// operator<<. For STL containers, other formats can be
// incompatible with Google Mock's format for the container
// elements; therefore we check for container types here to ensure
// that our format is used.
//
// Note that MSVC and clang-cl do allow an implicit conversion from
// pointer-to-function to pointer-to-object, but clang-cl warns on it.
// So don't use ImplicitlyConvertible if it can be helped since it will
// cause this warning, and use a separate overload of DefaultPrintTo for
// function pointers so that the `*os << p` in the object pointer overload
// doesn't cause that warning either.
DefaultPrintTo(
WrapPrinterType <
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value
? kPrintContainer
: !std::is_pointer<T>::value
? kPrintOther
: std::is_function<typename std::remove_pointer<T>::type>::value
? kPrintFunctionPointer
: kPrintPointer > (),
value, os);
internal::PrintWithFallback(value, os);
}
// The following list of PrintTo() overloads tells
@@ -541,6 +469,16 @@ inline void PrintTo(bool x, ::std::ostream* os) {
// is implemented as an unsigned type.
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
inline void PrintTo(char16_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
}
#ifdef __cpp_char8_t
inline void PrintTo(char8_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
}
#endif
// Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) {
@@ -561,6 +499,23 @@ inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const void*>(s), os);
}
#ifdef __cpp_char8_t
// Overloads for u8 strings.
GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);
inline void PrintTo(char8_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char8_t*>(s), os);
}
#endif
// Overloads for u16 strings.
GTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);
inline void PrintTo(char16_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char16_t*>(s), os);
}
// Overloads for u32 strings.
GTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);
inline void PrintTo(char32_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char32_t*>(s), os);
}
// MSVC can be configured to define wchar_t as a typedef of unsigned
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
@@ -595,6 +550,26 @@ inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os);
}
// Overloads for ::std::u8string
#ifdef __cpp_char8_t
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
PrintU8StringTo(s, os);
}
#endif
// Overloads for ::std::u16string
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
PrintU16StringTo(s, os);
}
// Overloads for ::std::u32string
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
PrintU32StringTo(s, os);
}
// Overloads for ::std::wstring.
#if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
@@ -603,12 +578,12 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
}
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_ABSL
// Overload for absl::string_view.
inline void PrintTo(absl::string_view sp, ::std::ostream* os) {
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Overload for internal::StringView.
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
PrintTo(::std::string(sp), os);
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
@@ -617,6 +592,43 @@ void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
UniversalPrinter<T&>::Print(ref.get(), os);
}
inline const void* VoidifyPointer(const void* p) { return p; }
inline const void* VoidifyPointer(volatile const void* p) {
return const_cast<const void*>(p);
}
template <typename T, typename Ptr>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {
if (ptr == nullptr) {
*os << "(nullptr)";
} else {
// We can't print the value. Just print the pointer..
*os << "(" << (VoidifyPointer)(ptr.get()) << ")";
}
}
template <typename T, typename Ptr,
typename = typename std::enable_if<!std::is_void<T>::value &&
!std::is_array<T>::value>::type>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
if (ptr == nullptr) {
*os << "(nullptr)";
} else {
*os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
UniversalPrinter<T>::Print(*ptr, os);
*os << ")";
}
}
template <typename T, typename D>
void PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
template <typename T>
void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>
@@ -682,14 +694,46 @@ class UniversalPrinter {
GTEST_DISABLE_MSC_WARNINGS_POP_()
};
#if GTEST_HAS_ABSL
// Remove any const-qualifiers before passing a type to UniversalPrinter.
template <typename T>
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
// Printer for absl::optional
#if GTEST_INTERNAL_HAS_ANY
// Printer for std::any / absl::any
template <>
class UniversalPrinter<Any> {
public:
static void Print(const Any& value, ::std::ostream* os) {
if (value.has_value()) {
*os << "value of type " << GetTypeName(value);
} else {
*os << "no value";
}
}
private:
static std::string GetTypeName(const Any& value) {
#if GTEST_HAS_RTTI
return internal::GetTypeName(value.type());
#else
static_cast<void>(value); // possibly unused
return "<unknown_type>";
#endif // GTEST_HAS_RTTI
}
};
#endif // GTEST_INTERNAL_HAS_ANY
#if GTEST_INTERNAL_HAS_OPTIONAL
// Printer for std::optional / absl::optional
template <typename T>
class UniversalPrinter<::absl::optional<T>> {
class UniversalPrinter<Optional<T>> {
public:
static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
static void Print(const Optional<T>& value, ::std::ostream* os) {
*os << '(';
if (!value) {
*os << "nullopt";
@@ -700,14 +744,22 @@ class UniversalPrinter<::absl::optional<T>> {
}
};
// Printer for absl::variant
#endif // GTEST_INTERNAL_HAS_OPTIONAL
#if GTEST_INTERNAL_HAS_VARIANT
// Printer for std::variant / absl::variant
template <typename... T>
class UniversalPrinter<::absl::variant<T...>> {
class UniversalPrinter<Variant<T...>> {
public:
static void Print(const ::absl::variant<T...>& value, ::std::ostream* os) {
static void Print(const Variant<T...>& value, ::std::ostream* os) {
*os << '(';
absl::visit(Visitor{os}, value);
#if GTEST_HAS_ABSL
absl::visit(Visitor{os, value.index()}, value);
#else
std::visit(Visitor{os, value.index()}, value);
#endif // GTEST_HAS_ABSL
*os << ')';
}
@@ -715,14 +767,16 @@ class UniversalPrinter<::absl::variant<T...>> {
struct Visitor {
template <typename U>
void operator()(const U& u) const {
*os << "'" << GetTypeName<U>() << "' with value ";
*os << "'" << GetTypeName<U>() << "(index = " << index
<< ")' with value ";
UniversalPrint(u, os);
}
::std::ostream* os;
std::size_t index;
};
};
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_VARIANT
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
@@ -751,6 +805,20 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
GTEST_API_ void UniversalPrintArray(
const char* begin, size_t len, ::std::ostream* os);
#ifdef __cpp_char8_t
// This overload prints a (const) char8_t array compactly.
GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
::std::ostream* os);
#endif
// This overload prints a (const) char16_t array compactly.
GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,
::std::ostream* os);
// This overload prints a (const) char32_t array compactly.
GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
::std::ostream* os);
// This overload prints a (const) wchar_t array compactly.
GTEST_API_ void UniversalPrintArray(
const wchar_t* begin, size_t len, ::std::ostream* os);
@@ -823,12 +891,55 @@ class UniversalTersePrinter<const char*> {
}
};
template <>
class UniversalTersePrinter<char*> {
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
};
#ifdef __cpp_char8_t
template <>
class UniversalTersePrinter<const char8_t*> {
public:
static void Print(char* str, ::std::ostream* os) {
UniversalTersePrinter<const char*>::Print(str, os);
static void Print(const char8_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::u8string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char8_t*>
: public UniversalTersePrinter<const char8_t*> {};
#endif
template <>
class UniversalTersePrinter<const char16_t*> {
public:
static void Print(const char16_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::u16string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char16_t*>
: public UniversalTersePrinter<const char16_t*> {};
template <>
class UniversalTersePrinter<const char32_t*> {
public:
static void Print(const char32_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::u32string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char32_t*>
: public UniversalTersePrinter<const char32_t*> {};
#if GTEST_HAS_STD_WSTRING
template <>
@@ -901,16 +1012,6 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
} // namespace internal
#if GTEST_HAS_ABSL
namespace internal2 {
template <typename T>
void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
const T& value, ::std::ostream* os) {
internal::PrintTo(absl::string_view(value), os);
}
} // namespace internal2
#endif
template <typename T>
::std::string PrintToString(const T& value) {
::std::stringstream ss;
@@ -925,4 +1026,4 @@ template <typename T>
// declarations from this file.
#include "gtest/internal/custom/gtest-printers.h"
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
@@ -33,8 +33,8 @@
// GOOGLETEST_CM0004 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#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"
@@ -235,4 +235,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
}\
} while (::testing::internal::AlwaysFalse())
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
@@ -29,8 +29,8 @@
//
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
#include <vector>
@@ -87,19 +87,19 @@ class GTEST_API_ TestPartResult {
// Gets the message associated with the test part.
const char* message() const { return message_.c_str(); }
// Returns true iff the test part was skipped.
// Returns true if and only if the test part was skipped.
bool skipped() const { return type_ == kSkip; }
// Returns true iff the test part passed.
// Returns true if and only if the test part passed.
bool passed() const { return type_ == kSuccess; }
// Returns true iff the test part non-fatally failed.
// Returns true if and only if the test part non-fatally failed.
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; }
// Returns true iff the test part failed.
// Returns true if and only if the test part failed.
bool failed() const { return fatally_failed() || nonfatally_failed(); }
private:
@@ -181,4 +181,4 @@ class GTEST_API_ HasNewFatalFailureHelper
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
@@ -27,11 +27,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#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.
@@ -65,9 +64,9 @@ TYPED_TEST_SUITE(FooTest, MyTypes);
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
// tests for this test suite as you want.
TYPED_TEST(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
// Since we are inside a derived class template, C++ requires use to
// visit the members of FooTest via 'this'.
// Inside a test, refer to the special name TypeParam to get the type
// parameter. Since we are inside a derived class template, C++ requires
// us to visit the members of FooTest via 'this'.
TypeParam n = this->value_;
// To visit static members of the fixture, add the TestFixture::
@@ -170,13 +169,12 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
#endif // 0
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-type-util.h"
// Implements typed tests.
#if GTEST_HAS_TYPED_TEST
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the typedef for the type parameters of the
@@ -188,27 +186,25 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
#define GTEST_NAME_GENERATOR_(TestSuiteName) \
gtest_type_params_##TestSuiteName##_NameGenerator
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
#define TYPED_TEST_SUITE(CaseName, Types, ...) \
typedef ::testing::internal::TypeList<Types>::type GTEST_TYPE_PARAMS_( \
CaseName); \
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
#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) \
#define TYPED_TEST(CaseName, TestName) \
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
"test-name must not be empty"); \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
void TestBody() override; \
}; \
static bool gtest_##CaseName##_##TestName##_registered_ \
GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTest< \
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
TestName)>, \
@@ -216,7 +212,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
CaseName)>::Register("", \
::testing::internal::CodeLocation( \
__FILE__, __LINE__), \
#CaseName, #TestName, 0, \
GTEST_STRINGIFY_(CaseName), \
GTEST_STRINGIFY_(TestName), 0, \
::testing::internal::GenerateNames< \
GTEST_NAME_GENERATOR_(CaseName), \
GTEST_TYPE_PARAMS_(CaseName)>()); \
@@ -231,12 +228,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
TYPED_TEST_SUITE
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_HAS_TYPED_TEST
// Implements type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the namespace name that the type-parameterized tests for
@@ -279,24 +272,26 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
void TestBody() override; \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, #SuiteName, #TestName); \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
__FILE__, __LINE__, #__VA_ARGS__)
// Note: this won't work correctly if the trailing arguments are macros.
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
@@ -306,22 +301,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
REGISTER_TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
#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::TypeList<Types>::type>:: \
Register(#Prefix, \
::testing::internal::GenerateTypeList<Types>::type>:: \
Register(GTEST_STRINGIFY_(Prefix), \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \
&GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
GTEST_STRINGIFY_(SuiteName), \
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
::testing::internal::GenerateNames< \
::testing::internal::NameGeneratorSelector< \
__VA_ARGS__>::type, \
::testing::internal::TypeList<Types>::type>())
::testing::internal::GenerateTypeList<Types>::type>())
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
@@ -331,6 +326,4 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
INSTANTIATE_TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+119 -82
View File
@@ -49,8 +49,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
#include <cstddef>
#include <limits>
@@ -101,6 +101,10 @@ GTEST_DECLARE_bool_(catch_exceptions);
// to let Google Test decide.
GTEST_DECLARE_string_(color);
// This flag controls whether the test runner should continue execution past
// first failure.
GTEST_DECLARE_bool_(fail_fast);
// This flag sets up the filter to select by name using a glob pattern
// the tests to run. If the filter is not given all tests are executed.
GTEST_DECLARE_string_(filter);
@@ -117,6 +121,9 @@ GTEST_DECLARE_bool_(list_tests);
// in addition to its normal textual output.
GTEST_DECLARE_string_(output);
// This flags control whether Google Test prints only test failures.
GTEST_DECLARE_bool_(brief);
// This flags control whether Google Test prints the elapsed time for each
// test.
GTEST_DECLARE_bool_(print_time);
@@ -177,6 +184,7 @@ class FuchsiaDeathTest;
class UnitTestImpl* GetUnitTestImpl();
void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
const std::string& message);
std::set<std::string>* GetIgnoredParameterizedTestSuites();
} // namespace internal
@@ -278,7 +286,11 @@ class GTEST_API_ AssertionResult {
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult(const AssertionResult& other);
#if defined(_MSC_VER) && _MSC_VER < 1910
// C4800 is a level 3 warning in Visual Studio 2015 and earlier.
// This warning is not emitted in Visual Studio 2017.
// This warning is off by default starting in Visual Studio 2019 but can be
// enabled with command-line options.
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
#endif
@@ -292,13 +304,13 @@ class GTEST_API_ AssertionResult {
template <typename T>
explicit AssertionResult(
const T& success,
typename internal::EnableIf<
typename std::enable_if<
!std::is_convertible<T, AssertionResult>::value>::type*
/*enabler*/
= nullptr)
: success_(success) {}
#if defined(_MSC_VER) && _MSC_VER < 1910
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
@@ -308,7 +320,7 @@ class GTEST_API_ AssertionResult {
return *this;
}
// Returns true iff the assertion succeeded.
// Returns true if and only if the assertion succeeded.
operator bool() const { return success_; } // NOLINT
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
@@ -406,10 +418,10 @@ class GTEST_API_ Test {
// The d'tor is virtual as we intend to inherit from Test.
virtual ~Test();
// Sets up the stuff shared by all tests in this test case.
// Sets up the stuff shared by all tests in this test suite.
//
// Google Test will call Foo::SetUpTestSuite() before running the first
// test in test case Foo. Hence a sub-class can define its own
// test in test suite Foo. Hence a sub-class can define its own
// SetUpTestSuite() method to shadow the one defined in the super
// class.
static void SetUpTestSuite() {}
@@ -417,27 +429,28 @@ class GTEST_API_ Test {
// Tears down the stuff shared by all tests in this test suite.
//
// Google Test will call Foo::TearDownTestSuite() after running the last
// test in test case Foo. Hence a sub-class can define its own
// test in test suite Foo. Hence a sub-class can define its own
// TearDownTestSuite() method to shadow the one defined in the super
// class.
static void TearDownTestSuite() {}
// Legacy API is deprecated but still available
// Legacy API is deprecated but still available. Use SetUpTestSuite and
// TearDownTestSuite instead.
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
static void TearDownTestCase() {}
static void SetUpTestCase() {}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Returns true iff the current test has a fatal failure.
// Returns true if and only if the current test has a fatal failure.
static bool HasFatalFailure();
// Returns true iff the current test has a non-fatal failure.
// Returns true if and only if the current test has a non-fatal failure.
static bool HasNonfatalFailure();
// Returns true iff the current test was skipped.
// Returns true if and only if the current test was skipped.
static bool IsSkipped();
// Returns true iff the current test has a (either fatal or
// Returns true if and only if the current test has a (either fatal or
// non-fatal) failure.
static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
@@ -468,8 +481,8 @@ class GTEST_API_ Test {
virtual void TearDown();
private:
// Returns true iff the current test has the same fixture class as
// the first test in the current test suite.
// Returns true if and only if the current test has the same fixture class
// as the first test in the current test suite.
static bool HasSameFixtureClass();
// Runs the test after the test fixture has been set up.
@@ -570,24 +583,28 @@ class GTEST_API_ TestResult {
// Returns the number of the test properties.
int test_property_count() const;
// Returns true iff the test passed (i.e. no test part failed).
// Returns true if and only if the test passed (i.e. no test part failed).
bool Passed() const { return !Skipped() && !Failed(); }
// Returns true iff the test was skipped.
// Returns true if and only if the test was skipped.
bool Skipped() const;
// Returns true iff the test failed.
// Returns true if and only if the test failed.
bool Failed() const;
// Returns true iff the test fatally failed.
// Returns true if and only if the test fatally failed.
bool HasFatalFailure() const;
// Returns true iff the test has a non-fatal failure.
// Returns true if and only if the test has a non-fatal failure.
bool HasNonfatalFailure() const;
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
// Gets the time of the test case start, in ms from the start of the
// UNIX epoch.
TimeInMillis start_timestamp() const { return start_timestamp_; }
// Returns the i-th test part result among all the results. i can range from 0
// to total_part_count() - 1. If i is not in that range, aborts the program.
const TestPartResult& GetTestPartResult(int i) const;
@@ -618,6 +635,9 @@ class GTEST_API_ TestResult {
return test_properties_;
}
// Sets the start time.
void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; }
// Sets the elapsed time.
void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
@@ -653,7 +673,7 @@ class GTEST_API_ TestResult {
// Protects mutable state of the property vector and of owned
// properties, whose values may be updated.
internal::Mutex test_properites_mutex_;
internal::Mutex test_properties_mutex_;
// The vector of TestPartResults
std::vector<TestPartResult> test_part_results_;
@@ -661,6 +681,8 @@ class GTEST_API_ TestResult {
std::vector<TestProperty> test_properties_;
// Running count of death tests.
int death_test_count_;
// The start time, in milliseconds since UNIX Epoch.
TimeInMillis start_timestamp_;
// The elapsed time, in milliseconds.
TimeInMillis elapsed_time_;
@@ -737,7 +759,7 @@ class GTEST_API_ TestInfo {
// contains the character 'A' or starts with "Foo.".
bool should_run() const { return should_run_; }
// Returns true iff this test will appear in the XML report.
// Returns true if and only if this test will appear in the XML report.
bool is_reportable() const {
// The XML report includes tests matching the filter, excluding those
// run in other shards.
@@ -781,6 +803,9 @@ class GTEST_API_ TestInfo {
// deletes it.
void Run();
// Skip and records the test result for this object.
void Skip();
static void ClearTestResult(TestInfo* test_info) {
test_info->result_.Clear();
}
@@ -795,12 +820,12 @@ class GTEST_API_ TestInfo {
// value-parameterized test.
const std::unique_ptr<const ::std::string> value_param_;
internal::CodeLocation location_;
const internal::TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled
bool matches_filter_; // True if this test matches the
// user-specified filter.
bool is_in_another_shard_; // Will be run in another shard.
const internal::TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True if and only if this test should run
bool is_disabled_; // True if and only if this test is disabled
bool matches_filter_; // True if this test matches the
// user-specified filter.
bool is_in_another_shard_; // Will be run in another shard.
internal::TestFactoryBase* const factory_; // The factory that creates
// the test object
@@ -872,15 +897,21 @@ class GTEST_API_ TestSuite {
// Gets the number of all tests in this test suite.
int total_test_count() const;
// Returns true iff the test suite passed.
// Returns true if and only if the test suite passed.
bool Passed() const { return !Failed(); }
// Returns true iff the test suite failed.
bool Failed() const { return failed_test_count() > 0; }
// Returns true if and only if the test suite failed.
bool Failed() const {
return failed_test_count() > 0 || ad_hoc_test_result().Failed();
}
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
// Gets the time of the test suite start, in ms from the start of the
// UNIX epoch.
TimeInMillis start_timestamp() const { return start_timestamp_; }
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* GetTestInfo(int i) const;
@@ -923,6 +954,9 @@ class GTEST_API_ TestSuite {
// Runs every test in this TestSuite.
void Run();
// Skips the execution of tests under this TestSuite
void Skip();
// Runs SetUpTestSuite() for this TestSuite. This wrapper is needed
// for catching exceptions thrown from SetUpTestSuite().
void RunSetUpTestSuite() {
@@ -939,33 +973,33 @@ class GTEST_API_ TestSuite {
}
}
// Returns true iff test passed.
// Returns true if and only if test passed.
static bool TestPassed(const TestInfo* test_info) {
return test_info->should_run() && test_info->result()->Passed();
}
// Returns true iff test skipped.
// Returns true if and only if test skipped.
static bool TestSkipped(const TestInfo* test_info) {
return test_info->should_run() && test_info->result()->Skipped();
}
// Returns true iff test failed.
// Returns true if and only if test failed.
static bool TestFailed(const TestInfo* test_info) {
return test_info->should_run() && test_info->result()->Failed();
}
// Returns true iff the test is disabled and will be reported in the XML
// report.
// Returns true if and only if the test is disabled and will be reported in
// the XML report.
static bool TestReportableDisabled(const TestInfo* test_info) {
return test_info->is_reportable() && test_info->is_disabled_;
}
// Returns true iff test is disabled.
// Returns true if and only if test is disabled.
static bool TestDisabled(const TestInfo* test_info) {
return test_info->is_disabled_;
}
// Returns true iff this test will appear in the XML report.
// Returns true if and only if this test will appear in the XML report.
static bool TestReportable(const TestInfo* test_info) {
return test_info->is_reportable();
}
@@ -997,8 +1031,10 @@ class GTEST_API_ TestSuite {
internal::SetUpTestSuiteFunc set_up_tc_;
// Pointer to the function that tears down the test suite.
internal::TearDownTestSuiteFunc tear_down_tc_;
// True iff any test in this test suite should run.
// True if and only if any test in this test suite should run.
bool should_run_;
// The start time, in milliseconds since UNIX Epoch.
TimeInMillis start_timestamp_;
// Elapsed time, in milliseconds.
TimeInMillis elapsed_time_;
// Holds test properties recorded during execution of SetUpTestSuite and
@@ -1297,7 +1333,7 @@ class GTEST_API_ UnitTest {
int failed_test_case_count() const;
int total_test_case_count() const;
int test_case_to_run_count() const;
#endif // EMOVE_LEGACY_TEST_CASEAPI
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Gets the number of successful tests.
int successful_test_count() const;
@@ -1330,11 +1366,12 @@ class GTEST_API_ UnitTest {
// Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const;
// Returns true iff the unit test passed (i.e. all test suites passed).
// Returns true if and only if the unit test passed (i.e. all test suites
// passed).
bool Passed() const;
// Returns true iff the unit test failed (i.e. some test suite failed
// or something outside of all tests failed).
// Returns true if and only if the unit test failed (i.e. some test suite
// failed or something outside of all tests failed).
bool Failed() const;
// Gets the i-th test suite among all the test suites. i can range from 0 to
@@ -1400,6 +1437,7 @@ class GTEST_API_ UnitTest {
friend class internal::StreamingListenerTest;
friend class internal::UnitTestRecordPropertyTestHelper;
friend Environment* AddGlobalTestEnvironment(Environment* env);
friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites();
friend internal::UnitTestImpl* internal::GetUnitTestImpl();
friend void internal::ReportFailureInUnknownLocation(
TestPartResult::Type result_type,
@@ -1511,14 +1549,6 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
}
// With this overloaded version, we allow anonymous enums to be used
// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
// can be implicitly cast to BiggestInt.
GTEST_API_ AssertionResult CmpHelperEQ(const char* lhs_expression,
const char* rhs_expression,
BiggestInt lhs,
BiggestInt rhs);
class EqHelper {
public:
// This templatized version is for the general case.
@@ -1575,11 +1605,6 @@ AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,
// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste
// of similar code.
//
// For each templatized helper function, we also define an overloaded
// version for BiggestInt in order to reduce code bloat and allow
// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled
// with gcc 4.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
@@ -1591,22 +1616,20 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
} else {\
return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\
}\
}\
GTEST_API_ AssertionResult CmpHelper##op_name(\
const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)
}
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
// Implements the helper function for {ASSERT|EXPECT}_NE
GTEST_IMPL_CMP_HELPER_(NE, !=);
GTEST_IMPL_CMP_HELPER_(NE, !=)
// Implements the helper function for {ASSERT|EXPECT}_LE
GTEST_IMPL_CMP_HELPER_(LE, <=);
GTEST_IMPL_CMP_HELPER_(LE, <=)
// Implements the helper function for {ASSERT|EXPECT}_LT
GTEST_IMPL_CMP_HELPER_(LT, <);
GTEST_IMPL_CMP_HELPER_(LT, <)
// Implements the helper function for {ASSERT|EXPECT}_GE
GTEST_IMPL_CMP_HELPER_(GE, >=);
GTEST_IMPL_CMP_HELPER_(GE, >=)
// Implements the helper function for {ASSERT|EXPECT}_GT
GTEST_IMPL_CMP_HELPER_(GT, >);
GTEST_IMPL_CMP_HELPER_(GT, >)
#undef GTEST_IMPL_CMP_HELPER_
@@ -1783,12 +1806,6 @@ class GTEST_API_ AssertHelper {
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
};
enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW };
GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color,
const char* fmt,
...);
} // namespace internal
// The pure interface class that all value-parameterized tests inherit from.
@@ -1869,7 +1886,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// Skips test in runtime.
// Skipping test aborts current function.
// Skipped tests are neither successful nor failed.
#define GTEST_SKIP() GTEST_SKIP_("Skipped")
#define GTEST_SKIP() GTEST_SKIP_("")
// ADD_FAILURE unconditionally adds a failure to the current test.
// SUCCEED generates a success - it doesn't automatically make the
@@ -1945,19 +1962,38 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// Boolean assertions. Condition can be either a Boolean expression or an
// AssertionResult. For more information on how to use AssertionResult with
// these macros see comments on that class.
#define EXPECT_TRUE(condition) \
#define GTEST_EXPECT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_NONFATAL_FAILURE_)
#define EXPECT_FALSE(condition) \
#define GTEST_EXPECT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_NONFATAL_FAILURE_)
#define ASSERT_TRUE(condition) \
#define GTEST_ASSERT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_FATAL_FAILURE_)
#define ASSERT_FALSE(condition) \
#define GTEST_ASSERT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_FATAL_FAILURE_)
// Define these macros to 1 to omit the definition of the corresponding
// EXPECT or ASSERT, which clashes with some users' own code.
#if !GTEST_DONT_DEFINE_EXPECT_TRUE
#define EXPECT_TRUE(condition) GTEST_EXPECT_TRUE(condition)
#endif
#if !GTEST_DONT_DEFINE_EXPECT_FALSE
#define EXPECT_FALSE(condition) GTEST_EXPECT_FALSE(condition)
#endif
#if !GTEST_DONT_DEFINE_ASSERT_TRUE
#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition)
#endif
#if !GTEST_DONT_DEFINE_ASSERT_FALSE
#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition)
#endif
// Macros for testing equalities and inequalities.
//
// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2
@@ -2246,10 +2282,9 @@ class GTEST_API_ ScopedTrace {
::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
__FILE__, __LINE__, (message))
// Compile-time assertion for type equality.
// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
// the same type. The value it returns is not interesting.
// StaticAssertTypeEq<type1, type2>() compiles if and only if type1 and type2
// are the same type. The value it returns is not interesting.
//
// Instead of making StaticAssertTypeEq a class template, we make it a
// function template that invokes a helper class template. This
@@ -2278,8 +2313,8 @@ class GTEST_API_ ScopedTrace {
//
// to cause a compiler error.
template <typename T1, typename T2>
bool StaticAssertTypeEq() {
(void)internal::StaticAssertTypeEqHelper<T1, T2>();
constexpr bool StaticAssertTypeEq() noexcept {
static_assert(std::is_same<T1, T2>::value, "T1 and T2 are not the same type");
return true;
}
@@ -2345,9 +2380,11 @@ bool StaticAssertTypeEq() {
// }
//
// GOOGLETEST_CM0011 DO NOT DELETE
#if !GTEST_DONT_DEFINE_TEST
#define TEST_F(test_fixture, test_name)\
GTEST_TEST_(test_fixture, test_name, test_fixture, \
::testing::internal::GetTypeId<test_fixture>())
#endif // !GTEST_DONT_DEFINE_TEST
// Returns a path to temporary directory.
// Tries to determine an appropriate directory for the platform.
@@ -2455,4 +2492,4 @@ inline int RUN_ALL_TESTS() {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_H_
@@ -33,8 +33,8 @@
// Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#include "gtest/gtest.h"
@@ -356,4 +356,4 @@ AssertionResult AssertPred5Helper(const char* pred_text,
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
@@ -31,8 +31,8 @@
// Google C++ Testing and Mocking Framework definitions useful in production code.
// GOOGLETEST_CM0003 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#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,
// use the FRIEND_TEST macro to declare your tests as friends of the
@@ -58,4 +58,4 @@
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
@@ -31,7 +31,7 @@
//
// ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#ifndef GOOGLETEST_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_
@@ -36,7 +36,7 @@
//
// ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#ifndef GOOGLETEST_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_
@@ -31,7 +31,7 @@
//
// ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#ifndef GOOGLETEST_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_
@@ -33,8 +33,8 @@
// death tests. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#ifndef GOOGLETEST_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"
@@ -301,4 +301,4 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
@@ -37,8 +37,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#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"
@@ -110,7 +110,7 @@ class GTEST_API_ FilePath {
const FilePath& base_name,
const char* extension);
// Returns true iff the path is "".
// Returns true if and only if the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns
@@ -195,7 +195,7 @@ class GTEST_API_ FilePath {
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
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
@@ -208,4 +208,4 @@ class GTEST_API_ FilePath {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
@@ -34,8 +34,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#include "gtest/internal/gtest-port.h"
@@ -53,6 +53,7 @@
#include <ctype.h>
#include <float.h>
#include <string.h>
#include <cstdint>
#include <iomanip>
#include <limits>
#include <map>
@@ -78,9 +79,20 @@
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
// Stringifies its argument.
#define GTEST_STRINGIFY_(name) #name
// Work around a bug in visual studio which doesn't accept code like this:
//
// #define GTEST_STRINGIFY_(name) #name
// #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ...
// MACRO(, x, y)
//
// Complaining about the argument to GTEST_STRINGIFY_ being empty.
// This is allowed by the spec.
#define GTEST_STRINGIFY_HELPER_(name, ...) #name
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
namespace proto2 { class Message; }
namespace proto2 {
class MessageLite;
}
namespace testing {
@@ -189,7 +201,7 @@ GTEST_API_ std::string DiffStrings(const std::string& left,
// expected_value: "5"
// actual_value: "6"
//
// The ignoring_case parameter is true iff the assertion is a
// The ignoring_case parameter is true if and only if the assertion is a
// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
// be inserted into the message.
GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
@@ -275,7 +287,7 @@ class FloatingPoint {
//
// See the following article for more details on ULP:
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
static const size_t kMaxUlps = 4;
static const uint32_t kMaxUlps = 4;
// Constructs a FloatingPoint from a raw floating-point number.
//
@@ -318,15 +330,15 @@ class FloatingPoint {
// Returns the sign bit of this number.
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
// Returns true iff this is NAN (not a number).
// Returns true if and only if this is NAN (not a number).
bool is_nan() const {
// It's a NAN if the exponent bits are all ones and the fraction
// bits are not entirely zeros.
return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
}
// Returns true iff this number is at most kMaxUlps ULP's away from
// rhs. In particular, this function:
// Returns true if and only if this number is at most kMaxUlps ULP's away
// from rhs. In particular, this function:
//
// - returns false if either number is (or both are) NAN.
// - treats really large numbers as almost equal to infinity.
@@ -508,6 +520,7 @@ struct SuiteApiResolver : T {
static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
int line_num) {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
SetUpTearDownSuiteFuncType test_case_fp =
GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
SetUpTearDownSuiteFuncType test_suite_fp =
@@ -519,10 +532,16 @@ struct SuiteApiResolver : T {
<< filename << ":" << line_num;
return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
#else
(void)(filename);
(void)(line_num);
return &T::SetUpTestSuite;
#endif
}
static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
int line_num) {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
SetUpTearDownSuiteFuncType test_case_fp =
GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
SetUpTearDownSuiteFuncType test_suite_fp =
@@ -534,6 +553,11 @@ struct SuiteApiResolver : T {
<< filename << ":" << line_num;
return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
#else
(void)(filename);
(void)(line_num);
return &T::TearDownTestSuite;
#endif
}
};
@@ -542,11 +566,11 @@ struct SuiteApiResolver : T {
//
// Arguments:
//
// test_suite_name: name of the test suite
// test_suite_name: name of the test suite
// name: name of the test
// 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.
// value_param text representation of the test's value parameter,
// value_param: text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class
@@ -566,8 +590,6 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
// and returns false. None of pstr, *pstr, and prefix can be NULL.
GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
@@ -607,8 +629,9 @@ class GTEST_API_ TypedTestSuitePState {
// Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise.
const char* VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests);
const char* VerifyRegisteredTestNames(const char* test_suite_name,
const char* file, int line,
const char* registered_tests);
private:
typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap;
@@ -662,7 +685,7 @@ struct NameGeneratorSelector {
};
template <typename NameGenerator>
void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {}
void GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}
template <typename NameGenerator, typename Types>
void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
@@ -729,7 +752,7 @@ class TypeParameterizedTest {
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, Types0> {
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
public:
static bool Register(const char* /*prefix*/, const CodeLocation&,
const char* /*case_name*/, const char* /*test_names*/,
@@ -740,6 +763,11 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> {
}
};
GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
CodeLocation code_location);
GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
const char* case_name);
// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()
// registers *all combinations* of 'Tests' and 'Types' with Google
// Test. The return value is insignificant - we just need to return
@@ -752,6 +780,7 @@ class TypeParameterizedTestSuite {
const char* test_names,
const std::vector<std::string>& type_names =
GenerateNames<DefaultNameGenerator, Types>()) {
RegisterTypeParameterizedTestSuiteInstantiation(case_name);
std::string test_name = StripTrailingSpaces(
GetPrefixUntilComma(test_names));
if (!state->TestExists(test_name)) {
@@ -781,7 +810,7 @@ class TypeParameterizedTestSuite {
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestSuite<Fixture, Templates0, Types> {
class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
public:
static bool Register(const char* /*prefix*/, const CodeLocation&,
const TypedTestSuitePState* /*state*/,
@@ -792,8 +821,6 @@ class TypeParameterizedTestSuite<Fixture, Templates0, Types> {
}
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// Returns the current OS stack trace as an std::string.
//
// The maximum number of stack frames to be included is specified by
@@ -825,6 +852,16 @@ struct GTEST_API_ ConstCharPtr {
const char* value;
};
// Helper for declaring std::string within 'if' statement
// in pre C++17 build environment.
struct TrueWithString {
TrueWithString() = default;
explicit TrueWithString(const char* str) : value(str) {}
explicit TrueWithString(const std::string& str) : value(str) {}
explicit operator bool() const { return true; }
std::string value;
};
// A simple Linear Congruential Generator for generating random
// numbers with a uniform distribution. Unlike rand() and srand(), it
// doesn't use global state (and therefore can't interfere with user
@@ -832,76 +869,54 @@ struct GTEST_API_ ConstCharPtr {
// but it's good enough for our purposes.
class GTEST_API_ Random {
public:
static const UInt32 kMaxRange = 1u << 31;
static const uint32_t kMaxRange = 1u << 31;
explicit Random(UInt32 seed) : state_(seed) {}
explicit Random(uint32_t seed) : state_(seed) {}
void Reseed(UInt32 seed) { state_ = seed; }
void Reseed(uint32_t seed) { state_ = seed; }
// Generates a random number from [0, range). Crashes if 'range' is
// 0 or greater than kMaxRange.
UInt32 Generate(UInt32 range);
uint32_t Generate(uint32_t range);
private:
UInt32 state_;
uint32_t state_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
};
// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
// compiler error iff T1 and T2 are different types.
template <typename T1, typename T2>
struct CompileAssertTypesEqual;
template <typename T>
struct CompileAssertTypesEqual<T, T> {
};
// Removes the reference from a type if it is a reference type,
// otherwise leaves it unchanged. This is the same as
// tr1::remove_reference, which is not widely available yet.
template <typename T>
struct RemoveReference { typedef T type; }; // NOLINT
template <typename T>
struct RemoveReference<T&> { typedef T type; }; // NOLINT
// A handy wrapper around RemoveReference that works when the argument
// T depends on template parameters.
#define GTEST_REMOVE_REFERENCE_(T) \
typename ::testing::internal::RemoveReference<T>::type
// Removes const from a type if it is a const type, otherwise leaves
// it unchanged. This is the same as tr1::remove_const, which is not
// widely available yet.
template <typename T>
struct RemoveConst { typedef T type; }; // NOLINT
template <typename T>
struct RemoveConst<const T> { typedef T type; }; // NOLINT
// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above
// definition to fail to remove the const in 'const int[3]' and 'const
// char[3][4]'. The following specialization works around the bug.
template <typename T, size_t N>
struct RemoveConst<const T[N]> {
typedef typename RemoveConst<T>::type type[N];
};
// A handy wrapper around RemoveConst that works when the argument
// T depends on template parameters.
#define GTEST_REMOVE_CONST_(T) \
typename ::testing::internal::RemoveConst<T>::type
// Turns const U&, U&, const U, and U all into U.
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
typename std::remove_const<typename std::remove_reference<T>::type>::type
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
// true iff T is type proto2::Message or a subclass of it.
// HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant
// that's true if and only if T has methods DebugString() and ShortDebugString()
// that return std::string.
template <typename T>
struct IsAProtocolMessage
: public bool_constant<
std::is_convertible<const T*, const ::proto2::Message*>::value> {
class HasDebugStringAndShortDebugString {
private:
template <typename C>
static auto CheckDebugString(C*) -> typename std::is_same<
std::string, decltype(std::declval<const C>().DebugString())>::type;
template <typename>
static std::false_type CheckDebugString(...);
template <typename C>
static auto CheckShortDebugString(C*) -> typename std::is_same<
std::string, decltype(std::declval<const C>().ShortDebugString())>::type;
template <typename>
static std::false_type CheckShortDebugString(...);
using HasDebugStringType = decltype(CheckDebugString<T>(nullptr));
using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr));
public:
static constexpr bool value =
HasDebugStringType::value && HasShortDebugStringType::value;
};
template <typename T>
constexpr bool HasDebugStringAndShortDebugString<T>::value;
// When the compiler sees expression IsContainerTest<C>(0), if C is an
// STL-style container class, the first overload of IsContainerTest
// will be viable (since both C::iterator* and C::const_iterator* are
@@ -967,7 +982,7 @@ template <typename C,
struct IsRecursiveContainerImpl;
template <typename C>
struct IsRecursiveContainerImpl<C, false> : public false_type {};
struct IsRecursiveContainerImpl<C, false> : public std::false_type {};
// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to
// obey the same inconsistencies as the IsContainerTest, namely check if
@@ -977,9 +992,9 @@ template <typename C>
struct IsRecursiveContainerImpl<C, true> {
using value_type = decltype(*std::declval<typename C::const_iterator>());
using type =
is_same<typename std::remove_const<
typename std::remove_reference<value_type>::type>::type,
C>;
std::is_same<typename std::remove_const<
typename std::remove_reference<value_type>::type>::type,
C>;
};
// IsRecursiveContainer<Type> is a unary compile-time predicate that
@@ -991,13 +1006,6 @@ struct IsRecursiveContainerImpl<C, true> {
template <typename C>
struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
// EnableIf<condition>::type is void when 'Cond' is true, and
// undefined when 'Cond' is false. To use SFINAE to make a function
// overload only apply when a particular expression is true, add
// "typename EnableIf<expression>::type* = 0" as the last parameter.
template<bool> struct EnableIf;
template<> struct EnableIf<true> { typedef void type; }; // NOLINT
// Utilities for native arrays.
// ArrayEq() compares two k-dimensional native arrays using the
@@ -1120,10 +1128,9 @@ class NativeArray {
}
private:
enum {
kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value
};
static_assert(!std::is_const<Element>::value, "Type must not be const");
static_assert(!std::is_reference<Element>::value,
"Type must not be a reference");
// Initializes this object with a copy of the input.
void InitCopy(const Element* array, size_t a_size) {
@@ -1144,8 +1151,6 @@ class NativeArray {
const Element* array_;
size_t size_;
void (NativeArray::*clone_)(const Element*, size_t);
GTEST_DISALLOW_ASSIGN_(NativeArray);
};
// Backport of std::index_sequence.
@@ -1169,32 +1174,44 @@ struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
// Backport of std::make_index_sequence.
// It uses O(ln(N)) instantiation depth.
template <size_t N>
struct MakeIndexSequence
: DoubleSequence<N % 2 == 1, typename MakeIndexSequence<N / 2>::type,
struct MakeIndexSequenceImpl
: DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
N / 2>::type {};
template <>
struct MakeIndexSequence<0> : IndexSequence<> {};
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
// FIXME: This implementation of ElemFromList is O(1) in instantiation depth,
// but it is O(N^2) in total instantiations. Not sure if this is the best
// tradeoff, as it will make it somewhat slow to compile.
template <typename T, size_t, size_t>
struct ElemFromListImpl {};
template <size_t N>
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
template <typename T, size_t I>
struct ElemFromListImpl<T, I, I> {
using type = T;
template <typename... T>
using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
template <size_t>
struct Ignore {
Ignore(...); // NOLINT
};
// Get the Nth element from T...
// It uses O(1) instantiation depth.
template <size_t N, typename I, typename... T>
struct ElemFromList;
template <typename>
struct ElemFromListImpl;
template <size_t... I>
struct ElemFromListImpl<IndexSequence<I...>> {
// We make Ignore a template to solve a problem with MSVC.
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
// MSVC doesn't understand how to deal with that pack expansion.
// Use `0 * I` to have a single instantiation of Ignore.
template <typename R>
static R Apply(Ignore<0 * I>..., R (*)(), ...);
};
template <size_t N, size_t... I, typename... T>
struct ElemFromList<N, IndexSequence<I...>, T...>
: ElemFromListImpl<T, N, I>... {};
template <size_t N, typename... T>
struct ElemFromList {
using type =
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
static_cast<T (*)()>(nullptr)...));
};
struct FlatTupleConstructTag {};
template <typename... T>
class FlatTuple;
@@ -1204,11 +1221,11 @@ struct FlatTupleElemBase;
template <typename... T, size_t I>
struct FlatTupleElemBase<FlatTuple<T...>, I> {
using value_type =
typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type,
T...>::type;
using value_type = typename ElemFromList<I, T...>::type;
FlatTupleElemBase() = default;
explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {}
template <typename Arg>
explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)
: value(std::forward<Arg>(t)) {}
value_type value;
};
@@ -1220,13 +1237,35 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
using Indices = IndexSequence<Idx...>;
FlatTupleBase() = default;
explicit FlatTupleBase(T... t)
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {}
template <typename... Args>
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
: FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},
std::forward<Args>(args))... {}
template <size_t I>
const typename ElemFromList<I, T...>::type& Get() const {
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
}
template <size_t I>
typename ElemFromList<I, T...>::type& Get() {
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
}
template <typename F>
auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
return std::forward<F>(f)(Get<Idx>()...);
}
template <typename F>
auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
return std::forward<F>(f)(Get<Idx>()...);
}
};
// Analog to std::tuple but with different tradeoffs.
// This class minimizes the template instantiation depth, thus allowing more
// elements that std::tuple would. std::tuple has been seen to require an
// elements than std::tuple would. std::tuple has been seen to require an
// instantiation depth of more than 10x the number of elements in some
// implementations.
// FlatTuple and ElemFromList are not recursive and have a fixed depth
@@ -1237,21 +1276,17 @@ template <typename... T>
class FlatTuple
: private FlatTupleBase<FlatTuple<T...>,
typename MakeIndexSequence<sizeof...(T)>::type> {
using Indices = typename FlatTuple::FlatTupleBase::Indices;
using Indices = typename FlatTupleBase<
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
public:
FlatTuple() = default;
explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {}
template <typename... Args>
explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)
: FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}
template <size_t I>
const typename ElemFromList<I, Indices, T...>::type& Get() const {
return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
template <size_t I>
typename ElemFromList<I, Indices, T...>::type& Get() {
return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
using FlatTuple::FlatTupleBase::Apply;
using FlatTuple::FlatTupleBase::Get;
};
// Utility functions to be called with static_assert to induce deprecation
@@ -1284,6 +1319,22 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
} // namespace internal
} // namespace testing
namespace std {
// Some standard library implementations use `struct tuple_size` and some use
// `class tuple_size`. Clang warns about the mismatch.
// https://reviews.llvm.org/D55466
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmismatched-tags"
#endif
template <typename... Ts>
struct tuple_size<testing::internal::FlatTuple<Ts...>>
: std::integral_constant<size_t, sizeof...(Ts)> {};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} // namespace std
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
::testing::internal::AssertHelper(result_type, file, line, message) \
= ::testing::Message()
@@ -1306,48 +1357,122 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
// Suppress MSVC warning 4072 (unreachable code) for the code following
// statement if it returns or throws (or doesn't return or throw in some
// situations).
// NOTE: The "else" is important to keep this expansion to prevent a top-level
// "else" from attaching to our "if".
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
if (::testing::internal::AlwaysTrue()) { statement; }
if (::testing::internal::AlwaysTrue()) { \
statement; \
} else /* NOLINT */ \
static_assert(true, "") // User must have a semicolon after expansion.
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::ConstCharPtr gtest_msg = "") { \
bool gtest_caught_expected = false; \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
catch (expected_exception const&) { \
gtest_caught_expected = true; \
} \
catch (...) { \
gtest_msg.value = \
"Expected: " #statement " throws an exception of type " \
#expected_exception ".\n Actual: it throws a different type."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
if (!gtest_caught_expected) { \
gtest_msg.value = \
"Expected: " #statement " throws an exception of type " \
#expected_exception ".\n Actual: it throws nothing."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
fail(gtest_msg.value)
#if GTEST_HAS_EXCEPTIONS
namespace testing {
namespace internal {
class NeverThrown {
public:
const char* what() const noexcept {
return "this exception should never be thrown";
}
};
} // namespace internal
} // namespace testing
#if GTEST_HAS_RTTI
#define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))
#else // GTEST_HAS_RTTI
#define GTEST_EXCEPTION_TYPE_(e) \
std::string { "an std::exception-derived error" }
#endif // GTEST_HAS_RTTI
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (typename std::conditional< \
std::is_same<typename std::remove_cv<typename std::remove_reference< \
expected_exception>::type>::type, \
std::exception>::value, \
const ::testing::internal::NeverThrown&, const std::exception&>::type \
e) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)
#endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::TrueWithString gtest_msg{}) { \
bool gtest_caught_expected = false; \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (expected_exception const&) { \
gtest_caught_expected = true; \
} \
GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (...) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws a different type."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
if (!gtest_caught_expected) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws nothing."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
} else /*NOLINT*/ \
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \
: fail(gtest_msg.value.c_str())
#if GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
catch (std::exception const& e) { \
gtest_msg.value = "it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()
#endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
if (::testing::internal::TrueWithString gtest_msg{}) { \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
catch (...) { \
gtest_msg.value = "it throws."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
fail("Expected: " #statement " doesn't throw an exception.\n" \
" Actual: it throws.")
fail(("Expected: " #statement " doesn't throw an exception.\n" \
" Actual: " + gtest_msg.value).c_str())
#define GTEST_TEST_ANY_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
@@ -1370,7 +1495,7 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual
// represenation of expression as it was passed into the EXPECT_TRUE.
// representation of expression as it was passed into the EXPECT_TRUE.
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar_ = \
@@ -1400,16 +1525,23 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
// Helper macro for defining tests.
#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \
static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \
"test_suite_name must not be empty"); \
static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \
"test_name must not be empty"); \
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
: public parent_class { \
public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
\
private: \
virtual void TestBody(); \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \
~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
\
private: \
void TestBody() override; \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
}; \
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
@@ -1425,4 +1557,4 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
test_suite_name, test_name)>); \
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
@@ -32,8 +32,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#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>
@@ -42,12 +42,14 @@
#include <memory>
#include <set>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h"
namespace testing {
// Input to a parameterized test name generator, describing a test parameter.
@@ -457,7 +459,7 @@ class ParameterizedTestSuiteInfoBase {
// Base part of test suite name for display purposes.
virtual const std::string& GetTestSuiteName() const = 0;
// Test case id to verify identity.
// Test suite id to verify identity.
virtual TypeId GetTestSuiteTypeId() const = 0;
// UnitTest class invokes this method to register tests in this
// test suite right before running them in RUN_ALL_TESTS macro.
@@ -472,6 +474,17 @@ class ParameterizedTestSuiteInfoBase {
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Report a the name of a test_suit as safe to ignore
// as the side effect of construction of this type.
struct GTEST_API_ MarkAsIgnored {
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
@@ -494,11 +507,11 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
CodeLocation code_location)
: test_suite_name_(name), code_location_(code_location) {}
// Test case base name for display purposes.
// Test suite base name for display purposes.
const std::string& GetTestSuiteName() const override {
return test_suite_name_;
}
// Test case id to verify identity.
// Test suite id to verify identity.
TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
// TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure.
@@ -507,9 +520,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test suite base name and DoBar is test base name.
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) {
tests_.push_back(std::shared_ptr<TestInfo>(
new TestInfo(test_suite_name, test_base_name, meta_factory)));
TestMetaFactoryBase<ParamType>* meta_factory,
CodeLocation code_location) {
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
test_suite_name, test_base_name, meta_factory, code_location)));
}
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator.
@@ -522,11 +536,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test suite
// test suites 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 than once on any single
// instance of a ParameterizedTestSuiteInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more than once.
void RegisterTests() override {
bool generated_instantiations = false;
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
std::shared_ptr<TestInfo> test_info = *test_it;
@@ -549,6 +565,8 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
generated_instantiations = true;
Message test_name_stream;
std::string param_name = name_func(
@@ -565,11 +583,14 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
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(
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
nullptr, // No type parameter.
PrintToString(*param_it).c_str(), code_location_,
PrintToString(*param_it).c_str(), test_info->code_location,
GetTestSuiteTypeId(),
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
@@ -577,6 +598,12 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
} // for param_it
} // for gen_it
} // for test_it
if (!generated_instantiations) {
// There are no generaotrs, or they all generate nothing ...
InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
!tests_.empty());
}
} // RegisterTests
private:
@@ -584,14 +611,17 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* a_test_suite_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_suite_base_name(a_test_suite_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 std::string test_suite_base_name;
const std::string test_base_name;
const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
const CodeLocation code_location;
};
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
// Records data received from INSTANTIATE_TEST_SUITE_P macros:
@@ -624,7 +654,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// Check for invalid characters
for (std::string::size_type index = 0; index < name.size(); ++index) {
if (!isalnum(name[index]) && name[index] != '_')
if (!IsAlNum(name[index]) && name[index] != '_')
return false;
}
@@ -714,6 +744,34 @@ class ParameterizedTestSuiteRegistry {
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
@@ -725,10 +783,15 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
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:
ValueArray(Ts... v) : v_{std::move(v)...} {}
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
@@ -744,6 +807,10 @@ class ValueArray {
FlatTuple<Ts...> v_;
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
template <typename... T>
class CartesianProductGenerator
: public ParamGeneratorInterface<::std::tuple<T...>> {
@@ -877,4 +944,4 @@ class CartesianProductHolder {
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
@@ -32,8 +32,8 @@
// This header file defines the GTEST_OS_* macro.
// 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_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#ifndef GOOGLETEST_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.
#ifdef __CYGWIN__
@@ -68,6 +68,7 @@
# define GTEST_OS_OS2 1
#elif defined __APPLE__
# define GTEST_OS_MAC 1
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1
# endif
@@ -102,6 +103,12 @@
# 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 // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
@@ -40,8 +40,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
// Environment-describing macros
// -----------------------------
@@ -190,23 +190,32 @@
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
// variable don't have to be used.
// GTEST_DISALLOW_ASSIGN_ - disables operator=.
// GTEST_DISALLOW_ASSIGN_ - disables copy operator=.
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
// GTEST_DISALLOW_MOVE_ASSIGN_ - disables move operator=.
// GTEST_DISALLOW_MOVE_AND_ASSIGN_ - disables move ctor and operator=.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
// suppressed (constant conditional).
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
// is suppressed.
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
// UniversalPrinter<absl::any> specializations.
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>
// or
// UniversalPrinter<absl::optional>
// specializations.
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
// Matcher<absl::string_view>
// specializations.
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
// UniversalPrinter<absl::variant>
// specializations.
//
// Synchronization:
// Mutex, MutexLock, ThreadLocal, GetThreadCount()
// - synchronization primitives.
//
// Template meta programming:
// IteratorTraits - partial implementation of std::iterator_traits, which
// is not available in libCstd when compiled with Sun C++.
//
//
// Regular expressions:
// RE - a simple regular expression class using the POSIX
// Extended Regular Expression syntax on UNIX-like platforms
@@ -228,8 +237,7 @@
//
// Integer types:
// TypeWithSize - maps an integer to a int type.
// Int32, UInt32, Int64, UInt64, TimeInMillis
// - integers of known sizes.
// TimeInMillis - integers of known sizes.
// BiggestInt - the biggest signed integer type.
//
// Command-line utilities:
@@ -240,7 +248,7 @@
// Environment variable utilities:
// GetEnv() - gets the value of an environment variable.
// BoolFromGTestEnv() - parses a bool environment variable.
// Int32FromGTestEnv() - parses an Int32 environment variable.
// Int32FromGTestEnv() - parses an int32_t environment variable.
// StringFromGTestEnv() - parses a string environment variable.
//
// Deprecation warnings:
@@ -253,7 +261,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>
#include <cerrno>
#include <cstdint>
#include <limits>
#include <type_traits>
#ifndef _WIN32_WCE
@@ -266,16 +277,15 @@
# include <TargetConditionals.h>
#endif
#include <algorithm> // NOLINT
#include <iostream> // NOLINT
#include <sstream> // NOLINT
#include <string> // NOLINT
#include <iostream> // NOLINT
#include <locale>
#include <memory>
#include <string> // NOLINT
#include <tuple>
#include <utility>
#include <vector> // NOLINT
#include "gtest/internal/gtest-port-arch.h"
#include "gtest/internal/custom/gtest-port.h"
#include "gtest/internal/gtest-port-arch.h"
#if !defined(GTEST_DEV_EMAIL_)
# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
@@ -349,6 +359,10 @@ typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.
typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif
#elif GTEST_OS_XTENSA
#include <unistd.h>
// Xtensa toolchains define strcasecmp in the string.h header instead of
// strings.h. string.h is already included.
#else
// This assumes that non-Windows OSes provide unistd.h. For OSes where this
// is not the case, we need to include headers that provide the functions
@@ -362,13 +376,14 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# include <android/api-level.h> // NOLINT
#endif
// Defines this to true iff Google Test can use POSIX regular expressions.
// Defines this to true if and only if Google Test can use POSIX regular
// expressions.
#ifndef GTEST_HAS_POSIX_RE
# if GTEST_OS_LINUX_ANDROID
// On Android, <regex.h> is only available starting with Gingerbread.
# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)
# else
# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS)
#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA)
# endif
#endif
@@ -403,7 +418,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// The user didn't tell us whether exceptions are enabled, so we need
// to figure it out.
# if defined(_MSC_VER) && defined(_CPPUNWIND)
// MSVC defines _CPPUNWIND to 1 iff exceptions are enabled.
// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__BORLANDC__)
// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS
@@ -414,16 +429,17 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# endif // _HAS_EXCEPTIONS
# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
# elif defined(__clang__)
// clang defines __EXCEPTIONS iff exceptions are enabled before clang 220714,
// but iff cleanups are enabled after that. In Obj-C++ files, there can be
// cleanups for ObjC exceptions which also need cleanups, even if C++ exceptions
// are disabled. clang has __has_feature(cxx_exceptions) which checks for C++
// exceptions starting at clang r206352, but which checked for cleanups prior to
// that. To reliably check for C++ exception availability with clang, check for
// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang
// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files,
// there can be cleanups for ObjC exceptions which also need cleanups, even if
// C++ exceptions are disabled. clang has __has_feature(cxx_exceptions) which
// checks for C++ exceptions starting at clang r206352, but which checked for
// cleanups prior to that. To reliably check for C++ exception availability with
// clang, check for
// __EXCEPTIONS && __has_feature(cxx_exceptions).
# define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions))
# elif defined(__GNUC__) && __EXCEPTIONS
// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__SUNPRO_CC)
// Sun Pro CC supports exceptions. However, there is no compile-time way of
@@ -431,7 +447,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// they are enabled unless the user tells us otherwise.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__IBMCPP__) && __EXCEPTIONS
// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__HP_aCC)
// Exception handling is in effect by default in HP aCC compiler. It has to
@@ -444,15 +460,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
#endif // GTEST_HAS_EXCEPTIONS
#if !defined(GTEST_HAS_STD_STRING)
// Even though we don't use this macro any longer, we keep it in case
// some clients still depend on it.
# define GTEST_HAS_STD_STRING 1
#elif !GTEST_HAS_STD_STRING
// The user told us that ::std::string isn't available.
# error "::std::string isn't available."
#endif // !defined(GTEST_HAS_STD_STRING)
#ifndef GTEST_HAS_STD_WSTRING
// The user didn't tell us whether ::std::wstring is available, so we need
// to figure it out.
@@ -461,7 +468,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// no support for it at least as recent as Froyo (2.2).
#define GTEST_HAS_STD_WSTRING \
(!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
GTEST_OS_HAIKU))
GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA))
#endif // GTEST_HAS_STD_WSTRING
@@ -472,13 +479,14 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# ifdef _MSC_VER
# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled.
#ifdef _CPPRTTI // MSVC defines this macro if and only if RTTI is enabled.
# define GTEST_HAS_RTTI 1
# else
# define GTEST_HAS_RTTI 0
# endif
// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
// Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is
// enabled.
# elif defined(__GNUC__)
# ifdef __GXX_RTTI
@@ -584,7 +592,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_HAS_STREAM_REDIRECTION
// By default, we assume that stream redirection is supported on all
// platforms except known mobile ones.
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
# define GTEST_HAS_STREAM_REDIRECTION 0
# else
# define GTEST_HAS_STREAM_REDIRECTION 1
@@ -678,16 +687,27 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif
// A macro to disallow operator=
// A macro to disallow copy operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_ASSIGN_(type) \
void operator=(type const &) = delete
type& operator=(type const &) = delete
// A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
type(type const &) = delete; \
GTEST_DISALLOW_ASSIGN_(type)
type(type const&) = delete; \
type& operator=(type const&) = delete
// A macro to disallow move operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_MOVE_ASSIGN_(type) \
type& operator=(type &&) noexcept = delete
// A macro to disallow move constructor and operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_MOVE_AND_ASSIGN_(type) \
type(type&&) noexcept = delete; \
type& operator=(type&&) noexcept = delete
// Tell the compiler to warn about unused return values for functions declared
// with this macro. The macro should be used on function declarations
@@ -858,30 +878,6 @@ class Secret;
// expression is false, compiler will issue an error containing this identifier.
#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h.
//
// This template is declared, but intentionally undefined.
template <typename T1, typename T2>
struct StaticAssertTypeEqHelper;
template <typename T>
struct StaticAssertTypeEqHelper<T, T> {
enum { value = true };
};
// Same as std::is_same<>.
template <typename T, typename U>
struct IsSame {
enum { value = false };
};
template <typename T>
struct IsSame<T, T> {
enum { value = true };
};
// Evaluates to the number of elements in 'array'.
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
// A helper for suppressing warnings on constant condition. It just
// returns 'condition'.
GTEST_API_ bool IsTrue(bool condition);
@@ -909,9 +905,9 @@ class GTEST_API_ RE {
// Returns the string representation of the regex.
const char* pattern() const { return pattern_; }
// FullMatch(str, re) returns true iff regular expression re matches
// the entire str.
// PartialMatch(str, re) returns true iff regular expression re
// FullMatch(str, re) returns true if and only if regular expression re
// matches the entire str.
// PartialMatch(str, re) returns true if and only if regular expression re
// matches a substring of str (including str itself).
static bool FullMatch(const ::std::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
@@ -938,8 +934,6 @@ class GTEST_API_ RE {
const char* full_pattern_; // For FullMatch();
# endif
GTEST_DISALLOW_ASSIGN_(RE);
};
#endif // GTEST_USES_PCRE
@@ -1029,19 +1023,6 @@ inline void FlushInfoLog() { fflush(nullptr); }
GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
<< gtest_error
// Adds reference to a type if it is not a reference type,
// otherwise leaves it unchanged. This is the same as
// tr1::add_reference, which is not widely available yet.
template <typename T>
struct AddReference { typedef T& type; }; // NOLINT
template <typename T>
struct AddReference<T&> { typedef T& type; }; // NOLINT
// A handy wrapper around AddReference that works when the argument T
// depends on template parameters.
#define GTEST_ADD_REFERENCE_(T) \
typename ::testing::internal::AddReference<T>::type
// Transforms "T" into "const T&" according to standard reference collapsing
// rules (this is only needed as a backport for C++98 compilers that do not
// support reference collapsing). Specifically, it transforms:
@@ -1266,7 +1247,8 @@ class GTEST_API_ AutoHandle {
void Reset(Handle handle);
private:
// Returns true iff the handle is a valid handle object that can be closed.
// Returns true if and only if the handle is a valid handle object that can be
// closed.
bool IsCloseable() const;
Handle handle_;
@@ -1368,7 +1350,8 @@ class ThreadWithParam : public ThreadWithParamBase {
// When non-NULL, used to block execution until the controller thread
// notifies.
Notification* const thread_can_start_;
bool finished_; // true iff we know that the thread function has finished.
bool finished_; // true if and only if we know that the thread function has
// finished.
pthread_t thread_; // The native thread object.
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
@@ -1633,7 +1616,7 @@ class ThreadLocal : public ThreadLocalBase {
class DefaultValueHolderFactory : public ValueHolderFactory {
public:
DefaultValueHolderFactory() {}
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); }
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
@@ -1642,7 +1625,7 @@ class ThreadLocal : public ThreadLocalBase {
class InstanceValueHolderFactory : public ValueHolderFactory {
public:
explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
virtual ValueHolder* MakeNewHolder() const {
ValueHolder* MakeNewHolder() const override {
return new ValueHolder(value_);
}
@@ -1842,7 +1825,7 @@ class GTEST_API_ ThreadLocal {
class DefaultValueHolderFactory : public ValueHolderFactory {
public:
DefaultValueHolderFactory() {}
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); }
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
@@ -1851,7 +1834,7 @@ class GTEST_API_ ThreadLocal {
class InstanceValueHolderFactory : public ValueHolderFactory {
public:
explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
virtual ValueHolder* MakeNewHolder() const {
ValueHolder* MakeNewHolder() const override {
return new ValueHolder(value_);
}
@@ -1921,47 +1904,12 @@ class GTEST_API_ ThreadLocal {
// we cannot detect it.
GTEST_API_ size_t GetThreadCount();
template <bool bool_value>
struct bool_constant {
typedef bool_constant<bool_value> type;
static const bool value = bool_value;
};
template <bool bool_value> const bool bool_constant<bool_value>::value;
typedef bool_constant<false> false_type;
typedef bool_constant<true> true_type;
template <typename T, typename U>
struct is_same : public false_type {};
template <typename T>
struct is_same<T, T> : public true_type {};
template <typename Iterator>
struct IteratorTraits {
typedef typename Iterator::value_type value_type;
};
template <typename T>
struct IteratorTraits<T*> {
typedef T value_type;
};
template <typename T>
struct IteratorTraits<const T*> {
typedef T value_type;
};
#if GTEST_OS_WINDOWS
# define GTEST_PATH_SEP_ "\\"
# define GTEST_HAS_ALT_PATH_SEP_ 1
// The biggest signed integer type the compiler supports.
typedef __int64 BiggestInt;
#else
# define GTEST_PATH_SEP_ "/"
# define GTEST_HAS_ALT_PATH_SEP_ 0
typedef long long BiggestInt; // NOLINT
#endif // GTEST_OS_WINDOWS
// Utilities for char.
@@ -1992,6 +1940,19 @@ inline bool IsUpper(char ch) {
inline bool IsXDigit(char ch) {
return isxdigit(static_cast<unsigned char>(ch)) != 0;
}
#ifdef __cpp_char8_t
inline bool IsXDigit(char8_t ch) {
return isxdigit(static_cast<unsigned char>(ch)) != 0;
}
#endif
inline bool IsXDigit(char16_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0;
}
inline bool IsXDigit(char32_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0;
}
inline bool IsXDigit(wchar_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0;
@@ -2026,16 +1987,16 @@ namespace posix {
typedef struct _stat StatStruct;
# ifdef __BORLANDC__
inline int IsATTY(int fd) { return isatty(fd); }
inline int DoIsATTY(int fd) { return isatty(fd); }
inline int StrCaseCmp(const char* s1, const char* s2) {
return stricmp(s1, s2);
}
inline char* StrDup(const char* src) { return strdup(src); }
# else // !__BORLANDC__
# if GTEST_OS_WINDOWS_MOBILE
inline int IsATTY(int /* fd */) { return 0; }
inline int DoIsATTY(int /* fd */) { return 0; }
# else
inline int IsATTY(int fd) { return _isatty(fd); }
inline int DoIsATTY(int fd) { return _isatty(fd); }
# endif // GTEST_OS_WINDOWS_MOBILE
inline int StrCaseCmp(const char* s1, const char* s2) {
return _stricmp(s1, s2);
@@ -2056,12 +2017,28 @@ inline bool IsDir(const StatStruct& st) {
}
# endif // GTEST_OS_WINDOWS_MOBILE
#elif GTEST_OS_ESP8266
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
inline int DoIsATTY(int fd) { return isatty(fd); }
inline int Stat(const char* path, StatStruct* buf) {
// stat function not implemented on ESP8266
return 0;
}
inline int StrCaseCmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2);
}
inline char* StrDup(const char* src) { return strdup(src); }
inline int RmDir(const char* dir) { return rmdir(dir); }
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#else
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
inline int IsATTY(int fd) { return isatty(fd); }
inline int DoIsATTY(int fd) { return isatty(fd); }
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
inline int StrCaseCmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2);
@@ -2072,23 +2049,39 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif // GTEST_OS_WINDOWS
inline int IsATTY(int fd) {
// DoIsATTY might change errno (for example ENOTTY in case you redirect stdout
// to a file on Linux), which is unexpected, so save the previous value, and
// restore it after the call.
int savedErrno = errno;
int isAttyValue = DoIsATTY(fd);
errno = savedErrno;
return isAttyValue;
}
// Functions deprecated by MSVC 8.0.
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
inline const char* StrNCpy(char* dest, const char* src, size_t n) {
return strncpy(dest, src, n);
}
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
// StrError() aren't needed on Windows CE at this time and thus not
// defined there.
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
!GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA
inline int ChDir(const char* dir) { return chdir(dir); }
#endif
inline FILE* FOpen(const char* path, const char* mode) {
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
struct wchar_codecvt : public std::codecvt<wchar_t, char, std::mbstate_t> {};
std::wstring_convert<wchar_codecvt> converter;
std::wstring wide_path = converter.from_bytes(path);
std::wstring wide_mode = converter.from_bytes(mode);
return _wfopen(wide_path.c_str(), wide_mode.c_str());
#else // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
return fopen(path, mode);
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
}
#if !GTEST_OS_WINDOWS_MOBILE
inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
@@ -2108,8 +2101,9 @@ inline int Close(int fd) { return close(fd); }
inline const char* StrError(int errnum) { return strerror(errnum); }
#endif
inline const char* GetEnv(const char* name) {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
// We are on Windows CE, which has no environment variables.
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
// We are on an embedded platform, which has no environment variables.
static_cast<void>(name); // To prevent 'unused argument' warning.
return nullptr;
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
@@ -2151,15 +2145,13 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_()
# define GTEST_SNPRINTF_ snprintf
#endif
// The maximum number a BiggestInt can represent. This definition
// works no matter BiggestInt is represented in one's complement or
// two's complement.
// The biggest signed integer type the compiler supports.
//
// We cannot rely on numeric_limits in STL, as __int64 and long long
// are not part of standard C++ and numeric_limits doesn't need to be
// defined for them.
const BiggestInt kMaxBiggestInt =
~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));
// long long is guaranteed to be at least 64-bits in C++11.
using BiggestInt = long long; // NOLINT
// The maximum number a BiggestInt can represent.
constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();
// This template class serves as a compile-time function from size to
// type. It maps a size in bytes to a primitive type with that
@@ -2184,40 +2176,27 @@ class TypeWithSize {
public:
// This prevents the user from using TypeWithSize<N> with incorrect
// values of N.
typedef void UInt;
using UInt = void;
};
// The specialization for size 4.
template <>
class TypeWithSize<4> {
public:
// unsigned int has size 4 in both gcc and MSVC.
//
// As base/basictypes.h doesn't compile on Windows, we cannot use
// uint32, uint64, and etc here.
typedef int Int;
typedef unsigned int UInt;
using Int = std::int32_t;
using UInt = std::uint32_t;
};
// The specialization for size 8.
template <>
class TypeWithSize<8> {
public:
#if GTEST_OS_WINDOWS
typedef __int64 Int;
typedef unsigned __int64 UInt;
#else
typedef long long Int; // NOLINT
typedef unsigned long long UInt; // NOLINT
#endif // GTEST_OS_WINDOWS
using Int = std::int64_t;
using UInt = std::uint64_t;
};
// Integer types of known sizes.
typedef TypeWithSize<4>::Int Int32;
typedef TypeWithSize<4>::UInt UInt32;
typedef TypeWithSize<8>::Int Int64;
typedef TypeWithSize<8>::UInt UInt64;
typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
using TimeInMillis = int64_t; // Represents time in milliseconds.
// Utilities for command line flags and environment variables.
@@ -2236,7 +2215,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
// Macros for declaring flags.
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
# define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
GTEST_API_ extern std::int32_t GTEST_FLAG(name)
# define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::std::string GTEST_FLAG(name)
@@ -2244,7 +2223,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
# define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GTEST_FLAG(name) = (default_val)
# define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val)
# define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
@@ -2259,12 +2238,13 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
// Parses 'str' for a 32-bit signed integer. If successful, writes the result
// to *value and returns true; otherwise leaves *value unchanged and returns
// false.
bool ParseInt32(const Message& src_text, const char* str, Int32* value);
GTEST_API_ bool ParseInt32(const Message& src_text, const char* str,
int32_t* value);
// Parses a bool/Int32/string from the environment variable
// Parses a bool/int32_t/string from the environment variable
// corresponding to the given Google Test flag.
bool BoolFromGTestEnv(const char* flag, bool default_val);
GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
GTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val);
std::string OutputFlagAlsoCheckEnvVar();
const char* StringFromGTestEnv(const char* flag, const char* default_val);
@@ -2291,4 +2271,119 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
#endif // !defined(GTEST_INTERNAL_DEPRECATED)
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#if GTEST_HAS_ABSL
// Always use absl::any for UniversalPrinter<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_ANY 1
#include "absl/types/any.h"
namespace testing {
namespace internal {
using Any = ::absl::any;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<any>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_ANY 1
#include <any>
namespace testing {
namespace internal {
using Any = ::std::any;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::any is not
// supported.
#endif // __has_include(<any>) && __cplusplus >= 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL
#if GTEST_HAS_ABSL
// Always use absl::optional for UniversalPrinter<> specializations if
// googletest is built with absl support.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
#include "absl/types/optional.h"
namespace testing {
namespace internal {
template <typename T>
using Optional = ::absl::optional<T>;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<optional>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
#include <optional>
namespace testing {
namespace internal {
template <typename T>
using Optional = ::std::optional<T>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::optional is not
// supported.
#endif // __has_include(<optional>) && __cplusplus >= 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL
#if GTEST_HAS_ABSL
// Always use absl::string_view for Matcher<> specializations if googletest
// is built with absl support.
# define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include "absl/strings/string_view.h"
namespace testing {
namespace internal {
using StringView = ::absl::string_view;
} // namespace internal
} // namespace testing
#else
# ifdef __has_include
# if __has_include(<string_view>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations.
# define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include <string_view>
namespace testing {
namespace internal {
using StringView = ::std::string_view;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::string_view is not
// supported.
# endif // __has_include(<string_view>) && __cplusplus >= 201703L
# endif // __has_include
#endif // GTEST_HAS_ABSL
#if GTEST_HAS_ABSL
// Always use absl::variant for UniversalPrinter<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_VARIANT 1
#include "absl/types/variant.h"
namespace testing {
namespace internal {
template <typename... T>
using Variant = ::absl::variant<T...>;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<variant>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_VARIANT 1
#include <variant>
namespace testing {
namespace internal {
template <typename... T>
using Variant = ::std::variant<T...>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::variant is not supported.
#endif // __has_include(<variant>) && __cplusplus >= 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
@@ -38,8 +38,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#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__
// string.h is not guaranteed to provide strcpy on C++ Builder.
@@ -47,6 +47,7 @@
#endif
#include <string.h>
#include <cstdint>
#include <string>
#include "gtest/internal/gtest-port.h"
@@ -94,7 +95,8 @@ class GTEST_API_ String {
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#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
// NULL C string is considered different to any non-NULL C string,
@@ -107,16 +109,16 @@ class GTEST_API_ String {
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same
// content.
// Compares two wide C strings. Returns true if and only if they have the
// same content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two C strings, ignoring case. Returns true iff they
// have the same content.
// Compares two C strings, ignoring case. Returns true if and only if
// they have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// 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,
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
// Compares two wide C strings, ignoring case. Returns true if and only if
// they have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
@@ -139,19 +141,22 @@ class GTEST_API_ String {
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Returns true iff the given string ends with the given suffix, ignoring
// case. Any string is considered to end with an empty suffix.
// Returns true if and only if the given string ends with the given suffix,
// ignoring case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
// Formats an int value as "%02d".
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".
static std::string FormatHexInt(int value);
// Formats an int value as "%X".
static std::string FormatHexUInt32(UInt32 value);
static std::string FormatHexUInt32(uint32_t value);
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
@@ -167,4 +172,4 @@ GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal
} // 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
@@ -1,314 +0,0 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of type lists we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Type utilities needed for implementing typed and type-parameterized
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently we support at most $n types in a list, and at most $n
// type-parameterized tests in one type-parameterized test suite.
// Please contact googletestframework@googlegroups.com if you need
// more.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
# if GTEST_HAS_CXXABI_H_
# include <cxxabi.h>
# elif defined(__HP_aCC)
# include <acxx_demangle.h>
# endif // GTEST_HASH_CXXABI_H_
namespace testing {
namespace internal {
// Canonicalizes a given name with respect to the Standard C++ Library.
// This handles removing the inline namespace within `std` that is
// used by various standard libraries (e.g., `std::__1`). Names outside
// of namespace std are returned unmodified.
inline std::string CanonicalizeForStdLibVersioning(std::string s) {
static const char prefix[] = "std::__";
if (s.compare(0, strlen(prefix), prefix) == 0) {
std::string::size_type end = s.find("::", strlen(prefix));
if (end != s.npos) {
// Erase everything between the initial `std` and the second `::`.
s.erase(strlen("std"), end - strlen("std"));
}
}
return s;
}
// GetTypeName<T>() returns a human-readable name of type T.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
# if GTEST_HAS_RTTI
const char* const name = typeid(T).name();
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it.
# if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
const std::string name_str(status == 0 ? readable_name : name);
free(readable_name);
return CanonicalizeForStdLibVersioning(name_str);
# else
return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else
return "<type>";
# endif // GTEST_HAS_RTTI
}
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
// type. This can be used as a compile-time assertion to ensure that
// two types are equal.
template <typename T1, typename T2>
struct AssertTypeEq;
template <typename T>
struct AssertTypeEq<T, T> {
typedef bool type;
};
// A unique type used as the default value for the arguments of class
// template Types. This allows us to simulate variadic templates
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
// support directly.
struct None {};
// The following family of struct and struct templates are used to
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
// represents a type list with N types (T1, T2, ..., and TN) in it.
// Except for Types0, every struct in the family has two member types:
// Head for the first type in the list, and Tail for the rest of the
// list.
// The empty type list.
struct Types0 {};
// Type lists of length 1, 2, 3, and so on.
template <typename T1>
struct Types1 {
typedef T1 Head;
typedef Types0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
struct Types$i {
typedef T1 Head;
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
};
]]
} // namespace internal
// We don't want to require the users to write TypesN<...> directly,
// as that would require them to count the length. Types<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Types<int>
// will appear as Types<int, None, None, ..., None> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Types<T1, ..., TN>, and Google Test will translate
// that to TypesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Types template.
$range i 1..n
template <$for i, [[typename T$i = internal::None]]>
struct Types {
typedef internal::Types$n<$for i, [[T$i]]> type;
};
template <>
struct Types<$for i, [[internal::None]]> {
typedef internal::Types0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[typename T$j]]>
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
typedef internal::Types$i<$for j, [[T$j]]> type;
};
]]
namespace internal {
# define GTEST_TEMPLATE_ template <typename T> class
// The template "selector" struct TemplateSel<Tmpl> is used to
// represent Tmpl, which must be a class template with one type
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
// as the type Tmpl<T>. This allows us to actually instantiate the
// template "selected" by TemplateSel<Tmpl>.
//
// This trick is necessary for simulating typedef for class templates,
// which C++ doesn't support directly.
template <GTEST_TEMPLATE_ Tmpl>
struct TemplateSel {
template <typename T>
struct Bind {
typedef Tmpl<T> type;
};
};
# define GTEST_BIND_(TmplSel, T) \
TmplSel::template Bind<T>::type
// A unique struct template used as the default value for the
// arguments of class template Templates. This allows us to simulate
// variadic templates (e.g. Templates<int>, Templates<int, double>,
// and etc), which C++ doesn't support directly.
template <typename T>
struct NoneT {};
// The following family of struct and struct templates are used to
// represent template lists. In particular, TemplatesN<T1, T2, ...,
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
// for Templates0, every struct in the family has two member types:
// Head for the selector of the first template in the list, and Tail
// for the rest of the list.
// The empty template list.
struct Templates0 {};
// Template lists of length 1, 2, 3, and so on.
template <GTEST_TEMPLATE_ T1>
struct Templates1 {
typedef TemplateSel<T1> Head;
typedef Templates0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates$i {
typedef TemplateSel<T1> Head;
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
};
]]
// We don't want to require the users to write TemplatesN<...> directly,
// as that would require them to count the length. Templates<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Templates<list>
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Templates<T1, ..., TN>, and Google Test will translate
// that to TemplatesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Templates template.
$range i 1..n
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
struct Templates {
typedef Templates$n<$for i, [[T$i]]> type;
};
template <>
struct Templates<$for i, [[NoneT]]> {
typedef Templates0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
typedef Templates$i<$for j, [[T$j]]> type;
};
]]
// The TypeList template makes it possible to use either a single type
// or a Types<...> list in TYPED_TEST_SUITE() and
// INSTANTIATE_TYPED_TEST_SUITE_P().
template <typename T>
struct TypeList {
typedef Types1<T> type;
};
$range i 1..n
template <$for i, [[typename T$i]]>
struct TypeList<Types<$for i, [[T$i]]> > {
typedef typename Types<$for i, [[T$i]]>::type type;
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
@@ -33,8 +33,8 @@
// prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests.
#ifndef GTEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_
#ifndef GOOGLETEST_SAMPLES_PRIME_TABLES_H_
#define GOOGLETEST_SAMPLES_PRIME_TABLES_H_
#include <algorithm>
@@ -43,7 +43,7 @@ class PrimeTable {
public:
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;
// Returns the smallest prime number greater than p; or returns -1
@@ -66,11 +66,11 @@ class OnTheFlyPrimeTable : public PrimeTable {
}
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;
}
return -1;
}
};
@@ -123,4 +123,4 @@ class PreCalculatedPrimeTable : public PrimeTable {
void operator=(const PreCalculatedPrimeTable& rhs);
};
#endif // GTEST_SAMPLES_PRIME_TABLES_H_
#endif // GOOGLETEST_SAMPLES_PRIME_TABLES_H_
@@ -41,7 +41,7 @@ int Factorial(int n) {
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) {
// Trivial case 1: small numbers
if (n <= 1) return false;
+4 -4
View File
@@ -29,13 +29,13 @@
// A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE1_H_
#define GTEST_SAMPLES_SAMPLE1_H_
#ifndef GOOGLETEST_SAMPLES_SAMPLE1_H_
#define GOOGLETEST_SAMPLES_SAMPLE1_H_
// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
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);
#endif // GTEST_SAMPLES_SAMPLE1_H_
#endif // GOOGLETEST_SAMPLES_SAMPLE1_H_
+3 -4
View File
@@ -29,8 +29,8 @@
// A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE2_H_
#define GTEST_SAMPLES_SAMPLE2_H_
#ifndef GOOGLETEST_SAMPLES_SAMPLE2_H_
#define GOOGLETEST_SAMPLES_SAMPLE2_H_
#include <string.h>
@@ -77,5 +77,4 @@ class MyString {
void Set(const char* c_string);
};
#endif // GTEST_SAMPLES_SAMPLE2_H_
#endif // GOOGLETEST_SAMPLES_SAMPLE2_H_
@@ -29,8 +29,8 @@
// A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
#define GTEST_SAMPLES_SAMPLE3_INL_H_
#ifndef GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
#define GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
#include <stddef.h>
@@ -169,4 +169,4 @@ class Queue {
const Queue& operator = (const Queue&);
};
#endif // GTEST_SAMPLES_SAMPLE3_INL_H_
#endif // GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
+3 -3
View File
@@ -28,8 +28,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE4_H_
#define GTEST_SAMPLES_SAMPLE4_H_
#ifndef GOOGLETEST_SAMPLES_SAMPLE4_H_
#define GOOGLETEST_SAMPLES_SAMPLE4_H_
// A simple monotonic counter.
class Counter {
@@ -50,4 +50,4 @@ class Counter {
void Print() const;
};
#endif // GTEST_SAMPLES_SAMPLE4_H_
#endif // GOOGLETEST_SAMPLES_SAMPLE4_H_
@@ -73,8 +73,6 @@ class PrimeTableTest : public testing::Test {
PrimeTable* const table_;
};
#if GTEST_HAS_TYPED_TEST
using testing::Types;
// Google Test offers two ways for reusing tests for different types.
@@ -134,10 +132,6 @@ TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
// in the type list specified in TYPED_TEST_SUITE. Sit back and be
// 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;
// Sometimes, however, you don't yet know all the types that you want
@@ -220,5 +214,4 @@ INSTANTIATE_TYPED_TEST_SUITE_P(OnTheFlyAndPreCalculated, // Instance name
PrimeTableTest2, // Test case name
PrimeTableImplementations); // Type list
#endif // GTEST_HAS_TYPED_TEST_P
} // namespace
@@ -135,10 +135,10 @@ int main(int argc, char **argv) {
// 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.
int unexpectedly_failed_tests = 0;
for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
const TestCase& test_case = *unit_test.GetTestCase(i);
for (int j = 0; j < test_case.total_test_count(); ++j) {
const TestInfo& test_info = *test_case.GetTestInfo(j);
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
const testing::TestSuite& test_suite = *unit_test.GetTestSuite(i);
for (int j = 0; j < test_suite.total_test_count(); ++j) {
const TestInfo& test_info = *test_suite.GetTestInfo(j);
// Counts failed tests that were not meant to fail (those without
// 'Fails' in the name).
if (test_info.result()->Failed() &&
@@ -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.
+13 -9
View File
@@ -172,7 +172,6 @@ def FuseGTestH(gtest_root, output_dir):
output_file.write(line)
ProcessFile(GTEST_H_SEED)
ProcessFile(GTEST_SPI_H_SEED)
output_file.close()
@@ -194,15 +193,20 @@ def FuseGTestAllCcToFile(gtest_root, output_file):
for line in open(os.path.join(gtest_root, gtest_source_file), 'r'):
m = INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# It's '#include "gtest/foo.h"'.
# We treat it as '#include "gtest/gtest.h"', as all other
# gtest headers are being fused into gtest.h and cannot be
# #included directly.
if 'include/' + m.group(1) == GTEST_SPI_H_SEED:
# It's '#include "gtest/gtest-spi.h"'. This file is not
# #included by "gtest/gtest.h", so we need to process it.
ProcessFile(GTEST_SPI_H_SEED)
else:
# It's '#include "gtest/foo.h"' where foo is not gtest-spi.
# We treat it as '#include "gtest/gtest.h"', as all other
# gtest headers are being fused into gtest.h and cannot be
# #included directly.
# There is no need to #include "gtest/gtest.h" more than once.
if not GTEST_H_SEED in processed_files:
processed_files.add(GTEST_H_SEED)
output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,))
# There is no need to #include "gtest/gtest.h" more than once.
if not GTEST_H_SEED in processed_files:
processed_files.add(GTEST_H_SEED)
output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,))
else:
m = INCLUDE_SRC_FILE_REGEX.match(line)
if m:
+21 -18
View File
@@ -78,7 +78,7 @@ def HeaderPreamble(n):
}
return (
"""// Copyright 2006, Google Inc.
"""// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -111,6 +111,8 @@ def HeaderPreamble(n):
// '%(command)s'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
@@ -246,8 +248,10 @@ AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
impl += ' << ") evaluates to false, where"'
impl += Iter(n, """
<< "\\n" << e%s << " evaluates to " << v%s""")
impl += Iter(
n, """
<< "\\n" << e%s << " evaluates to " << ::testing::PrintToString(v%s)"""
)
impl += """;
}
@@ -333,7 +337,7 @@ def UnitTestPreamble():
}
return (
"""// Copyright 2006, Google Inc.
"""// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -427,7 +431,7 @@ def TestsForArity(n):
}
tests = (
"""// Sample functions/functors for testing %(arity)s predicate assertions.
"""// Sample functions/functors for testing %(arity)s predicate assertions.
// A %(arity)s predicate function.
template <%(types)s>
@@ -435,9 +439,8 @@ bool PredFunction%(n)s(%(tvs)s) {
return %(v_sum)s > 0;
}
// The following two functions are needed to circumvent a bug in
// gcc 2.95.3, which sometimes has problem with the above template
// function.
// The following two functions are needed because a compiler doesn't have
// a context yet to know which template function must be instantiated.
bool PredFunction%(n)sInt(%(int_vs)s) {
return %(v_sum)s > 0;
}
@@ -510,7 +513,7 @@ struct PredFormatFunctor%(n)s {
class Predicate%(n)sTest : public testing::Test {
protected:
virtual void SetUp() {
void SetUp() override {
expected_to_finish_ = true;
finished_ = false;""" % DEFS
@@ -520,7 +523,7 @@ class Predicate%(n)sTest : public testing::Test {
"""
tests += """
virtual void TearDown() {
void TearDown() override {
// Verifies that each of the predicate's arguments was evaluated
// 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_;
// true iff the test function did run to finish.
// true if and only if the test function did run to finish.
static bool finished_;
""" % DEFS
@@ -572,12 +575,12 @@ typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
"""Returns the test for a predicate assertion macro.
Args:
use_format: true iff the assertion is a *_PRED_FORMAT*.
use_assert: true iff the assertion is a ASSERT_*.
expect_failure: true iff the assertion is expected to fail.
use_functor: true iff the first argument of the assertion is
use_format: true if and only if the assertion is a *_PRED_FORMAT*.
use_assert: true if and only if the assertion is a ASSERT_*.
expect_failure: true if and only if the assertion is expected to fail.
use_functor: true if and only if the first argument of the assertion is
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.
Example:
@@ -588,7 +591,7 @@ typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
if use_assert:
assrt = 'ASSERT' # 'assert' is reserved, so we cannot use
# that identifier here.
# that identifier here.
else:
assrt = 'EXPECT'
View File
-855
View File
@@ -1,855 +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.
"""pump v0.2.0 - Pretty Useful for Meta Programming.
A tool for preprocessor meta programming. Useful for generating
repetitive boilerplate code. Especially useful for writing C++
classes, functions, macros, and templates that need to work with
various number of arguments.
USAGE:
pump.py SOURCE_FILE
EXAMPLES:
pump.py foo.cc.pump
Converts foo.cc.pump to foo.cc.
GRAMMAR:
CODE ::= ATOMIC_CODE*
ATOMIC_CODE ::= $var ID = EXPRESSION
| $var ID = [[ CODE ]]
| $range ID EXPRESSION..EXPRESSION
| $for ID SEPARATOR [[ CODE ]]
| $($)
| $ID
| $(EXPRESSION)
| $if EXPRESSION [[ CODE ]] ELSE_BRANCH
| [[ CODE ]]
| RAW_CODE
SEPARATOR ::= RAW_CODE | EMPTY
ELSE_BRANCH ::= $else [[ CODE ]]
| $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
| EMPTY
EXPRESSION has Python syntax.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sys
TOKEN_TABLE = [
(re.compile(r'\$var\s+'), '$var'),
(re.compile(r'\$elif\s+'), '$elif'),
(re.compile(r'\$else\s+'), '$else'),
(re.compile(r'\$for\s+'), '$for'),
(re.compile(r'\$if\s+'), '$if'),
(re.compile(r'\$range\s+'), '$range'),
(re.compile(r'\$[_A-Za-z]\w*'), '$id'),
(re.compile(r'\$\(\$\)'), '$($)'),
(re.compile(r'\$'), '$'),
(re.compile(r'\[\[\n?'), '[['),
(re.compile(r'\]\]\n?'), ']]'),
]
class Cursor:
"""Represents a position (line and column) in a text file."""
def __init__(self, line=-1, column=-1):
self.line = line
self.column = column
def __eq__(self, rhs):
return self.line == rhs.line and self.column == rhs.column
def __ne__(self, rhs):
return not self == rhs
def __lt__(self, rhs):
return self.line < rhs.line or (
self.line == rhs.line and self.column < rhs.column)
def __le__(self, rhs):
return self < rhs or self == rhs
def __gt__(self, rhs):
return rhs < self
def __ge__(self, rhs):
return rhs <= self
def __str__(self):
if self == Eof():
return 'EOF'
else:
return '%s(%s)' % (self.line + 1, self.column)
def __add__(self, offset):
return Cursor(self.line, self.column + offset)
def __sub__(self, offset):
return Cursor(self.line, self.column - offset)
def Clone(self):
"""Returns a copy of self."""
return Cursor(self.line, self.column)
# Special cursor to indicate the end-of-file.
def Eof():
"""Returns the special cursor to denote the end-of-file."""
return Cursor(-1, -1)
class Token:
"""Represents a token in a Pump source file."""
def __init__(self, start=None, end=None, value=None, token_type=None):
if start is None:
self.start = Eof()
else:
self.start = start
if end is None:
self.end = Eof()
else:
self.end = end
self.value = value
self.token_type = token_type
def __str__(self):
return 'Token @%s: \'%s\' type=%s' % (
self.start, self.value, self.token_type)
def Clone(self):
"""Returns a copy of self."""
return Token(self.start.Clone(), self.end.Clone(), self.value,
self.token_type)
def StartsWith(lines, pos, string):
"""Returns True iff the given position in lines starts with 'string'."""
return lines[pos.line][pos.column:].startswith(string)
def FindFirstInLine(line, token_table):
best_match_start = -1
for (regex, token_type) in token_table:
m = regex.search(line)
if m:
# We found regex in lines
if best_match_start < 0 or m.start() < best_match_start:
best_match_start = m.start()
best_match_length = m.end() - m.start()
best_match_token_type = token_type
if best_match_start < 0:
return None
return (best_match_start, best_match_length, best_match_token_type)
def FindFirst(lines, token_table, cursor):
"""Finds the first occurrence of any string in strings in lines."""
start = cursor.Clone()
cur_line_number = cursor.line
for line in lines[start.line:]:
if cur_line_number == start.line:
line = line[start.column:]
m = FindFirstInLine(line, token_table)
if m:
# We found a regex in line.
(start_column, length, token_type) = m
if cur_line_number == start.line:
start_column += start.column
found_start = Cursor(cur_line_number, start_column)
found_end = found_start + length
return MakeToken(lines, found_start, found_end, token_type)
cur_line_number += 1
# We failed to find str in lines
return None
def SubString(lines, start, end):
"""Returns a substring in lines."""
if end == Eof():
end = Cursor(len(lines) - 1, len(lines[-1]))
if start >= end:
return ''
if start.line == end.line:
return lines[start.line][start.column:end.column]
result_lines = ([lines[start.line][start.column:]] +
lines[start.line + 1:end.line] +
[lines[end.line][:end.column]])
return ''.join(result_lines)
def StripMetaComments(str):
"""Strip meta comments from each line in the given string."""
# First, completely remove lines containing nothing but a meta
# comment, including the trailing \n.
str = re.sub(r'^\s*\$\$.*\n', '', str)
# Then, remove meta comments from contentful lines.
return re.sub(r'\s*\$\$.*', '', str)
def MakeToken(lines, start, end, token_type):
"""Creates a new instance of Token."""
return Token(start, end, SubString(lines, start, end), token_type)
def ParseToken(lines, pos, regex, token_type):
line = lines[pos.line][pos.column:]
m = regex.search(line)
if m and not m.start():
return MakeToken(lines, pos, pos + m.end(), token_type)
else:
print 'ERROR: %s expected at %s.' % (token_type, pos)
sys.exit(1)
ID_REGEX = re.compile(r'[_A-Za-z]\w*')
EQ_REGEX = re.compile(r'=')
REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
WHITE_SPACE_REGEX = re.compile(r'\s')
DOT_DOT_REGEX = re.compile(r'\.\.')
def Skip(lines, pos, regex):
line = lines[pos.line][pos.column:]
m = re.search(regex, line)
if m and not m.start():
return pos + m.end()
else:
return pos
def SkipUntil(lines, pos, regex, token_type):
line = lines[pos.line][pos.column:]
m = re.search(regex, line)
if m:
return pos + m.start()
else:
print ('ERROR: %s expected on line %s after column %s.' %
(token_type, pos.line + 1, pos.column))
sys.exit(1)
def ParseExpTokenInParens(lines, pos):
def ParseInParens(pos):
pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
pos = Skip(lines, pos, r'\(')
pos = Parse(pos)
pos = Skip(lines, pos, r'\)')
return pos
def Parse(pos):
pos = SkipUntil(lines, pos, r'\(|\)', ')')
if SubString(lines, pos, pos + 1) == '(':
pos = Parse(pos + 1)
pos = Skip(lines, pos, r'\)')
return Parse(pos)
else:
return pos
start = pos.Clone()
pos = ParseInParens(pos)
return MakeToken(lines, start, pos, 'exp')
def RStripNewLineFromToken(token):
if token.value.endswith('\n'):
return Token(token.start, token.end, token.value[:-1], token.token_type)
else:
return token
def TokenizeLines(lines, pos):
while True:
found = FindFirst(lines, TOKEN_TABLE, pos)
if not found:
yield MakeToken(lines, pos, Eof(), 'code')
return
if found.start == pos:
prev_token = None
prev_token_rstripped = None
else:
prev_token = MakeToken(lines, pos, found.start, 'code')
prev_token_rstripped = RStripNewLineFromToken(prev_token)
if found.token_type == '$var':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
yield eq_token
pos = Skip(lines, eq_token.end, r'\s*')
if SubString(lines, pos, pos + 2) != '[[':
exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
yield exp_token
pos = Cursor(exp_token.end.line + 1, 0)
elif found.token_type == '$for':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
elif found.token_type == '$range':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
yield MakeToken(lines, pos, dots_pos, 'exp')
yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
pos = dots_pos + 2
new_pos = Cursor(pos.line + 1, 0)
yield MakeToken(lines, pos, new_pos, 'exp')
pos = new_pos
elif found.token_type == '$':
if prev_token:
yield prev_token
yield found
exp_token = ParseExpTokenInParens(lines, found.end)
yield exp_token
pos = exp_token.end
elif (found.token_type == ']]' or found.token_type == '$if' or
found.token_type == '$elif' or found.token_type == '$else'):
if prev_token_rstripped:
yield prev_token_rstripped
yield found
pos = found.end
else:
if prev_token:
yield prev_token
yield found
pos = found.end
def Tokenize(s):
"""A generator that yields the tokens in the given string."""
if s != '':
lines = s.splitlines(True)
for token in TokenizeLines(lines, Cursor(0, 0)):
yield token
class CodeNode:
def __init__(self, atomic_code_list=None):
self.atomic_code = atomic_code_list
class VarNode:
def __init__(self, identifier=None, atomic_code=None):
self.identifier = identifier
self.atomic_code = atomic_code
class RangeNode:
def __init__(self, identifier=None, exp1=None, exp2=None):
self.identifier = identifier
self.exp1 = exp1
self.exp2 = exp2
class ForNode:
def __init__(self, identifier=None, sep=None, code=None):
self.identifier = identifier
self.sep = sep
self.code = code
class ElseNode:
def __init__(self, else_branch=None):
self.else_branch = else_branch
class IfNode:
def __init__(self, exp=None, then_branch=None, else_branch=None):
self.exp = exp
self.then_branch = then_branch
self.else_branch = else_branch
class RawCodeNode:
def __init__(self, token=None):
self.raw_code = token
class LiteralDollarNode:
def __init__(self, token):
self.token = token
class ExpNode:
def __init__(self, token, python_exp):
self.token = token
self.python_exp = python_exp
def PopFront(a_list):
head = a_list[0]
a_list[:1] = []
return head
def PushFront(a_list, elem):
a_list[:0] = [elem]
def PopToken(a_list, token_type=None):
token = PopFront(a_list)
if token_type is not None and token.token_type != token_type:
print 'ERROR: %s expected at %s' % (token_type, token.start)
print 'ERROR: %s found instead' % (token,)
sys.exit(1)
return token
def PeekToken(a_list):
if not a_list:
return None
return a_list[0]
def ParseExpNode(token):
python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
return ExpNode(token, python_exp)
def ParseElseNode(tokens):
def Pop(token_type=None):
return PopToken(tokens, token_type)
next = PeekToken(tokens)
if not next:
return None
if next.token_type == '$else':
Pop('$else')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return code_node
elif next.token_type == '$elif':
Pop('$elif')
exp = Pop('code')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
inner_else_node = ParseElseNode(tokens)
return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
elif not next.value.strip():
Pop('code')
return ParseElseNode(tokens)
else:
return None
def ParseAtomicCodeNode(tokens):
def Pop(token_type=None):
return PopToken(tokens, token_type)
head = PopFront(tokens)
t = head.token_type
if t == 'code':
return RawCodeNode(head)
elif t == '$var':
id_token = Pop('id')
Pop('=')
next = PeekToken(tokens)
if next.token_type == 'exp':
exp_token = Pop()
return VarNode(id_token, ParseExpNode(exp_token))
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return VarNode(id_token, code_node)
elif t == '$for':
id_token = Pop('id')
next_token = PeekToken(tokens)
if next_token.token_type == 'code':
sep_token = next_token
Pop('code')
else:
sep_token = None
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return ForNode(id_token, sep_token, code_node)
elif t == '$if':
exp_token = Pop('code')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
else_node = ParseElseNode(tokens)
return IfNode(ParseExpNode(exp_token), code_node, else_node)
elif t == '$range':
id_token = Pop('id')
exp1_token = Pop('exp')
Pop('..')
exp2_token = Pop('exp')
return RangeNode(id_token, ParseExpNode(exp1_token),
ParseExpNode(exp2_token))
elif t == '$id':
return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
elif t == '$($)':
return LiteralDollarNode(head)
elif t == '$':
exp_token = Pop('exp')
return ParseExpNode(exp_token)
elif t == '[[':
code_node = ParseCodeNode(tokens)
Pop(']]')
return code_node
else:
PushFront(tokens, head)
return None
def ParseCodeNode(tokens):
atomic_code_list = []
while True:
if not tokens:
break
atomic_code_node = ParseAtomicCodeNode(tokens)
if atomic_code_node:
atomic_code_list.append(atomic_code_node)
else:
break
return CodeNode(atomic_code_list)
def ParseToAST(pump_src_text):
"""Convert the given Pump source text into an AST."""
tokens = list(Tokenize(pump_src_text))
code_node = ParseCodeNode(tokens)
return code_node
class Env:
def __init__(self):
self.variables = []
self.ranges = []
def Clone(self):
clone = Env()
clone.variables = self.variables[:]
clone.ranges = self.ranges[:]
return clone
def PushVariable(self, var, value):
# If value looks like an int, store it as an int.
try:
int_value = int(value)
if ('%s' % int_value) == value:
value = int_value
except Exception:
pass
self.variables[:0] = [(var, value)]
def PopVariable(self):
self.variables[:1] = []
def PushRange(self, var, lower, upper):
self.ranges[:0] = [(var, lower, upper)]
def PopRange(self):
self.ranges[:1] = []
def GetValue(self, identifier):
for (var, value) in self.variables:
if identifier == var:
return value
print 'ERROR: meta variable %s is undefined.' % (identifier,)
sys.exit(1)
def EvalExp(self, exp):
try:
result = eval(exp.python_exp)
except Exception, e:
print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
print ('ERROR: failed to evaluate meta expression %s at %s' %
(exp.python_exp, exp.token.start))
sys.exit(1)
return result
def GetRange(self, identifier):
for (var, lower, upper) in self.ranges:
if identifier == var:
return (lower, upper)
print 'ERROR: range %s is undefined.' % (identifier,)
sys.exit(1)
class Output:
def __init__(self):
self.string = ''
def GetLastLine(self):
index = self.string.rfind('\n')
if index < 0:
return ''
return self.string[index + 1:]
def Append(self, s):
self.string += s
def RunAtomicCode(env, node, output):
if isinstance(node, VarNode):
identifier = node.identifier.value.strip()
result = Output()
RunAtomicCode(env.Clone(), node.atomic_code, result)
value = result.string
env.PushVariable(identifier, value)
elif isinstance(node, RangeNode):
identifier = node.identifier.value.strip()
lower = int(env.EvalExp(node.exp1))
upper = int(env.EvalExp(node.exp2))
env.PushRange(identifier, lower, upper)
elif isinstance(node, ForNode):
identifier = node.identifier.value.strip()
if node.sep is None:
sep = ''
else:
sep = node.sep.value
(lower, upper) = env.GetRange(identifier)
for i in range(lower, upper + 1):
new_env = env.Clone()
new_env.PushVariable(identifier, i)
RunCode(new_env, node.code, output)
if i != upper:
output.Append(sep)
elif isinstance(node, RawCodeNode):
output.Append(node.raw_code.value)
elif isinstance(node, IfNode):
cond = env.EvalExp(node.exp)
if cond:
RunCode(env.Clone(), node.then_branch, output)
elif node.else_branch is not None:
RunCode(env.Clone(), node.else_branch, output)
elif isinstance(node, ExpNode):
value = env.EvalExp(node)
output.Append('%s' % (value,))
elif isinstance(node, LiteralDollarNode):
output.Append('$')
elif isinstance(node, CodeNode):
RunCode(env.Clone(), node, output)
else:
print 'BAD'
print node
sys.exit(1)
def RunCode(env, code_node, output):
for atomic_code in code_node.atomic_code:
RunAtomicCode(env, atomic_code, output)
def IsSingleLineComment(cur_line):
return '//' in cur_line
def IsInPreprocessorDirective(prev_lines, cur_line):
if cur_line.lstrip().startswith('#'):
return True
return prev_lines and prev_lines[-1].endswith('\\')
def WrapComment(line, output):
loc = line.find('//')
before_comment = line[:loc].rstrip()
if before_comment == '':
indent = loc
else:
output.append(before_comment)
indent = len(before_comment) - len(before_comment.lstrip())
prefix = indent*' ' + '// '
max_len = 80 - len(prefix)
comment = line[loc + 2:].strip()
segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
cur_line = ''
for seg in segs:
if len((cur_line + seg).rstrip()) < max_len:
cur_line += seg
else:
if cur_line.strip() != '':
output.append(prefix + cur_line.rstrip())
cur_line = seg.lstrip()
if cur_line.strip() != '':
output.append(prefix + cur_line.strip())
def WrapCode(line, line_concat, output):
indent = len(line) - len(line.lstrip())
prefix = indent*' ' # Prefix of the current line
max_len = 80 - indent - len(line_concat) # Maximum length of the current line
new_prefix = prefix + 4*' ' # Prefix of a continuation line
new_max_len = max_len - 4 # Maximum length of a continuation line
# Prefers to wrap a line after a ',' or ';'.
segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
cur_line = '' # The current line without leading spaces.
for seg in segs:
# If the line is still too long, wrap at a space.
while cur_line == '' and len(seg.strip()) > max_len:
seg = seg.lstrip()
split_at = seg.rfind(' ', 0, max_len)
output.append(prefix + seg[:split_at].strip() + line_concat)
seg = seg[split_at + 1:]
prefix = new_prefix
max_len = new_max_len
if len((cur_line + seg).rstrip()) < max_len:
cur_line = (cur_line + seg).lstrip()
else:
output.append(prefix + cur_line.rstrip() + line_concat)
prefix = new_prefix
max_len = new_max_len
cur_line = seg.lstrip()
if cur_line.strip() != '':
output.append(prefix + cur_line.strip())
def WrapPreprocessorDirective(line, output):
WrapCode(line, ' \\', output)
def WrapPlainCode(line, output):
WrapCode(line, '', output)
def IsMultiLineIWYUPragma(line):
return re.search(r'/\* IWYU pragma: ', line)
def IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
re.match(r'^#include\s', line) or
# Don't break IWYU pragmas, either; that causes iwyu.py problems.
re.search(r'// IWYU pragma: ', line))
def WrapLongLine(line, output):
line = line.rstrip()
if len(line) <= 80:
output.append(line)
elif IsSingleLineComment(line):
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines,
# includes and IWYU pragmas.
output.append(line)
else:
WrapComment(line, output)
elif IsInPreprocessorDirective(output, line):
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines,
# includes and IWYU pragmas.
output.append(line)
else:
WrapPreprocessorDirective(line, output)
elif IsMultiLineIWYUPragma(line):
output.append(line)
else:
WrapPlainCode(line, output)
def BeautifyCode(string):
lines = string.splitlines()
output = []
for line in lines:
WrapLongLine(line, output)
output2 = [line.rstrip() for line in output]
return '\n'.join(output2) + '\n'
def ConvertFromPumpSource(src_text):
"""Return the text generated from the given Pump source text."""
ast = ParseToAST(StripMetaComments(src_text))
output = Output()
RunCode(Env(), ast, output)
return BeautifyCode(output.string)
def main(argv):
if len(argv) == 1:
print __doc__
sys.exit(1)
file_path = argv[-1]
output_str = ConvertFromPumpSource(file(file_path, 'r').read())
if file_path.endswith('.pump'):
output_file_path = file_path[:-5]
else:
output_file_path = '-'
if output_file_path == '-':
print output_str,
else:
output_file = file(output_file_path, 'w')
output_file.write('// This file was GENERATED by command:\n')
output_file.write('// %s %s\n' %
(os.path.basename(__file__), os.path.basename(file_path)))
output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
output_file.write(output_str)
output_file.close()
if __name__ == '__main__':
main(sys.argv)
+158
View File
@@ -0,0 +1,158 @@
#!/usr/bin/env python
#
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Script for branching Google Test/Mock wiki pages for a new version.
SYNOPSIS
release_docs.py NEW_RELEASE_VERSION
Google Test and Google Mock's external user documentation is in
interlinked wiki files. When we release a new version of
Google Test or Google Mock, we need to branch the wiki files
such that users of a specific version of Google Test/Mock can
look up documentation relevant for that version. This script
automates that process by:
- branching the current wiki pages (which document the
behavior of the SVN trunk head) to pages for the specified
version (e.g. branching FAQ.wiki to V2_6_FAQ.wiki when
NEW_RELEASE_VERSION is 2.6);
- updating the links in the branched files to point to the branched
version (e.g. a link in V2_6_FAQ.wiki that pointed to
Primer.wiki#Anchor will now point to V2_6_Primer.wiki#Anchor).
NOTE: NEW_RELEASE_VERSION must be a NEW version number for
which the wiki pages don't yet exist; otherwise you'll get SVN
errors like "svn: Path 'V1_7_PumpManual.wiki' is not a
directory" when running the script.
EXAMPLE
$ cd PATH/TO/GTEST_SVN_WORKSPACE/trunk
$ scripts/release_docs.py 2.6 # create wiki pages for v2.6
$ svn status # verify the file list
$ svn diff # verify the file contents
$ svn commit -m "release wiki pages for v2.6"
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sys
import common
# Wiki pages that shouldn't be branched for every gtest/gmock release.
GTEST_UNVERSIONED_WIKIS = ['DevGuide.wiki']
GMOCK_UNVERSIONED_WIKIS = [
'DesignDoc.wiki',
'DevGuide.wiki',
'KnownIssues.wiki'
]
def DropWikiSuffix(wiki_filename):
"""Removes the .wiki suffix (if any) from the given filename."""
return (wiki_filename[:-len('.wiki')] if wiki_filename.endswith('.wiki')
else wiki_filename)
class WikiBrancher(object):
"""Branches ..."""
def __init__(self, dot_version):
self.project, svn_root_path = common.GetSvnInfo()
if self.project not in ('googletest', 'googlemock'):
sys.exit('This script must be run in a gtest or gmock SVN workspace.')
self.wiki_dir = svn_root_path + '/wiki'
# Turn '2.6' to 'V2_6_'.
self.version_prefix = 'V' + dot_version.replace('.', '_') + '_'
self.files_to_branch = self.GetFilesToBranch()
page_names = [DropWikiSuffix(f) for f in self.files_to_branch]
# A link to Foo.wiki is in one of the following forms:
# [Foo words]
# [Foo#Anchor words]
# [http://code.google.com/.../wiki/Foo words]
# [http://code.google.com/.../wiki/Foo#Anchor words]
# We want to replace 'Foo' with 'V2_6_Foo' in the above cases.
self.search_for_re = re.compile(
# This regex matches either
# [Foo
# or
# /wiki/Foo
# followed by a space or a #, where Foo is the name of an
# unversioned wiki page.
r'(\[|/wiki/)(%s)([ #])' % '|'.join(page_names))
self.replace_with = r'\1%s\2\3' % (self.version_prefix,)
def GetFilesToBranch(self):
"""Returns a list of .wiki file names that need to be branched."""
unversioned_wikis = (GTEST_UNVERSIONED_WIKIS if self.project == 'googletest'
else GMOCK_UNVERSIONED_WIKIS)
return [f for f in os.listdir(self.wiki_dir)
if (f.endswith('.wiki') and
not re.match(r'^V\d', f) and # Excluded versioned .wiki files.
f not in unversioned_wikis)]
def BranchFiles(self):
"""Branches the .wiki files needed to be branched."""
print 'Branching %d .wiki files:' % (len(self.files_to_branch),)
os.chdir(self.wiki_dir)
for f in self.files_to_branch:
command = 'svn cp %s %s%s' % (f, self.version_prefix, f)
print command
os.system(command)
def UpdateLinksInBranchedFiles(self):
for f in self.files_to_branch:
source_file = os.path.join(self.wiki_dir, f)
versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f)
print 'Updating links in %s.' % (versioned_file,)
text = file(source_file, 'r').read()
new_text = self.search_for_re.sub(self.replace_with, text)
file(versioned_file, 'w').write(new_text)
def main():
if len(sys.argv) != 2:
sys.exit(__doc__)
brancher = WikiBrancher(sys.argv[1])
brancher.BranchFiles()
brancher.UpdateLinksInBranchedFiles()
if __name__ == '__main__':
main()
+32
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()
+25 -10
View File
@@ -1,18 +1,33 @@
#!/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");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# 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
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 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.
"""Tool for uploading diffs from a version control system to the codereview app.
View File
@@ -32,6 +32,7 @@
#include "gtest/gtest-death-test.h"
#include <functional>
#include <utility>
#include "gtest/internal/gtest-port.h"
@@ -68,6 +69,7 @@
# 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>
@@ -121,8 +123,8 @@ GTEST_DEFINE_string_(
"Indicates the file, line number, temporal index of "
"the single death test to run, and a file descriptor to "
"which a success code may be sent, all separated by "
"the '|' characters. This flag is specified if and only if the current "
"process is a sub-process launched for running a thread-safe "
"the '|' characters. This flag is specified if and only if the "
"current process is a sub-process launched for running a thread-safe "
"death test. FOR INTERNAL USE ONLY.");
} // namespace internal
@@ -246,7 +248,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
msg << "detected " << thread_count << " threads.";
}
msg << " See "
"https://github.com/google/googletest/blob/master/googletest/docs/"
"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.";
@@ -562,8 +564,8 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) {
// status_ok: true if exit_status is acceptable in the context of
// this particular death test, which fails if it is false
//
// Returns true iff all of the above conditions are met. Otherwise, the
// first failing condition, in the order given above, is the one that is
// Returns true if and only if all of the above conditions are met. Otherwise,
// the first failing condition, in the order given above, is the one that is
// reported. Also sets the last death test message string.
bool DeathTestImpl::Passed(bool status_ok) {
if (!spawned())
@@ -831,7 +833,7 @@ class FuchsiaDeathTest : public DeathTestImpl {
std::string captured_stderr_;
zx::process child_process_;
zx::port port_;
zx::channel exception_channel_;
zx::socket stderr_socket_;
};
@@ -863,7 +865,7 @@ class Arguments {
}
int size() {
return args_.size() - 1;
return static_cast<int>(args_.size()) - 1;
}
private:
@@ -876,41 +878,50 @@ class Arguments {
int FuchsiaDeathTest::Wait() {
const int kProcessKey = 0;
const int kSocketKey = 1;
const int kExceptionKey = 2;
if (!spawned())
return 0;
// Register to wait for the child process to terminate.
// Create a port to wait for socket/task/exception events.
zx_status_t status_zx;
status_zx = child_process_.wait_async(
port_, kProcessKey, ZX_PROCESS_TERMINATED, ZX_WAIT_ASYNC_ONCE);
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,
ZX_WAIT_ASYNC_ONCE);
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);
status_zx = port.wait(zx::time::infinite(), &packet);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
if (packet.key == kProcessKey) {
if (ZX_PKT_IS_EXCEPTION(packet.type)) {
// Process encountered an exception. Kill it directly rather than
// letting other handlers process the event. We will get a second
// kProcessKey event when the process actually terminates.
status_zx = child_process_.kill();
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
} else {
// 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;
}
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) {
@@ -930,8 +941,7 @@ int FuchsiaDeathTest::Wait() {
} 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,
ZX_WAIT_ASYNC_ONCE);
port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
}
} else {
@@ -944,12 +954,12 @@ int FuchsiaDeathTest::Wait() {
ReadAndInterpretStatusByte();
zx_info_process_t buffer;
status_zx = child_process_.get_info(
ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr);
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.exited);
set_status(buffer.return_code);
GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED);
set_status(static_cast<int>(buffer.return_code));
return status();
}
@@ -1033,12 +1043,11 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Create an exception port and attach it to the |child_job|, to allow
// Create an exception channel attached to the |child_job|, to allow
// us to suppress the system default exception handler from firing.
status = zx::port::create(0, &port_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
status = zx_task_bind_exception_port(
child_job, port_.get(), 0 /* key */, 0 /*options */);
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.
@@ -1215,21 +1224,9 @@ struct ExecDeathTestArgs {
int close_fd; // File descriptor to close; the read end of a pipe
};
# if GTEST_OS_MAC
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.
# if GTEST_OS_QNX
extern "C" char** environ;
inline char** GetEnviron() { return environ; }
# endif // GTEST_OS_MAC
# if !GTEST_OS_QNX
# else // GTEST_OS_QNX
// The main function for a threadsafe-style death test child process.
// This function is called in a clone()-ed process and thus must avoid
// any potentially unsafe operations like malloc or libc functions.
@@ -1249,18 +1246,18 @@ static int ExecDeathTestChildMain(void* child_arg) {
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
// 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
// one path separator.
execve(args->argv[0], args->argv, GetEnviron());
DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " +
execv(args->argv[0], args->argv);
DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " +
original_dir + " failed: " +
GetLastErrnoDescription());
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
@@ -1274,19 +1271,24 @@ static int ExecDeathTestChildMain(void* child_arg) {
// correct answer.
static void StackLowerThanAddress(const void* ptr,
bool* result) GTEST_NO_INLINE_;
// Make sure sanitizers do not tamper with the stack here.
// 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;
*result = (&dummy < ptr);
int dummy = 0;
*result = std::less<const void*>()(&dummy, ptr);
}
// Make sure AddressSanitizer does not tamper with the stack here.
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
static bool StackGrowsDown() {
int dummy;
int dummy = 0;
bool result;
StackLowerThanAddress(&dummy, &result);
return result;
@@ -1329,8 +1331,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
fd_flags | FD_CLOEXEC));
struct inheritance inherit = {0};
// spawn is a system call.
child_pid =
spawn(args.argv[0], 0, nullptr, &inherit, args.argv, GetEnviron());
child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ);
// Restores the current working directory.
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
@@ -1354,7 +1355,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
if (!use_fork) {
static const bool stack_grows_down = StackGrowsDown();
const auto stack_size = static_cast<size_t>(getpagesize());
const auto stack_size = static_cast<size_t>(getpagesize() * 2);
// MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
@@ -92,9 +92,10 @@ static bool IsPathSeparator(char c) {
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || ARDUINO
// Windows CE and Arduino don't have a current directory, so we just return
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
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.
return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS
@@ -209,7 +210,7 @@ bool FilePath::FileOrDirectoryExists() const {
delete [] unicode;
return attributes != kInvalidFileAttributes;
#else
posix::StatStruct file_stat;
posix::StatStruct file_stat{};
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
#endif // GTEST_OS_WINDOWS_MOBILE
}
@@ -236,7 +237,7 @@ bool FilePath::DirectoryExists() const {
result = true;
}
#else
posix::StatStruct file_stat;
posix::StatStruct file_stat{};
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
posix::IsDir(file_stat);
#endif // GTEST_OS_WINDOWS_MOBILE
@@ -323,6 +324,9 @@ bool FilePath::CreateFolder() const {
delete [] unicode;
#elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str());
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA
// do nothing
int result = 0;
#else
int result = mkdir(pathname_.c_str(), 0777);
#endif // GTEST_OS_WINDOWS_MOBILE
@@ -346,33 +350,19 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
void FilePath::Normalize() {
if (pathname_.c_str() == nullptr) {
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);
auto out = pathname_.begin();
while (*src != '\0') {
*dest_ptr = *src;
if (!IsPathSeparator(*src)) {
src++;
for (const char character : pathname_) {
if (!IsPathSeparator(character)) {
*(out++) = character;
} else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
*(out++) = kPathSeparator;
} else {
#if GTEST_HAS_ALT_PATH_SEP_
if (*dest_ptr == kAlternatePathSeparator) {
*dest_ptr = kPathSeparator;
}
#endif
while (IsPathSeparator(*src))
src++;
continue;
}
dest_ptr++;
}
*dest_ptr = '\0';
pathname_ = dest;
delete[] dest;
pathname_.erase(out, pathname_.end());
}
} // namespace internal
@@ -31,8 +31,8 @@
// This file contains purely Google Test's internal implementation. Please
// DO NOT #INCLUDE IT IN A USER PROGRAM.
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
#define GTEST_SRC_GTEST_INTERNAL_INL_H_
#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
#ifndef _WIN32_WCE
# include <errno.h>
@@ -42,6 +42,7 @@
#include <string.h> // For memmove.
#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
@@ -83,9 +84,11 @@ const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color";
const char kFailFast[] = "fail_fast";
const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kBriefFlag[] = "brief";
const char kPrintTimeFlag[] = "print_time";
const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed";
@@ -99,14 +102,14 @@ const char kFlagfileFlag[] = "flagfile";
// A valid random seed must be in [1, kMaxRandomSeed].
const int kMaxRandomSeed = 99999;
// g_help_flag is true iff the --help flag or an equivalent form is
// specified on the command line.
// g_help_flag is true if and only if the --help flag or an equivalent form
// is specified on the command line.
GTEST_API_ extern bool g_help_flag;
// Returns the current time in milliseconds.
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);
// Formats the given time in milliseconds as seconds.
@@ -123,11 +126,11 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
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
// 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) ?
static_cast<unsigned int>(GetTimeInMillis()) :
static_cast<unsigned int>(random_seed_flag);
@@ -163,10 +166,12 @@ class GTestFlagSaver {
color_ = GTEST_FLAG(color);
death_test_style_ = GTEST_FLAG(death_test_style);
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
fail_fast_ = GTEST_FLAG(fail_fast);
filter_ = GTEST_FLAG(filter);
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
list_tests_ = GTEST_FLAG(list_tests);
output_ = GTEST_FLAG(output);
brief_ = GTEST_FLAG(brief);
print_time_ = GTEST_FLAG(print_time);
print_utf8_ = GTEST_FLAG(print_utf8);
random_seed_ = GTEST_FLAG(random_seed);
@@ -186,9 +191,11 @@ class GTestFlagSaver {
GTEST_FLAG(death_test_style) = death_test_style_;
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
GTEST_FLAG(filter) = filter_;
GTEST_FLAG(fail_fast) = fail_fast_;
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_;
GTEST_FLAG(brief) = brief_;
GTEST_FLAG(print_time) = print_time_;
GTEST_FLAG(print_utf8) = print_utf8_;
GTEST_FLAG(random_seed) = random_seed_;
@@ -207,16 +214,18 @@ class GTestFlagSaver {
std::string color_;
std::string death_test_style_;
bool death_test_use_fork_;
bool fail_fast_;
std::string filter_;
std::string internal_run_death_test_;
bool list_tests_;
std::string output_;
bool brief_;
bool print_time_;
bool print_utf8_;
internal::Int32 random_seed_;
internal::Int32 repeat_;
int32_t random_seed_;
int32_t repeat_;
bool shuffle_;
internal::Int32 stack_trace_depth_;
int32_t stack_trace_depth_;
std::string stream_result_to_;
bool throw_on_failure_;
} GTEST_ATTRIBUTE_UNUSED_;
@@ -227,7 +236,7 @@ class GTestFlagSaver {
// 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
// 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.
// The wide string is assumed to have the following encoding:
@@ -260,14 +269,14 @@ GTEST_API_ bool ShouldShard(const char* total_shards_str,
const char* shard_index_str,
bool in_subprocess_for_death_test);
// Parses the environment variable var as an Int32. If it is unset,
// returns default_val. If it is not an Int32, prints an error and
// Parses the environment variable var as a 32-bit integer. If it is unset,
// returns default_val. If it is not a 32-bit integer, prints an error and
// 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,
// returns true iff the test should be run on this shard. The test id is
// some arbitrary but unique non-negative integer assigned to each test
// returns true if and only if the test should be run on this shard. The test id
// is some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards.
GTEST_API_ bool ShouldRunTestOnShard(
int total_shards, int shard_index, int test_id);
@@ -323,7 +332,7 @@ void ShuffleRange(internal::Random* random, int begin, int end,
const int last_in_range = begin + range_width - 1;
const int selected =
begin +
static_cast<int>(random->Generate(static_cast<UInt32>(range_width)));
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)]);
}
@@ -352,7 +361,7 @@ class TestPropertyKeyIs {
// TestPropertyKeyIs has NO default constructor.
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 {
return test_property.key() == key_;
}
@@ -385,15 +394,8 @@ class GTEST_API_ UnitTestOptions {
// Functions for processing the gtest_filter flag.
// Returns true iff the wildcard pattern matches the string. The
// first ':' or '\0' character in pattern marks the end of it.
//
// This recursive algorithm isn't very efficient, but is clear and
// 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 suite
// name and the test name.
// Returns true if and only if the user-specified filter matches the test
// suite name and the test name.
static bool FilterMatchesTest(const std::string& test_suite_name,
const std::string& test_name);
@@ -577,11 +579,12 @@ class GTEST_API_ UnitTestImpl {
// Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
// Returns true iff the unit test passed (i.e. all test suites passed).
// Returns true if and only if the unit test passed (i.e. all test suites
// passed).
bool Passed() const { return !Failed(); }
// Returns true iff the unit test failed (i.e. some test suite failed
// or something outside of all tests failed).
// Returns true if and only if the unit test failed (i.e. some test suite
// failed or something outside of all tests failed).
bool Failed() const {
return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed();
}
@@ -645,10 +648,10 @@ class GTEST_API_ UnitTestImpl {
// Arguments:
//
// test_suite_name: name of the test suite
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// 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 suite
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// 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 suite
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc);
@@ -672,6 +675,7 @@ class GTEST_API_ UnitTestImpl {
void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc,
TestInfo* test_info) {
#if GTEST_HAS_DEATH_TEST
// In order to support thread-safe death tests, we need to
// remember the original working directory when the test program
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as
@@ -684,6 +688,7 @@ class GTEST_API_ UnitTestImpl {
GTEST_CHECK_(!original_working_dir_.IsEmpty())
<< "Failed to get the current working directory.";
}
#endif // GTEST_HAS_DEATH_TEST
GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
set_up_tc, tear_down_tc)
@@ -696,6 +701,17 @@ class GTEST_API_ UnitTestImpl {
return parameterized_test_registry_;
}
std::set<std::string>* ignored_parameterized_test_suites() {
return &ignored_parameterized_test_suites_;
}
// 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;
@@ -872,6 +888,12 @@ class GTEST_API_ UnitTestImpl {
// ParameterizedTestRegistry object used to register value-parameterized
// tests.
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.
bool parameterized_tests_registered_;
@@ -911,7 +933,7 @@ class GTEST_API_ UnitTestImpl {
// desired.
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_;
// The random number seed used at the beginning of the test run.
@@ -998,20 +1020,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
char* end;
// BiggestConvertible is the largest integer type that system-provided
// string-to-number conversion routines can return.
using BiggestConvertible = unsigned long long; // NOLINT
# if GTEST_OS_WINDOWS && !defined(__GNUC__)
// 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 BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT
const bool parse_success = *end == '\0' && errno == 0;
GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
@@ -1153,13 +1164,13 @@ class StreamingListener : public EmptyTestEventListener {
}
// Note that "event=TestCaseStart" is a wire format and has to remain
// "case" for compatibilty
// "case" for compatibility
void OnTestCaseStart(const TestCase& test_case) override {
SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
}
// Note that "event=TestCaseEnd" is a wire format and has to remain
// "case" for compatibilty
// "case" for compatibility
void OnTestCaseEnd(const TestCase& test_case) override {
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) +
"&elapsed_time=" + StreamableToString(test_case.elapsed_time()) +
@@ -1207,4 +1218,4 @@ class StreamingListener : public EmptyTestEventListener {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_
#endif // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
@@ -58,40 +58,40 @@ Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
// s.
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
#if GTEST_HAS_ABSL
// Constructs a matcher that matches a const absl::string_view& whose value is
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const absl::string_view&>::Matcher(const std::string& s) {
Matcher<const internal::StringView&>::Matcher(const std::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const absl::string_view& whose value is
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const absl::string_view&>::Matcher(const char* s) {
Matcher<const internal::StringView&>::Matcher(const char* s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a const absl::string_view& whose value is
// Constructs a matcher that matches a const StringView& whose value is
// equal to s.
Matcher<const absl::string_view&>::Matcher(absl::string_view s) {
Matcher<const internal::StringView&>::Matcher(internal::StringView s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a absl::string_view whose value is equal to
// Constructs a matcher that matches a StringView whose value is equal to
// s.
Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); }
Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a absl::string_view whose value is equal to
// Constructs a matcher that matches a StringView whose value is equal to
// s.
Matcher<absl::string_view>::Matcher(const char* s) {
Matcher<internal::StringView>::Matcher(const char* s) {
*this = Eq(std::string(s));
}
// Constructs a matcher that matches a absl::string_view whose value is equal to
// Constructs a matcher that matches a StringView whose value is equal to
// s.
Matcher<absl::string_view>::Matcher(absl::string_view s) {
Matcher<internal::StringView>::Matcher(internal::StringView s) {
*this = Eq(std::string(s));
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
} // namespace testing
+74 -43
View File
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdint>
#include <fstream>
#include <memory>
@@ -197,7 +198,8 @@ size_t GetThreadCount() {
if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {
return 0;
}
mib[5] = size / mib[4];
mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4]));
// populate array of structs
struct kinfo_proc info[mib[5]];
@@ -206,8 +208,8 @@ size_t GetThreadCount() {
}
// exclude empty members
int nthreads = 0;
for (int i = 0; i < size / mib[4]; i++) {
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++;
}
@@ -536,6 +538,9 @@ class ThreadLocalRegistryImpl {
// Returns a value that can be used to identify the thread from other threads.
static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) {
#ifdef _MSC_VER
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
DWORD current_thread = ::GetCurrentThreadId();
MutexLock lock(&mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
@@ -683,8 +688,8 @@ class ThreadLocalRegistryImpl {
static Mutex thread_map_mutex_;
};
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex);
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex);
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); // NOLINT
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) {
@@ -715,7 +720,7 @@ RE::~RE() {
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) {
if (!re.is_valid_) return false;
@@ -723,8 +728,8 @@ bool RE::FullMatch(const char* str, const RE& re) {
return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
}
// Returns true iff regular expression re matches a substring of str
// (including str itself).
// Returns true if and only if regular expression re matches a substring of
// str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false;
@@ -764,14 +769,14 @@ void RE::Init(const char* regex) {
#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).
bool IsInSet(char ch, const char* str) {
return ch != '\0' && strchr(str, ch) != nullptr;
}
// Returns true iff ch belongs to the given classification. Unlike
// similar functions in <ctype.h>, these aren't affected by the
// Returns true if and only if ch belongs to the given classification.
// Unlike similar functions in <ctype.h>, these aren't affected by the
// current locale.
bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
bool IsAsciiPunct(char ch) {
@@ -784,13 +789,13 @@ bool IsAsciiWordChar(char 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) {
return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
}
// Returns true iff the given atom (specified by escaped and pattern)
// matches ch. The result is undefined if the atom is invalid.
// Returns true if and only if the given atom (specified by escaped and
// pattern) matches ch. The result is undefined if the atom is invalid.
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
if (escaped) { // "\\p" where p is pattern_char.
switch (pattern_char) {
@@ -828,7 +833,7 @@ bool ValidateRegex(const char* regex) {
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;
for (int i = 0; regex[i]; i++) {
if (regex[i] == '\\') { // An escape sequence
@@ -904,8 +909,8 @@ bool MatchRepetitionAndRegexAtHead(
return false;
}
// Returns true iff regex matches a prefix of str. regex must be a
// valid simple regular expression and not start with "^", or the
// Returns true if and only if regex matches a prefix of str. regex must
// be a valid simple regular expression and not start with "^", or the
// result is undefined.
bool MatchRegexAtHead(const char* regex, const char* str) {
if (*regex == '\0') // An empty regex matches a prefix of anything.
@@ -935,8 +940,8 @@ bool MatchRegexAtHead(const char* regex, const char* str) {
}
}
// Returns true iff regex matches any substring of str. regex must be
// a valid simple regular expression, or the result is undefined.
// Returns true if and only if regex matches any substring of str. regex must
// be a valid simple regular expression, or the result is undefined.
//
// 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
@@ -964,13 +969,13 @@ RE::~RE() {
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) {
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
}
// Returns true iff regular expression re matches a substring of str
// (including str itself).
// Returns true if and only if regular expression re matches a substring of
// str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
}
@@ -1090,9 +1095,9 @@ class CapturedStream {
filename_ = temp_file_path;
# else
// There's no guarantee that a test has write access to the current
// directory, so we create the temporary file in the /tmp directory
// instead. We use /tmp on most systems, and /sdcard on Android.
// That's because Android doesn't have /tmp.
// directory, so we create the temporary file in a temporary directory.
std::string name_template;
# if GTEST_OS_LINUX_ANDROID
// Note: Android applications are expected to call the framework's
// Context.getExternalStorageDirectory() method through JNI to get
@@ -1102,23 +1107,49 @@ class CapturedStream {
// code as part of a regular standalone executable, which doesn't
// run in a Dalvik process (e.g. when running it through 'adb shell').
//
// The location /sdcard is directly accessible from native code
// and is the only location (unofficially) supported by the Android
// team. It's generally a symlink to the real SD Card mount point
// which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or
// other OEM-customized locations. Never rely on these, and always
// use /sdcard.
char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
// The location /data/local/tmp is directly accessible from native code.
// '/sdcard' and other variants cannot be relied on, as they are not
// guaranteed to be mounted, or may have a delay in mounting.
name_template = "/data/local/tmp/";
# elif GTEST_OS_IOS
char user_temp_dir[PATH_MAX + 1];
// 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
char name_template[] = "/tmp/captured_stream.XXXXXX";
# endif // GTEST_OS_LINUX_ANDROID
const int captured_fd = mkstemp(name_template);
name_template = "/tmp/";
# endif
name_template.append("gtest_captured_stream.XXXXXX");
// 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_ = name_template;
filename_ = std::move(name_template);
# endif // GTEST_OS_WINDOWS
fflush(nullptr);
dup2(captured_fd, fd_);
@@ -1289,7 +1320,7 @@ static std::string FlagToEnvVar(const char* flag) {
// Parses 'str' for a 32-bit signed integer. If successful, writes
// the result to *value and returns true; otherwise leaves *value
// 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.
char* end = nullptr;
const long long_value = strtol(str, &end, 10); // NOLINT
@@ -1306,13 +1337,13 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
return false;
}
// Is the parsed value in the range of an Int32?
const Int32 result = static_cast<Int32>(long_value);
// Is the parsed value in the range of an int32_t?
const auto result = static_cast<int32_t>(long_value);
if (long_value == LONG_MAX || long_value == LONG_MIN ||
// The parsed value overflows as a long. (strtol() returns
// LONG_MAX or LONG_MIN when the input overflows.)
result != long_value
// The parsed value overflows as an Int32.
// The parsed value overflows as an int32_t.
) {
Message msg;
msg << "WARNING: " << src_text
@@ -1330,7 +1361,7 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
// Reads and returns the Boolean environment variable corresponding to
// 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) {
#if defined(GTEST_GET_BOOL_FROM_ENV_)
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
@@ -1345,7 +1376,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
// Reads and returns a 32-bit integer stored in the environment
// variable corresponding to the given flag; if it isn't set or
// 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_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
#else
@@ -1356,7 +1387,7 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
return default_value;
}
Int32 result = default_value;
int32_t result = default_value;
if (!ParseInt32(Message() << "Environment variable " << env_var,
string_value, &result)) {
printf("The default value %s is used.\n",
+144 -53
View File
@@ -42,11 +42,16 @@
// defines Foo.
#include "gtest/gtest-printers.h"
#include <stdio.h>
#include <cctype>
#include <cstdint>
#include <cwchar>
#include <ostream> // NOLINT
#include <string>
#include <type_traits>
#include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
@@ -102,9 +107,19 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
*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 internal2 {
namespace internal {
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object. The delegation simplifies the implementation, which
@@ -116,10 +131,6 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
PrintBytesInObjectToImpl(obj_bytes, count, os);
}
} // namespace internal2
namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one
// of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
@@ -134,18 +145,15 @@ enum CharFormat {
// Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
return 0x20 <= c && c <= 0x7E;
}
inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; }
// Prints a wide or narrow char c as a character literal without the
// quotes, escaping it when necessary; returns how c was formatted.
// The template argument UnsignedChar is the unsigned version of Char,
// which is the type of c.
template <typename UnsignedChar, typename Char>
// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a
// character literal without the quotes, escaping it when necessary; returns how
// c was formatted.
template <typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
wchar_t w_c = static_cast<wchar_t>(c);
switch (w_c) {
const char32_t u_c = ToChar32(c);
switch (u_c) {
case L'\0':
*os << "\\0";
break;
@@ -177,13 +185,12 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
*os << "\\v";
break;
default:
if (IsPrintableAscii(w_c)) {
if (IsPrintableAscii(u_c)) {
*os << static_cast<char>(c);
return kAsIs;
} else {
ostream::fmtflags flags = os->flags();
*os << "\\x" << std::hex << std::uppercase
<< static_cast<int>(static_cast<UnsignedChar>(c));
*os << "\\x" << std::hex << std::uppercase << static_cast<int>(u_c);
os->flags(flags);
return kHexEscape;
}
@@ -191,9 +198,9 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
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.
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {
switch (c) {
case L'\'':
*os << "'";
@@ -202,26 +209,68 @@ static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
*os << "\\\"";
return kSpecialEscape;
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
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
return PrintAsStringLiteralTo(
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
return PrintAsStringLiteralTo(ToChar32(c), os);
}
// Prints a wide or narrow character c and its code. '\0' is printed
// as "'\\0'", other unprintable characters are also properly escaped
// using the standard C++ escape sequence. The template argument
// UnsignedChar is the unsigned version of Char, which is the type of c.
template <typename UnsignedChar, typename Char>
#ifdef __cpp_char8_t
static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) {
return PrintAsStringLiteralTo(ToChar32(c), os);
}
#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) {
// First, print c as a literal in the most readable form we can find.
*os << ((sizeof(c) > 1) ? "L'" : "'");
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
*os << GetCharWidthPrefix(c) << "'";
const CharFormat format = PrintAsCharLiteralTo(c, os);
*os << "'";
// To aid user debugging, we also print c's code in decimal, unless
@@ -242,21 +291,21 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
*os << ")";
}
void PrintTo(unsigned char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(signed char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }
void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }
// 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'".
void PrintTo(wchar_t wc, ostream* os) {
PrintCharAndCodeTo<wchar_t>(wc, os);
void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(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
// 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
// and may not be NUL-terminated.
template <typename CharType>
@@ -266,8 +315,8 @@ GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
const char* const quote_prefix = GetCharWidthPrefix(*begin);
*os << quote_prefix << "\"";
bool is_previous_hex = false;
CharFormat print_format = kAsIs;
for (size_t index = 0; index < len; ++index) {
@@ -276,7 +325,7 @@ static CharFormat PrintCharsAsStringTo(
// Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to
// disambiguate.
*os << "\" " << kQuoteBegin;
*os << "\" " << quote_prefix << "\"";
}
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
// Remember if any characters required hex escaping.
@@ -322,22 +371,57 @@ void UniversalPrintArray(const char* begin, size_t len, ostream* 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
// 'begin'.
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
namespace {
// 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";
} else {
*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
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
@@ -346,14 +430,7 @@ void PrintTo(const char* s, ostream* os) {
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
if (s == nullptr) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, wcslen(s), os);
}
}
void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
#endif // wchar_t is native
namespace {
@@ -431,6 +508,20 @@ void PrintStringTo(const ::std::string& s, ostream* 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);
}
void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
@@ -31,6 +31,8 @@
// The Google C++ Testing and Mocking Framework (Google Test)
#include "gtest/gtest-test-part.h"
#include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
namespace testing {
@@ -46,7 +48,9 @@ std::string TestPartResult::ExtractSummary(const char* message) {
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
return os << result.file_name() << ":" << result.line_number() << ": "
return os << internal::FormatFileLocation(result.file_name(),
result.line_number())
<< " "
<< (result.type() == TestPartResult::kSuccess
? "Success"
: result.type() == TestPartResult::kSkip
@@ -35,8 +35,6 @@
namespace testing {
namespace internal {
#if GTEST_HAS_TYPED_TEST_P
// Skips to the first non-space char in str. Returns an empty string if str
// contains only whitespace characters.
static const char* SkipSpaces(const char* str) {
@@ -58,7 +56,10 @@ static std::vector<std::string> SplitIntoTestNames(const char* src) {
// registered_tests_; returns registered_tests if successful, or
// aborts the program otherwise.
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;
registered_ = true;
@@ -75,17 +76,7 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
continue;
}
bool found = false;
for (RegisteredTestIter it = registered_tests_.begin();
it != registered_tests_.end();
++it) {
if (name == it->first) {
found = true;
break;
}
}
if (found) {
if (registered_tests_.count(name) != 0) {
tests.insert(name);
} else {
errors << "No test named " << name
@@ -112,7 +103,5 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
return registered_tests;
}
#endif // GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -30,13 +30,20 @@
#include <cstdio>
#include "gtest/gtest.h"
#ifdef ARDUINO
#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) {
+75 -3
View File
@@ -28,12 +28,15 @@
# (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: misterg@google.com (Gennadiy Civil)
#
# Bazel BUILD for The Google C++ Testing Framework (Google Test)
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
load("@rules_python//python:defs.bzl", "py_library", "py_test")
licenses(["notice"])
package(default_visibility = ["//:__subpackages__"])
#on windows exclude gtest-tuple.h
cc_test(
name = "gtest_all_test",
@@ -53,15 +56,19 @@ cc_test(
"gtest-listener_test.cc",
"gtest-unittest-api_test.cc",
"googletest-param-test-test.cc",
"googletest-param-test2-test.cc",
"googletest-catch-exceptions-test_.cc",
"googletest-color-test_.cc",
"googletest-env-var-test_.cc",
"googletest-failfast-unittest_.cc",
"googletest-filter-unittest_.cc",
"googletest-global-environment-unittest_.cc",
"googletest-break-on-failure-unittest_.cc",
"googletest-listener-test.cc",
"googletest-output-test_.cc",
"googletest-list-tests-unittest_.cc",
"googletest-shuffle-test_.cc",
"googletest-setuptestsuite-test_.cc",
"googletest-uninitialized-test_.cc",
"googletest-death-test_ex_test.cc",
"googletest-param-test-test",
@@ -76,6 +83,10 @@ cc_test(
copts = select({
"//:windows": ["-DGTEST_USE_OWN_TR1_TUPLE=0"],
"//conditions:default": ["-DGTEST_USE_OWN_TR1_TUPLE=1"],
}) + select({
# Ensure MSVC treats source files as UTF-8 encoded.
"//:msvc_compiler": ["-utf-8"],
"//conditions:default": [],
}),
includes = [
"googletest",
@@ -139,7 +150,6 @@ cc_test(
name = "gtest_unittest",
size = "small",
srcs = ["gtest_unittest.cc"],
args = ["--heap_check=strict"],
shard_count = 2,
deps = ["//:gtest_main"],
)
@@ -150,6 +160,7 @@ py_library(
name = "gtest_test_utils",
testonly = 1,
srcs = ["gtest_test_utils.py"],
imports = ["."],
)
cc_binary(
@@ -219,6 +230,21 @@ py_test(
deps = [":gtest_test_utils"],
)
cc_binary(
name = "googletest-failfast-unittest_",
testonly = 1,
srcs = ["googletest-failfast-unittest_.cc"],
deps = ["//:gtest"],
)
py_test(
name = "googletest-failfast-unittest",
size = "medium",
srcs = ["googletest-failfast-unittest.py"],
data = [":googletest-failfast-unittest_"],
deps = [":gtest_test_utils"],
)
cc_binary(
name = "googletest-filter-unittest_",
testonly = 1,
@@ -234,6 +260,21 @@ py_test(
deps = [":gtest_test_utils"],
)
cc_binary(
name = "googletest-global-environment-unittest_",
testonly = 1,
srcs = ["googletest-global-environment-unittest_.cc"],
deps = ["//:gtest"],
)
py_test(
name = "googletest-global-environment-unittest",
size = "medium",
srcs = ["googletest-global-environment-unittest.py"],
data = [":googletest-global-environment-unittest_"],
deps = [":gtest_test_utils"],
)
cc_binary(
name = "googletest-break-on-failure-unittest_",
testonly = 1,
@@ -292,6 +333,14 @@ cc_test(
deps = ["//:gtest_main"],
)
py_test(
name = "gtest_skip_check_output_test",
size = "small",
srcs = ["gtest_skip_check_output_test.py"],
data = [":gtest_skip_test"],
deps = [":gtest_test_utils"],
)
py_test(
name = "gtest_skip_environment_check_output_test",
size = "small",
@@ -412,6 +461,21 @@ py_test(
deps = [":gtest_test_utils"],
)
cc_binary(
name = "googletest-setuptestsuite-test_",
testonly = 1,
srcs = ["googletest-setuptestsuite-test_.cc"],
deps = ["//:gtest_main"],
)
py_test(
name = "googletest-setuptestsuite-test",
size = "medium",
srcs = ["googletest-setuptestsuite-test.py"],
data = [":googletest-setuptestsuite-test_"],
deps = [":gtest_test_utils"],
)
cc_binary(
name = "googletest-uninitialized-test_",
testonly = 1,
@@ -506,6 +570,10 @@ py_test(
size = "small",
srcs = ["googletest-param-test-invalid-name1-test.py"],
data = [":googletest-param-test-invalid-name1-test_"],
tags = [
"no_test_msvc2015",
"no_test_msvc2017",
],
deps = [":gtest_test_utils"],
)
@@ -514,5 +582,9 @@ py_test(
size = "small",
srcs = ["googletest-param-test-invalid-name2-test.py"],
data = [":googletest-param-test-invalid-name2-test_"],
tags = [
"no_test_msvc2015",
"no_test_msvc2017",
],
deps = [":gtest_test_utils"],
)
View File
View File
@@ -41,7 +41,9 @@ using testing::internal::AlwaysTrue;
#if GTEST_HAS_DEATH_TEST
# if GTEST_OS_WINDOWS
# include <fcntl.h> // For O_BINARY
# include <direct.h> // For chdir().
# include <io.h>
# else
# include <unistd.h>
# include <sys/wait.h> // For waitpid.
@@ -139,7 +141,7 @@ class TestForDeathTest : public testing::Test {
DieInside("MemberFunction");
}
// True iff MemberFunction() should die.
// True if and only if MemberFunction() should die.
bool should_die_;
const FilePath original_dir_;
};
@@ -156,7 +158,7 @@ class MayDie {
}
private:
// True iff MemberFunction() should die.
// True if and only if MemberFunction() should die.
bool should_die_;
};
@@ -202,6 +204,26 @@ int DieInDebugElse12(int* sideeffect) {
return 12;
}
# if GTEST_OS_WINDOWS
// Death in dbg due to Windows CRT assertion failure, not opt.
int DieInCRTDebugElse12(int* sideeffect) {
if (sideeffect) *sideeffect = 12;
// Create an invalid fd by closing a valid one
int fdpipe[2];
EXPECT_EQ(_pipe(fdpipe, 256, O_BINARY), 0);
EXPECT_EQ(_close(fdpipe[0]), 0);
EXPECT_EQ(_close(fdpipe[1]), 0);
// _dup() should crash in debug mode
EXPECT_EQ(_dup(fdpipe[0]), -1);
return 12;
}
#endif // GTEST_OS_WINDOWS
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
// Tests the ExitedWithCode predicate.
@@ -276,6 +298,13 @@ TEST(ExitStatusPredicateTest, KilledBySignal) {
# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
// The following code intentionally tests a suboptimal syntax.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-else"
#pragma GCC diagnostic ignored "-Wempty-body"
#pragma GCC diagnostic ignored "-Wpragmas"
#endif
// Tests that the death test macros expand to code which may or may not
// be followed by operator<<, and that in either case the complete text
// comprises only a single C++ statement.
@@ -299,6 +328,9 @@ TEST_F(TestForDeathTest, SingleStatement) {
else
EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
# if GTEST_USES_PCRE
@@ -369,17 +401,19 @@ void SigprofAction(int, siginfo_t*, void*) { /* no op */ }
// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms).
void SetSigprofActionAndTimer() {
struct itimerval timer;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 1;
timer.it_value = timer.it_interval;
ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr));
struct sigaction signal_action;
memset(&signal_action, 0, sizeof(signal_action));
sigemptyset(&signal_action.sa_mask);
signal_action.sa_sigaction = SigprofAction;
signal_action.sa_flags = SA_RESTART | SA_SIGINFO;
ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, nullptr));
// timer comes second, to avoid SIGPROF premature delivery, as suggested at
// https://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html
struct itimerval timer;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 1;
timer.it_value = timer.it_interval;
ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr));
}
// Disables ITIMER_PROF timer and ignores SIGPROF signal.
@@ -551,8 +585,8 @@ TEST_F(TestForDeathTest, ErrorMessageMismatch) {
}, "died but not with expected error");
}
// On exit, *aborted will be true iff the EXPECT_DEATH() statement
// aborted the function.
// On exit, *aborted will be true if and only if the EXPECT_DEATH()
// statement aborted the function.
void ExpectDeathTestHelper(bool* aborted) {
*aborted = true;
EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail.
@@ -632,6 +666,40 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) {
# endif
}
# if GTEST_OS_WINDOWS
// Tests that EXPECT_DEBUG_DEATH works as expected when in debug mode
// the Windows CRT crashes the process with an assertion failure.
// 1. Asserts on death.
// 2. Has no side effect (doesn't pop up a window or wait for user input).
//
// And in opt mode, it:
// 1. Has side effects but does not assert.
TEST_F(TestForDeathTest, CRTDebugDeath) {
int sideeffect = 0;
// Put the regex in a local variable to make sure we don't get an "unused"
// warning in opt mode.
const char* regex = "dup.* : Assertion failed";
EXPECT_DEBUG_DEATH(DieInCRTDebugElse12(&sideeffect), regex)
<< "Must accept a streamed message";
# ifdef NDEBUG
// Checks that the assignment occurs in opt mode (sideeffect).
EXPECT_EQ(12, sideeffect);
# else
// Checks that the assignment does not occur in dbg mode (no sideeffect).
EXPECT_EQ(0, sideeffect);
# endif
}
# endif // GTEST_OS_WINDOWS
// Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a
// message to it, and in debug mode it:
// 1. Asserts on death.
@@ -1318,7 +1386,11 @@ void DieWithMessage(const char* message) {
TEST(MatcherDeathTest, DoesNotBreakBareRegexMatching) {
// googletest tests this, of course; here we ensure that including googlemock
// has not broken it.
#if GTEST_USES_POSIX_RE
EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I d[aeiou]e");
#else
EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I di?e");
#endif
}
TEST(MatcherDeathTest, MonomorphicMatcherMatches) {
@@ -1406,6 +1478,13 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) {
namespace {
// The following code intentionally tests a suboptimal syntax.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-else"
#pragma GCC diagnostic ignored "-Wempty-body"
#pragma GCC diagnostic ignored "-Wpragmas"
#endif
// Tests that the death test macros expand to code which may or may not
// be followed by operator<<, and that in either case the complete text
// comprises only a single C++ statement.
@@ -1431,6 +1510,9 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) {
else
EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
// Tests that conditional death test macros expand to code which interacts
// well with switch statements.
@@ -59,7 +59,7 @@ TEST(CxxExceptionDeathTest, ExceptionIsFailure) {
class TestException : public std::exception {
public:
const char* what() const throw() override { return "exceptional message"; }
const char* what() const noexcept override { return "exceptional message"; }
};
TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) {
+3
View File
@@ -85,9 +85,12 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
TestFlag('break_on_failure', '1', '0')
TestFlag('color', 'yes', 'auto')
SetEnvVar('TESTBRIDGE_TEST_RUNNER_FAIL_FAST', None) # For 'fail_fast' test
TestFlag('fail_fast', '1', '0')
TestFlag('filter', 'FooTest.Bar', '*')
SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test
TestFlag('output', 'xml:tmp/foo.xml', '')
TestFlag('brief', '1', '0')
TestFlag('print_time', '0', '1')
TestFlag('repeat', '999', '1')
TestFlag('throw_on_failure', '1', '0')
@@ -72,6 +72,11 @@ void PrintFlag(const char* flag) {
return;
}
if (strcmp(flag, "fail_fast") == 0) {
cout << GTEST_FLAG(fail_fast);
return;
}
if (strcmp(flag, "filter") == 0) {
cout << GTEST_FLAG(filter);
return;
@@ -82,6 +87,11 @@ void PrintFlag(const char* flag) {
return;
}
if (strcmp(flag, "brief") == 0) {
cout << GTEST_FLAG(brief);
return;
}
if (strcmp(flag, "print_time") == 0) {
cout << GTEST_FLAG(print_time);
return;
@@ -0,0 +1,410 @@
#!/usr/bin/env python
#
# Copyright 2020 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 fail_fast.
A user can specify if a Google Test program should continue test execution
after a test failure via the GTEST_FAIL_FAST environment variable or the
--gtest_fail_fast flag. The default value of the flag can also be changed
by Bazel fail fast environment variable TESTBRIDGE_TEST_RUNNER_FAIL_FAST.
This script tests such functionality by invoking googletest-failfast-unittest_
(a program written with Google Test) with different environments and command
line flags.
"""
import os
import gtest_test_utils
# Constants.
# Bazel testbridge environment variable for fail fast
BAZEL_FAIL_FAST_ENV_VAR = 'TESTBRIDGE_TEST_RUNNER_FAIL_FAST'
# The environment variable for specifying fail fast.
FAIL_FAST_ENV_VAR = 'GTEST_FAIL_FAST'
# The command line flag for specifying fail fast.
FAIL_FAST_FLAG = 'gtest_fail_fast'
# The command line flag to run disabled tests.
RUN_DISABLED_FLAG = 'gtest_also_run_disabled_tests'
# The command line flag for specifying a filter.
FILTER_FLAG = 'gtest_filter'
# Command to run the googletest-failfast-unittest_ program.
COMMAND = gtest_test_utils.GetTestExecutablePath(
'googletest-failfast-unittest_')
# 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
# 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(test_suite=None, fail_fast=None, run_disabled=False):
"""Runs the test program and returns its output."""
args = []
xml_path = os.path.join(gtest_test_utils.GetTempDir(),
'.GTestFailFastUnitTest.xml')
args += ['--gtest_output=xml:' + xml_path]
if fail_fast is not None:
if isinstance(fail_fast, str):
args += ['--%s=%s' % (FAIL_FAST_FLAG, fail_fast)]
elif fail_fast:
args += ['--%s' % FAIL_FAST_FLAG]
else:
args += ['--no%s' % FAIL_FAST_FLAG]
if test_suite:
args += ['--%s=%s.*' % (FILTER_FLAG, test_suite)]
if run_disabled:
args += ['--%s' % RUN_DISABLED_FLAG]
txt_out = gtest_test_utils.Subprocess([COMMAND] + args, env=environ).output
with open(xml_path) as xml_file:
return txt_out, xml_file.read()
# The unit test.
class GTestFailFastUnitTest(gtest_test_utils.TestCase):
"""Tests the env variable or the command line flag for fail_fast."""
def testDefaultBehavior(self):
"""Tests the behavior of not specifying the fail_fast."""
txt, _ = RunAndReturnOutput()
self.assertIn('22 FAILED TEST', txt)
def testGoogletestFlag(self):
txt, _ = RunAndReturnOutput(test_suite='HasSimpleTest', fail_fast=True)
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
txt, _ = RunAndReturnOutput(test_suite='HasSimpleTest', fail_fast=False)
self.assertIn('4 FAILED TEST', txt)
self.assertNotIn('[ SKIPPED ]', txt)
def testGoogletestEnvVar(self):
"""Tests the behavior of specifying fail_fast via Googletest env var."""
try:
SetEnvVar(FAIL_FAST_ENV_VAR, '1')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
SetEnvVar(FAIL_FAST_ENV_VAR, '0')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('4 FAILED TEST', txt)
self.assertNotIn('[ SKIPPED ]', txt)
finally:
SetEnvVar(FAIL_FAST_ENV_VAR, None)
def testBazelEnvVar(self):
"""Tests the behavior of specifying fail_fast via Bazel testbridge."""
try:
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '1')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '0')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('4 FAILED TEST', txt)
self.assertNotIn('[ SKIPPED ]', txt)
finally:
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, None)
def testFlagOverridesEnvVar(self):
"""Tests precedence of flag over env var."""
try:
SetEnvVar(FAIL_FAST_ENV_VAR, '0')
txt, _ = RunAndReturnOutput('HasSimpleTest', True)
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
finally:
SetEnvVar(FAIL_FAST_ENV_VAR, None)
def testGoogletestEnvVarOverridesBazelEnvVar(self):
"""Tests that the Googletest native env var over Bazel testbridge."""
try:
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '0')
SetEnvVar(FAIL_FAST_ENV_VAR, '1')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
finally:
SetEnvVar(FAIL_FAST_ENV_VAR, None)
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, None)
def testEventListener(self):
txt, _ = RunAndReturnOutput(test_suite='HasSkipTest', fail_fast=True)
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
for expected_count, callback in [(1, 'OnTestSuiteStart'),
(5, 'OnTestStart'),
(5, 'OnTestEnd'),
(5, 'OnTestPartResult'),
(1, 'OnTestSuiteEnd')]:
self.assertEqual(
expected_count, txt.count(callback),
'Expected %d calls to callback %s match count on output: %s ' %
(expected_count, callback, txt))
txt, _ = RunAndReturnOutput(test_suite='HasSkipTest', fail_fast=False)
self.assertIn('3 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 1 test', txt)
for expected_count, callback in [(1, 'OnTestSuiteStart'),
(5, 'OnTestStart'),
(5, 'OnTestEnd'),
(5, 'OnTestPartResult'),
(1, 'OnTestSuiteEnd')]:
self.assertEqual(
expected_count, txt.count(callback),
'Expected %d calls to callback %s match count on output: %s ' %
(expected_count, callback, txt))
def assertXmlResultCount(self, result, count, xml):
self.assertEqual(
count, xml.count('result="%s"' % result),
'Expected \'result="%s"\' match count of %s: %s ' %
(result, count, xml))
def assertXmlStatusCount(self, status, count, xml):
self.assertEqual(
count, xml.count('status="%s"' % status),
'Expected \'status="%s"\' match count of %s: %s ' %
(status, count, xml))
def assertFailFastXmlAndTxtOutput(self,
fail_fast,
test_suite,
passed_count,
failure_count,
skipped_count,
suppressed_count,
run_disabled=False):
"""Assert XML and text output of a test execution."""
txt, xml = RunAndReturnOutput(test_suite, fail_fast, run_disabled)
if failure_count > 0:
self.assertIn('%s FAILED TEST' % failure_count, txt)
if suppressed_count > 0:
self.assertIn('%s DISABLED TEST' % suppressed_count, txt)
if skipped_count > 0:
self.assertIn('[ SKIPPED ] %s tests' % skipped_count, txt)
self.assertXmlStatusCount('run',
passed_count + failure_count + skipped_count, xml)
self.assertXmlStatusCount('notrun', suppressed_count, xml)
self.assertXmlResultCount('completed', passed_count + failure_count, xml)
self.assertXmlResultCount('skipped', skipped_count, xml)
self.assertXmlResultCount('suppressed', suppressed_count, xml)
def assertFailFastBehavior(self,
test_suite,
passed_count,
failure_count,
skipped_count,
suppressed_count,
run_disabled=False):
"""Assert --fail_fast via flag."""
for fail_fast in ('true', '1', 't', True):
self.assertFailFastXmlAndTxtOutput(fail_fast, test_suite, passed_count,
failure_count, skipped_count,
suppressed_count, run_disabled)
def assertNotFailFastBehavior(self,
test_suite,
passed_count,
failure_count,
skipped_count,
suppressed_count,
run_disabled=False):
"""Assert --nofail_fast via flag."""
for fail_fast in ('false', '0', 'f', False):
self.assertFailFastXmlAndTxtOutput(fail_fast, test_suite, passed_count,
failure_count, skipped_count,
suppressed_count, run_disabled)
def testFlag_HasFixtureTest(self):
"""Tests the behavior of fail_fast and TEST_F."""
self.assertFailFastBehavior(
test_suite='HasFixtureTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasFixtureTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0)
def testFlag_HasSimpleTest(self):
"""Tests the behavior of fail_fast and TEST."""
self.assertFailFastBehavior(
test_suite='HasSimpleTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasSimpleTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0)
def testFlag_HasParametersTest(self):
"""Tests the behavior of fail_fast and TEST_P."""
self.assertFailFastBehavior(
test_suite='HasParametersSuite/HasParametersTest',
passed_count=0,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasParametersSuite/HasParametersTest',
passed_count=0,
failure_count=4,
skipped_count=0,
suppressed_count=0)
def testFlag_HasDisabledTest(self):
"""Tests the behavior of fail_fast and Disabled test cases."""
self.assertFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=1,
skipped_count=2,
suppressed_count=1,
run_disabled=False)
self.assertNotFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=3,
skipped_count=0,
suppressed_count=1,
run_disabled=False)
def testFlag_HasDisabledRunDisabledTest(self):
"""Tests the behavior of fail_fast and Disabled test cases enabled."""
self.assertFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0,
run_disabled=True)
self.assertNotFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0,
run_disabled=True)
def testFlag_HasDisabledSuiteTest(self):
"""Tests the behavior of fail_fast and Disabled test suites."""
self.assertFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=0,
failure_count=0,
skipped_count=0,
suppressed_count=5,
run_disabled=False)
self.assertNotFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=0,
failure_count=0,
skipped_count=0,
suppressed_count=5,
run_disabled=False)
def testFlag_HasDisabledSuiteRunDisabledTest(self):
"""Tests the behavior of fail_fast and Disabled test suites enabled."""
self.assertFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0,
run_disabled=True)
self.assertNotFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0,
run_disabled=True)
if SUPPORTS_DEATH_TESTS:
def testFlag_HasDeathTest(self):
"""Tests the behavior of fail_fast and death tests."""
self.assertFailFastBehavior(
test_suite='HasDeathTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasDeathTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0)
if __name__ == '__main__':
gtest_test_utils.Main()
@@ -0,0 +1,167 @@
// 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 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 HasFixtureTest.
class HasFixtureTest : public testing::Test {};
TEST_F(HasFixtureTest, Test0) {}
TEST_F(HasFixtureTest, Test1) { FAIL() << "Expected failure."; }
TEST_F(HasFixtureTest, Test2) { FAIL() << "Expected failure."; }
TEST_F(HasFixtureTest, Test3) { FAIL() << "Expected failure."; }
TEST_F(HasFixtureTest, Test4) { FAIL() << "Expected failure."; }
// Test HasSimpleTest.
TEST(HasSimpleTest, Test0) {}
TEST(HasSimpleTest, Test1) { FAIL() << "Expected failure."; }
TEST(HasSimpleTest, Test2) { FAIL() << "Expected failure."; }
TEST(HasSimpleTest, Test3) { FAIL() << "Expected failure."; }
TEST(HasSimpleTest, Test4) { FAIL() << "Expected failure."; }
// Test HasDisabledTest.
TEST(HasDisabledTest, Test0) {}
TEST(HasDisabledTest, DISABLED_Test1) { FAIL() << "Expected failure."; }
TEST(HasDisabledTest, Test2) { FAIL() << "Expected failure."; }
TEST(HasDisabledTest, Test3) { FAIL() << "Expected failure."; }
TEST(HasDisabledTest, Test4) { FAIL() << "Expected failure."; }
// Test HasDeathTest
TEST(HasDeathTest, Test0) { EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); }
TEST(HasDeathTest, Test1) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
TEST(HasDeathTest, Test2) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
TEST(HasDeathTest, Test3) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
TEST(HasDeathTest, Test4) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
// Test DISABLED_HasDisabledSuite
TEST(DISABLED_HasDisabledSuite, Test0) {}
TEST(DISABLED_HasDisabledSuite, Test1) { FAIL() << "Expected failure."; }
TEST(DISABLED_HasDisabledSuite, Test2) { FAIL() << "Expected failure."; }
TEST(DISABLED_HasDisabledSuite, Test3) { FAIL() << "Expected failure."; }
TEST(DISABLED_HasDisabledSuite, Test4) { FAIL() << "Expected failure."; }
// Test HasParametersTest
class HasParametersTest : public testing::TestWithParam<int> {};
TEST_P(HasParametersTest, Test1) { FAIL() << "Expected failure."; }
TEST_P(HasParametersTest, Test2) { FAIL() << "Expected failure."; }
INSTANTIATE_TEST_SUITE_P(HasParametersSuite, HasParametersTest,
testing::Values(1, 2));
class MyTestListener : public ::testing::EmptyTestEventListener {
void OnTestSuiteStart(const ::testing::TestSuite& test_suite) override {
printf("We are in OnTestSuiteStart of %s.\n", test_suite.name());
}
void OnTestStart(const ::testing::TestInfo& test_info) override {
printf("We are in OnTestStart of %s.%s.\n", test_info.test_suite_name(),
test_info.name());
}
void OnTestPartResult(
const ::testing::TestPartResult& test_part_result) override {
printf("We are in OnTestPartResult %s:%d.\n", test_part_result.file_name(),
test_part_result.line_number());
}
void OnTestEnd(const ::testing::TestInfo& test_info) override {
printf("We are in OnTestEnd of %s.%s.\n", test_info.test_suite_name(),
test_info.name());
}
void OnTestSuiteEnd(const ::testing::TestSuite& test_suite) override {
printf("We are in OnTestSuiteEnd of %s.\n", test_suite.name());
}
};
TEST(HasSkipTest, Test0) { SUCCEED() << "Expected success."; }
TEST(HasSkipTest, Test1) { GTEST_SKIP() << "Expected skip."; }
TEST(HasSkipTest, Test2) { FAIL() << "Expected failure."; }
TEST(HasSkipTest, Test3) { FAIL() << "Expected failure."; }
TEST(HasSkipTest, Test4) { FAIL() << "Expected failure."; }
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::UnitTest::GetInstance()->listeners().Append(new MyTestListener());
return RUN_ALL_TESTS();
}
View File
@@ -0,0 +1,72 @@
# Copyright 2021 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 global test environment behavior.
A user can specify a global test environment via
testing::AddGlobalTestEnvironment. Failures in the global environment should
result in all unit tests being skipped.
This script tests such functionality by invoking
googletest-global-environment-unittest_ (a program written with Google Test).
"""
import gtest_test_utils
def RunAndReturnOutput():
"""Runs the test program and returns its output."""
return gtest_test_utils.Subprocess([
gtest_test_utils.GetTestExecutablePath(
'googletest-global-environment-unittest_')
]).output
class GTestGlobalEnvironmentUnitTest(gtest_test_utils.TestCase):
"""Tests global test environment failures."""
def testEnvironmentSetUpFails(self):
"""Tests the behavior of not specifying the fail_fast."""
# Run the test.
txt = RunAndReturnOutput()
# We should see the text of the global environment setup error.
self.assertIn('Canned environment setup error', txt)
# Our test should have been skipped due to the error, and not treated as a
# pass.
self.assertIn('[ SKIPPED ] 1 test', txt)
self.assertIn('[ PASSED ] 0 tests', txt)
# The test case shouldn't have been run.
self.assertNotIn('Unexpected call', txt)
if __name__ == '__main__':
gtest_test_utils.Main()
@@ -0,0 +1,58 @@
// 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 global test environments.
//
// The program will be invoked from a Python unit test. Don't run it
// directly.
#include "gtest/gtest.h"
namespace {
// An environment that always fails in its SetUp method.
class FailingEnvironment final : public ::testing::Environment {
public:
void SetUp() override { FAIL() << "Canned environment setup error"; }
};
// Register the environment.
auto* const g_environment_ =
::testing::AddGlobalTestEnvironment(new FailingEnvironment);
// A test that doesn't actually run.
TEST(SomeTest, DoesFoo) { FAIL() << "Unexpected call"; }
} // namespace
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
@@ -67,11 +67,14 @@ EXPECTED_1 = {
0,
u'time':
u'*',
u'timestamp':
u'*',
u'testsuite': [{
u'name': u'TestSomeProperties',
u'status': u'RUN',
u'result': u'COMPLETED',
u'time': u'*',
u'timestamp': u'*',
u'classname': u'PropertyOne',
u'SetUpProp': u'1',
u'TestSomeProperty': u'1',
@@ -108,10 +111,13 @@ EXPECTED_2 = {
0,
u'time':
u'*',
u'timestamp':
u'*',
u'testsuite': [{
u'name': u'TestSomeProperties',
u'status': u'RUN',
u'result': u'COMPLETED',
u'timestamp': u'*',
u'time': u'*',
u'classname': u'PropertyTwo',
u'SetUpProp': u'2',
File diff suppressed because it is too large Load Diff
View File
@@ -35,6 +35,7 @@
#include <vector>
#include "gtest/gtest.h"
#include "gtest/internal/custom/gtest.h"
using ::testing::AddGlobalTestEnvironment;
using ::testing::Environment;
@@ -76,10 +77,11 @@ class EventRecordingListener : public TestEventListener {
void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {
g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd"));
}
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void OnTestCaseStart(const TestCase& /*test_case*/) override {
g_events->push_back(GetFullMethodName("OnTestCaseStart"));
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void OnTestStart(const TestInfo& /*test_info*/) override {
g_events->push_back(GetFullMethodName("OnTestStart"));
@@ -93,9 +95,11 @@ class EventRecordingListener : public TestEventListener {
g_events->push_back(GetFullMethodName("OnTestEnd"));
}
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void OnTestCaseEnd(const TestCase& /*test_case*/) override {
g_events->push_back(GetFullMethodName("OnTestCaseEnd"));
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {
g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart"));
@@ -283,6 +287,9 @@ int main(int argc, char **argv) {
::testing::GTEST_FLAG(repeat) = 2;
int ret_val = RUN_ALL_TESTS();
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// The deprecated OnTestSuiteStart/OnTestCaseStart events are included
const char* const expected_events[] = {"1st.OnTestProgramStart",
"2nd.OnTestProgramStart",
"3rd.OnTestProgramStart",
@@ -393,6 +400,110 @@ int main(int argc, char **argv) {
"3rd.OnTestProgramEnd",
"2nd.OnTestProgramEnd",
"1st.OnTestProgramEnd"};
#else
const char* const expected_events[] = {"1st.OnTestProgramStart",
"2nd.OnTestProgramStart",
"3rd.OnTestProgramStart",
"1st.OnTestIterationStart(0)",
"2nd.OnTestIterationStart(0)",
"3rd.OnTestIterationStart(0)",
"1st.OnEnvironmentsSetUpStart",
"2nd.OnEnvironmentsSetUpStart",
"3rd.OnEnvironmentsSetUpStart",
"Environment::SetUp",
"3rd.OnEnvironmentsSetUpEnd",
"2nd.OnEnvironmentsSetUpEnd",
"1st.OnEnvironmentsSetUpEnd",
"3rd.OnTestSuiteStart",
"ListenerTest::SetUpTestSuite",
"1st.OnTestStart",
"2nd.OnTestStart",
"3rd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"3rd.OnTestPartResult",
"ListenerTest::TearDown",
"3rd.OnTestEnd",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"1st.OnTestStart",
"2nd.OnTestStart",
"3rd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"3rd.OnTestPartResult",
"ListenerTest::TearDown",
"3rd.OnTestEnd",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"ListenerTest::TearDownTestSuite",
"3rd.OnTestSuiteEnd",
"1st.OnEnvironmentsTearDownStart",
"2nd.OnEnvironmentsTearDownStart",
"3rd.OnEnvironmentsTearDownStart",
"Environment::TearDown",
"3rd.OnEnvironmentsTearDownEnd",
"2nd.OnEnvironmentsTearDownEnd",
"1st.OnEnvironmentsTearDownEnd",
"3rd.OnTestIterationEnd(0)",
"2nd.OnTestIterationEnd(0)",
"1st.OnTestIterationEnd(0)",
"1st.OnTestIterationStart(1)",
"2nd.OnTestIterationStart(1)",
"3rd.OnTestIterationStart(1)",
"1st.OnEnvironmentsSetUpStart",
"2nd.OnEnvironmentsSetUpStart",
"3rd.OnEnvironmentsSetUpStart",
"Environment::SetUp",
"3rd.OnEnvironmentsSetUpEnd",
"2nd.OnEnvironmentsSetUpEnd",
"1st.OnEnvironmentsSetUpEnd",
"3rd.OnTestSuiteStart",
"ListenerTest::SetUpTestSuite",
"1st.OnTestStart",
"2nd.OnTestStart",
"3rd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"3rd.OnTestPartResult",
"ListenerTest::TearDown",
"3rd.OnTestEnd",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"1st.OnTestStart",
"2nd.OnTestStart",
"3rd.OnTestStart",
"ListenerTest::SetUp",
"ListenerTest::* Test Body",
"1st.OnTestPartResult",
"2nd.OnTestPartResult",
"3rd.OnTestPartResult",
"ListenerTest::TearDown",
"3rd.OnTestEnd",
"2nd.OnTestEnd",
"1st.OnTestEnd",
"ListenerTest::TearDownTestSuite",
"3rd.OnTestSuiteEnd",
"1st.OnEnvironmentsTearDownStart",
"2nd.OnEnvironmentsTearDownStart",
"3rd.OnEnvironmentsTearDownStart",
"Environment::TearDown",
"3rd.OnEnvironmentsTearDownEnd",
"2nd.OnEnvironmentsTearDownEnd",
"1st.OnEnvironmentsTearDownEnd",
"3rd.OnTestIterationEnd(1)",
"2nd.OnTestIterationEnd(1)",
"1st.OnTestIterationEnd(1)",
"3rd.OnTestProgramEnd",
"2nd.OnTestProgramEnd",
"1st.OnTestProgramEnd"};
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
VerifyResults(events,
expected_events,
@@ -42,6 +42,9 @@
# include <windows.h>
#elif GTEST_OS_WINDOWS
# include <direct.h>
#elif GTEST_OS_OS2
// For strcasecmp on OS/2
#include <strings.h>
#endif // GTEST_OS_WINDOWS_MOBILE
#include "src/gtest-internal-inl.h"
@@ -12,7 +12,7 @@ Expected equality of these values:
3
Stack trace: (omitted)
[==========] Running 84 tests from 39 test suites.
[==========] Running 88 tests from 41 test suites.
[----------] Global test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
@@ -966,6 +966,9 @@ Expected equality of these values:
Stack trace: (omitted)
[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
[----------] 1 test from EmptyBasenameParamInst
[ RUN ] EmptyBasenameParamInst.Passes/0
[ OK ] EmptyBasenameParamInst.Passes/0
[----------] 2 tests from PrintingStrings/ParamTest
[ RUN ] PrintingStrings/ParamTest.Success/a
[ OK ] PrintingStrings/ParamTest.Success/a
@@ -979,6 +982,43 @@ Expected failure
Stack trace: (omitted)
[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a"
[----------] 3 tests from GoogleTestVerification
[ RUN ] GoogleTestVerification.UninstantiatedParameterizedTestSuite<NoTests>
googletest-output-test_.cc:#: Failure
Parameterized test suite NoTests is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are defined via TEST_P . No test cases will run.
Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from code that always depend on code that provides TEST_P. Failing to do so is often an indication of dead code, e.g. the last TEST_P was removed but the rest got left behind.
To suppress this error for this test suite, insert the following line (in a non-header) in the namespace it is defined in:
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NoTests);
Stack trace: (omitted)
[ FAILED ] GoogleTestVerification.UninstantiatedParameterizedTestSuite<NoTests>
[ RUN ] GoogleTestVerification.UninstantiatedParameterizedTestSuite<DetectNotInstantiatedTest>
googletest-output-test_.cc:#: Failure
Parameterized test suite DetectNotInstantiatedTest is defined via TEST_P, but never instantiated. None of the test cases will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only ones provided expand to nothing.
Ideally, TEST_P definitions should only ever be included as part of binaries that intend to use them. (As opposed to, for example, being placed in a library that may be linked in to get other utilities.)
To suppress this error for this test suite, insert the following line (in a non-header) in the namespace it is defined in:
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DetectNotInstantiatedTest);
Stack trace: (omitted)
[ FAILED ] GoogleTestVerification.UninstantiatedParameterizedTestSuite<DetectNotInstantiatedTest>
[ RUN ] GoogleTestVerification.UninstantiatedTypeParameterizedTestSuite<DetectNotInstantiatedTypesTest>
googletest-output-test_.cc:#: Failure
Type parameterized test suite DetectNotInstantiatedTypesTest is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run.
Ideally, TYPED_TEST_P definitions should only ever be included as part of binaries that intend to use them. (As opposed to, for example, being placed in a library that may be linked in to get other utilities.)
To suppress this error for this test suite, insert the following line (in a non-header) in the namespace it is defined in:
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DetectNotInstantiatedTypesTest);
Stack trace: (omitted)
[ FAILED ] GoogleTestVerification.UninstantiatedTypeParameterizedTestSuite<DetectNotInstantiatedTypesTest>
[----------] Global test environment tear-down
BarEnvironment::TearDown() called.
googletest-output-test_.cc:#: Failure
@@ -992,9 +1032,9 @@ Failed
Expected fatal failure.
Stack trace: (omitted)
[==========] 84 tests from 39 test suites ran.
[ PASSED ] 30 tests.
[ FAILED ] 54 tests, listed below:
[==========] 88 tests from 41 test suites ran.
[ PASSED ] 31 tests.
[ FAILED ] 57 tests, listed below:
[ FAILED ] NonfatalFailureTest.EscapesStringOperands
[ FAILED ] NonfatalFailureTest.DiffForLongStrings
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine
@@ -1049,8 +1089,11 @@ Stack trace: (omitted)
[ FAILED ] BadDynamicFixture2.Derived
[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a"
[ FAILED ] GoogleTestVerification.UninstantiatedParameterizedTestSuite<NoTests>
[ FAILED ] GoogleTestVerification.UninstantiatedParameterizedTestSuite<DetectNotInstantiatedTest>
[ FAILED ] GoogleTestVerification.UninstantiatedTypeParameterizedTestSuite<DetectNotInstantiatedTypesTest>
54 FAILED TESTS
57 FAILED TESTS
 YOU HAVE 1 DISABLED TEST
Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
+2 -2
View File
@@ -29,7 +29,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tests the text output of Google C++ Testing and Mocking Framework.
r"""Tests the text output of Google C++ Testing and Mocking Framework.
To update the golden file:
googletest_output_test.py --build_dir=BUILD/DIR --gengolden
@@ -331,7 +331,7 @@ if __name__ == '__main__':
if CAN_GENERATE_GOLDEN_FILE:
output = GetOutputOfAllCommands()
golden_file = open(GOLDEN_PATH, 'wb')
golden_file.write(output)
golden_file.write(output.encode())
golden_file.close()
else:
message = (
@@ -96,6 +96,14 @@ INSTANTIATE_TEST_SUITE_P(PrintingFailingParams,
FailingParamTest,
testing::Values(2));
// Tests that an empty value for the test suite basename yields just
// the test name without any prior /
class EmptyBasenameParamInst : public testing::TestWithParam<int> {};
TEST_P(EmptyBasenameParamInst, Passes) { EXPECT_EQ(1, GetParam()); }
INSTANTIATE_TEST_SUITE_P(, EmptyBasenameParamInst, testing::Values(1));
static const char kGoldenString[] = "\"Line\0 1\"\nLine 2";
TEST(NonfatalFailureTest, EscapesStringOperands) {
@@ -468,63 +476,6 @@ TEST(GtestFailAtTest, MessageContainsSpecifiedFileAndLineNumber) {
GTEST_FAIL_AT("foo.cc", 42) << "Expected fatal failure in foo.cc";
}
#if GTEST_IS_THREADSAFE
// A unary function that may die.
void DieIf(bool should_die) {
GTEST_CHECK_(!should_die) << " - death inside DieIf().";
}
// Tests running death tests in a multi-threaded context.
// Used for coordination between the main and the spawn thread.
struct SpawnThreadNotifications {
SpawnThreadNotifications() {}
Notification spawn_thread_started;
Notification spawn_thread_ok_to_terminate;
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications);
};
// The function to be executed in the thread spawn by the
// MultipleThreads test (below).
static void ThreadRoutine(SpawnThreadNotifications* notifications) {
// Signals the main thread that this thread has started.
notifications->spawn_thread_started.Notify();
// Waits for permission to finish from the main thread.
notifications->spawn_thread_ok_to_terminate.WaitForNotification();
}
// This is a death-test test, but it's not named with a DeathTest
// suffix. It starts threads which might interfere with later
// death tests, so it must run after all other death tests.
class DeathTestAndMultiThreadsTest : public testing::Test {
protected:
// Starts a thread and waits for it to begin.
void SetUp() override {
thread_.reset(new ThreadWithParam<SpawnThreadNotifications*>(
&ThreadRoutine, &notifications_, nullptr));
notifications_.spawn_thread_started.WaitForNotification();
}
// Tells the thread to finish, and reaps it.
// Depending on the version of the thread library in use,
// a manager thread might still be left running that will interfere
// with later death tests. This is unfortunate, but this class
// cleans up after itself as best it can.
void TearDown() override {
notifications_.spawn_thread_ok_to_terminate.Notify();
}
private:
SpawnThreadNotifications notifications_;
std::unique_ptr<ThreadWithParam<SpawnThreadNotifications*> > thread_;
};
#endif // GTEST_IS_THREADSAFE
// The MixedUpTestSuiteTest test case verifies that Google Test will fail a
// test if it uses a different fixture class than what other tests in
// the same test case use. It deliberately contains two fixture
@@ -782,8 +733,16 @@ INSTANTIATE_TEST_SUITE_P(PrintingStrings,
testing::Values(std::string("a")),
ParamNameFunc);
// This #ifdef block tests the output of typed tests.
#if GTEST_HAS_TYPED_TEST
// The case where a suite has INSTANTIATE_TEST_SUITE_P but not TEST_P.
using NoTests = ParamTest;
INSTANTIATE_TEST_SUITE_P(ThisIsOdd, NoTests, ::testing::Values("Hello"));
// fails under kErrorOnUninstantiatedParameterizedTest=true
class DetectNotInstantiatedTest : public testing::TestWithParam<int> {};
TEST_P(DetectNotInstantiatedTest, Used) { }
// This would make the test failure from the above go away.
// INSTANTIATE_TEST_SUITE_P(Fix, DetectNotInstantiatedTest, testing::Values(1));
template <typename T>
class TypedTest : public testing::Test {
@@ -808,9 +767,9 @@ class TypedTestNames {
public:
template <typename T>
static std::string GetName(int i) {
if (testing::internal::IsSame<T, char>::value)
if (std::is_same<T, char>::value)
return std::string("char") + ::testing::PrintToString(i);
if (testing::internal::IsSame<T, int>::value)
if (std::is_same<T, int>::value)
return std::string("int") + ::testing::PrintToString(i);
}
};
@@ -821,11 +780,6 @@ TYPED_TEST(TypedTestWithNames, Success) {}
TYPED_TEST(TypedTestWithNames, Failure) { FAIL(); }
#endif // GTEST_HAS_TYPED_TEST
// This #ifdef block tests the output of type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
template <typename T>
class TypedTestP : public testing::Test {
};
@@ -849,10 +803,10 @@ class TypedTestPNames {
public:
template <typename T>
static std::string GetName(int i) {
if (testing::internal::IsSame<T, unsigned char>::value) {
if (std::is_same<T, unsigned char>::value) {
return std::string("unsignedChar") + ::testing::PrintToString(i);
}
if (testing::internal::IsSame<T, unsigned int>::value) {
if (std::is_same<T, unsigned int>::value) {
return std::string("unsignedInt") + ::testing::PrintToString(i);
}
}
@@ -861,7 +815,20 @@ class TypedTestPNames {
INSTANTIATE_TYPED_TEST_SUITE_P(UnsignedCustomName, TypedTestP, UnsignedTypes,
TypedTestPNames);
#endif // GTEST_HAS_TYPED_TEST_P
template <typename T>
class DetectNotInstantiatedTypesTest : public testing::Test {};
TYPED_TEST_SUITE_P(DetectNotInstantiatedTypesTest);
TYPED_TEST_P(DetectNotInstantiatedTypesTest, Used) {
TypeParam instantiate;
(void)instantiate;
}
REGISTER_TYPED_TEST_SUITE_P(DetectNotInstantiatedTypesTest, Used);
// kErrorOnUninstantiatedTypeParameterizedTest=true would make the above fail.
// Adding the following would make that test failure go away.
//
// typedef ::testing::Types<char, int, unsigned int> MyTypes;
// INSTANTIATE_TYPED_TEST_SUITE_P(All, DetectNotInstantiatedTypesTest, MyTypes);
#if GTEST_HAS_DEATH_TEST
@@ -871,8 +838,6 @@ INSTANTIATE_TYPED_TEST_SUITE_P(UnsignedCustomName, TypedTestP, UnsignedTypes,
TEST(ADeathTest, ShouldRunFirst) {
}
# if GTEST_HAS_TYPED_TEST
// We rely on the golden file to verify that typed tests whose test
// case name ends with DeathTest are run first.
@@ -886,10 +851,6 @@ TYPED_TEST_SUITE(ATypedDeathTest, NumericTypes);
TYPED_TEST(ATypedDeathTest, ShouldRunFirst) {
}
# endif // GTEST_HAS_TYPED_TEST
# if GTEST_HAS_TYPED_TEST_P
// We rely on the golden file to verify that type-parameterized tests
// whose test case name ends with DeathTest are run first.
@@ -907,8 +868,6 @@ REGISTER_TYPED_TEST_SUITE_P(ATypeParamDeathTest, ShouldRunFirst);
INSTANTIATE_TYPED_TEST_SUITE_P(My, ATypeParamDeathTest, NumericTypes);
# endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_HAS_DEATH_TEST
// Tests various failure conditions of
@@ -1070,7 +1029,7 @@ auto dynamic_test = (
"BadDynamicFixture1", "TestBase", nullptr, nullptr, __FILE__, __LINE__,
[]() -> testing::Test* { return new DynamicTest<true>; }),
// Register two tests with the same fixture incorrectly by ommiting the
// Register two tests with the same fixture incorrectly by omitting the
// return type.
testing::RegisterTest(
"BadDynamicFixture2", "FixtureBase", nullptr, nullptr, __FILE__,
@@ -37,6 +37,7 @@
# include <algorithm>
# include <iostream>
# include <list>
# include <set>
# include <sstream>
# include <string>
# include <vector>
@@ -489,16 +490,17 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
class NonDefaultConstructAssignString {
public:
NonDefaultConstructAssignString(const std::string& s) : str_(s) {}
NonDefaultConstructAssignString() = delete;
NonDefaultConstructAssignString(const NonDefaultConstructAssignString&) =
default;
NonDefaultConstructAssignString& operator=(
const NonDefaultConstructAssignString&) = delete;
~NonDefaultConstructAssignString() = default;
const std::string& str() const { return str_; }
private:
std::string str_;
// Not default constructible
NonDefaultConstructAssignString();
// Not assignable
void operator=(const NonDefaultConstructAssignString&);
};
TEST(CombineTest, NonDefaultConstructAssign) {
@@ -802,7 +804,7 @@ TEST_P(PREFIX_WITH_MACRO(NamingTest), PREFIX_WITH_FOO(SomeTestName)) {
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("FortyTwo/MacroNamingTest", test_info->test_suite_name());
EXPECT_STREQ("FooSomeTestName", test_info->name());
EXPECT_STREQ("FooSomeTestName/0", test_info->name());
}
INSTANTIATE_TEST_SUITE_P(FortyTwo, MacroNamingTest, Values(42));
@@ -819,6 +821,36 @@ TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized),
EXPECT_STREQ("FooSomeTestName", test_info->name());
}
TEST(MacroNameing, LookupNames) {
std::set<std::string> know_suite_names, know_test_names;
auto ins = testing::UnitTest::GetInstance();
int ts = 0;
while (const testing::TestSuite* suite = ins->GetTestSuite(ts++)) {
know_suite_names.insert(suite->name());
int ti = 0;
while (const testing::TestInfo* info = suite->GetTestInfo(ti++)) {
know_test_names.insert(std::string(suite->name()) + "." + info->name());
}
}
// Check that the expected form of the test suit name actually exists.
EXPECT_NE( //
know_suite_names.find("FortyTwo/MacroNamingTest"),
know_suite_names.end());
EXPECT_NE(
know_suite_names.find("MacroNamingTestNonParametrized"),
know_suite_names.end());
// Check that the expected form of the test name actually exists.
EXPECT_NE( //
know_test_names.find("FortyTwo/MacroNamingTest.FooSomeTestName/0"),
know_test_names.end());
EXPECT_NE(
know_test_names.find("MacroNamingTestNonParametrized.FooSomeTestName"),
know_test_names.end());
}
// Tests that user supplied custom parameter names are working correctly.
// Runs the test with a builtin helper method which uses PrintToString,
// as well as a custom function and custom functor to ensure all possible
@@ -1037,6 +1069,38 @@ TEST_P(MyEnumTest, ChecksParamMoreThanZero) { EXPECT_GE(10, GetParam()); }
INSTANTIATE_TEST_SUITE_P(MyEnumTests, MyEnumTest,
::testing::Values(ENUM1, ENUM2, 0));
namespace works_here {
// Never used not instantiated, this should work.
class NotUsedTest : public testing::TestWithParam<int> {};
///////
// Never used not instantiated, this should work.
template <typename T>
class NotUsedTypeTest : public testing::Test {};
TYPED_TEST_SUITE_P(NotUsedTypeTest);
// Used but not instantiated, this would fail. but...
class NotInstantiatedTest : public testing::TestWithParam<int> {};
// ... we mark is as allowed.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NotInstantiatedTest);
TEST_P(NotInstantiatedTest, Used) { }
using OtherName = NotInstantiatedTest;
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OtherName);
TEST_P(OtherName, Used) { }
// Used but not instantiated, this would fail. but...
template <typename T>
class NotInstantiatedTypeTest : public testing::Test {};
TYPED_TEST_SUITE_P(NotInstantiatedTypeTest);
// ... we mark is as allowed.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NotInstantiatedTypeTest);
TYPED_TEST_P(NotInstantiatedTypeTest, Used) { }
REGISTER_TYPED_TEST_SUITE_P(NotInstantiatedTypeTest, Used);
} // namespace works_here
int main(int argc, char **argv) {
// Used in TestGenerationTest test suite.
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
@@ -32,8 +32,8 @@
// 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_
#ifndef GOOGLETEST_TEST_GOOGLETEST_PARAM_TEST_TEST_H_
#define GOOGLETEST_TEST_GOOGLETEST_PARAM_TEST_TEST_H_
#include "gtest/gtest.h"
@@ -48,4 +48,4 @@ class InstantiationInMultipleTranslationUnitsTest
: public ::testing::TestWithParam<int> {
};
#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
#endif // GOOGLETEST_TEST_GOOGLETEST_PARAM_TEST_TEST_H_
@@ -90,10 +90,10 @@ TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) {
class Base {
public:
// Copy constructor and assignment operator do exactly what we need, so we
// use them.
Base() : member_(0) {}
explicit Base(int n) : member_(n) {}
Base(const Base&) = default;
Base& operator=(const Base&) = default;
virtual ~Base() {}
int member() { return member_; }
@@ -201,24 +201,13 @@ TEST(ImplicitCastTest, CanUseImplicitConstructor) {
EXPECT_TRUE(converted);
}
TEST(IteratorTraitsTest, WorksForSTLContainerIterators) {
StaticAssertTypeEq<int,
IteratorTraits< ::std::vector<int>::const_iterator>::value_type>();
StaticAssertTypeEq<bool,
IteratorTraits< ::std::list<bool>::iterator>::value_type>();
}
TEST(IteratorTraitsTest, WorksForPointerToNonConst) {
StaticAssertTypeEq<char, IteratorTraits<char*>::value_type>();
StaticAssertTypeEq<const void*, IteratorTraits<const void**>::value_type>();
}
TEST(IteratorTraitsTest, WorksForPointerToConst) {
StaticAssertTypeEq<char, IteratorTraits<const char*>::value_type>();
StaticAssertTypeEq<const void*,
IteratorTraits<const void* const*>::value_type>();
}
// The following code intentionally tests a suboptimal syntax.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-else"
#pragma GCC diagnostic ignored "-Wempty-body"
#pragma GCC diagnostic ignored "-Wpragmas"
#endif
TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
if (AlwaysFalse())
GTEST_CHECK_(false) << "This should never be executed; "
@@ -234,6 +223,9 @@ TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
else
GTEST_CHECK_(true) << "";
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
switch (0) {
@@ -381,8 +373,6 @@ TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
#if GTEST_USES_POSIX_RE
# if GTEST_HAS_TYPED_TEST
template <typename Str>
class RETest : public ::testing::Test {};
@@ -438,8 +428,6 @@ TYPED_TEST(RETest, PartialMatchWorks) {
EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
}
# endif // GTEST_HAS_TYPED_TEST
#elif GTEST_USES_SIMPLE_RE
TEST(IsInSetTest, NulCharIsNotInAnySet) {
@@ -1198,8 +1186,6 @@ class DestructorTracker {
return DestructorCall::List().size() - 1;
}
const size_t index_;
GTEST_DISALLOW_ASSIGN_(DestructorTracker);
};
typedef ThreadLocal<DestructorTracker>* ThreadParam;
@@ -32,14 +32,16 @@
//
// This file tests the universal value printer.
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <deque>
#include <forward_list>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
@@ -89,6 +91,18 @@ class BiggestIntConvertible {
operator ::testing::internal::BiggestInt() const { return 42; }
};
// A parent class with two child classes. The parent and one of the kids have
// stream operators.
class ParentClass {};
class ChildClassWithStreamOperator : public ParentClass {};
class ChildClassWithoutStreamOperator : public ParentClass {};
static void operator<<(std::ostream& os, const ParentClass&) {
os << "ParentClass";
}
static void operator<<(std::ostream& os, const ChildClassWithStreamOperator&) {
os << "ChildClassWithStreamOperator";
}
// A user-defined unprintable class template in the global namespace.
template <typename T>
class UnprintableTemplateInGlobal {
@@ -176,7 +190,18 @@ inline ::std::ostream& operator<<(::std::ostream& os,
return os << "StreamableTemplateInFoo: " << x.value();
}
// A user-defined streamable but recursivly-defined container type in
// A user-defined streamable type in a user namespace whose operator<< is
// templated on the type of the output stream.
struct TemplatedStreamableInFoo {};
template <typename OutputStream>
OutputStream& operator<<(OutputStream& os,
const TemplatedStreamableInFoo& /*ts*/) {
os << "TemplatedStreamableInFoo";
return os;
}
// A user-defined streamable but recursively-defined container type in
// a user namespace, it mimics therefore std::filesystem::path or
// boost::filesystem::path.
class PathLike {
@@ -204,6 +229,33 @@ class PathLike {
} // namespace foo
namespace testing {
namespace {
template <typename T>
class Wrapper {
public:
explicit Wrapper(T&& value) : value_(std::forward<T>(value)) {}
const T& value() const { return value_; }
private:
T value_;
};
} // namespace
namespace internal {
template <typename T>
class UniversalPrinter<Wrapper<T>> {
public:
static void Print(const Wrapper<T>& w, ::std::ostream* os) {
*os << "Wrapper(";
UniversalPrint(w.value(), os);
*os << ')';
}
};
} // namespace internal
namespace gtest_printers_test {
using ::std::deque;
@@ -219,7 +271,6 @@ using ::testing::PrintToString;
using ::testing::internal::FormatForComparisonFailureMessage;
using ::testing::internal::ImplicitCast_;
using ::testing::internal::NativeArray;
using ::testing::internal::RE;
using ::testing::internal::RelationToSourceReference;
using ::testing::internal::Strings;
using ::testing::internal::UniversalPrint;
@@ -310,6 +361,20 @@ TEST(PrintCharTest, UnsignedChar) {
Print(static_cast<unsigned char>('b')));
}
TEST(PrintCharTest, Char16) {
EXPECT_EQ("U+0041", Print(u'A'));
}
TEST(PrintCharTest, Char32) {
EXPECT_EQ("U+0041", Print(U'A'));
}
#ifdef __cpp_char8_t
TEST(PrintCharTest, Char8) {
EXPECT_EQ("U+0041", Print(u8'A'));
}
#endif
// Tests printing other simple, built-in types.
// bool.
@@ -340,23 +405,39 @@ TEST(PrintBuiltInTypeTest, Wchar_t) {
EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast<wchar_t>(0xC74D)));
}
// Test that Int64 provides more storage than wchar_t.
// Test that int64_t provides more storage than wchar_t.
TEST(PrintTypeSizeTest, Wchar_t) {
EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64));
EXPECT_LT(sizeof(wchar_t), sizeof(int64_t));
}
// Various integer types.
TEST(PrintBuiltInTypeTest, Integer) {
EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8
EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8
EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16
EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16
EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32
EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32
EXPECT_EQ("65535", Print(std::numeric_limits<uint16_t>::max())); // uint16
EXPECT_EQ("-32768", Print(std::numeric_limits<int16_t>::min())); // int16
EXPECT_EQ("4294967295",
Print(std::numeric_limits<uint32_t>::max())); // uint32
EXPECT_EQ("-2147483648",
Print(std::numeric_limits<int32_t>::min())); // int32
EXPECT_EQ("18446744073709551615",
Print(static_cast<testing::internal::UInt64>(-1))); // uint64
Print(std::numeric_limits<uint64_t>::max())); // uint64
EXPECT_EQ("-9223372036854775808",
Print(static_cast<testing::internal::Int64>(1) << 63)); // int64
Print(std::numeric_limits<int64_t>::min())); // int64
#ifdef __cpp_char8_t
EXPECT_EQ("U+0000",
Print(std::numeric_limits<char8_t>::min())); // char8_t
EXPECT_EQ("U+00FF",
Print(std::numeric_limits<char8_t>::max())); // char8_t
#endif
EXPECT_EQ("U+0000",
Print(std::numeric_limits<char16_t>::min())); // char16_t
EXPECT_EQ("U+FFFF",
Print(std::numeric_limits<char16_t>::max())); // char16_t
EXPECT_EQ("U+0000",
Print(std::numeric_limits<char32_t>::min())); // char32_t
EXPECT_EQ("U+FFFFFFFF",
Print(std::numeric_limits<char32_t>::max())); // char32_t
}
// Size types.
@@ -412,6 +493,92 @@ TEST(PrintCStringTest, EscapesProperly) {
Print(p));
}
#ifdef __cpp_char8_t
// const char8_t*.
TEST(PrintU8StringTest, Const) {
const char8_t* p = u8"界";
EXPECT_EQ(PrintPointer(p) + " pointing to u8\"\\xE7\\x95\\x8C\"", Print(p));
}
// char8_t*.
TEST(PrintU8StringTest, NonConst) {
char8_t p[] = u8"世";
EXPECT_EQ(PrintPointer(p) + " pointing to u8\"\\xE4\\xB8\\x96\"",
Print(static_cast<char8_t*>(p)));
}
// NULL u8 string.
TEST(PrintU8StringTest, Null) {
const char8_t* p = nullptr;
EXPECT_EQ("NULL", Print(p));
}
// Tests that u8 strings are escaped properly.
TEST(PrintU8StringTest, EscapesProperly) {
const char8_t* p = u8"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 世界";
EXPECT_EQ(PrintPointer(p) +
" pointing to u8\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF "
"hello \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"",
Print(p));
}
#endif
// const char16_t*.
TEST(PrintU16StringTest, Const) {
const char16_t* p = u"界";
EXPECT_EQ(PrintPointer(p) + " pointing to u\"\\x754C\"", Print(p));
}
// char16_t*.
TEST(PrintU16StringTest, NonConst) {
char16_t p[] = u"世";
EXPECT_EQ(PrintPointer(p) + " pointing to u\"\\x4E16\"",
Print(static_cast<char16_t*>(p)));
}
// NULL u16 string.
TEST(PrintU16StringTest, Null) {
const char16_t* p = nullptr;
EXPECT_EQ("NULL", Print(p));
}
// Tests that u16 strings are escaped properly.
TEST(PrintU16StringTest, EscapesProperly) {
const char16_t* p = u"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 世界";
EXPECT_EQ(PrintPointer(p) +
" pointing to u\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF "
"hello \\x4E16\\x754C\"",
Print(p));
}
// const char32_t*.
TEST(PrintU32StringTest, Const) {
const char32_t* p = U"🗺️";
EXPECT_EQ(PrintPointer(p) + " pointing to U\"\\x1F5FA\\xFE0F\"", Print(p));
}
// char32_t*.
TEST(PrintU32StringTest, NonConst) {
char32_t p[] = U"🌌";
EXPECT_EQ(PrintPointer(p) + " pointing to U\"\\x1F30C\"",
Print(static_cast<char32_t*>(p)));
}
// NULL u32 string.
TEST(PrintU32StringTest, Null) {
const char32_t* p = nullptr;
EXPECT_EQ("NULL", Print(p));
}
// Tests that u32 strings are escaped properly.
TEST(PrintU32StringTest, EscapesProperly) {
const char32_t* p = U"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 🗺️";
EXPECT_EQ(PrintPointer(p) +
" pointing to U\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF "
"hello \\x1F5FA\\xFE0F\"",
Print(p));
}
// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
@@ -622,21 +789,66 @@ TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) {
EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a));
}
// const char array with terminating NUL.
TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) {
// char array with terminating NUL.
TEST(PrintArrayTest, CharArrayWithTerminatingNul) {
const char a[] = "\0Hi";
EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a));
}
// const wchar_t array without terminating NUL.
#ifdef __cpp_char8_t
// char_t array without terminating NUL.
TEST(PrintArrayTest, Char8ArrayWithNoTerminatingNul) {
// Array a contains '\0' in the middle and doesn't end with '\0'.
const char8_t a[] = {u8'H', u8'\0', u8'i'};
EXPECT_EQ("u8\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a));
}
// char8_t array with terminating NUL.
TEST(PrintArrayTest, Char8ArrayWithTerminatingNul) {
const char8_t a[] = u8"\0世界";
EXPECT_EQ(
"u8\"\\0\\xE4\\xB8\\x96\\xE7\\x95\\x8C\"",
PrintArrayHelper(a));
}
#endif
// const char16_t array without terminating NUL.
TEST(PrintArrayTest, Char16ArrayWithNoTerminatingNul) {
// Array a contains '\0' in the middle and doesn't end with '\0'.
const char16_t a[] = {u'こ', u'\0', u'ん', u'に', u'ち', u'は'};
EXPECT_EQ("u\"\\x3053\\0\\x3093\\x306B\\x3061\\x306F\" (no terminating NUL)",
PrintArrayHelper(a));
}
// char16_t array with terminating NUL.
TEST(PrintArrayTest, Char16ArrayWithTerminatingNul) {
const char16_t a[] = u"\0こんにちは";
EXPECT_EQ("u\"\\0\\x3053\\x3093\\x306B\\x3061\\x306F\"", PrintArrayHelper(a));
}
// char32_t array without terminating NUL.
TEST(PrintArrayTest, Char32ArrayWithNoTerminatingNul) {
// Array a contains '\0' in the middle and doesn't end with '\0'.
const char32_t a[] = {U'👋', U'\0', U'🌌'};
EXPECT_EQ("U\"\\x1F44B\\0\\x1F30C\" (no terminating NUL)",
PrintArrayHelper(a));
}
// char32_t array with terminating NUL.
TEST(PrintArrayTest, Char32ArrayWithTerminatingNul) {
const char32_t a[] = U"\0👋🌌";
EXPECT_EQ("U\"\\0\\x1F44B\\x1F30C\"", PrintArrayHelper(a));
}
// wchar_t array without terminating NUL.
TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) {
// Array a contains '\0' in the middle and doesn't end with '\0'.
const wchar_t a[] = { L'H', L'\0', L'i' };
const wchar_t a[] = {L'H', L'\0', L'i'};
EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a));
}
// wchar_t array with terminating NUL.
TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) {
TEST(PrintArrayTest, WCharArrayWithTerminatingNul) {
const wchar_t a[] = L"\0Hi";
EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a));
}
@@ -700,6 +912,26 @@ TEST(PrintWideStringTest, StringAmbiguousHex) {
}
#endif // GTEST_HAS_STD_WSTRING
#ifdef __cpp_char8_t
TEST(PrintStringTest, U8String) {
std::u8string str = u8"Hello, 世界";
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str));
}
#endif
TEST(PrintStringTest, U16String) {
std::u16string str = u"Hello, 世界";
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str));
}
TEST(PrintStringTest, U32String) {
std::u32string str = U"Hello, 🗺️";
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type
EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str));
}
// Tests printing types that support generic streaming (i.e. streaming
// to std::basic_ostream<Char, CharTraits> for any valid Char and
// CharTraits types).
@@ -758,22 +990,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) {
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a));
}
#if GTEST_HAS_ABSL
#if GTEST_INTERNAL_HAS_STRING_VIEW
// Tests printing ::absl::string_view.
// Tests printing internal::StringView.
TEST(PrintStringViewTest, SimpleStringView) {
const ::absl::string_view sp = "Hello";
const internal::StringView sp = "Hello";
EXPECT_EQ("\"Hello\"", Print(sp));
}
TEST(PrintStringViewTest, UnprintableCharacters) {
const char str[] = "NUL (\0) and \r\t";
const ::absl::string_view sp(str, sizeof(str) - 1);
const internal::StringView sp(str, sizeof(str) - 1);
EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp));
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Tests printing STL containers.
@@ -978,9 +1210,8 @@ TEST(PrintStdTupleTest, VariousSizes) {
EXPECT_EQ("(false, 2, 3, 4)", Print(t4));
const char* const str = "8";
::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT
testing::internal::Int64, float, double, const char*, void*,
std::string>
::std::tuple<bool, char, short, int32_t, int64_t, float, double, // NOLINT
const char*, void*, std::string>
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT
nullptr, "10");
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
@@ -1064,6 +1295,20 @@ TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) {
Print(::foo::StreamableTemplateInFoo<int>()));
}
TEST(PrintStreamableTypeTest, TypeInUserNamespaceWithTemplatedStreamOperator) {
EXPECT_EQ("TemplatedStreamableInFoo",
Print(::foo::TemplatedStreamableInFoo()));
}
TEST(PrintStreamableTypeTest, SubclassUsesSuperclassStreamOperator) {
ParentClass parent;
ChildClassWithStreamOperator child_stream;
ChildClassWithoutStreamOperator child_no_stream;
EXPECT_EQ("ParentClass", Print(parent));
EXPECT_EQ("ChildClassWithStreamOperator", Print(child_stream));
EXPECT_EQ("ParentClass", Print(child_no_stream));
}
// Tests printing a user-defined recursive container type that has a <<
// operator.
TEST(PrintStreamableTypeTest, PathLikeInUserNamespace) {
@@ -1472,6 +1717,13 @@ TEST(UniversalPrintTest, WorksForReference) {
EXPECT_EQ("123", ss.str());
}
TEST(UniversalPrintTest, WorksForPairWithConst) {
std::pair<const Wrapper<std::string>, int> p(Wrapper<std::string>("abc"), 1);
::std::stringstream ss;
UniversalPrint(p, &ss);
EXPECT_EQ("(Wrapper(\"abc\"), 1)", ss.str());
}
TEST(UniversalPrintTest, WorksForCString) {
const char* s1 = "abc";
::std::stringstream ss1;
@@ -1501,6 +1753,63 @@ TEST(UniversalPrintTest, WorksForCharArray) {
EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str());
}
TEST(UniversalPrintTest, IncompleteType) {
struct Incomplete;
char some_object = 0;
EXPECT_EQ("(incomplete type)",
PrintToString(reinterpret_cast<Incomplete&>(some_object)));
}
TEST(UniversalPrintTest, SmartPointers) {
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int>()));
std::unique_ptr<int> p(new int(17));
EXPECT_EQ("(ptr = " + PrintPointer(p.get()) + ", value = 17)",
PrintToString(p));
std::unique_ptr<int[]> p2(new int[2]);
EXPECT_EQ("(" + PrintPointer(p2.get()) + ")", PrintToString(p2));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int>()));
std::shared_ptr<int> p3(new int(1979));
EXPECT_EQ("(ptr = " + PrintPointer(p3.get()) + ", value = 1979)",
PrintToString(p3));
#if __cpp_lib_shared_ptr_arrays >= 201611L
std::shared_ptr<int[]> p4(new int[2]);
EXPECT_EQ("(" + PrintPointer(p4.get()) + ")", PrintToString(p4));
#endif
// modifiers
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<const int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile const int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<const int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<volatile int[]>()));
EXPECT_EQ("(nullptr)",
PrintToString(std::unique_ptr<volatile const int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<const int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile int>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile const int>()));
#if __cpp_lib_shared_ptr_arrays >= 201611L
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<const int[]>()));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<volatile int[]>()));
EXPECT_EQ("(nullptr)",
PrintToString(std::shared_ptr<volatile const int[]>()));
#endif
// void
EXPECT_EQ("(nullptr)", PrintToString(std::unique_ptr<void, void (*)(void*)>(
nullptr, nullptr)));
EXPECT_EQ("(" + PrintPointer(p.get()) + ")",
PrintToString(
std::unique_ptr<void, void (*)(void*)>(p.get(), [](void*) {})));
EXPECT_EQ("(nullptr)", PrintToString(std::shared_ptr<void>()));
EXPECT_EQ("(" + PrintPointer(p.get()) + ")",
PrintToString(std::shared_ptr<void>(p.get(), [](void*) {})));
}
TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) {
Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple());
EXPECT_EQ(0u, result.size());
@@ -1530,32 +1839,65 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
EXPECT_EQ("\"a\"", result[1]);
}
#if GTEST_HAS_ABSL
#if GTEST_INTERNAL_HAS_ANY
class PrintAnyTest : public ::testing::Test {
protected:
template <typename T>
static std::string ExpectedTypeName() {
#if GTEST_HAS_RTTI
return internal::GetTypeName<T>();
#else
return "<unknown_type>";
#endif // GTEST_HAS_RTTI
}
};
TEST_F(PrintAnyTest, Empty) {
internal::Any any;
EXPECT_EQ("no value", PrintToString(any));
}
TEST_F(PrintAnyTest, NonEmpty) {
internal::Any any;
constexpr int val1 = 10;
const std::string val2 = "content";
any = val1;
EXPECT_EQ("value of type " + ExpectedTypeName<int>(), PrintToString(any));
any = val2;
EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(),
PrintToString(any));
}
#endif // GTEST_INTERNAL_HAS_ANY
#if GTEST_INTERNAL_HAS_OPTIONAL
TEST(PrintOptionalTest, Basic) {
absl::optional<int> value;
internal::Optional<int> value;
EXPECT_EQ("(nullopt)", PrintToString(value));
value = {7};
EXPECT_EQ("(7)", PrintToString(value));
EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1}));
EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"}));
EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1}));
EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"}));
}
#endif // GTEST_INTERNAL_HAS_OPTIONAL
#if GTEST_INTERNAL_HAS_VARIANT
struct NonPrintable {
unsigned char contents = 17;
};
TEST(PrintOneofTest, Basic) {
using Type = absl::variant<int, StreamableInGlobal, NonPrintable>;
EXPECT_EQ("('int' with value 7)", PrintToString(Type(7)));
EXPECT_EQ("('StreamableInGlobal' with value StreamableInGlobal)",
using Type = internal::Variant<int, StreamableInGlobal, NonPrintable>;
EXPECT_EQ("('int(index = 0)' with value 7)", PrintToString(Type(7)));
EXPECT_EQ("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)",
PrintToString(Type(StreamableInGlobal{})));
EXPECT_EQ(
"('testing::gtest_printers_test::NonPrintable' with value 1-byte object "
"<11>)",
"('testing::gtest_printers_test::NonPrintable(index = 2)' with value "
"1-byte object <11>)",
PrintToString(Type(NonPrintable{})));
}
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_VARIANT
namespace {
class string_ref;
@@ -0,0 +1,54 @@
#!/usr/bin/env python
#
# Copyright 2019, 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 SetUpTestSuite and TearDownTestSuite errors are noticed."""
import gtest_test_utils
COMMAND = gtest_test_utils.GetTestExecutablePath(
'googletest-setuptestsuite-test_')
class GTestSetUpTestSuiteTest(gtest_test_utils.TestCase):
def testSetupErrorAndTearDownError(self):
p = gtest_test_utils.Subprocess(COMMAND)
self.assertNotEqual(p.exit_code, 0, msg=p.output)
self.assertIn(
'[ FAILED ] SetupFailTest: SetUpTestSuite or TearDownTestSuite\n'
'[ FAILED ] TearDownFailTest: SetUpTestSuite or TearDownTestSuite\n'
'\n'
' 2 FAILED TEST SUITES\n',
p.output)
if __name__ == '__main__':
gtest_test_utils.Main()
@@ -27,35 +27,23 @@
// (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 for Google Test itself. This verifies that the basic constructs of
// Google Test work.
#include "gtest/gtest.h"
#include "googletest-param-test-test.h"
using ::testing::Values;
using ::testing::internal::ParamGenerator;
class SetupFailTest : public ::testing::Test {
protected:
static void SetUpTestSuite() {
ASSERT_EQ("", "SET_UP_FAIL");
}
};
// Tests that generators defined in a different translation unit
// are functional. The test using extern_gen_2 is defined
// in googletest-param-test-test.cc.
ParamGenerator<int> extern_gen_2 = Values(33);
TEST_F(SetupFailTest, NoopPassingTest) {}
// Tests that a parameterized test case can be defined in one translation unit
// and instantiated in another. The test is defined in
// googletest-param-test-test.cc and ExternalInstantiationTest fixture class is
// defined in gtest-param-test_test.h.
INSTANTIATE_TEST_SUITE_P(MultiplesOf33,
ExternalInstantiationTest,
Values(33, 66));
// Tests that a parameterized test case can be instantiated
// in multiple translation units. Another instantiation is defined
// in googletest-param-test-test.cc and
// InstantiationInMultipleTranslationUnitsTest fixture is defined in
// gtest-param-test_test.h
INSTANTIATE_TEST_SUITE_P(Sequence2,
InstantiationInMultipleTranslationUnitsTest,
Values(42*3, 42*4, 42*5));
class TearDownFailTest : public ::testing::Test {
protected:
static void TearDownTestSuite() {
ASSERT_EQ("", "TEAR_DOWN_FAIL");
}
};
TEST_F(TearDownFailTest, NoopPassingTest) {}
View File
@@ -82,7 +82,7 @@ class TestNamePrinter : public EmptyTestEventListener {
}
void OnTestStart(const TestInfo& test_info) override {
printf("%s.%s\n", test_info.test_case_name(), test_info.name());
printf("%s.%s\n", test_info.test_suite_name(), test_info.name());
}
};
+1 -1
View File
@@ -86,7 +86,7 @@ class ThrowOnFailureTest(gtest_test_utils.TestCase):
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.
should_fail: True iff the program is expected to fail.
should_fail: True if and only if the program is expected to fail.
"""
SetEnvVar(THROW_ON_FAILURE, env_var_value)
View File
@@ -33,12 +33,8 @@
#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_SUITE_P(Vector, ContainerTest,
testing::Types<std::vector<int> >);
#endif // GTEST_HAS_TYPED_TEST_P
@@ -31,6 +31,7 @@
#include "test/gtest-typed-test_test.h"
#include <set>
#include <type_traits>
#include <vector>
#include "gtest/gtest.h"
@@ -87,9 +88,6 @@ class CommonTest : public Test {
template <typename T>
T* CommonTest<T>::shared_ = nullptr;
// This #ifdef block tests typed tests.
#if GTEST_HAS_TYPED_TEST
using testing::Types;
// Tests that SetUpTestSuite()/TearDownTestSuite(), fixture ctor/dtor,
@@ -177,10 +175,10 @@ class TypedTestNames {
public:
template <typename T>
static std::string GetName(int i) {
if (testing::internal::IsSame<T, char>::value) {
if (std::is_same<T, char>::value) {
return std::string("char") + ::testing::PrintToString(i);
}
if (testing::internal::IsSame<T, int>::value) {
if (std::is_same<T, int>::value) {
return std::string("int") + ::testing::PrintToString(i);
}
}
@@ -189,25 +187,20 @@ class TypedTestNames {
TYPED_TEST_SUITE(TypedTestWithNames, TwoTypes, TypedTestNames);
TYPED_TEST(TypedTestWithNames, TestSuiteName) {
if (testing::internal::IsSame<TypeParam, char>::value) {
if (std::is_same<TypeParam, char>::value) {
EXPECT_STREQ(::testing::UnitTest::GetInstance()
->current_test_info()
->test_case_name(),
->test_suite_name(),
"TypedTestWithNames/char0");
}
if (testing::internal::IsSame<TypeParam, int>::value) {
if (std::is_same<TypeParam, int>::value) {
EXPECT_STREQ(::testing::UnitTest::GetInstance()
->current_test_info()
->test_case_name(),
->test_suite_name(),
"TypedTestWithNames/int1");
}
}
#endif // GTEST_HAS_TYPED_TEST
// This #ifdef block tests type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
using testing::Types;
using testing::internal::TypedTestSuitePState;
@@ -227,7 +220,7 @@ class TypedTestSuitePStateTest : public Test {
TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) {
const char* tests = "A, B, C";
EXPECT_EQ(tests,
state_.VerifyRegisteredTestNames("foo.cc", 1, tests));
state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, tests));
}
// Makes sure that the order of the tests and spaces around the names
@@ -235,33 +228,33 @@ TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) {
TEST_F(TypedTestSuitePStateTest, IgnoresOrderAndSpaces) {
const char* tests = "A,C, B";
EXPECT_EQ(tests,
state_.VerifyRegisteredTestNames("foo.cc", 1, tests));
state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, tests));
}
using TypedTestSuitePStateDeathTest = TypedTestSuitePStateTest;
TEST_F(TypedTestSuitePStateDeathTest, DetectsDuplicates) {
EXPECT_DEATH_IF_SUPPORTED(
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"),
state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, A, C"),
"foo\\.cc.1.?: Test A is listed more than once\\.");
}
TEST_F(TypedTestSuitePStateDeathTest, DetectsExtraTest) {
EXPECT_DEATH_IF_SUPPORTED(
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"),
state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, C, D"),
"foo\\.cc.1.?: No test named D can be found in this test suite\\.");
}
TEST_F(TypedTestSuitePStateDeathTest, DetectsMissedTest) {
EXPECT_DEATH_IF_SUPPORTED(
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"),
state_.VerifyRegisteredTestNames("Suite", "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(TypedTestSuitePStateDeathTest, DetectsTestAfterRegistration) {
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C");
state_.VerifyRegisteredTestNames("Suite", "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_SUITE_P"
@@ -311,16 +304,16 @@ class TypeParametrizedTestWithNames : public Test {};
TYPED_TEST_SUITE_P(TypeParametrizedTestWithNames);
TYPED_TEST_P(TypeParametrizedTestWithNames, TestSuiteName) {
if (testing::internal::IsSame<TypeParam, char>::value) {
if (std::is_same<TypeParam, char>::value) {
EXPECT_STREQ(::testing::UnitTest::GetInstance()
->current_test_info()
->test_case_name(),
->test_suite_name(),
"CustomName/TypeParametrizedTestWithNames/parChar0");
}
if (testing::internal::IsSame<TypeParam, int>::value) {
if (std::is_same<TypeParam, int>::value) {
EXPECT_STREQ(::testing::UnitTest::GetInstance()
->current_test_info()
->test_case_name(),
->test_suite_name(),
"CustomName/TypeParametrizedTestWithNames/parInt1");
}
}
@@ -331,10 +324,10 @@ class TypeParametrizedTestNames {
public:
template <typename T>
static std::string GetName(int i) {
if (testing::internal::IsSame<T, char>::value) {
if (std::is_same<T, char>::value) {
return std::string("parChar") + ::testing::PrintToString(i);
}
if (testing::internal::IsSame<T, int>::value) {
if (std::is_same<T, int>::value) {
return std::string("parInt") + ::testing::PrintToString(i);
}
}
@@ -442,20 +435,3 @@ INSTANTIATE_TYPED_TEST_SUITE_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) {}
#if _MSC_VER
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4127
#endif // _MSC_VER
#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
@@ -27,14 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
#ifndef GOOGLETEST_TEST_GTEST_TYPED_TEST_TEST_H_
#define GOOGLETEST_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
@@ -60,6 +57,4 @@ TYPED_TEST_P(ContainerTest, InitialSizeIsZero) {
REGISTER_TYPED_TEST_SUITE_P(ContainerTest,
CanBeDefaultConstructed, InitialSizeIsZero);
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
#endif // GOOGLETEST_TEST_GTEST_TYPED_TEST_TEST_H_
@@ -55,8 +55,8 @@ class UnitTestHelper {
// name. The caller is responsible for deleting the array.
static TestSuite const** GetSortedTestSuites() {
UnitTest& unit_test = *UnitTest::GetInstance();
auto const** const test_suites =
new const TestSuite*[unit_test.total_test_suite_count()];
auto const** const test_suites = new const TestSuite*[static_cast<size_t>(
unit_test.total_test_suite_count())];
for (int i = 0; i < unit_test.total_test_suite_count(); ++i)
test_suites[i] = unit_test.GetTestSuite(i);
@@ -83,8 +83,8 @@ class UnitTestHelper {
// sorted by the test name. The caller is responsible for deleting the
// array.
static TestInfo const** GetSortedTests(const TestSuite* test_suite) {
TestInfo const** const tests =
new const TestInfo*[test_suite->total_test_count()];
TestInfo const** const tests = new const TestInfo*[static_cast<size_t>(
test_suite->total_test_count())];
for (int i = 0; i < test_suite->total_test_count(); ++i)
tests[i] = test_suite->GetTestInfo(i);
@@ -95,17 +95,12 @@ class UnitTestHelper {
}
};
#if GTEST_HAS_TYPED_TEST
template <typename T> class TestSuiteWithCommentTest : public Test {};
TYPED_TEST_SUITE(TestSuiteWithCommentTest, Types<int>);
TYPED_TEST(TestSuiteWithCommentTest, Dummy) {}
const int kTypedTestSuites = 1;
const int kTypedTests = 1;
#else
const int kTypedTestSuites = 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
@@ -123,9 +118,7 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) {
EXPECT_STREQ("ApiTest", test_suites[0]->name());
EXPECT_STREQ("DISABLED_Test", test_suites[1]->name());
#if GTEST_HAS_TYPED_TEST
EXPECT_STREQ("TestSuiteWithCommentTest/0", test_suites[2]->name());
#endif // GTEST_HAS_TYPED_TEST
delete[] test_suites;
@@ -183,12 +176,11 @@ TEST(ApiTest, TestSuiteImmutableAccessorsWork) {
delete[] tests;
tests = nullptr;
#if GTEST_HAS_TYPED_TEST
test_suite = UnitTestHelper::FindTestSuite("TestSuiteWithCommentTest/0");
ASSERT_TRUE(test_suite != nullptr);
EXPECT_STREQ("TestSuiteWithCommentTest/0", test_suite->name());
EXPECT_STREQ(GetTypeName<int>().c_str(), test_suite->type_param());
EXPECT_STREQ(GetTypeName<Types<int>>().c_str(), test_suite->type_param());
EXPECT_TRUE(test_suite->should_run());
EXPECT_EQ(0, test_suite->disabled_test_count());
EXPECT_EQ(1, test_suite->test_to_run_count());
@@ -199,11 +191,10 @@ TEST(ApiTest, TestSuiteImmutableAccessorsWork) {
EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestSuiteWithCommentTest/0", tests[0]->test_suite_name());
EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
EXPECT_STREQ(GetTypeName<Types<int>>().c_str(), tests[0]->type_param());
EXPECT_TRUE(tests[0]->should_run());
delete[] tests;
#endif // GTEST_HAS_TYPED_TEST
}
TEST(ApiTest, TestSuiteDisabledAccessorsWork) {
@@ -263,9 +254,9 @@ class FinalSuccessChecker : public Environment {
EXPECT_EQ(0, test_suites[1]->successful_test_count());
EXPECT_EQ(0, test_suites[1]->failed_test_count());
#if GTEST_HAS_TYPED_TEST
EXPECT_STREQ("TestSuiteWithCommentTest/0", test_suites[2]->name());
EXPECT_STREQ(GetTypeName<int>().c_str(), test_suites[2]->type_param());
EXPECT_STREQ(GetTypeName<Types<int>>().c_str(),
test_suites[2]->type_param());
EXPECT_TRUE(test_suites[2]->should_run());
EXPECT_EQ(0, test_suites[2]->disabled_test_count());
ASSERT_EQ(1, test_suites[2]->total_test_count());
@@ -273,7 +264,6 @@ class FinalSuccessChecker : public Environment {
EXPECT_EQ(0, test_suites[2]->failed_test_count());
EXPECT_TRUE(test_suites[2]->Passed());
EXPECT_FALSE(test_suites[2]->Failed());
#endif // GTEST_HAS_TYPED_TEST
const TestSuite* test_suite = UnitTestHelper::FindTestSuite("ApiTest");
const TestInfo** tests = UnitTestHelper::GetSortedTests(test_suite);
@@ -310,20 +300,18 @@ class FinalSuccessChecker : public Environment {
delete[] tests;
#if GTEST_HAS_TYPED_TEST
test_suite = UnitTestHelper::FindTestSuite("TestSuiteWithCommentTest/0");
tests = UnitTestHelper::GetSortedTests(test_suite);
EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestSuiteWithCommentTest/0", tests[0]->test_suite_name());
EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
EXPECT_STREQ(GetTypeName<Types<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_suites;
}
};
@@ -116,7 +116,7 @@ void Check(bool condition, const char* msg) {
}
}
// Runs the tests. Return true iff successful.
// Runs the tests. Return true if and only if successful.
//
// The 'failure' parameter specifies the type of failure that should
// be generated by the global set-up.

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