* Add PDAL-remove-gtest.patch to remove the venored gtest, which was
re-added by 2.9.1
* PDAL 2.9.1 contained the following changes:
+ Sorting behaviour was changed, due to issues on Windows
+ Fixed build issues and compiler warnings
+ pdal --info will now return the same data as the python library's
pipeline.quickinfo
+ Adds support for Arrow 21+
+ Adds protection against empty views to some filters
+ Adds new Radius assign filter
+ Venored gtest was added back, with intent to drop again for 2.10
* PDAL 2.9.2 contains the following changes:
+ Vendored arbiter now has a custom pdal namespace
+ VSIIO will now call fp->Flush() when syncing the VSIStreamBuffer
+ StageWrapper will no longer run on empty views
OBS-URL: https://build.opensuse.org/package/show/Application:Geo/PDAL?expand=0&rev=55
28744 lines
1.1 MiB
28744 lines
1.1 MiB
5fbda53ee N 2025-09-12 18:08:10 +0200 Enno Tensing <tenno+suse@suij.in> Revert "Back to vendor'd gtest (#4801)"
|
|
diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake
|
|
index f555c2235..749418fb1 100644
|
|
--- a/cmake/gtest.cmake
|
|
+++ b/cmake/gtest.cmake
|
|
@@ -1,42 +1,86 @@
|
|
-if (MSVC)
|
|
- # Since tests link CRT dynamically (/MD[d]), require gtest to
|
|
- #link dynamically too (default is /MT[d])
|
|
- option(gtest_force_shared_crt "Always use shared Visual C++ run-time DLL" ON)
|
|
+# CMake configuration stolen from PROJ unit tests
|
|
+# External GTest provided by (e.g.) libgtest-dev
|
|
+
|
|
+set(MIN_GTest_VERSION "1.15.0")
|
|
+
|
|
+if(NOT CMAKE_REQUIRED_QUIET)
|
|
+ # CMake 3.17+ use CHECK_START/CHECK_PASS/CHECK_FAIL
|
|
+ message(STATUS "Looking for GTest")
|
|
+endif()
|
|
+find_package(GTest QUIET CONFIG)
|
|
+set(USE_EXTERNAL_GTEST_DEFAULT OFF)
|
|
+if(GTest_FOUND)
|
|
+ if(NOT CMAKE_REQUIRED_QUIET)
|
|
+ message(STATUS "Looking for GTest - found (${GTest_VERSION})")
|
|
+ endif()
|
|
+ if(GTest_VERSION VERSION_LESS MIN_GTest_VERSION)
|
|
+ message(WARNING "External GTest version is too old")
|
|
+ else()
|
|
+ set(USE_EXTERNAL_GTEST_DEFAULT ON)
|
|
+ endif()
|
|
+else()
|
|
+ if(NOT CMAKE_REQUIRED_QUIET)
|
|
+ message(STATUS "Looking for GTest - not found")
|
|
+ endif()
|
|
endif()
|
|
|
|
- include_directories(${ROOT_DIR}/vendor/gtest/include
|
|
- ${ROOT_DIR}/vendor/gtest)
|
|
+option(USE_EXTERNAL_GTEST
|
|
+ "Compile against external GTest"
|
|
+ ${USE_EXTERNAL_GTEST_DEFAULT}
|
|
+)
|
|
|
|
-set(GOOGLETEST_VERSION 1.12.1)
|
|
-add_subdirectory(vendor/gtest)
|
|
+if(USE_EXTERNAL_GTEST)
|
|
|
|
-set(FPHSA_NAME_MISMATCHED 1) # Suppress warnings, see https://cmake.org/cmake/help/v3.17/module/FindPackageHandleStandardArgs.html
|
|
+ if(NOT GTest_FOUND)
|
|
+ message(SEND_ERROR "External GTest >= ${MIN_GTest_VERSION} not found, \
|
|
+ skipping some tests")
|
|
+ # exit the remainder of this file
|
|
+ return()
|
|
+ endif()
|
|
+ message(STATUS "Using external GTest from build environment")
|
|
|
|
+ # CMake < 3.20.0 uses GTest::GTest
|
|
+ # CMake >= 3.20 uses GTest::gtest, and deprecates GTest::GTest
|
|
+ # so for older CMake, create an alias from GTest::GTest to GTest::gtest
|
|
+ if(NOT TARGET GTest::gtest)
|
|
+ add_library(GTest::gtest INTERFACE IMPORTED)
|
|
+ set_target_properties(GTest::gtest PROPERTIES
|
|
+ INTERFACE_LINK_LIBRARIES "GTest::GTest")
|
|
+ endif()
|
|
|
|
-if (WITH_ABSEIL)
|
|
- find_package(absl REQUIRED)
|
|
- set(FPHSA_NAME_MISMATCHED 0)
|
|
+else()
|
|
|
|
- if (absl_FOUND)
|
|
- find_package(re2 REQUIRED)
|
|
+ message(STATUS "Fetching GTest from GitHub ...")
|
|
|
|
- if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
|
|
- cmake_policy(SET CMP0079 NEW)
|
|
- endif()
|
|
- target_compile_definitions(gtest PUBLIC GTEST_HAS_ABSL=1)
|
|
- target_compile_definitions(gtest_main PUBLIC GTEST_HAS_ABSL=1)
|
|
- target_link_libraries(gtest PRIVATE absl::algorithm
|
|
- absl::base
|
|
- absl::flags
|
|
- absl::flags_internal
|
|
- absl::flags_usage
|
|
- absl::flags_commandlineflag
|
|
- absl::flags_parse
|
|
- absl::debugging
|
|
- absl::numeric
|
|
- absl::strings
|
|
- absl::utility
|
|
- absl::failure_signal_handler)
|
|
- target_link_libraries(gtest PUBLIC re2::re2)
|
|
+ # Add Google Test
|
|
+ #
|
|
+ # See https://github.com/google/googletest/blob/main/googletest/README.md
|
|
+
|
|
+ if(POLICY CMP0135)
|
|
+ cmake_policy(SET CMP0135 NEW) # for DOWNLOAD_EXTRACT_TIMESTAMP option
|
|
+ endif()
|
|
+
|
|
+ set(GTEST_VERSION "1.15.2")
|
|
+
|
|
+ include(FetchContent)
|
|
+ FetchContent_Declare(
|
|
+ googletest
|
|
+ URL https://github.com/google/googletest/archive/refs/tags/v${GTEST_VERSION}.zip
|
|
+ EXCLUDE_FROM_ALL # ignored before CMake 3.28
|
|
+ )
|
|
+
|
|
+ # For Windows: Prevent overriding the parent project's compiler/linker settings
|
|
+ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
+
|
|
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.28.0")
|
|
+ FetchContent_MakeAvailable(googletest)
|
|
+ else()
|
|
+ # Pre CMake 3.28 workaround to prevent installing files
|
|
+ FetchContent_GetProperties(googletest)
|
|
+ if(NOT googletest_POPULATED)
|
|
+ FetchContent_Populate(googletest)
|
|
+ add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
|
|
endif()
|
|
+ endif()
|
|
endif()
|
|
+
|
|
diff --git a/cmake/macros.cmake b/cmake/macros.cmake
|
|
index 07b81d1f6..645c77e1c 100644
|
|
--- a/cmake/macros.cmake
|
|
+++ b/cmake/macros.cmake
|
|
@@ -184,6 +184,10 @@ endmacro(PDAL_ADD_PLUGIN)
|
|
# LINK_WITH link test executable with libraries
|
|
# INCLUDES header file directories
|
|
#
|
|
+# If we don't have GTest go activate it first
|
|
+if(WITH_TESTS AND NOT TARGET GTest::gtest)
|
|
+ include (${PDAL_CMAKE_DIR}/gtest.cmake)
|
|
+endif()
|
|
|
|
macro(PDAL_ADD_TEST _name)
|
|
|
|
@@ -217,6 +221,7 @@ macro(PDAL_ADD_TEST _name)
|
|
PRIVATE
|
|
${PDAL_LIB_NAME}
|
|
GTest::gtest
|
|
+ GTest::gtest_main
|
|
${PDAL_ADD_TEST_LINK_WITH}
|
|
${WINSOCK_LIBRARY}
|
|
)
|
|
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
|
|
index 5ab4dc9a1..875e9f687 100644
|
|
--- a/test/unit/CMakeLists.txt
|
|
+++ b/test/unit/CMakeLists.txt
|
|
@@ -21,6 +21,7 @@ target_link_libraries(${PDAL_TEST_SUPPORT_OBJS}
|
|
PRIVATE
|
|
${PDAL_LIB_NAME}
|
|
GTest::gtest
|
|
+ GTest::gtest_main
|
|
)
|
|
target_include_directories(${PDAL_TEST_SUPPORT_OBJS}
|
|
PRIVATE
|
|
diff --git a/vendor/gtest/CMakeLists.txt b/vendor/gtest/CMakeLists.txt
|
|
deleted file mode 100644
|
|
index 028911295..000000000
|
|
--- a/vendor/gtest/CMakeLists.txt
|
|
+++ /dev/null
|
|
@@ -1,322 +0,0 @@
|
|
-########################################################################
|
|
-# Note: CMake support is community-based. The maintainers do not use CMake
|
|
-# internally.
|
|
-#
|
|
-# CMake build script for Google Test.
|
|
-#
|
|
-# To run the tests for Google Test itself on Linux, use 'make test' or
|
|
-# ctest. You can select which tests to run using 'ctest -R regex'.
|
|
-# For more options, run 'ctest --help'.
|
|
-
|
|
-# When other libraries are using a shared version of runtime libraries,
|
|
-# Google Test also has to use one.
|
|
-option(
|
|
- gtest_force_shared_crt
|
|
- "Use shared (DLL) run-time lib even when Google Test is built as static lib."
|
|
- OFF)
|
|
-
|
|
-option(gtest_build_tests "Build all of gtest's own tests." OFF)
|
|
-
|
|
-option(gtest_build_samples "Build gtest's sample programs." OFF)
|
|
-
|
|
-option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
|
|
-
|
|
-option(
|
|
- gtest_hide_internal_symbols
|
|
- "Build gtest with internal symbols hidden in shared libraries."
|
|
- OFF)
|
|
-
|
|
-# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
|
-include(cmake/hermetic_build.cmake OPTIONAL)
|
|
-
|
|
-if (COMMAND pre_project_set_up_hermetic_build)
|
|
- pre_project_set_up_hermetic_build()
|
|
-endif()
|
|
-
|
|
-########################################################################
|
|
-#
|
|
-# Project-wide settings
|
|
-
|
|
-# Name of the project.
|
|
-#
|
|
-# CMake files in this project can refer to the root source directory
|
|
-# as ${gtest_SOURCE_DIR} and to the root binary directory as
|
|
-# ${gtest_BINARY_DIR}.
|
|
-# Language "C" is required for find_package(Threads).
|
|
-
|
|
-# Project version:
|
|
-
|
|
-cmake_minimum_required(VERSION 3.13)
|
|
-cmake_policy(SET CMP0048 NEW)
|
|
-project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
|
|
-
|
|
-if (POLICY CMP0063) # Visibility
|
|
- cmake_policy(SET CMP0063 NEW)
|
|
-endif (POLICY CMP0063)
|
|
-
|
|
-if (COMMAND set_up_hermetic_build)
|
|
- set_up_hermetic_build()
|
|
-endif()
|
|
-
|
|
-# These commands only run if this is the main project
|
|
-if(CMAKE_PROJECT_NAME STREQUAL "gtest" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution")
|
|
-
|
|
- # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
|
- # make it prominent in the GUI.
|
|
- option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
|
|
-
|
|
-else()
|
|
-
|
|
- mark_as_advanced(
|
|
- gtest_force_shared_crt
|
|
- gtest_build_tests
|
|
- gtest_build_samples
|
|
- gtest_disable_pthreads
|
|
- gtest_hide_internal_symbols)
|
|
-
|
|
-endif()
|
|
-
|
|
-
|
|
-if (gtest_hide_internal_symbols)
|
|
- set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
|
- set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
|
|
-endif()
|
|
-
|
|
-# Define helper functions and macros used by Google Test.
|
|
-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(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}")
|
|
- set(version_file "${generated_dir}/${cmake_package_name}ConfigVersion.cmake")
|
|
- write_basic_package_version_file(${version_file} VERSION ${GOOGLETEST_VERSION} COMPATIBILITY AnyNewerVersion)
|
|
- install(EXPORT ${targets_export_name}
|
|
- NAMESPACE ${cmake_package_name}::
|
|
- DESTINATION ${cmake_files_install_dir})
|
|
- set(config_file "${generated_dir}/${cmake_package_name}Config.cmake")
|
|
- configure_package_config_file("${gtest_SOURCE_DIR}/cmake/Config.cmake.in"
|
|
- "${config_file}" INSTALL_DESTINATION ${cmake_files_install_dir})
|
|
- install(FILES ${version_file} ${config_file}
|
|
- DESTINATION ${cmake_files_install_dir})
|
|
-endif()
|
|
-
|
|
-# Where Google Test's .h files can be found.
|
|
-set(gtest_build_include_dirs
|
|
- "${gtest_SOURCE_DIR}/include"
|
|
- "${gtest_SOURCE_DIR}")
|
|
-include_directories(${gtest_build_include_dirs})
|
|
-
|
|
-########################################################################
|
|
-#
|
|
-# Defines the gtest & gtest_main libraries. User tests should link
|
|
-# with one of them.
|
|
-
|
|
-# Google Test libraries. We build them using more strict warnings than what
|
|
-# 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).
|
|
-if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
|
- string(REPLACE ";" "$<SEMICOLON>" dirs "${gtest_build_include_dirs}")
|
|
- target_include_directories(gtest SYSTEM INTERFACE
|
|
- "$<BUILD_INTERFACE:${dirs}>"
|
|
- "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
|
- target_include_directories(gtest_main SYSTEM INTERFACE
|
|
- "$<BUILD_INTERFACE:${dirs}>"
|
|
- "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
|
|
-endif()
|
|
-if(CMAKE_SYSTEM_NAME MATCHES "QNX")
|
|
- target_link_libraries(gtest PUBLIC regex)
|
|
-endif()
|
|
-target_link_libraries(gtest_main PUBLIC gtest)
|
|
-
|
|
-########################################################################
|
|
-#
|
|
-# Install rules
|
|
-install_project(gtest gtest_main)
|
|
-
|
|
-########################################################################
|
|
-#
|
|
-# Samples on how to link user tests with gtest or gtest_main.
|
|
-#
|
|
-# They are not built by default. To build them, set the
|
|
-# gtest_build_samples option to ON. You can do it by running ccmake
|
|
-# or specifying the -Dgtest_build_samples=ON flag when running cmake.
|
|
-
|
|
-if (gtest_build_samples)
|
|
- cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
|
|
- cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)
|
|
- cxx_executable(sample3_unittest samples gtest_main)
|
|
- cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)
|
|
- cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)
|
|
- cxx_executable(sample6_unittest samples gtest_main)
|
|
- cxx_executable(sample7_unittest samples gtest_main)
|
|
- cxx_executable(sample8_unittest samples gtest_main)
|
|
- cxx_executable(sample9_unittest samples gtest)
|
|
- cxx_executable(sample10_unittest samples gtest)
|
|
-endif()
|
|
-
|
|
-########################################################################
|
|
-#
|
|
-# Google Test's own tests.
|
|
-#
|
|
-# You can skip this section if you aren't interested in testing
|
|
-# Google Test itself.
|
|
-#
|
|
-# The tests are not built by default. To build them, set the
|
|
-# gtest_build_tests option to ON. You can do it by running ccmake
|
|
-# or specifying the -Dgtest_build_tests=ON flag when running cmake.
|
|
-
|
|
-if (gtest_build_tests)
|
|
- # This must be set in the root directory for the tests to be run by
|
|
- # 'make test' or ctest.
|
|
- enable_testing()
|
|
-
|
|
- ############################################################
|
|
- # C++ tests built with standard compiler flags.
|
|
-
|
|
- cxx_test(googletest-death-test-test gtest_main)
|
|
- cxx_test(gtest_environment_test gtest)
|
|
- cxx_test(googletest-filepath-test gtest_main)
|
|
- cxx_test(googletest-listener-test gtest_main)
|
|
- cxx_test(gtest_main_unittest gtest_main)
|
|
- cxx_test(googletest-message-test gtest_main)
|
|
- cxx_test(gtest_no_test_unittest gtest)
|
|
- cxx_test(googletest-options-test gtest_main)
|
|
- cxx_test(googletest-param-test-test gtest
|
|
- test/googletest-param-test2-test.cc)
|
|
- cxx_test(googletest-port-test gtest_main)
|
|
- cxx_test(gtest_pred_impl_unittest gtest_main)
|
|
- cxx_test(gtest_premature_exit_test gtest
|
|
- test/gtest_premature_exit_test.cc)
|
|
- cxx_test(googletest-printers-test gtest_main)
|
|
- cxx_test(gtest_prod_test gtest_main
|
|
- test/production.cc)
|
|
- cxx_test(gtest_repeat_test gtest)
|
|
- cxx_test(gtest_sole_header_test gtest_main)
|
|
- cxx_test(gtest_stress_test gtest)
|
|
- cxx_test(googletest-test-part-test gtest_main)
|
|
- cxx_test(gtest_throw_on_failure_ex_test gtest)
|
|
- cxx_test(gtest-typed-test_test gtest_main
|
|
- test/gtest-typed-test2_test.cc)
|
|
- cxx_test(gtest_unittest gtest_main)
|
|
- cxx_test(gtest-unittest-api_test gtest)
|
|
- cxx_test(gtest_skip_in_environment_setup_test gtest_main)
|
|
- cxx_test(gtest_skip_test gtest_main)
|
|
-
|
|
- ############################################################
|
|
- # C++ tests built with non-standard compiler flags.
|
|
-
|
|
- # MSVC 7.1 does not support STL with exceptions disabled.
|
|
- if (NOT MSVC OR MSVC_VERSION GREATER 1310)
|
|
- cxx_library(gtest_no_exception "${cxx_no_exception}"
|
|
- src/gtest-all.cc)
|
|
- cxx_library(gtest_main_no_exception "${cxx_no_exception}"
|
|
- src/gtest-all.cc src/gtest_main.cc)
|
|
- endif()
|
|
- cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
|
|
- src/gtest-all.cc src/gtest_main.cc)
|
|
-
|
|
- cxx_test_with_flags(gtest-death-test_ex_nocatch_test
|
|
- "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0"
|
|
- gtest test/googletest-death-test_ex_test.cc)
|
|
- cxx_test_with_flags(gtest-death-test_ex_catch_test
|
|
- "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1"
|
|
- gtest test/googletest-death-test_ex_test.cc)
|
|
-
|
|
- cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
|
|
- gtest_main_no_rtti test/gtest_unittest.cc)
|
|
-
|
|
- cxx_shared_library(gtest_dll "${cxx_default}"
|
|
- src/gtest-all.cc src/gtest_main.cc)
|
|
-
|
|
- cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}"
|
|
- gtest_dll test/gtest_all_test.cc)
|
|
- set_target_properties(gtest_dll_test_
|
|
- PROPERTIES
|
|
- COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
|
|
-
|
|
- ############################################################
|
|
- # Python tests.
|
|
-
|
|
- 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.
|
|
- if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003
|
|
- cxx_executable_with_flags(
|
|
- googletest-catch-exceptions-no-ex-test_
|
|
- "${cxx_no_exception}"
|
|
- gtest_main_no_exception
|
|
- test/googletest-catch-exceptions-test_.cc)
|
|
- endif()
|
|
-
|
|
- cxx_executable_with_flags(
|
|
- googletest-catch-exceptions-ex-test_
|
|
- "${cxx_exception}"
|
|
- gtest_main
|
|
- test/googletest-catch-exceptions-test_.cc)
|
|
- py_test(googletest-catch-exceptions-test)
|
|
-
|
|
- cxx_executable(googletest-color-test_ test gtest)
|
|
- py_test(googletest-color-test)
|
|
-
|
|
- cxx_executable(googletest-env-var-test_ test gtest)
|
|
- py_test(googletest-env-var-test)
|
|
-
|
|
- cxx_executable(googletest-filter-unittest_ test gtest)
|
|
- py_test(googletest-filter-unittest)
|
|
-
|
|
- cxx_executable(gtest_help_test_ test gtest_main)
|
|
- py_test(gtest_help_test)
|
|
-
|
|
- cxx_executable(googletest-list-tests-unittest_ test gtest)
|
|
- py_test(googletest-list-tests-unittest)
|
|
-
|
|
- cxx_executable(googletest-output-test_ test gtest)
|
|
- py_test(googletest-output-test --no_stacktrace_support)
|
|
-
|
|
- cxx_executable(googletest-shuffle-test_ test gtest)
|
|
- py_test(googletest-shuffle-test)
|
|
-
|
|
- # MSVC 7.1 does not support STL with exceptions disabled.
|
|
- if (NOT MSVC OR MSVC_VERSION GREATER 1310)
|
|
- cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception)
|
|
- set_target_properties(googletest-throw-on-failure-test_
|
|
- PROPERTIES
|
|
- COMPILE_FLAGS "${cxx_no_exception}")
|
|
- py_test(googletest-throw-on-failure-test)
|
|
- endif()
|
|
-
|
|
- 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)
|
|
- py_test(googletest-json-outfiles-test)
|
|
-
|
|
- cxx_executable(gtest_xml_output_unittest_ test gtest)
|
|
- py_test(gtest_xml_output_unittest --no_stacktrace_support)
|
|
- py_test(googletest-json-output-unittest --no_stacktrace_support)
|
|
-endif()
|
|
diff --git a/vendor/gtest/README.md b/vendor/gtest/README.md
|
|
deleted file mode 100644
|
|
index d26b309ed..000000000
|
|
--- a/vendor/gtest/README.md
|
|
+++ /dev/null
|
|
@@ -1,217 +0,0 @@
|
|
-### Generic Build Instructions
|
|
-
|
|
-#### Setup
|
|
-
|
|
-To build GoogleTest and your tests that use it, you need to tell your build
|
|
-system where to find its headers and source files. The exact way to do it
|
|
-depends on which build system you use, and is usually straightforward.
|
|
-
|
|
-### Build with CMake
|
|
-
|
|
-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 GoogleTest as a
|
|
-standalone project or it can be incorporated into an existing CMake build for
|
|
-another project.
|
|
-
|
|
-#### Standalone CMake Project
|
|
-
|
|
-When building GoogleTest as a standalone project, the typical workflow starts
|
|
-with
|
|
-
|
|
-```
|
|
-git clone https://github.com/google/googletest.git -b release-1.11.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 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
|
|
-Studio.
|
|
-
|
|
-On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated.
|
|
-
|
|
-#### Incorporating Into An Existing CMake Project
|
|
-
|
|
-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:
|
|
-
|
|
-* Download the GoogleTest source code manually and place it at a known
|
|
- location. This is the least flexible approach and can make it more difficult
|
|
- to use with continuous integration systems, etc.
|
|
-* Embed the GoogleTest source code as a direct copy in the main project's
|
|
- source tree. This is often the simplest approach, but is also the hardest to
|
|
- keep up to date. Some organizations may not permit this method.
|
|
-* Add GoogleTest as a git submodule or equivalent. This may not always be
|
|
- possible or appropriate. Git submodules, for example, have their own set of
|
|
- advantages and drawbacks.
|
|
-* Use CMake to download GoogleTest as part of the build's configure step. This
|
|
- approach doesn't have the limitations of the other methods.
|
|
-
|
|
-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.
|
|
-
|
|
-Just add to your `CMakeLists.txt`:
|
|
-
|
|
-```cmake
|
|
-include(FetchContent)
|
|
-FetchContent_Declare(
|
|
- googletest
|
|
- # Specify the commit you depend on and update it regularly.
|
|
- URL https://github.com/google/googletest/archive/e2239ee6043f73722e7aa812a459f54a28552929.zip
|
|
-)
|
|
-# For Windows: Prevent overriding the parent project's compiler/linker settings
|
|
-set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
-FetchContent_MakeAvailable(googletest)
|
|
-
|
|
-# Now simply link against gtest or gtest_main as needed. Eg
|
|
-add_executable(example example.cpp)
|
|
-target_link_libraries(example gtest_main)
|
|
-add_test(NAME example_test COMMAND example)
|
|
-```
|
|
-
|
|
-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
|
|
-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
|
|
-
|
|
-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.
|
|
-
|
|
-#### C++ Standard Version
|
|
-
|
|
-An environment that supports C++11 is required in order to successfully build
|
|
-GoogleTest. One way to ensure this is to specify the standard in the top-level
|
|
-project, for example by using the `set(CMAKE_CXX_STANDARD 11)` command. If this
|
|
-is not feasible, for example in a C project using GoogleTest for validation,
|
|
-then it can be specified by adding it to the options for cmake via the
|
|
-`DCMAKE_CXX_FLAGS` option.
|
|
-
|
|
-### Tweaking GoogleTest
|
|
-
|
|
-GoogleTest can be used in diverse environments. The default configuration may
|
|
-not work (or may not work well) out of the box in some environments. However,
|
|
-you can easily tweak GoogleTest by defining control macros on the compiler
|
|
-command line. Generally, these macros are named like `GTEST_XYZ` and you define
|
|
-them to either 1 or 0 to enable or disable a certain feature.
|
|
-
|
|
-We list the most frequently used macros below. For a complete list, see file
|
|
-[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/master/googletest/include/gtest/internal/gtest-port.h).
|
|
-
|
|
-### Multi-threaded Tests
|
|
-
|
|
-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 GoogleTest doesn't correctly detect whether pthread is available in your
|
|
-environment, you can force it with
|
|
-
|
|
- -DGTEST_HAS_PTHREAD=1
|
|
-
|
|
-or
|
|
-
|
|
- -DGTEST_HAS_PTHREAD=0
|
|
-
|
|
-When 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, 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)
|
|
-
|
|
-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
|
|
-
|
|
- -DGTEST_CREATE_SHARED_LIBRARY=1
|
|
-
|
|
-to the compiler flags. You'll also need to tell the linker to produce a shared
|
|
-library instead - consult your linker's manual for how to do it.
|
|
-
|
|
-To compile your *tests* that use the gtest shared library, add
|
|
-
|
|
- -DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
|
-
|
|
-to the compiler flags.
|
|
-
|
|
-Note: while the above steps aren't technically necessary today when using some
|
|
-compilers (e.g. GCC), they may become necessary in the future, if we decide to
|
|
-improve the speed of loading the library (see
|
|
-<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are recommended
|
|
-to always add the above flags when using 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
|
|
-GoogleTest macro clashes with another library, you can force GoogleTest to
|
|
-rename its macro to avoid the conflict.
|
|
-
|
|
-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 GoogleTest to change the macro's name from `FOO`
|
|
-to `GTEST_FOO`. Currently `FOO` can be `ASSERT_EQ`, `ASSERT_FALSE`, `ASSERT_GE`,
|
|
-`ASSERT_GT`, `ASSERT_LE`, `ASSERT_LT`, `ASSERT_NE`, `ASSERT_TRUE`,
|
|
-`EXPECT_FALSE`, `EXPECT_TRUE`, `FAIL`, `SUCCEED`, `TEST`, or `TEST_F`. For
|
|
-example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
|
|
-
|
|
- GTEST_TEST(SomeTest, DoesThis) { ... }
|
|
-
|
|
-instead of
|
|
-
|
|
- TEST(SomeTest, DoesThis) { ... }
|
|
-
|
|
-in order to define a test.
|
|
diff --git a/vendor/gtest/cmake/Config.cmake.in b/vendor/gtest/cmake/Config.cmake.in
|
|
deleted file mode 100644
|
|
index 12be4498b..000000000
|
|
--- a/vendor/gtest/cmake/Config.cmake.in
|
|
+++ /dev/null
|
|
@@ -1,9 +0,0 @@
|
|
-@PACKAGE_INIT@
|
|
-include(CMakeFindDependencyMacro)
|
|
-if (@GTEST_HAS_PTHREAD@)
|
|
- set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@)
|
|
- find_dependency(Threads)
|
|
-endif()
|
|
-
|
|
-include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
|
|
-check_required_components("@project_name@")
|
|
diff --git a/vendor/gtest/cmake/gtest.pc.in b/vendor/gtest/cmake/gtest.pc.in
|
|
deleted file mode 100644
|
|
index b4148fae4..000000000
|
|
--- a/vendor/gtest/cmake/gtest.pc.in
|
|
+++ /dev/null
|
|
@@ -1,9 +0,0 @@
|
|
-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@
|
|
diff --git a/vendor/gtest/cmake/gtest_main.pc.in b/vendor/gtest/cmake/gtest_main.pc.in
|
|
deleted file mode 100644
|
|
index 38c88c54d..000000000
|
|
--- a/vendor/gtest/cmake/gtest_main.pc.in
|
|
+++ /dev/null
|
|
@@ -1,10 +0,0 @@
|
|
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
|
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
|
-
|
|
-Name: gtest_main
|
|
-Description: GoogleTest (with main() function)
|
|
-Version: @PROJECT_VERSION@
|
|
-URL: https://github.com/google/googletest
|
|
-Requires: gtest = @PROJECT_VERSION@
|
|
-Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@
|
|
-Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@
|
|
diff --git a/vendor/gtest/cmake/internal_utils.cmake b/vendor/gtest/cmake/internal_utils.cmake
|
|
deleted file mode 100644
|
|
index 5a34c07a1..000000000
|
|
--- a/vendor/gtest/cmake/internal_utils.cmake
|
|
+++ /dev/null
|
|
@@ -1,342 +0,0 @@
|
|
-# Defines functions and macros useful for building Google Test and
|
|
-# Google Mock.
|
|
-#
|
|
-# Note:
|
|
-#
|
|
-# - This file will be run twice when building Google Mock (once via
|
|
-# Google Test's CMakeLists.txt, and once via Google Mock's).
|
|
-# Therefore it shouldn't have any side effects other than defining
|
|
-# the functions and macros.
|
|
-#
|
|
-# - The functions/macros defined in this file may depend on Google
|
|
-# Test and Google Mock's option() definitions, and thus must be
|
|
-# called *after* the options have been defined.
|
|
-
|
|
-if (POLICY CMP0054)
|
|
- cmake_policy(SET CMP0054 NEW)
|
|
-endif (POLICY CMP0054)
|
|
-
|
|
-# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
|
|
-#
|
|
-# This must be a macro(), as inside a function string() can only
|
|
-# update variables in the function scope.
|
|
-macro(fix_default_compiler_settings_)
|
|
- if (MSVC)
|
|
- # For MSVC, CMake sets certain flags to defaults we want to override.
|
|
- # This replacement code is taken from sample in the CMake Wiki at
|
|
- # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.
|
|
- foreach (flag_var
|
|
- CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
|
- CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
|
- CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
|
- CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
|
- if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
|
|
- # When Google Test is built as a shared library, it should also use
|
|
- # shared runtime libraries. Otherwise, it may end up with multiple
|
|
- # copies of runtime library data in different modules, resulting in
|
|
- # hard-to-find crashes. When it is built as a static library, it is
|
|
- # preferable to use CRT as static libraries, as we don't have to rely
|
|
- # on CRT DLLs being available. CMake always defaults to using shared
|
|
- # CRT libraries, so we override that default here.
|
|
- string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
|
|
- endif()
|
|
-
|
|
- # We prefer more strict warning checking for building Google Test.
|
|
- # Replaces /W3 with /W4 in defaults.
|
|
- string(REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}")
|
|
-
|
|
- # Prevent D9025 warning for targets that have exception handling
|
|
- # turned off (/EHs-c- flag). Where required, exceptions are explicitly
|
|
- # re-enabled using the cxx_exception_flags variable.
|
|
- string(REPLACE "/EHsc" "" ${flag_var} "${${flag_var}}")
|
|
- endforeach()
|
|
- endif()
|
|
-endmacro()
|
|
-
|
|
-# Defines the compiler/linker flags used to build Google Test and
|
|
-# Google Mock. You can tweak these definitions to suit your need. A
|
|
-# variable's value is empty before it's explicitly assigned to.
|
|
-macro(config_compiler_and_linker)
|
|
- # Note: pthreads on MinGW is not supported, even if available
|
|
- # instead, we use windows threading primitives
|
|
- unset(GTEST_HAS_PTHREAD)
|
|
- if (NOT gtest_disable_pthreads AND NOT MINGW)
|
|
- # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
|
|
- find_package(Threads)
|
|
- if (CMAKE_USE_PTHREADS_INIT)
|
|
- set(GTEST_HAS_PTHREAD ON)
|
|
- endif()
|
|
- endif()
|
|
-
|
|
- fix_default_compiler_settings_()
|
|
- 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")
|
|
- 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")
|
|
- set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0")
|
|
- set(cxx_no_rtti_flags "-GR-")
|
|
- # Suppress "unreachable code" warning
|
|
- # http://stackoverflow.com/questions/3232669 explains the issue.
|
|
- set(cxx_base_flags "${cxx_base_flags} -wd4702")
|
|
- # Ensure MSVC treats source files as UTF-8 encoded.
|
|
- set(cxx_base_flags "${cxx_base_flags} -utf-8")
|
|
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
- set(cxx_base_flags "-Wall -Wshadow -Wconversion")
|
|
- set(cxx_exception_flags "-fexceptions")
|
|
- set(cxx_no_exception_flags "-fno-exceptions")
|
|
- set(cxx_strict_flags "-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wredundant-decls")
|
|
- set(cxx_no_rtti_flags "-fno-rtti")
|
|
- elseif (CMAKE_COMPILER_IS_GNUCXX)
|
|
- set(cxx_base_flags "-Wall -Wshadow")
|
|
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
|
- set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
|
|
- endif()
|
|
- set(cxx_exception_flags "-fexceptions")
|
|
- set(cxx_no_exception_flags "-fno-exceptions")
|
|
- # Until version 4.3.2, GCC doesn't define a macro to indicate
|
|
- # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
|
- # explicitly.
|
|
- set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
|
|
- set(cxx_strict_flags
|
|
- "-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
|
|
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
|
|
- set(cxx_exception_flags "-features=except")
|
|
- # Sun Pro doesn't provide macros to indicate whether exceptions and
|
|
- # RTTI are enabled, so we define GTEST_HAS_* explicitly.
|
|
- set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
|
|
- set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
|
|
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
|
|
- CMAKE_CXX_COMPILER_ID STREQUAL "XL")
|
|
- # CMake 2.8 changes Visual Age's compiler ID to "XL".
|
|
- set(cxx_exception_flags "-qeh")
|
|
- set(cxx_no_exception_flags "-qnoeh")
|
|
- # Until version 9.0, Visual Age doesn't define a macro to indicate
|
|
- # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
|
- # explicitly.
|
|
- set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
|
|
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
|
|
- set(cxx_base_flags "-AA -mt")
|
|
- set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1")
|
|
- set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0")
|
|
- # RTTI can not be disabled in HP aCC compiler.
|
|
- set(cxx_no_rtti_flags "")
|
|
- endif()
|
|
-
|
|
- # The pthreads library is available and allowed?
|
|
- if (DEFINED GTEST_HAS_PTHREAD)
|
|
- set(GTEST_HAS_PTHREAD_MACRO "-DGTEST_HAS_PTHREAD=1")
|
|
- else()
|
|
- set(GTEST_HAS_PTHREAD_MACRO "-DGTEST_HAS_PTHREAD=0")
|
|
- endif()
|
|
- set(cxx_base_flags "${cxx_base_flags} ${GTEST_HAS_PTHREAD_MACRO}")
|
|
-
|
|
- # For building gtest's own tests and samples.
|
|
- set(cxx_exception "${cxx_base_flags} ${cxx_exception_flags}")
|
|
- set(cxx_no_exception
|
|
- "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
|
|
- set(cxx_default "${cxx_exception}")
|
|
- set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
|
|
-
|
|
- # For building the gtest libraries.
|
|
- set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
|
|
-endmacro()
|
|
-
|
|
-# Defines the gtest & gtest_main libraries. User tests should link
|
|
-# with one of them.
|
|
-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}")
|
|
- # Set the output directory for build artifacts
|
|
- set_target_properties(${name}
|
|
- PROPERTIES
|
|
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
|
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
|
- ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
|
- PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
- # make PDBs match library name
|
|
- get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX)
|
|
- set_target_properties(${name}
|
|
- PROPERTIES
|
|
- PDB_NAME "${name}"
|
|
- PDB_NAME_DEBUG "${name}${pdb_debug_postfix}"
|
|
- COMPILE_PDB_NAME "${name}"
|
|
- COMPILE_PDB_NAME_DEBUG "${name}${pdb_debug_postfix}")
|
|
-
|
|
- if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
|
|
- set_target_properties(${name}
|
|
- PROPERTIES
|
|
- COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
|
|
- if (NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
|
- target_compile_definitions(${name} INTERFACE
|
|
- $<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)
|
|
- endif()
|
|
- endif()
|
|
- if (DEFINED GTEST_HAS_PTHREAD)
|
|
- if ("${CMAKE_VERSION}" VERSION_LESS "3.1.0")
|
|
- set(threads_spec ${CMAKE_THREAD_LIBS_INIT})
|
|
- else()
|
|
- set(threads_spec Threads::Threads)
|
|
- endif()
|
|
- target_link_libraries(${name} PUBLIC ${threads_spec})
|
|
- endif()
|
|
-
|
|
- if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8")
|
|
- target_compile_features(${name} PUBLIC cxx_std_11)
|
|
- endif()
|
|
-endfunction()
|
|
-
|
|
-########################################################################
|
|
-#
|
|
-# Helper functions for creating build targets.
|
|
-
|
|
-function(cxx_shared_library name cxx_flags)
|
|
- cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
|
|
-endfunction()
|
|
-
|
|
-function(cxx_library name cxx_flags)
|
|
- cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN})
|
|
-endfunction()
|
|
-
|
|
-# cxx_executable_with_flags(name cxx_flags libs srcs...)
|
|
-#
|
|
-# creates a named C++ executable that depends on the given libraries and
|
|
-# is built from the given source files with the given compiler flags.
|
|
-function(cxx_executable_with_flags name cxx_flags libs)
|
|
- add_executable(${name} ${ARGN})
|
|
- if (MSVC)
|
|
- # BigObj required for tests.
|
|
- set(cxx_flags "${cxx_flags} -bigobj")
|
|
- endif()
|
|
- if (cxx_flags)
|
|
- set_target_properties(${name}
|
|
- PROPERTIES
|
|
- COMPILE_FLAGS "${cxx_flags}")
|
|
- endif()
|
|
- if (BUILD_SHARED_LIBS)
|
|
- set_target_properties(${name}
|
|
- PROPERTIES
|
|
- COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
|
|
- endif()
|
|
- # To support mixing linking in static and dynamic libraries, link each
|
|
- # library in with an extra call to target_link_libraries.
|
|
- foreach (lib "${libs}")
|
|
- target_link_libraries(${name} ${lib})
|
|
- endforeach()
|
|
-endfunction()
|
|
-
|
|
-# cxx_executable(name dir lib srcs...)
|
|
-#
|
|
-# creates a named target that depends on the given libs and is built
|
|
-# from the given source files. dir/name.cc is implicitly included in
|
|
-# the source file list.
|
|
-function(cxx_executable name dir libs)
|
|
- cxx_executable_with_flags(
|
|
- ${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
|
|
-endfunction()
|
|
-
|
|
-# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
|
|
-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...)
|
|
-#
|
|
-# creates a named C++ test that depends on the given libs and is built
|
|
-# 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})
|
|
- add_test(NAME ${name} COMMAND "$<TARGET_FILE:${name}>")
|
|
-endfunction()
|
|
-
|
|
-# cxx_test(name libs srcs...)
|
|
-#
|
|
-# creates a named test target that depends on the given libs and is
|
|
-# built from the given source files. Unlike cxx_test_with_flags,
|
|
-# test/name.cc is already implicitly included in the source file list.
|
|
-function(cxx_test name libs)
|
|
- cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
|
|
- "test/${name}.cc" ${ARGN})
|
|
-endfunction()
|
|
-
|
|
-# py_test(name)
|
|
-#
|
|
-# creates a Python test with the given name whose main module is in
|
|
-# test/name.py. It does nothing if Python is not installed.
|
|
-function(py_test name)
|
|
- if (PYTHONINTERP_FOUND)
|
|
- if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 3.1)
|
|
- if (CMAKE_CONFIGURATION_TYPES)
|
|
- # Multi-configuration build generators as for Visual Studio save
|
|
- # output in a subdirectory of CMAKE_CURRENT_BINARY_DIR (Debug,
|
|
- # Release etc.), so we have to provide it here.
|
|
- add_test(NAME ${name}
|
|
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
|
|
- --build_dir=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG> ${ARGN})
|
|
- else (CMAKE_CONFIGURATION_TYPES)
|
|
- # Single-configuration build generators like Makefile generators
|
|
- # don't have subdirs below CMAKE_CURRENT_BINARY_DIR.
|
|
- add_test(NAME ${name}
|
|
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
|
|
- --build_dir=${CMAKE_CURRENT_BINARY_DIR} ${ARGN})
|
|
- endif (CMAKE_CONFIGURATION_TYPES)
|
|
- else()
|
|
- # ${CMAKE_CURRENT_BINARY_DIR} is known at configuration time, so we can
|
|
- # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known
|
|
- # only at ctest runtime (by calling ctest -c <Configuration>), so
|
|
- # we have to escape $ to delay variable substitution here.
|
|
- 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()
|
|
- # Make the Python import path consistent between Bazel and CMake.
|
|
- set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR})
|
|
- endif(PYTHONINTERP_FOUND)
|
|
-endfunction()
|
|
-
|
|
-# install_project(targets...)
|
|
-#
|
|
-# Installs the specified targets and configures the associated pkgconfig files.
|
|
-function(install_project)
|
|
- if(INSTALL_GTEST)
|
|
- install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/"
|
|
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
- # Install the project targets.
|
|
- install(TARGETS ${ARGN}
|
|
- EXPORT ${targets_export_name}
|
|
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
|
- ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
|
- if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|
- # Install PDBs
|
|
- foreach(t ${ARGN})
|
|
- get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME)
|
|
- get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG)
|
|
- get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)
|
|
- install(FILES
|
|
- "${t_pdb_output_directory}/\${CMAKE_INSTALL_CONFIG_NAME}/$<$<CONFIG:Debug>:${t_pdb_name_debug}>$<$<NOT:$<CONFIG:Debug>>:${t_pdb_name}>.pdb"
|
|
- DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
- OPTIONAL)
|
|
- endforeach()
|
|
- endif()
|
|
- # Configure and install pkgconfig files.
|
|
- foreach(t ${ARGN})
|
|
- set(configured_pc "${generated_dir}/${t}.pc")
|
|
- configure_file("${PROJECT_SOURCE_DIR}/cmake/${t}.pc.in"
|
|
- "${configured_pc}" @ONLY)
|
|
- install(FILES "${configured_pc}"
|
|
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
|
- endforeach()
|
|
- endif()
|
|
-endfunction()
|
|
diff --git a/vendor/gtest/cmake/libgtest.la.in b/vendor/gtest/cmake/libgtest.la.in
|
|
deleted file mode 100644
|
|
index 840c83885..000000000
|
|
--- a/vendor/gtest/cmake/libgtest.la.in
|
|
+++ /dev/null
|
|
@@ -1,21 +0,0 @@
|
|
-# libgtest.la - a libtool library file
|
|
-# Generated by libtool (GNU libtool) 2.4.6
|
|
-
|
|
-# Please DO NOT delete this file!
|
|
-# It is necessary for linking the library.
|
|
-
|
|
-# Names of this library.
|
|
-library_names='libgtest.so'
|
|
-
|
|
-# Is this an already installed library?
|
|
-installed=yes
|
|
-
|
|
-# Should we warn about portability when linking against -modules?
|
|
-shouldnotlink=no
|
|
-
|
|
-# Files to dlopen/dlpreopen
|
|
-dlopen=''
|
|
-dlpreopen=''
|
|
-
|
|
-# Directory that this library needs to be installed in:
|
|
-libdir='@CMAKE_INSTALL_FULL_LIBDIR@'
|
|
diff --git a/vendor/gtest/include/gtest/gtest-assertion-result.h b/vendor/gtest/include/gtest/gtest-assertion-result.h
|
|
deleted file mode 100644
|
|
index addbb59c6..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-assertion-result.h
|
|
+++ /dev/null
|
|
@@ -1,237 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This file implements the AssertionResult type.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
|
|
-
|
|
-#include <memory>
|
|
-#include <ostream>
|
|
-#include <string>
|
|
-#include <type_traits>
|
|
-
|
|
-#include "gtest/gtest-message.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// A class for indicating whether an assertion was successful. When
|
|
-// the assertion wasn't successful, the AssertionResult object
|
|
-// remembers a non-empty message that describes how it failed.
|
|
-//
|
|
-// To create an instance of this class, use one of the factory functions
|
|
-// (AssertionSuccess() and AssertionFailure()).
|
|
-//
|
|
-// This class is useful for two purposes:
|
|
-// 1. Defining predicate functions to be used with Boolean test assertions
|
|
-// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
|
|
-// 2. Defining predicate-format functions to be
|
|
-// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
|
|
-//
|
|
-// For example, if you define IsEven predicate:
|
|
-//
|
|
-// testing::AssertionResult IsEven(int n) {
|
|
-// if ((n % 2) == 0)
|
|
-// return testing::AssertionSuccess();
|
|
-// else
|
|
-// return testing::AssertionFailure() << n << " is odd";
|
|
-// }
|
|
-//
|
|
-// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
|
|
-// will print the message
|
|
-//
|
|
-// Value of: IsEven(Fib(5))
|
|
-// Actual: false (5 is odd)
|
|
-// Expected: true
|
|
-//
|
|
-// instead of a more opaque
|
|
-//
|
|
-// Value of: IsEven(Fib(5))
|
|
-// Actual: false
|
|
-// Expected: true
|
|
-//
|
|
-// in case IsEven is a simple Boolean predicate.
|
|
-//
|
|
-// If you expect your predicate to be reused and want to support informative
|
|
-// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
|
|
-// about half as often as positive ones in our tests), supply messages for
|
|
-// both success and failure cases:
|
|
-//
|
|
-// testing::AssertionResult IsEven(int n) {
|
|
-// if ((n % 2) == 0)
|
|
-// return testing::AssertionSuccess() << n << " is even";
|
|
-// else
|
|
-// return testing::AssertionFailure() << n << " is odd";
|
|
-// }
|
|
-//
|
|
-// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
|
|
-//
|
|
-// Value of: IsEven(Fib(6))
|
|
-// Actual: true (8 is even)
|
|
-// Expected: false
|
|
-//
|
|
-// NB: Predicates that support negative Boolean assertions have reduced
|
|
-// performance in positive ones so be careful not to use them in tests
|
|
-// that have lots (tens of thousands) of positive Boolean assertions.
|
|
-//
|
|
-// To use this class with EXPECT_PRED_FORMAT assertions such as:
|
|
-//
|
|
-// // Verifies that Foo() returns an even number.
|
|
-// EXPECT_PRED_FORMAT1(IsEven, Foo());
|
|
-//
|
|
-// you need to define:
|
|
-//
|
|
-// testing::AssertionResult IsEven(const char* expr, int n) {
|
|
-// if ((n % 2) == 0)
|
|
-// return testing::AssertionSuccess();
|
|
-// else
|
|
-// return testing::AssertionFailure()
|
|
-// << "Expected: " << expr << " is even\n Actual: it's " << n;
|
|
-// }
|
|
-//
|
|
-// If Foo() returns 5, you will see the following message:
|
|
-//
|
|
-// Expected: Foo() is even
|
|
-// Actual: it's 5
|
|
-//
|
|
-class GTEST_API_ AssertionResult {
|
|
- public:
|
|
- // Copy constructor.
|
|
- // Used in EXPECT_TRUE/FALSE(assertion_result).
|
|
- AssertionResult(const AssertionResult& other);
|
|
-
|
|
-// 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
|
|
-
|
|
- // Used in the EXPECT_TRUE/FALSE(bool_expression).
|
|
- //
|
|
- // T must be contextually convertible to bool.
|
|
- //
|
|
- // The second parameter prevents this overload from being considered if
|
|
- // the argument is implicitly convertible to AssertionResult. In that case
|
|
- // we want AssertionResult's copy constructor to be used.
|
|
- template <typename T>
|
|
- explicit AssertionResult(
|
|
- const T& success,
|
|
- typename std::enable_if<
|
|
- !std::is_convertible<T, AssertionResult>::value>::type*
|
|
- /*enabler*/
|
|
- = nullptr)
|
|
- : success_(success) {}
|
|
-
|
|
-#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
|
|
- GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-#endif
|
|
-
|
|
- // Assignment operator.
|
|
- AssertionResult& operator=(AssertionResult other) {
|
|
- swap(other);
|
|
- return *this;
|
|
- }
|
|
-
|
|
- // 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.
|
|
- AssertionResult operator!() const;
|
|
-
|
|
- // Returns the text streamed into this AssertionResult. Test assertions
|
|
- // use it when they fail (i.e., the predicate's outcome doesn't match the
|
|
- // assertion's expectation). When nothing has been streamed into the
|
|
- // object, returns an empty string.
|
|
- const char* message() const {
|
|
- return message_.get() != nullptr ? message_->c_str() : "";
|
|
- }
|
|
- // Deprecated; please use message() instead.
|
|
- const char* failure_message() const { return message(); }
|
|
-
|
|
- // Streams a custom failure message into this object.
|
|
- template <typename T>
|
|
- AssertionResult& operator<<(const T& value) {
|
|
- AppendMessage(Message() << value);
|
|
- return *this;
|
|
- }
|
|
-
|
|
- // Allows streaming basic output manipulators such as endl or flush into
|
|
- // this object.
|
|
- AssertionResult& operator<<(
|
|
- ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
|
|
- AppendMessage(Message() << basic_manipulator);
|
|
- return *this;
|
|
- }
|
|
-
|
|
- private:
|
|
- // Appends the contents of message to message_.
|
|
- void AppendMessage(const Message& a_message) {
|
|
- if (message_.get() == nullptr) message_.reset(new ::std::string);
|
|
- message_->append(a_message.GetString().c_str());
|
|
- }
|
|
-
|
|
- // Swap the contents of this AssertionResult with other.
|
|
- void swap(AssertionResult& other);
|
|
-
|
|
- // Stores result of the assertion predicate.
|
|
- bool success_;
|
|
- // Stores the message describing the condition in case the expectation
|
|
- // construct is not satisfied with the predicate's outcome.
|
|
- // Referenced via a pointer to avoid taking too much stack frame space
|
|
- // with test assertions.
|
|
- std::unique_ptr< ::std::string> message_;
|
|
-};
|
|
-
|
|
-// Makes a successful assertion result.
|
|
-GTEST_API_ AssertionResult AssertionSuccess();
|
|
-
|
|
-// Makes a failed assertion result.
|
|
-GTEST_API_ AssertionResult AssertionFailure();
|
|
-
|
|
-// Makes a failed assertion result with the given failure message.
|
|
-// Deprecated; use AssertionFailure() << msg.
|
|
-GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-death-test.h b/vendor/gtest/include/gtest/gtest-death-test.h
|
|
deleted file mode 100644
|
|
index 84e5a5bbd..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-death-test.h
|
|
+++ /dev/null
|
|
@@ -1,345 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file defines the public API for death tests. It is
|
|
-// #included by gtest.h so a user doesn't need to include this
|
|
-// directly.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
|
-
|
|
-#include "gtest/internal/gtest-death-test-internal.h"
|
|
-
|
|
-// This flag controls the style of death tests. Valid values are "threadsafe",
|
|
-// meaning that the death test child process will re-execute the test binary
|
|
-// from the start, running only a single death test, or "fast",
|
|
-// meaning that the child process will execute the test logic immediately
|
|
-// after forking.
|
|
-GTEST_DECLARE_string_(death_test_style);
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Returns a Boolean value indicating whether the caller is currently
|
|
-// executing in the context of the death test child process. Tools such as
|
|
-// Valgrind heap checkers may need this to modify their behavior in death
|
|
-// tests. IMPORTANT: This is an internal utility. Using it may break the
|
|
-// implementation of death tests. User code MUST NOT use it.
|
|
-GTEST_API_ bool InDeathTestChild();
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// The following macros are useful for writing death tests.
|
|
-
|
|
-// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
|
-// executed:
|
|
-//
|
|
-// 1. It generates a warning if there is more than one active
|
|
-// thread. This is because it's safe to fork() or clone() only
|
|
-// when there is a single thread.
|
|
-//
|
|
-// 2. The parent process clone()s a sub-process and runs the death
|
|
-// test in it; the sub-process exits with code 0 at the end of the
|
|
-// death test, if it hasn't exited already.
|
|
-//
|
|
-// 3. The parent process waits for the sub-process to terminate.
|
|
-//
|
|
-// 4. The parent process checks the exit code and error message of
|
|
-// the sub-process.
|
|
-//
|
|
-// Examples:
|
|
-//
|
|
-// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
|
-// for (int i = 0; i < 5; i++) {
|
|
-// EXPECT_DEATH(server.ProcessRequest(i),
|
|
-// "Invalid request .* in ProcessRequest()")
|
|
-// << "Failed to die on request " << i;
|
|
-// }
|
|
-//
|
|
-// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
|
-//
|
|
-// bool KilledBySIGHUP(int exit_code) {
|
|
-// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
|
-// }
|
|
-//
|
|
-// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
|
-//
|
|
-// The final parameter to each of these macros is a matcher applied to any data
|
|
-// the sub-process wrote to stderr. For compatibility with existing tests, a
|
|
-// bare string is interpreted as a regular expression matcher.
|
|
-//
|
|
-// On the regular expressions used in death tests:
|
|
-//
|
|
-// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
|
-// which uses the POSIX extended regex syntax.
|
|
-//
|
|
-// On other platforms (e.g. Windows or Mac), we only support a simple regex
|
|
-// syntax implemented as part of Google Test. This limited
|
|
-// implementation should be enough most of the time when writing
|
|
-// death tests; though it lacks many features you can find in PCRE
|
|
-// or POSIX extended regex syntax. For example, we don't support
|
|
-// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
|
-// repetition count ("x{5,7}"), among others.
|
|
-//
|
|
-// Below is the syntax that we do support. We chose it to be a
|
|
-// subset of both PCRE and POSIX extended regex, so it's easy to
|
|
-// learn wherever you come from. In the following: 'A' denotes a
|
|
-// literal character, period (.), or a single \\ escape sequence;
|
|
-// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
|
-// natural numbers.
|
|
-//
|
|
-// c matches any literal character c
|
|
-// \\d matches any decimal digit
|
|
-// \\D matches any character that's not a decimal digit
|
|
-// \\f matches \f
|
|
-// \\n matches \n
|
|
-// \\r matches \r
|
|
-// \\s matches any ASCII whitespace, including \n
|
|
-// \\S matches any character that's not a whitespace
|
|
-// \\t matches \t
|
|
-// \\v matches \v
|
|
-// \\w matches any letter, _, or decimal digit
|
|
-// \\W matches any character that \\w doesn't match
|
|
-// \\c matches any literal character c, which must be a punctuation
|
|
-// . matches any single character except \n
|
|
-// A? matches 0 or 1 occurrences of A
|
|
-// A* matches 0 or many occurrences of A
|
|
-// A+ matches 1 or many occurrences of A
|
|
-// ^ matches the beginning of a string (not that of each line)
|
|
-// $ matches the end of a string (not that of each line)
|
|
-// xy matches x followed by y
|
|
-//
|
|
-// If you accidentally use PCRE or POSIX extended regex features
|
|
-// not implemented by us, you will get a run-time failure. In that
|
|
-// case, please try to rewrite your regular expression within the
|
|
-// above syntax.
|
|
-//
|
|
-// This implementation is *not* meant to be as highly tuned or robust
|
|
-// as a compiled regex library, but should perform well enough for a
|
|
-// death test, which already incurs significant overhead by launching
|
|
-// a child process.
|
|
-//
|
|
-// Known caveats:
|
|
-//
|
|
-// A "threadsafe" style death test obtains the path to the test
|
|
-// program from argv[0] and re-executes it in the sub-process. For
|
|
-// simplicity, the current implementation doesn't search the PATH
|
|
-// when launching the sub-process. This means that the user must
|
|
-// invoke the test program via a path that contains at least one
|
|
-// path separator (e.g. path/to/foo_test and
|
|
-// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
|
-// is rarely a problem as people usually don't put the test binary
|
|
-// 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 `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
|
|
-// test suite, if any:
|
|
-#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
|
|
-// explicitly exiting with a nonzero exit code or being killed by a
|
|
-// 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
|
|
-// test suite, if any:
|
|
-#define EXPECT_DEATH(statement, matcher) \
|
|
- EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
|
|
-
|
|
-// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
|
-
|
|
-// Tests that an exit code describes a normal exit with a given exit code.
|
|
-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:
|
|
- const int exit_code_;
|
|
-};
|
|
-
|
|
-#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
|
-// Tests that an exit code describes an exit due to termination by a
|
|
-// given signal.
|
|
-class GTEST_API_ KilledBySignal {
|
|
- public:
|
|
- explicit KilledBySignal(int signum);
|
|
- bool operator()(int exit_status) const;
|
|
-
|
|
- private:
|
|
- const int signum_;
|
|
-};
|
|
-#endif // !GTEST_OS_WINDOWS
|
|
-
|
|
-// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
|
-// The death testing framework causes this to have interesting semantics,
|
|
-// since the sideeffects of the call are only visible in opt mode, and not
|
|
-// in debug mode.
|
|
-//
|
|
-// In practice, this can be used to test functions that utilize the
|
|
-// LOG(DFATAL) macro using the following style:
|
|
-//
|
|
-// int DieInDebugOr12(int* sideeffect) {
|
|
-// if (sideeffect) {
|
|
-// *sideeffect = 12;
|
|
-// }
|
|
-// LOG(DFATAL) << "death";
|
|
-// return 12;
|
|
-// }
|
|
-//
|
|
-// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
|
|
-// int sideeffect = 0;
|
|
-// // Only asserts in dbg.
|
|
-// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
|
-//
|
|
-// #ifdef NDEBUG
|
|
-// // opt-mode has sideeffect visible.
|
|
-// EXPECT_EQ(12, sideeffect);
|
|
-// #else
|
|
-// // dbg-mode no visible sideeffect.
|
|
-// EXPECT_EQ(0, sideeffect);
|
|
-// #endif
|
|
-// }
|
|
-//
|
|
-// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
|
-// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
|
-// appropriate fallback value (12 in this case) in opt mode. If you
|
|
-// need to test that a function has appropriate side-effects in opt
|
|
-// mode, include assertions against the side-effects. A general
|
|
-// pattern for this is:
|
|
-//
|
|
-// EXPECT_DEBUG_DEATH({
|
|
-// // Side-effects here will have an effect after this statement in
|
|
-// // opt mode, but none in debug mode.
|
|
-// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
|
-// }, "death");
|
|
-//
|
|
-#ifdef NDEBUG
|
|
-
|
|
-#define EXPECT_DEBUG_DEATH(statement, regex) \
|
|
- GTEST_EXECUTE_STATEMENT_(statement, regex)
|
|
-
|
|
-#define ASSERT_DEBUG_DEATH(statement, regex) \
|
|
- GTEST_EXECUTE_STATEMENT_(statement, regex)
|
|
-
|
|
-#else
|
|
-
|
|
-#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
|
|
-
|
|
-#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex)
|
|
-
|
|
-#endif // NDEBUG for EXPECT_DEBUG_DEATH
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-// This macro is used for implementing macros such as
|
|
-// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
|
-// death tests are not supported. Those macros must compile on such systems
|
|
-// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters
|
|
-// on systems that support death tests. This allows one to write such a macro on
|
|
-// a system that does not support death tests and be sure that it will compile
|
|
-// on a death-test supporting system. It is exposed publicly so that systems
|
|
-// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST
|
|
-// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and
|
|
-// ASSERT_DEATH_IF_SUPPORTED.
|
|
-//
|
|
-// Parameters:
|
|
-// statement - A statement that a macro such as EXPECT_DEATH would test
|
|
-// for program termination. This macro has to make sure this
|
|
-// statement is compiled but not executed, to ensure that
|
|
-// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
|
-// parameter if and only if EXPECT_DEATH compiles with it.
|
|
-// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
|
-// the output of statement. This parameter has to be
|
|
-// compiled but not evaluated by this macro, to ensure that
|
|
-// this macro only accepts expressions that a macro such as
|
|
-// EXPECT_DEATH would accept.
|
|
-// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
|
-// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
|
-// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
|
-// compile inside functions where ASSERT_DEATH doesn't
|
|
-// compile.
|
|
-//
|
|
-// The branch that has an always false condition is used to ensure that
|
|
-// statement and regex are compiled (and thus syntactically correct) but
|
|
-// never executed. The unreachable code macro protects the terminator
|
|
-// statement from generating an 'unreachable code' warning in case
|
|
-// statement unconditionally returns or throws. The Message constructor at
|
|
-// the end allows the syntax of streaming additional messages into the
|
|
-// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
|
-#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
|
|
- << "Statement '" #statement "' cannot be verified."; \
|
|
- } else if (::testing::internal::AlwaysFalse()) { \
|
|
- ::testing::internal::RE::PartialMatch(".*", (regex)); \
|
|
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
|
- terminator; \
|
|
- } else \
|
|
- ::testing::Message()
|
|
-
|
|
-// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
|
-// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
|
-// death tests are supported; otherwise they just issue a warning. This is
|
|
-// useful when you are combining death test assertions with normal test
|
|
-// assertions in one test.
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
|
- EXPECT_DEATH(statement, regex)
|
|
-#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
|
- ASSERT_DEATH(statement, regex)
|
|
-#else
|
|
-#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
|
- GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
|
|
-#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
|
- GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
|
|
-#endif
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-matchers.h b/vendor/gtest/include/gtest/gtest-matchers.h
|
|
deleted file mode 100644
|
|
index bffa00c53..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-matchers.h
|
|
+++ /dev/null
|
|
@@ -1,956 +0,0 @@
|
|
-// Copyright 2007, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This file implements just enough of the matcher interface to allow
|
|
-// EXPECT_DEATH and friends to accept a matcher argument.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
|
-
|
|
-#include <atomic>
|
|
-#include <memory>
|
|
-#include <ostream>
|
|
-#include <string>
|
|
-#include <type_traits>
|
|
-
|
|
-#include "gtest/gtest-printers.h"
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-// MSVC warning C5046 is new as of VS2017 version 15.8.
|
|
-#if defined(_MSC_VER) && _MSC_VER >= 1915
|
|
-#define GTEST_MAYBE_5046_ 5046
|
|
-#else
|
|
-#define GTEST_MAYBE_5046_
|
|
-#endif
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
|
- 4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
|
|
- clients of class B */
|
|
- /* Symbol involving type with internal linkage not defined */)
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// To implement a matcher Foo for type T, define:
|
|
-// 1. a class FooMatcherMatcher that implements the matcher interface:
|
|
-// using is_gtest_matcher = void;
|
|
-// bool MatchAndExplain(const T&, std::ostream*);
|
|
-// (MatchResultListener* can also be used instead of std::ostream*)
|
|
-// void DescribeTo(std::ostream*);
|
|
-// void DescribeNegationTo(std::ostream*);
|
|
-//
|
|
-// 2. a factory function that creates a Matcher<T> object from a
|
|
-// FooMatcherMatcher.
|
|
-
|
|
-class MatchResultListener {
|
|
- public:
|
|
- // Creates a listener object with the given underlying ostream. The
|
|
- // listener does not own the ostream, and does not dereference it
|
|
- // in the constructor or destructor.
|
|
- explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
|
|
- virtual ~MatchResultListener() = 0; // Makes this class abstract.
|
|
-
|
|
- // Streams x to the underlying ostream; does nothing if the ostream
|
|
- // is NULL.
|
|
- template <typename T>
|
|
- MatchResultListener& operator<<(const T& x) {
|
|
- if (stream_ != nullptr) *stream_ << x;
|
|
- return *this;
|
|
- }
|
|
-
|
|
- // Returns the underlying ostream.
|
|
- ::std::ostream* stream() { return stream_; }
|
|
-
|
|
- // Returns true if and only if the listener is interested in an explanation
|
|
- // of the match result. A matcher's MatchAndExplain() method can use
|
|
- // this information to avoid generating the explanation when no one
|
|
- // intends to hear it.
|
|
- bool IsInterested() const { return stream_ != nullptr; }
|
|
-
|
|
- private:
|
|
- ::std::ostream* const stream_;
|
|
-
|
|
- MatchResultListener(const MatchResultListener&) = delete;
|
|
- MatchResultListener& operator=(const MatchResultListener&) = delete;
|
|
-};
|
|
-
|
|
-inline MatchResultListener::~MatchResultListener() {}
|
|
-
|
|
-// An instance of a subclass of this knows how to describe itself as a
|
|
-// matcher.
|
|
-class GTEST_API_ MatcherDescriberInterface {
|
|
- public:
|
|
- virtual ~MatcherDescriberInterface() {}
|
|
-
|
|
- // Describes this matcher to an ostream. The function should print
|
|
- // a verb phrase that describes the property a value matching this
|
|
- // matcher should have. The subject of the verb phrase is the value
|
|
- // being matched. For example, the DescribeTo() method of the Gt(7)
|
|
- // matcher prints "is greater than 7".
|
|
- virtual void DescribeTo(::std::ostream* os) const = 0;
|
|
-
|
|
- // Describes the negation of this matcher to an ostream. For
|
|
- // example, if the description of this matcher is "is greater than
|
|
- // 7", the negated description could be "is not greater than 7".
|
|
- // You are not required to override this when implementing
|
|
- // MatcherInterface, but it is highly advised so that your matcher
|
|
- // can produce good error messages.
|
|
- virtual void DescribeNegationTo(::std::ostream* os) const {
|
|
- *os << "not (";
|
|
- DescribeTo(os);
|
|
- *os << ")";
|
|
- }
|
|
-};
|
|
-
|
|
-// The implementation of a matcher.
|
|
-template <typename T>
|
|
-class MatcherInterface : public MatcherDescriberInterface {
|
|
- public:
|
|
- // Returns true if and only if the matcher matches x; also explains the
|
|
- // match result to 'listener' if necessary (see the next paragraph), in
|
|
- // the form of a non-restrictive relative clause ("which ...",
|
|
- // "whose ...", etc) that describes x. For example, the
|
|
- // MatchAndExplain() method of the Pointee(...) matcher should
|
|
- // generate an explanation like "which points to ...".
|
|
- //
|
|
- // Implementations of MatchAndExplain() should add an explanation of
|
|
- // the match result *if and only if* they can provide additional
|
|
- // information that's not already present (or not obvious) in the
|
|
- // print-out of x and the matcher's description. Whether the match
|
|
- // succeeds is not a factor in deciding whether an explanation is
|
|
- // needed, as sometimes the caller needs to print a failure message
|
|
- // when the match succeeds (e.g. when the matcher is used inside
|
|
- // Not()).
|
|
- //
|
|
- // For example, a "has at least 10 elements" matcher should explain
|
|
- // what the actual element count is, regardless of the match result,
|
|
- // as it is useful information to the reader; on the other hand, an
|
|
- // "is empty" matcher probably only needs to explain what the actual
|
|
- // size is when the match fails, as it's redundant to say that the
|
|
- // size is 0 when the value is already known to be empty.
|
|
- //
|
|
- // You should override this method when defining a new matcher.
|
|
- //
|
|
- // It's the responsibility of the caller (Google Test) to guarantee
|
|
- // that 'listener' is not NULL. This helps to simplify a matcher's
|
|
- // implementation when it doesn't care about the performance, as it
|
|
- // can talk to 'listener' without checking its validity first.
|
|
- // However, in order to implement dummy listeners efficiently,
|
|
- // listener->stream() may be NULL.
|
|
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
|
|
-
|
|
- // Inherits these methods from MatcherDescriberInterface:
|
|
- // virtual void DescribeTo(::std::ostream* os) const = 0;
|
|
- // virtual void DescribeNegationTo(::std::ostream* os) const;
|
|
-};
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-struct AnyEq {
|
|
- template <typename A, typename B>
|
|
- bool operator()(const A& a, const B& b) const {
|
|
- return a == b;
|
|
- }
|
|
-};
|
|
-struct AnyNe {
|
|
- template <typename A, typename B>
|
|
- bool operator()(const A& a, const B& b) const {
|
|
- return a != b;
|
|
- }
|
|
-};
|
|
-struct AnyLt {
|
|
- template <typename A, typename B>
|
|
- bool operator()(const A& a, const B& b) const {
|
|
- return a < b;
|
|
- }
|
|
-};
|
|
-struct AnyGt {
|
|
- template <typename A, typename B>
|
|
- bool operator()(const A& a, const B& b) const {
|
|
- return a > b;
|
|
- }
|
|
-};
|
|
-struct AnyLe {
|
|
- template <typename A, typename B>
|
|
- bool operator()(const A& a, const B& b) const {
|
|
- return a <= b;
|
|
- }
|
|
-};
|
|
-struct AnyGe {
|
|
- template <typename A, typename B>
|
|
- bool operator()(const A& a, const B& b) const {
|
|
- return a >= b;
|
|
- }
|
|
-};
|
|
-
|
|
-// A match result listener that ignores the explanation.
|
|
-class DummyMatchResultListener : public MatchResultListener {
|
|
- public:
|
|
- DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
|
-
|
|
- private:
|
|
- DummyMatchResultListener(const DummyMatchResultListener&) = delete;
|
|
- DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;
|
|
-};
|
|
-
|
|
-// A match result listener that forwards the explanation to a given
|
|
-// ostream. The difference between this and MatchResultListener is
|
|
-// that the former is concrete.
|
|
-class StreamMatchResultListener : public MatchResultListener {
|
|
- public:
|
|
- explicit StreamMatchResultListener(::std::ostream* os)
|
|
- : MatchResultListener(os) {}
|
|
-
|
|
- private:
|
|
- StreamMatchResultListener(const StreamMatchResultListener&) = delete;
|
|
- StreamMatchResultListener& operator=(const StreamMatchResultListener&) =
|
|
- delete;
|
|
-};
|
|
-
|
|
-struct SharedPayloadBase {
|
|
- std::atomic<int> ref{1};
|
|
- void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
|
|
- bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
|
|
-};
|
|
-
|
|
-template <typename T>
|
|
-struct SharedPayload : SharedPayloadBase {
|
|
- explicit SharedPayload(const T& v) : value(v) {}
|
|
- explicit SharedPayload(T&& v) : value(std::move(v)) {}
|
|
-
|
|
- static void Destroy(SharedPayloadBase* shared) {
|
|
- delete static_cast<SharedPayload*>(shared);
|
|
- }
|
|
-
|
|
- T value;
|
|
-};
|
|
-
|
|
-// An internal class for implementing Matcher<T>, which will derive
|
|
-// from it. We put functionalities common to all Matcher<T>
|
|
-// specializations here to avoid code duplication.
|
|
-template <typename T>
|
|
-class MatcherBase : private MatcherDescriberInterface {
|
|
- public:
|
|
- // Returns true if and only if the matcher matches x; also explains the
|
|
- // match result to 'listener'.
|
|
- bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
|
|
- GTEST_CHECK_(vtable_ != nullptr);
|
|
- return vtable_->match_and_explain(*this, x, listener);
|
|
- }
|
|
-
|
|
- // Returns true if and only if this matcher matches x.
|
|
- bool Matches(const T& x) const {
|
|
- DummyMatchResultListener dummy;
|
|
- return MatchAndExplain(x, &dummy);
|
|
- }
|
|
-
|
|
- // Describes this matcher to an ostream.
|
|
- void DescribeTo(::std::ostream* os) const final {
|
|
- GTEST_CHECK_(vtable_ != nullptr);
|
|
- vtable_->describe(*this, os, false);
|
|
- }
|
|
-
|
|
- // Describes the negation of this matcher to an ostream.
|
|
- void DescribeNegationTo(::std::ostream* os) const final {
|
|
- GTEST_CHECK_(vtable_ != nullptr);
|
|
- vtable_->describe(*this, os, true);
|
|
- }
|
|
-
|
|
- // Explains why x matches, or doesn't match, the matcher.
|
|
- void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
|
|
- StreamMatchResultListener listener(os);
|
|
- MatchAndExplain(x, &listener);
|
|
- }
|
|
-
|
|
- // Returns the describer for this matcher object; retains ownership
|
|
- // of the describer, which is only guaranteed to be alive when
|
|
- // this matcher object is alive.
|
|
- const MatcherDescriberInterface* GetDescriber() const {
|
|
- if (vtable_ == nullptr) return nullptr;
|
|
- return vtable_->get_describer(*this);
|
|
- }
|
|
-
|
|
- protected:
|
|
- MatcherBase() : vtable_(nullptr), buffer_() {}
|
|
-
|
|
- // Constructs a matcher from its implementation.
|
|
- template <typename U>
|
|
- explicit MatcherBase(const MatcherInterface<U>* impl)
|
|
- : vtable_(nullptr), buffer_() {
|
|
- Init(impl);
|
|
- }
|
|
-
|
|
- template <typename M, typename = typename std::remove_reference<
|
|
- M>::type::is_gtest_matcher>
|
|
- MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT
|
|
- Init(std::forward<M>(m));
|
|
- }
|
|
-
|
|
- MatcherBase(const MatcherBase& other)
|
|
- : vtable_(other.vtable_), buffer_(other.buffer_) {
|
|
- if (IsShared()) buffer_.shared->Ref();
|
|
- }
|
|
-
|
|
- MatcherBase& operator=(const MatcherBase& other) {
|
|
- if (this == &other) return *this;
|
|
- Destroy();
|
|
- vtable_ = other.vtable_;
|
|
- buffer_ = other.buffer_;
|
|
- if (IsShared()) buffer_.shared->Ref();
|
|
- return *this;
|
|
- }
|
|
-
|
|
- MatcherBase(MatcherBase&& other)
|
|
- : vtable_(other.vtable_), buffer_(other.buffer_) {
|
|
- other.vtable_ = nullptr;
|
|
- }
|
|
-
|
|
- MatcherBase& operator=(MatcherBase&& other) {
|
|
- if (this == &other) return *this;
|
|
- Destroy();
|
|
- vtable_ = other.vtable_;
|
|
- buffer_ = other.buffer_;
|
|
- other.vtable_ = nullptr;
|
|
- return *this;
|
|
- }
|
|
-
|
|
- ~MatcherBase() override { Destroy(); }
|
|
-
|
|
- private:
|
|
- struct VTable {
|
|
- bool (*match_and_explain)(const MatcherBase&, const T&,
|
|
- MatchResultListener*);
|
|
- void (*describe)(const MatcherBase&, std::ostream*, bool negation);
|
|
- // Returns the captured object if it implements the interface, otherwise
|
|
- // returns the MatcherBase itself.
|
|
- const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);
|
|
- // Called on shared instances when the reference count reaches 0.
|
|
- void (*shared_destroy)(SharedPayloadBase*);
|
|
- };
|
|
-
|
|
- bool IsShared() const {
|
|
- return vtable_ != nullptr && vtable_->shared_destroy != nullptr;
|
|
- }
|
|
-
|
|
- // If the implementation uses a listener, call that.
|
|
- template <typename P>
|
|
- static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
|
|
- MatchResultListener* listener)
|
|
- -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
|
|
- return P::Get(m).MatchAndExplain(value, listener->stream());
|
|
- }
|
|
-
|
|
- template <typename P>
|
|
- static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
|
|
- MatchResultListener* listener)
|
|
- -> decltype(P::Get(m).MatchAndExplain(value, listener)) {
|
|
- return P::Get(m).MatchAndExplain(value, listener);
|
|
- }
|
|
-
|
|
- template <typename P>
|
|
- static void DescribeImpl(const MatcherBase& m, std::ostream* os,
|
|
- bool negation) {
|
|
- if (negation) {
|
|
- P::Get(m).DescribeNegationTo(os);
|
|
- } else {
|
|
- P::Get(m).DescribeTo(os);
|
|
- }
|
|
- }
|
|
-
|
|
- template <typename P>
|
|
- static const MatcherDescriberInterface* GetDescriberImpl(
|
|
- const MatcherBase& m) {
|
|
- // If the impl is a MatcherDescriberInterface, then return it.
|
|
- // Otherwise use MatcherBase itself.
|
|
- // This allows us to implement the GetDescriber() function without support
|
|
- // from the impl, but some users really want to get their impl back when
|
|
- // they call GetDescriber().
|
|
- // We use std::get on a tuple as a workaround of not having `if constexpr`.
|
|
- return std::get<(
|
|
- std::is_convertible<decltype(&P::Get(m)),
|
|
- const MatcherDescriberInterface*>::value
|
|
- ? 1
|
|
- : 0)>(std::make_tuple(&m, &P::Get(m)));
|
|
- }
|
|
-
|
|
- template <typename P>
|
|
- const VTable* GetVTable() {
|
|
- static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
|
|
- &DescribeImpl<P>, &GetDescriberImpl<P>,
|
|
- P::shared_destroy};
|
|
- return &kVTable;
|
|
- }
|
|
-
|
|
- union Buffer {
|
|
- // Add some types to give Buffer some common alignment/size use cases.
|
|
- void* ptr;
|
|
- double d;
|
|
- int64_t i;
|
|
- // And add one for the out-of-line cases.
|
|
- SharedPayloadBase* shared;
|
|
- };
|
|
-
|
|
- void Destroy() {
|
|
- if (IsShared() && buffer_.shared->Unref()) {
|
|
- vtable_->shared_destroy(buffer_.shared);
|
|
- }
|
|
- }
|
|
-
|
|
- template <typename M>
|
|
- static constexpr bool IsInlined() {
|
|
- return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
|
|
- std::is_trivially_copy_constructible<M>::value &&
|
|
- std::is_trivially_destructible<M>::value;
|
|
- }
|
|
-
|
|
- template <typename M, bool = MatcherBase::IsInlined<M>()>
|
|
- struct ValuePolicy {
|
|
- static const M& Get(const MatcherBase& m) {
|
|
- // When inlined along with Init, need to be explicit to avoid violating
|
|
- // strict aliasing rules.
|
|
- const M* ptr =
|
|
- static_cast<const M*>(static_cast<const void*>(&m.buffer_));
|
|
- return *ptr;
|
|
- }
|
|
- static void Init(MatcherBase& m, M impl) {
|
|
- ::new (static_cast<void*>(&m.buffer_)) M(impl);
|
|
- }
|
|
- static constexpr auto shared_destroy = nullptr;
|
|
- };
|
|
-
|
|
- template <typename M>
|
|
- struct ValuePolicy<M, false> {
|
|
- using Shared = SharedPayload<M>;
|
|
- static const M& Get(const MatcherBase& m) {
|
|
- return static_cast<Shared*>(m.buffer_.shared)->value;
|
|
- }
|
|
- template <typename Arg>
|
|
- static void Init(MatcherBase& m, Arg&& arg) {
|
|
- m.buffer_.shared = new Shared(std::forward<Arg>(arg));
|
|
- }
|
|
- static constexpr auto shared_destroy = &Shared::Destroy;
|
|
- };
|
|
-
|
|
- template <typename U, bool B>
|
|
- struct ValuePolicy<const MatcherInterface<U>*, B> {
|
|
- using M = const MatcherInterface<U>;
|
|
- using Shared = SharedPayload<std::unique_ptr<M>>;
|
|
- static const M& Get(const MatcherBase& m) {
|
|
- return *static_cast<Shared*>(m.buffer_.shared)->value;
|
|
- }
|
|
- static void Init(MatcherBase& m, M* impl) {
|
|
- m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));
|
|
- }
|
|
-
|
|
- static constexpr auto shared_destroy = &Shared::Destroy;
|
|
- };
|
|
-
|
|
- template <typename M>
|
|
- void Init(M&& m) {
|
|
- using MM = typename std::decay<M>::type;
|
|
- using Policy = ValuePolicy<MM>;
|
|
- vtable_ = GetVTable<Policy>();
|
|
- Policy::Init(*this, std::forward<M>(m));
|
|
- }
|
|
-
|
|
- const VTable* vtable_;
|
|
- Buffer buffer_;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
|
|
-// object that can check whether a value of type T matches. The
|
|
-// implementation of Matcher<T> is just a std::shared_ptr to const
|
|
-// MatcherInterface<T>. Don't inherit from Matcher!
|
|
-template <typename T>
|
|
-class Matcher : public internal::MatcherBase<T> {
|
|
- public:
|
|
- // Constructs a null matcher. Needed for storing Matcher objects in STL
|
|
- // containers. A default-constructed matcher is not yet initialized. You
|
|
- // cannot use it until a valid value has been assigned to it.
|
|
- explicit Matcher() {} // NOLINT
|
|
-
|
|
- // Constructs a matcher from its implementation.
|
|
- explicit Matcher(const MatcherInterface<const T&>* impl)
|
|
- : internal::MatcherBase<T>(impl) {}
|
|
-
|
|
- template <typename U>
|
|
- explicit Matcher(
|
|
- const MatcherInterface<U>* impl,
|
|
- typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
|
|
- nullptr)
|
|
- : internal::MatcherBase<T>(impl) {}
|
|
-
|
|
- template <typename M, typename = typename std::remove_reference<
|
|
- M>::type::is_gtest_matcher>
|
|
- Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
|
|
-
|
|
- // Implicit constructor here allows people to write
|
|
- // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
|
- Matcher(T value); // NOLINT
|
|
-};
|
|
-
|
|
-// The following two specializations allow the user to write str
|
|
-// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
|
-// matcher is expected.
|
|
-template <>
|
|
-class GTEST_API_ Matcher<const std::string&>
|
|
- : public internal::MatcherBase<const std::string&> {
|
|
- public:
|
|
- Matcher() {}
|
|
-
|
|
- explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
|
- : internal::MatcherBase<const std::string&>(impl) {}
|
|
-
|
|
- template <typename M, typename = typename std::remove_reference<
|
|
- M>::type::is_gtest_matcher>
|
|
- Matcher(M&& m) // NOLINT
|
|
- : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
|
|
-
|
|
- // Allows the user to write str instead of Eq(str) sometimes, where
|
|
- // str is a std::string object.
|
|
- Matcher(const std::string& s); // NOLINT
|
|
-
|
|
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
|
|
- Matcher(const char* s); // NOLINT
|
|
-};
|
|
-
|
|
-template <>
|
|
-class GTEST_API_ Matcher<std::string>
|
|
- : public internal::MatcherBase<std::string> {
|
|
- public:
|
|
- Matcher() {}
|
|
-
|
|
- explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
|
- : internal::MatcherBase<std::string>(impl) {}
|
|
- explicit Matcher(const MatcherInterface<std::string>* impl)
|
|
- : internal::MatcherBase<std::string>(impl) {}
|
|
-
|
|
- template <typename M, typename = typename std::remove_reference<
|
|
- M>::type::is_gtest_matcher>
|
|
- Matcher(M&& m) // NOLINT
|
|
- : internal::MatcherBase<std::string>(std::forward<M>(m)) {}
|
|
-
|
|
- // Allows the user to write str instead of Eq(str) sometimes, where
|
|
- // str is a string object.
|
|
- Matcher(const std::string& s); // NOLINT
|
|
-
|
|
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
|
|
- Matcher(const char* s); // NOLINT
|
|
-};
|
|
-
|
|
-#if GTEST_INTERNAL_HAS_STRING_VIEW
|
|
-// The following two specializations allow the user to write str
|
|
-// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
|
|
-// matcher is expected.
|
|
-template <>
|
|
-class GTEST_API_ Matcher<const internal::StringView&>
|
|
- : public internal::MatcherBase<const internal::StringView&> {
|
|
- public:
|
|
- Matcher() {}
|
|
-
|
|
- explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
|
- : internal::MatcherBase<const internal::StringView&>(impl) {}
|
|
-
|
|
- template <typename M, typename = typename std::remove_reference<
|
|
- M>::type::is_gtest_matcher>
|
|
- Matcher(M&& m) // NOLINT
|
|
- : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
|
|
- }
|
|
-
|
|
- // Allows the user to write str instead of Eq(str) sometimes, where
|
|
- // str is a std::string object.
|
|
- Matcher(const std::string& s); // NOLINT
|
|
-
|
|
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
|
|
- Matcher(const char* s); // NOLINT
|
|
-
|
|
- // Allows the user to pass absl::string_views or std::string_views directly.
|
|
- Matcher(internal::StringView s); // NOLINT
|
|
-};
|
|
-
|
|
-template <>
|
|
-class GTEST_API_ Matcher<internal::StringView>
|
|
- : public internal::MatcherBase<internal::StringView> {
|
|
- public:
|
|
- Matcher() {}
|
|
-
|
|
- explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
|
- : internal::MatcherBase<internal::StringView>(impl) {}
|
|
- explicit Matcher(const MatcherInterface<internal::StringView>* impl)
|
|
- : internal::MatcherBase<internal::StringView>(impl) {}
|
|
-
|
|
- template <typename M, typename = typename std::remove_reference<
|
|
- M>::type::is_gtest_matcher>
|
|
- Matcher(M&& m) // NOLINT
|
|
- : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
|
|
-
|
|
- // Allows the user to write str instead of Eq(str) sometimes, where
|
|
- // str is a std::string object.
|
|
- Matcher(const std::string& s); // NOLINT
|
|
-
|
|
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
|
|
- Matcher(const char* s); // NOLINT
|
|
-
|
|
- // Allows the user to pass absl::string_views or std::string_views directly.
|
|
- Matcher(internal::StringView s); // NOLINT
|
|
-};
|
|
-#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
|
-
|
|
-// Prints a matcher in a human-readable format.
|
|
-template <typename T>
|
|
-std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
|
|
- matcher.DescribeTo(&os);
|
|
- return os;
|
|
-}
|
|
-
|
|
-// The PolymorphicMatcher class template makes it easy to implement a
|
|
-// polymorphic matcher (i.e. a matcher that can match values of more
|
|
-// than one type, e.g. Eq(n) and NotNull()).
|
|
-//
|
|
-// To define a polymorphic matcher, a user should provide an Impl
|
|
-// class that has a DescribeTo() method and a DescribeNegationTo()
|
|
-// method, and define a member function (or member function template)
|
|
-//
|
|
-// bool MatchAndExplain(const Value& value,
|
|
-// MatchResultListener* listener) const;
|
|
-//
|
|
-// See the definition of NotNull() for a complete example.
|
|
-template <class Impl>
|
|
-class PolymorphicMatcher {
|
|
- public:
|
|
- explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
|
|
-
|
|
- // Returns a mutable reference to the underlying matcher
|
|
- // implementation object.
|
|
- Impl& mutable_impl() { return impl_; }
|
|
-
|
|
- // Returns an immutable reference to the underlying matcher
|
|
- // implementation object.
|
|
- const Impl& impl() const { return impl_; }
|
|
-
|
|
- template <typename T>
|
|
- operator Matcher<T>() const {
|
|
- return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
|
|
- }
|
|
-
|
|
- private:
|
|
- template <typename T>
|
|
- class MonomorphicImpl : public MatcherInterface<T> {
|
|
- public:
|
|
- explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
|
-
|
|
- void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
|
|
-
|
|
- void DescribeNegationTo(::std::ostream* os) const override {
|
|
- impl_.DescribeNegationTo(os);
|
|
- }
|
|
-
|
|
- bool MatchAndExplain(T x, MatchResultListener* listener) const override {
|
|
- return impl_.MatchAndExplain(x, listener);
|
|
- }
|
|
-
|
|
- private:
|
|
- const Impl impl_;
|
|
- };
|
|
-
|
|
- Impl impl_;
|
|
-};
|
|
-
|
|
-// Creates a matcher from its implementation.
|
|
-// DEPRECATED: Especially in the generic code, prefer:
|
|
-// Matcher<T>(new MyMatcherImpl<const T&>(...));
|
|
-//
|
|
-// MakeMatcher may create a Matcher that accepts its argument by value, which
|
|
-// leads to unnecessary copies & lack of support for non-copyable types.
|
|
-template <typename T>
|
|
-inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
|
|
- return Matcher<T>(impl);
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher from its implementation. This is
|
|
-// easier to use than the PolymorphicMatcher<Impl> constructor as it
|
|
-// doesn't require you to explicitly write the template argument, e.g.
|
|
-//
|
|
-// MakePolymorphicMatcher(foo);
|
|
-// vs
|
|
-// PolymorphicMatcher<TypeOfFoo>(foo);
|
|
-template <class Impl>
|
|
-inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
|
|
- return PolymorphicMatcher<Impl>(impl);
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-// Implements a matcher that compares a given value with a
|
|
-// pre-supplied value using one of the ==, <=, <, etc, operators. The
|
|
-// two values being compared don't have to have the same type.
|
|
-//
|
|
-// The matcher defined here is polymorphic (for example, Eq(5) can be
|
|
-// used to match an int, a short, a double, etc). Therefore we use
|
|
-// a template type conversion operator in the implementation.
|
|
-//
|
|
-// The following template definition assumes that the Rhs parameter is
|
|
-// a "bare" type (i.e. neither 'const T' nor 'T&').
|
|
-template <typename D, typename Rhs, typename Op>
|
|
-class ComparisonBase {
|
|
- public:
|
|
- explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
|
-
|
|
- using is_gtest_matcher = void;
|
|
-
|
|
- template <typename Lhs>
|
|
- bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
|
|
- return Op()(lhs, Unwrap(rhs_));
|
|
- }
|
|
- void DescribeTo(std::ostream* os) const {
|
|
- *os << D::Desc() << " ";
|
|
- UniversalPrint(Unwrap(rhs_), os);
|
|
- }
|
|
- void DescribeNegationTo(std::ostream* os) const {
|
|
- *os << D::NegatedDesc() << " ";
|
|
- UniversalPrint(Unwrap(rhs_), os);
|
|
- }
|
|
-
|
|
- private:
|
|
- template <typename T>
|
|
- static const T& Unwrap(const T& v) {
|
|
- return v;
|
|
- }
|
|
- template <typename T>
|
|
- static const T& Unwrap(std::reference_wrapper<T> v) {
|
|
- return v;
|
|
- }
|
|
-
|
|
- Rhs rhs_;
|
|
-};
|
|
-
|
|
-template <typename Rhs>
|
|
-class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
|
|
- public:
|
|
- explicit EqMatcher(const Rhs& rhs)
|
|
- : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) {}
|
|
- static const char* Desc() { return "is equal to"; }
|
|
- static const char* NegatedDesc() { return "isn't equal to"; }
|
|
-};
|
|
-template <typename Rhs>
|
|
-class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
|
|
- public:
|
|
- explicit NeMatcher(const Rhs& rhs)
|
|
- : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) {}
|
|
- static const char* Desc() { return "isn't equal to"; }
|
|
- static const char* NegatedDesc() { return "is equal to"; }
|
|
-};
|
|
-template <typename Rhs>
|
|
-class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
|
|
- public:
|
|
- explicit LtMatcher(const Rhs& rhs)
|
|
- : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) {}
|
|
- static const char* Desc() { return "is <"; }
|
|
- static const char* NegatedDesc() { return "isn't <"; }
|
|
-};
|
|
-template <typename Rhs>
|
|
-class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
|
|
- public:
|
|
- explicit GtMatcher(const Rhs& rhs)
|
|
- : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) {}
|
|
- static const char* Desc() { return "is >"; }
|
|
- static const char* NegatedDesc() { return "isn't >"; }
|
|
-};
|
|
-template <typename Rhs>
|
|
-class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
|
|
- public:
|
|
- explicit LeMatcher(const Rhs& rhs)
|
|
- : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) {}
|
|
- static const char* Desc() { return "is <="; }
|
|
- static const char* NegatedDesc() { return "isn't <="; }
|
|
-};
|
|
-template <typename Rhs>
|
|
-class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
|
|
- public:
|
|
- explicit GeMatcher(const Rhs& rhs)
|
|
- : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) {}
|
|
- static const char* Desc() { return "is >="; }
|
|
- static const char* NegatedDesc() { return "isn't >="; }
|
|
-};
|
|
-
|
|
-template <typename T, typename = typename std::enable_if<
|
|
- std::is_constructible<std::string, T>::value>::type>
|
|
-using StringLike = T;
|
|
-
|
|
-// Implements polymorphic matchers MatchesRegex(regex) and
|
|
-// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
|
-// T can be converted to a string.
|
|
-class MatchesRegexMatcher {
|
|
- public:
|
|
- MatchesRegexMatcher(const RE* regex, bool full_match)
|
|
- : regex_(regex), full_match_(full_match) {}
|
|
-
|
|
-#if GTEST_INTERNAL_HAS_STRING_VIEW
|
|
- bool MatchAndExplain(const internal::StringView& s,
|
|
- MatchResultListener* listener) const {
|
|
- return MatchAndExplain(std::string(s), listener);
|
|
- }
|
|
-#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
|
-
|
|
- // Accepts pointer types, particularly:
|
|
- // const char*
|
|
- // char*
|
|
- // const wchar_t*
|
|
- // wchar_t*
|
|
- template <typename CharType>
|
|
- bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
|
|
- return s != nullptr && MatchAndExplain(std::string(s), listener);
|
|
- }
|
|
-
|
|
- // Matches anything that can convert to std::string.
|
|
- //
|
|
- // This is a template, not just a plain function with const std::string&,
|
|
- // because absl::string_view has some interfering non-explicit constructors.
|
|
- template <class MatcheeStringType>
|
|
- bool MatchAndExplain(const MatcheeStringType& s,
|
|
- MatchResultListener* /* listener */) const {
|
|
- const std::string& s2(s);
|
|
- return full_match_ ? RE::FullMatch(s2, *regex_)
|
|
- : RE::PartialMatch(s2, *regex_);
|
|
- }
|
|
-
|
|
- void DescribeTo(::std::ostream* os) const {
|
|
- *os << (full_match_ ? "matches" : "contains") << " regular expression ";
|
|
- UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
|
- }
|
|
-
|
|
- void DescribeNegationTo(::std::ostream* os) const {
|
|
- *os << "doesn't " << (full_match_ ? "match" : "contain")
|
|
- << " regular expression ";
|
|
- UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
|
- }
|
|
-
|
|
- private:
|
|
- const std::shared_ptr<const RE> regex_;
|
|
- const bool full_match_;
|
|
-};
|
|
-} // namespace internal
|
|
-
|
|
-// Matches a string that fully matches regular expression 'regex'.
|
|
-// The matcher takes ownership of 'regex'.
|
|
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
|
- const internal::RE* regex) {
|
|
- return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
|
|
-}
|
|
-template <typename T = std::string>
|
|
-PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
|
- const internal::StringLike<T>& regex) {
|
|
- return MatchesRegex(new internal::RE(std::string(regex)));
|
|
-}
|
|
-
|
|
-// Matches a string that contains regular expression 'regex'.
|
|
-// The matcher takes ownership of 'regex'.
|
|
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
|
- const internal::RE* regex) {
|
|
- return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
|
|
-}
|
|
-template <typename T = std::string>
|
|
-PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
|
- const internal::StringLike<T>& regex) {
|
|
- return ContainsRegex(new internal::RE(std::string(regex)));
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher that matches anything equal to x.
|
|
-// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
|
|
-// wouldn't compile.
|
|
-template <typename T>
|
|
-inline internal::EqMatcher<T> Eq(T x) {
|
|
- return internal::EqMatcher<T>(x);
|
|
-}
|
|
-
|
|
-// Constructs a Matcher<T> from a 'value' of type T. The constructed
|
|
-// matcher matches any value that's equal to 'value'.
|
|
-template <typename T>
|
|
-Matcher<T>::Matcher(T value) {
|
|
- *this = Eq(value);
|
|
-}
|
|
-
|
|
-// Creates a monomorphic matcher that matches anything with type Lhs
|
|
-// and equal to rhs. A user may need to use this instead of Eq(...)
|
|
-// in order to resolve an overloading ambiguity.
|
|
-//
|
|
-// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
|
|
-// or Matcher<T>(x), but more readable than the latter.
|
|
-//
|
|
-// We could define similar monomorphic matchers for other comparison
|
|
-// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
|
|
-// it yet as those are used much less than Eq() in practice. A user
|
|
-// can always write Matcher<T>(Lt(5)) to be explicit about the type,
|
|
-// for example.
|
|
-template <typename Lhs, typename Rhs>
|
|
-inline Matcher<Lhs> TypedEq(const Rhs& rhs) {
|
|
- return Eq(rhs);
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher that matches anything >= x.
|
|
-template <typename Rhs>
|
|
-inline internal::GeMatcher<Rhs> Ge(Rhs x) {
|
|
- return internal::GeMatcher<Rhs>(x);
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher that matches anything > x.
|
|
-template <typename Rhs>
|
|
-inline internal::GtMatcher<Rhs> Gt(Rhs x) {
|
|
- return internal::GtMatcher<Rhs>(x);
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher that matches anything <= x.
|
|
-template <typename Rhs>
|
|
-inline internal::LeMatcher<Rhs> Le(Rhs x) {
|
|
- return internal::LeMatcher<Rhs>(x);
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher that matches anything < x.
|
|
-template <typename Rhs>
|
|
-inline internal::LtMatcher<Rhs> Lt(Rhs x) {
|
|
- return internal::LtMatcher<Rhs>(x);
|
|
-}
|
|
-
|
|
-// Creates a polymorphic matcher that matches anything != x.
|
|
-template <typename Rhs>
|
|
-inline internal::NeMatcher<Rhs> Ne(Rhs x) {
|
|
- return internal::NeMatcher<Rhs>(x);
|
|
-}
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-message.h b/vendor/gtest/include/gtest/gtest-message.h
|
|
deleted file mode 100644
|
|
index 6c8bf9000..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-message.h
|
|
+++ /dev/null
|
|
@@ -1,218 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file defines the Message class.
|
|
-//
|
|
-// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
|
-// leave some internal implementation details in this header file.
|
|
-// They are clearly marked by comments like this:
|
|
-//
|
|
-// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-//
|
|
-// Such code is NOT meant to be used by a user directly, and is subject
|
|
-// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
|
-// program!
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#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"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-// Ensures that there is at least one operator<< in the global namespace.
|
|
-// See Message& operator<<(...) below for why.
|
|
-void operator<<(const testing::internal::Secret&, int);
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// The Message class works like an ostream repeater.
|
|
-//
|
|
-// Typical usage:
|
|
-//
|
|
-// 1. You stream a bunch of values to a Message object.
|
|
-// It will remember the text in a stringstream.
|
|
-// 2. Then you stream the Message object to an ostream.
|
|
-// This causes the text in the Message to be streamed
|
|
-// to the ostream.
|
|
-//
|
|
-// For example;
|
|
-//
|
|
-// testing::Message foo;
|
|
-// foo << 1 << " != " << 2;
|
|
-// std::cout << foo;
|
|
-//
|
|
-// will print "1 != 2".
|
|
-//
|
|
-// Message is not intended to be inherited from. In particular, its
|
|
-// destructor is not virtual.
|
|
-//
|
|
-// Note that stringstream behaves differently in gcc and in MSVC. You
|
|
-// can stream a NULL char pointer to it in the former, but not in the
|
|
-// latter (it causes an access violation if you do). The Message
|
|
-// class hides this difference by treating a NULL char pointer as
|
|
-// "(null)".
|
|
-class GTEST_API_ Message {
|
|
- private:
|
|
- // The type of basic IO manipulators (endl, ends, and flush) for
|
|
- // narrow streams.
|
|
- typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
|
|
-
|
|
- public:
|
|
- // Constructs an empty Message.
|
|
- Message();
|
|
-
|
|
- // Copy constructor.
|
|
- Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
|
- *ss_ << msg.GetString();
|
|
- }
|
|
-
|
|
- // Constructs a Message from a C-string.
|
|
- explicit Message(const char* str) : ss_(new ::std::stringstream) {
|
|
- *ss_ << str;
|
|
- }
|
|
-
|
|
- // Streams a non-pointer value to this object.
|
|
- template <typename T>
|
|
- inline Message& operator<<(const T& val) {
|
|
- // Some libraries overload << for STL containers. These
|
|
- // overloads are defined in the global namespace instead of ::std.
|
|
- //
|
|
- // C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
|
- // overloads are visible in either the std namespace or the global
|
|
- // namespace, but not other namespaces, including the testing
|
|
- // namespace which Google Test's Message class is in.
|
|
- //
|
|
- // To allow STL containers (and other types that has a << operator
|
|
- // defined in the global namespace) to be used in Google Test
|
|
- // assertions, testing::Message must access the custom << operator
|
|
- // from the global namespace. With this using declaration,
|
|
- // overloads of << defined in the global namespace and those
|
|
- // visible via Koenig lookup are both exposed in this function.
|
|
- using ::operator<<;
|
|
- *ss_ << val;
|
|
- return *this;
|
|
- }
|
|
-
|
|
- // Streams a pointer value to this object.
|
|
- //
|
|
- // This function is an overload of the previous one. When you
|
|
- // stream a pointer to a Message, this definition will be used as it
|
|
- // is more specialized. (The C++ Standard, section
|
|
- // [temp.func.order].) If you stream a non-pointer, then the
|
|
- // previous definition will be used.
|
|
- //
|
|
- // The reason for this overload is that streaming a NULL pointer to
|
|
- // ostream is undefined behavior. Depending on the compiler, you
|
|
- // may get "0", "(nil)", "(null)", or an access violation. To
|
|
- // ensure consistent result across compilers, we always treat NULL
|
|
- // as "(null)".
|
|
- template <typename T>
|
|
- inline Message& operator<<(T* const& pointer) { // NOLINT
|
|
- if (pointer == nullptr) {
|
|
- *ss_ << "(null)";
|
|
- } else {
|
|
- *ss_ << pointer;
|
|
- }
|
|
- return *this;
|
|
- }
|
|
-
|
|
- // Since the basic IO manipulators are overloaded for both narrow
|
|
- // and wide streams, we have to provide this specialized definition
|
|
- // of operator <<, even though its body is the same as the
|
|
- // templatized version above. Without this definition, streaming
|
|
- // endl or other basic IO manipulators to Message will confuse the
|
|
- // compiler.
|
|
- Message& operator<<(BasicNarrowIoManip val) {
|
|
- *ss_ << val;
|
|
- return *this;
|
|
- }
|
|
-
|
|
- // Instead of 1/0, we want to see true/false for bool values.
|
|
- Message& operator<<(bool b) { return *this << (b ? "true" : "false"); }
|
|
-
|
|
- // These two overloads allow streaming a wide C string to a Message
|
|
- // using the UTF-8 encoding.
|
|
- Message& operator<<(const wchar_t* wide_c_str);
|
|
- Message& operator<<(wchar_t* wide_c_str);
|
|
-
|
|
-#if GTEST_HAS_STD_WSTRING
|
|
- // Converts the given wide string to a narrow string using the UTF-8
|
|
- // encoding, and streams the result to this Message object.
|
|
- Message& operator<<(const ::std::wstring& wstr);
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
- // Gets the text streamed to this object so far as an std::string.
|
|
- // Each '\0' character in the buffer is replaced with "\\0".
|
|
- //
|
|
- // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
- std::string GetString() const;
|
|
-
|
|
- private:
|
|
- // We'll hold the text streamed to this object here.
|
|
- const std::unique_ptr< ::std::stringstream> ss_;
|
|
-
|
|
- // We declare (but don't implement) this to prevent the compiler
|
|
- // from implementing the assignment operator.
|
|
- void operator=(const Message&);
|
|
-};
|
|
-
|
|
-// Streams a Message to an ostream.
|
|
-inline std::ostream& operator<<(std::ostream& os, const Message& sb) {
|
|
- return os << sb.GetString();
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Converts a streamable value to an std::string. A NULL pointer is
|
|
-// converted to "(null)". When the input value is a ::string,
|
|
-// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
|
-// character in it is replaced with "\\0".
|
|
-template <typename T>
|
|
-std::string StreamableToString(const T& streamable) {
|
|
- return (Message() << streamable).GetString();
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-param-test.h b/vendor/gtest/include/gtest/gtest-param-test.h
|
|
deleted file mode 100644
|
|
index b55119ac6..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-param-test.h
|
|
+++ /dev/null
|
|
@@ -1,510 +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.
|
|
-
|
|
-// Macros and functions for implementing parameterized tests
|
|
-// in Google C++ Testing and Mocking Framework (Google Test)
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#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.
|
|
-//
|
|
-// Here is how you use value-parameterized tests:
|
|
-
|
|
-#if 0
|
|
-
|
|
-// To write value-parameterized tests, first you should define a fixture
|
|
-// class. It is usually derived from testing::TestWithParam<T> (see below for
|
|
-// another inheritance scheme that's sometimes useful in more complicated
|
|
-// class hierarchies), where the type of your parameter values.
|
|
-// TestWithParam<T> is itself derived from testing::Test. T can be any
|
|
-// copyable type. If it's a raw pointer, you are responsible for managing the
|
|
-// lifespan of the pointed values.
|
|
-
|
|
-class FooTest : public ::testing::TestWithParam<const char*> {
|
|
- // You can implement all the usual class fixture members here.
|
|
-};
|
|
-
|
|
-// Then, use the TEST_P macro to define as many parameterized tests
|
|
-// for this fixture as you want. The _P suffix is for "parameterized"
|
|
-// or "pattern", whichever you prefer to think.
|
|
-
|
|
-TEST_P(FooTest, DoesBlah) {
|
|
- // Inside a test, access the test parameter with the GetParam() method
|
|
- // of the TestWithParam<T> class:
|
|
- EXPECT_TRUE(foo.Blah(GetParam()));
|
|
- ...
|
|
-}
|
|
-
|
|
-TEST_P(FooTest, HasBlahBlah) {
|
|
- ...
|
|
-}
|
|
-
|
|
-// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test
|
|
-// case with any set of parameters you want. Google Test defines a number
|
|
-// of functions for generating test parameters. They return what we call
|
|
-// (surprise!) parameter generators. Here is a summary of them, which
|
|
-// are all in the testing namespace:
|
|
-//
|
|
-//
|
|
-// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
|
-// begin+step+step, ...}. The values do not
|
|
-// include end. step defaults to 1.
|
|
-// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
|
-// ValuesIn(container) - Yields values from a C-style array, an STL
|
|
-// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
|
-// Bool() - Yields sequence {false, true}.
|
|
-// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
|
-// for the math savvy) of the values generated
|
|
-// by the N generators.
|
|
-//
|
|
-// For more details, see comments at the definitions of these functions below
|
|
-// in this file.
|
|
-//
|
|
-// The following statement will instantiate tests from the FooTest test suite
|
|
-// each with parameter values "meeny", "miny", and "moe".
|
|
-
|
|
-INSTANTIATE_TEST_SUITE_P(InstantiationName,
|
|
- FooTest,
|
|
- Values("meeny", "miny", "moe"));
|
|
-
|
|
-// To distinguish different instances of the pattern, (yes, you
|
|
-// can instantiate it more than once) the first argument to the
|
|
-// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the
|
|
-// actual test suite name. Remember to pick unique prefixes for different
|
|
-// instantiations. The tests from the instantiation above will have
|
|
-// these names:
|
|
-//
|
|
-// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
|
-// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
|
-// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
|
-// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
|
-// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
|
-// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
|
-//
|
|
-// You can use these names in --gtest_filter.
|
|
-//
|
|
-// This statement will instantiate all tests from FooTest again, each
|
|
-// with parameter values "cat" and "dog":
|
|
-
|
|
-const char* pets[] = {"cat", "dog"};
|
|
-INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
|
-
|
|
-// The tests from the instantiation above will have these names:
|
|
-//
|
|
-// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
|
-// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
|
-// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
|
-// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
|
-//
|
|
-// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests
|
|
-// in the given test suite, whether their definitions come before or
|
|
-// AFTER the INSTANTIATE_TEST_SUITE_P statement.
|
|
-//
|
|
-// Please also note that generator expressions (including parameters to the
|
|
-// generators) are evaluated in InitGoogleTest(), after main() has started.
|
|
-// This allows the user on one hand, to adjust generator parameters in order
|
|
-// to dynamically determine a set of tests to run and on the other hand,
|
|
-// give the user a chance to inspect the generated tests with Google Test
|
|
-// reflection API before RUN_ALL_TESTS() is executed.
|
|
-//
|
|
-// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
|
-// for more examples.
|
|
-//
|
|
-// In the future, we plan to publish the API for defining new parameter
|
|
-// generators. But for now this interface remains part of the internal
|
|
-// implementation and is subject to change.
|
|
-//
|
|
-//
|
|
-// A parameterized test fixture must be derived from testing::Test and from
|
|
-// testing::WithParamInterface<T>, where T is the type of the parameter
|
|
-// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
|
-// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
|
-// complicated hierarchies, however, it is occasionally useful to inherit
|
|
-// separately from Test and WithParamInterface. For example:
|
|
-
|
|
-class BaseTest : public ::testing::Test {
|
|
- // You can inherit all the usual members for a non-parameterized test
|
|
- // fixture here.
|
|
-};
|
|
-
|
|
-class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
|
- // The usual test fixture members go here too.
|
|
-};
|
|
-
|
|
-TEST_F(BaseTest, HasFoo) {
|
|
- // This is an ordinary non-parameterized test.
|
|
-}
|
|
-
|
|
-TEST_P(DerivedTest, DoesBlah) {
|
|
- // GetParam works just the same here as if you inherit from TestWithParam.
|
|
- EXPECT_TRUE(foo.Blah(GetParam()));
|
|
-}
|
|
-
|
|
-#endif // 0
|
|
-
|
|
-#include <iterator>
|
|
-#include <utility>
|
|
-
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-param-util.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// Functions producing parameter generators.
|
|
-//
|
|
-// Google Test uses these generators to produce parameters for value-
|
|
-// parameterized tests. When a parameterized test suite is instantiated
|
|
-// with a particular generator, Google Test creates and runs tests
|
|
-// for each element in the sequence produced by the generator.
|
|
-//
|
|
-// In the following sample, tests from test suite FooTest are instantiated
|
|
-// each three times with parameter values 3, 5, and 8:
|
|
-//
|
|
-// class FooTest : public TestWithParam<int> { ... };
|
|
-//
|
|
-// TEST_P(FooTest, TestThis) {
|
|
-// }
|
|
-// TEST_P(FooTest, TestThat) {
|
|
-// }
|
|
-// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));
|
|
-//
|
|
-
|
|
-// Range() returns generators providing sequences of values in a range.
|
|
-//
|
|
-// Synopsis:
|
|
-// Range(start, end)
|
|
-// - returns a generator producing a sequence of values {start, start+1,
|
|
-// start+2, ..., }.
|
|
-// Range(start, end, step)
|
|
-// - returns a generator producing a sequence of values {start, start+step,
|
|
-// start+step+step, ..., }.
|
|
-// Notes:
|
|
-// * The generated sequences never include end. For example, Range(1, 5)
|
|
-// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
|
-// returns a generator producing {1, 3, 5, 7}.
|
|
-// * start and end must have the same type. That type may be any integral or
|
|
-// floating-point type or a user defined type satisfying these conditions:
|
|
-// * It must be assignable (have operator=() defined).
|
|
-// * It must have operator+() (operator+(int-compatible type) for
|
|
-// two-operand version).
|
|
-// * It must have operator<() defined.
|
|
-// Elements in the resulting sequences will also have that type.
|
|
-// * Condition start < end must be satisfied in order for resulting sequences
|
|
-// to contain any elements.
|
|
-//
|
|
-template <typename T, typename IncrementT>
|
|
-internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
|
- return internal::ParamGenerator<T>(
|
|
- new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
|
-}
|
|
-
|
|
-template <typename T>
|
|
-internal::ParamGenerator<T> Range(T start, T end) {
|
|
- return Range(start, end, 1);
|
|
-}
|
|
-
|
|
-// ValuesIn() function allows generation of tests with parameters coming from
|
|
-// a container.
|
|
-//
|
|
-// Synopsis:
|
|
-// ValuesIn(const T (&array)[N])
|
|
-// - returns a generator producing sequences with elements from
|
|
-// a C-style array.
|
|
-// ValuesIn(const Container& container)
|
|
-// - returns a generator producing sequences with elements from
|
|
-// an STL-style container.
|
|
-// ValuesIn(Iterator begin, Iterator end)
|
|
-// - returns a generator producing sequences with elements from
|
|
-// a range [begin, end) defined by a pair of STL-style iterators. These
|
|
-// iterators can also be plain C pointers.
|
|
-//
|
|
-// Please note that ValuesIn copies the values from the containers
|
|
-// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
|
-//
|
|
-// Examples:
|
|
-//
|
|
-// This instantiates tests from test suite StringTest
|
|
-// each with C-string values of "foo", "bar", and "baz":
|
|
-//
|
|
-// const char* strings[] = {"foo", "bar", "baz"};
|
|
-// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));
|
|
-//
|
|
-// This instantiates tests from test suite StlStringTest
|
|
-// each with STL strings with values "a" and "b":
|
|
-//
|
|
-// ::std::vector< ::std::string> GetParameterStrings() {
|
|
-// ::std::vector< ::std::string> v;
|
|
-// v.push_back("a");
|
|
-// v.push_back("b");
|
|
-// return v;
|
|
-// }
|
|
-//
|
|
-// INSTANTIATE_TEST_SUITE_P(CharSequence,
|
|
-// StlStringTest,
|
|
-// ValuesIn(GetParameterStrings()));
|
|
-//
|
|
-//
|
|
-// This will also instantiate tests from CharTest
|
|
-// each with parameter values 'a' and 'b':
|
|
-//
|
|
-// ::std::list<char> GetParameterChars() {
|
|
-// ::std::list<char> list;
|
|
-// list.push_back('a');
|
|
-// list.push_back('b');
|
|
-// return list;
|
|
-// }
|
|
-// ::std::list<char> l = GetParameterChars();
|
|
-// INSTANTIATE_TEST_SUITE_P(CharSequence2,
|
|
-// CharTest,
|
|
-// ValuesIn(l.begin(), l.end()));
|
|
-//
|
|
-template <typename ForwardIterator>
|
|
-internal::ParamGenerator<
|
|
- typename std::iterator_traits<ForwardIterator>::value_type>
|
|
-ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
|
- typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;
|
|
- return internal::ParamGenerator<ParamType>(
|
|
- new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
|
-}
|
|
-
|
|
-template <typename T, size_t N>
|
|
-internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
|
- return ValuesIn(array, array + N);
|
|
-}
|
|
-
|
|
-template <class Container>
|
|
-internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
|
- const Container& container) {
|
|
- return ValuesIn(container.begin(), container.end());
|
|
-}
|
|
-
|
|
-// Values() allows generating tests from explicitly specified list of
|
|
-// parameters.
|
|
-//
|
|
-// Synopsis:
|
|
-// Values(T v1, T v2, ..., T vN)
|
|
-// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
|
-//
|
|
-// For example, this instantiates tests from test suite BarTest each
|
|
-// with values "one", "two", and "three":
|
|
-//
|
|
-// INSTANTIATE_TEST_SUITE_P(NumSequence,
|
|
-// BarTest,
|
|
-// Values("one", "two", "three"));
|
|
-//
|
|
-// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.
|
|
-// The exact type of values will depend on the type of parameter in BazTest.
|
|
-//
|
|
-// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
|
-//
|
|
-//
|
|
-template <typename... T>
|
|
-internal::ValueArray<T...> Values(T... v) {
|
|
- return internal::ValueArray<T...>(std::move(v)...);
|
|
-}
|
|
-
|
|
-// Bool() allows generating tests with parameters in a set of (false, true).
|
|
-//
|
|
-// Synopsis:
|
|
-// Bool()
|
|
-// - returns a generator producing sequences with elements {false, true}.
|
|
-//
|
|
-// It is useful when testing code that depends on Boolean flags. Combinations
|
|
-// of multiple flags can be tested when several Bool()'s are combined using
|
|
-// Combine() function.
|
|
-//
|
|
-// In the following example all tests in the test suite FlagDependentTest
|
|
-// will be instantiated twice with parameters false and true.
|
|
-//
|
|
-// class FlagDependentTest : public testing::TestWithParam<bool> {
|
|
-// virtual void SetUp() {
|
|
-// external_flag = GetParam();
|
|
-// }
|
|
-// }
|
|
-// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
|
|
-//
|
|
-inline internal::ParamGenerator<bool> Bool() { return Values(false, true); }
|
|
-
|
|
-// Combine() allows the user to combine two or more sequences to produce
|
|
-// values of a Cartesian product of those sequences' elements.
|
|
-//
|
|
-// Synopsis:
|
|
-// Combine(gen1, gen2, ..., genN)
|
|
-// - returns a generator producing sequences with elements coming from
|
|
-// the Cartesian product of elements from the sequences generated by
|
|
-// gen1, gen2, ..., genN. The sequence elements will have a type of
|
|
-// std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
|
-// of elements from sequences produces by gen1, gen2, ..., genN.
|
|
-//
|
|
-// Example:
|
|
-//
|
|
-// This will instantiate tests in test suite AnimalTest each one with
|
|
-// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
|
-// tuple("dog", BLACK), and tuple("dog", WHITE):
|
|
-//
|
|
-// enum Color { BLACK, GRAY, WHITE };
|
|
-// class AnimalTest
|
|
-// : public testing::TestWithParam<std::tuple<const char*, Color> > {...};
|
|
-//
|
|
-// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
|
-//
|
|
-// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
|
|
-// Combine(Values("cat", "dog"),
|
|
-// Values(BLACK, WHITE)));
|
|
-//
|
|
-// This will instantiate tests in FlagDependentTest with all variations of two
|
|
-// Boolean flags:
|
|
-//
|
|
-// class FlagDependentTest
|
|
-// : public testing::TestWithParam<std::tuple<bool, bool> > {
|
|
-// virtual void SetUp() {
|
|
-// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
|
-// std::tie(external_flag_1, external_flag_2) = GetParam();
|
|
-// }
|
|
-// };
|
|
-//
|
|
-// TEST_P(FlagDependentTest, TestFeature1) {
|
|
-// // Test your code using external_flag_1 and external_flag_2 here.
|
|
-// }
|
|
-// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,
|
|
-// Combine(Bool(), Bool()));
|
|
-//
|
|
-template <typename... Generator>
|
|
-internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
|
- return internal::CartesianProductHolder<Generator...>(g...);
|
|
-}
|
|
-
|
|
-#define TEST_P(test_suite_name, test_name) \
|
|
- class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
|
- : public test_suite_name { \
|
|
- public: \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
|
- void TestBody() override; \
|
|
- \
|
|
- private: \
|
|
- static int AddToRegistry() { \
|
|
- ::testing::UnitTest::GetInstance() \
|
|
- ->parameterized_test_registry() \
|
|
- .GetTestSuitePatternHolder<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)>(), \
|
|
- ::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
|
- return 0; \
|
|
- } \
|
|
- static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
|
- (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
|
|
- const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
|
- test_name) &) = delete; /* NOLINT */ \
|
|
- }; \
|
|
- int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
|
- test_name)::gtest_registering_dummy_ = \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \
|
|
- void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
|
|
-
|
|
-// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify
|
|
-// generator and an optional function or functor that generates custom test name
|
|
-// suffixes based on the test parameters. Such a function or functor should
|
|
-// accept one argument of type testing::TestParamInfo<class ParamType>, and
|
|
-// return std::string.
|
|
-//
|
|
-// testing::PrintToStringParamName is a builtin test suffix generator that
|
|
-// returns the value of testing::PrintToString(GetParam()).
|
|
-//
|
|
-// Note: test names must be non-empty, unique, and may only contain ASCII
|
|
-// alphanumeric characters or underscore. Because PrintToString adds quotes
|
|
-// to std::string and C strings, it won't work for these types.
|
|
-
|
|
-#define GTEST_EXPAND_(arg) arg
|
|
-#define GTEST_GET_FIRST_(first, ...) first
|
|
-#define GTEST_GET_SECOND_(first, second, ...) second
|
|
-
|
|
-#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
|
- static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
|
- gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
|
- return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
|
- } \
|
|
- static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
|
- const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
|
- if (::testing::internal::AlwaysFalse()) { \
|
|
- ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
|
- __VA_ARGS__, \
|
|
- ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
|
- DUMMY_PARAM_))); \
|
|
- auto t = std::make_tuple(__VA_ARGS__); \
|
|
- static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
|
- "Too Many Args!"); \
|
|
- } \
|
|
- return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
|
- __VA_ARGS__, \
|
|
- ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
|
- DUMMY_PARAM_))))(info); \
|
|
- } \
|
|
- static int gtest_##prefix##test_suite_name##_dummy_ \
|
|
- GTEST_ATTRIBUTE_UNUSED_ = \
|
|
- ::testing::UnitTest::GetInstance() \
|
|
- ->parameterized_test_registry() \
|
|
- .GetTestSuitePatternHolder<test_suite_name>( \
|
|
- GTEST_STRINGIFY_(test_suite_name), \
|
|
- ::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
|
- ->AddTestSuiteInstantiation( \
|
|
- GTEST_STRINGIFY_(prefix), \
|
|
- >est_##prefix##test_suite_name##_EvalGenerator_, \
|
|
- >est_##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 \
|
|
- static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \
|
|
- ""); \
|
|
- INSTANTIATE_TEST_SUITE_P
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-printers.h b/vendor/gtest/include/gtest/gtest-printers.h
|
|
deleted file mode 100644
|
|
index a91e8b8b1..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-printers.h
|
|
+++ /dev/null
|
|
@@ -1,1048 +0,0 @@
|
|
-// Copyright 2007, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// Google Test - The Google C++ Testing and Mocking Framework
|
|
-//
|
|
-// This file implements a universal value printer that can print a
|
|
-// value of any type T:
|
|
-//
|
|
-// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
|
-//
|
|
-// A user can teach this function how to print a class type T by
|
|
-// defining either operator<<() or PrintTo() in the namespace that
|
|
-// defines T. More specifically, the FIRST defined function in the
|
|
-// following list will be used (assuming T is defined in namespace
|
|
-// foo):
|
|
-//
|
|
-// 1. foo::PrintTo(const T&, ostream*)
|
|
-// 2. operator<<(ostream&, const T&) defined in either foo or the
|
|
-// global namespace.
|
|
-//
|
|
-// However if T is an STL-style container then it is printed element-wise
|
|
-// unless foo::PrintTo(const T&, ostream*) is defined. Note that
|
|
-// operator<<() is ignored for container types.
|
|
-//
|
|
-// If none of the above is defined, it will print the debug string of
|
|
-// the value if it is a protocol buffer, or print the raw bytes in the
|
|
-// value otherwise.
|
|
-//
|
|
-// To aid debugging: when T is a reference type, the address of the
|
|
-// value is also printed; when T is a (const) char pointer, both the
|
|
-// pointer value and the NUL-terminated string it points to are
|
|
-// printed.
|
|
-//
|
|
-// We also provide some convenient wrappers:
|
|
-//
|
|
-// // Prints a value to a string. For a (const or not) char
|
|
-// // pointer, the NUL-terminated string (but not the pointer) is
|
|
-// // printed.
|
|
-// std::string ::testing::PrintToString(const T& value);
|
|
-//
|
|
-// // Prints a value tersely: for a reference type, the referenced
|
|
-// // value (but not the address) is printed; for a (const or not) char
|
|
-// // pointer, the NUL-terminated string (but not the pointer) is
|
|
-// // printed.
|
|
-// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
|
|
-//
|
|
-// // Prints value using the type inferred by the compiler. The difference
|
|
-// // from UniversalTersePrint() is that this function prints both the
|
|
-// // pointer and the NUL-terminated string for a (const or not) char pointer.
|
|
-// void ::testing::internal::UniversalPrint(const T& value, ostream*);
|
|
-//
|
|
-// // Prints the fields of a tuple tersely to a string vector, one
|
|
-// // element for each field. Tuple support must be enabled in
|
|
-// // gtest-port.h.
|
|
-// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
|
|
-// const Tuple& value);
|
|
-//
|
|
-// Known limitation:
|
|
-//
|
|
-// The print primitives print the elements of an STL-style container
|
|
-// using the compiler-inferred type of *iter where iter is a
|
|
-// const_iterator of the container. When const_iterator is an input
|
|
-// iterator but not a forward iterator, this inferred type may not
|
|
-// match value_type, and the print output may be incorrect. In
|
|
-// practice, this is rarely a problem as for most containers
|
|
-// const_iterator is a forward iterator. We'll fix this if there's an
|
|
-// actual need for it. Note that this fix cannot rely on value_type
|
|
-// being defined as many user-defined container types don't have
|
|
-// value_type.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#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>
|
|
-#include <tuple>
|
|
-#include <type_traits>
|
|
-#include <utility>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// Definitions in the internal* namespaces are subject to change without notice.
|
|
-// DO NOT USE THEM IN USER CODE!
|
|
-namespace internal {
|
|
-
|
|
-template <typename T>
|
|
-void UniversalPrint(const T& value, ::std::ostream* os);
|
|
-
|
|
-// 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;
|
|
- }
|
|
-
|
|
- 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.)
|
|
-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);
|
|
- }
|
|
- }
|
|
-};
|
|
-
|
|
-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) {
|
|
- pretty_str = "\n" + value.DebugString();
|
|
- }
|
|
- *os << ("<" + pretty_str + ">");
|
|
- }
|
|
-};
|
|
-
|
|
-struct ConvertibleToIntegerPrinter {
|
|
- // Since T has no << operator or PrintTo() but can be implicitly
|
|
- // converted to BiggestInt, we print it as a BiggestInt.
|
|
- //
|
|
- // Most likely T is an enum type (either named or unnamed), in which
|
|
- // 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(internal::BiggestInt value, ::std::ostream* os) {
|
|
- *os << value;
|
|
- }
|
|
-};
|
|
-
|
|
-struct ConvertibleToStringViewPrinter {
|
|
-#if GTEST_INTERNAL_HAS_STRING_VIEW
|
|
- static void PrintValue(internal::StringView value, ::std::ostream* os) {
|
|
- internal::UniversalPrint(value, os);
|
|
- }
|
|
-#endif
|
|
-};
|
|
-
|
|
-// 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);
|
|
- }
|
|
-};
|
|
-
|
|
-struct FallbackPrinter {
|
|
- template <typename T>
|
|
- static void PrintValue(const T&, ::std::ostream* os) {
|
|
- *os << "(incomplete type)";
|
|
- }
|
|
-};
|
|
-
|
|
-// 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 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);
|
|
-}
|
|
-
|
|
-// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
|
|
-// value of type ToPrint that is an operand of a comparison assertion
|
|
-// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
|
|
-// the comparison, and is used to help determine the best way to
|
|
-// format the value. In particular, when the value is a C string
|
|
-// (char pointer) and the other operand is an STL string object, we
|
|
-// want to format the C string as a string, since we know it is
|
|
-// compared by value with the string object. If the value is a char
|
|
-// pointer but the other operand is not an STL string object, we don't
|
|
-// know whether the pointer is supposed to point to a NUL-terminated
|
|
-// string, and thus want to print it as a pointer to be safe.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-
|
|
-// The default case.
|
|
-template <typename ToPrint, typename OtherOperand>
|
|
-class FormatForComparison {
|
|
- public:
|
|
- static ::std::string Format(const ToPrint& value) {
|
|
- return ::testing::PrintToString(value);
|
|
- }
|
|
-};
|
|
-
|
|
-// Array.
|
|
-template <typename ToPrint, size_t N, typename OtherOperand>
|
|
-class FormatForComparison<ToPrint[N], OtherOperand> {
|
|
- public:
|
|
- static ::std::string Format(const ToPrint* value) {
|
|
- return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
|
- }
|
|
-};
|
|
-
|
|
-// By default, print C string as pointers to be safe, as we don't know
|
|
-// whether they actually point to a NUL-terminated string.
|
|
-
|
|
-#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
|
|
- template <typename OtherOperand> \
|
|
- class FormatForComparison<CharType*, OtherOperand> { \
|
|
- public: \
|
|
- static ::std::string Format(CharType* value) { \
|
|
- return ::testing::PrintToString(static_cast<const void*>(value)); \
|
|
- } \
|
|
- }
|
|
-
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
|
-#ifdef __cpp_lib_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_
|
|
-
|
|
-// If a C string is compared with an STL string object, we know it's meant
|
|
-// to point to a NUL-terminated string, and thus can print it as a string.
|
|
-
|
|
-#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
|
|
- template <> \
|
|
- class FormatForComparison<CharType*, OtherStringType> { \
|
|
- public: \
|
|
- static ::std::string Format(CharType* value) { \
|
|
- return ::testing::PrintToString(value); \
|
|
- } \
|
|
- }
|
|
-
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
|
-#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);
|
|
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
|
-#endif
|
|
-
|
|
-#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
|
|
-
|
|
-// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
|
|
-// operand to be used in a failure message. The type (but not value)
|
|
-// of the other operand may affect the format. This allows us to
|
|
-// print a char* as a raw pointer when it is compared against another
|
|
-// char* or void*, and print it as a C string when it is compared
|
|
-// against an std::string object, for example.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-template <typename T1, typename T2>
|
|
-std::string FormatForComparisonFailureMessage(const T1& value,
|
|
- const T2& /* other_operand */) {
|
|
- return FormatForComparison<T1, T2>::Format(value);
|
|
-}
|
|
-
|
|
-// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
|
-// value to the given ostream. The caller must ensure that
|
|
-// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
|
-//
|
|
-// We define UniversalPrinter as a class template (as opposed to a
|
|
-// function template), as we need to partially specialize it for
|
|
-// reference types, which cannot be done with function templates.
|
|
-template <typename T>
|
|
-class UniversalPrinter;
|
|
-
|
|
-// 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
|
|
-// or overloaded for type T.
|
|
-//
|
|
-// A user can override this behavior for a class type Foo by defining
|
|
-// an overload of PrintTo() in the namespace where Foo is defined. We
|
|
-// give the user this option as sometimes defining a << operator for
|
|
-// Foo is not desirable (e.g. the coding style may prevent doing it,
|
|
-// or there is already a << operator but it doesn't do what the user
|
|
-// wants).
|
|
-template <typename T>
|
|
-void PrintTo(const T& value, ::std::ostream* os) {
|
|
- internal::PrintWithFallback(value, os);
|
|
-}
|
|
-
|
|
-// The following list of PrintTo() overloads tells
|
|
-// UniversalPrinter<T>::Print() how to print standard types (built-in
|
|
-// types, strings, plain arrays, and pointers).
|
|
-
|
|
-// Overloads for various char types.
|
|
-GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
|
|
-GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
|
|
-inline void PrintTo(char c, ::std::ostream* os) {
|
|
- // When printing a plain char, we always treat it as unsigned. This
|
|
- // way, the output won't be affected by whether the compiler thinks
|
|
- // char is signed or not.
|
|
- PrintTo(static_cast<unsigned char>(c), os);
|
|
-}
|
|
-
|
|
-// Overloads for other simple built-in types.
|
|
-inline void PrintTo(bool x, ::std::ostream* os) {
|
|
- *os << (x ? "true" : "false");
|
|
-}
|
|
-
|
|
-// Overload for wchar_t type.
|
|
-// Prints a wchar_t as a symbol if it is printable or as its internal
|
|
-// code otherwise and also as its decimal code (except for L'\0').
|
|
-// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
|
-// as signed integer when wchar_t is implemented by the compiler
|
|
-// as a signed type and is printed as an unsigned integer when wchar_t
|
|
-// 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
|
|
-
|
|
-// gcc/clang __{u,}int128_t
|
|
-#if defined(__SIZEOF_INT128__)
|
|
-GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
|
|
-GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
|
|
-#endif // __SIZEOF_INT128__
|
|
-
|
|
-// Overloads for C strings.
|
|
-GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
|
-inline void PrintTo(char* s, ::std::ostream* os) {
|
|
- PrintTo(ImplicitCast_<const char*>(s), os);
|
|
-}
|
|
-
|
|
-// signed/unsigned char is often used for representing binary data, so
|
|
-// we print pointers to it as void* to be safe.
|
|
-inline void PrintTo(const signed char* s, ::std::ostream* os) {
|
|
- PrintTo(ImplicitCast_<const void*>(s), os);
|
|
-}
|
|
-inline void PrintTo(signed char* s, ::std::ostream* os) {
|
|
- PrintTo(ImplicitCast_<const void*>(s), os);
|
|
-}
|
|
-inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
|
|
- PrintTo(ImplicitCast_<const void*>(s), 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
|
|
-// type. When wchar_t is a typedef, defining an overload for const
|
|
-// wchar_t* would cause unsigned short* be printed as a wide string,
|
|
-// possibly causing invalid memory accesses.
|
|
-#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
|
-// Overloads for wide C strings
|
|
-GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
|
|
-inline void PrintTo(wchar_t* s, ::std::ostream* os) {
|
|
- PrintTo(ImplicitCast_<const wchar_t*>(s), os);
|
|
-}
|
|
-#endif
|
|
-
|
|
-// Overload for C arrays. Multi-dimensional arrays are printed
|
|
-// properly.
|
|
-
|
|
-// Prints the given number of elements in an array, without printing
|
|
-// the curly braces.
|
|
-template <typename T>
|
|
-void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
|
- UniversalPrint(a[0], os);
|
|
- for (size_t i = 1; i != count; i++) {
|
|
- *os << ", ";
|
|
- UniversalPrint(a[i], os);
|
|
- }
|
|
-}
|
|
-
|
|
-// Overloads for ::std::string.
|
|
-GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
|
|
-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);
|
|
-inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
|
- PrintWideStringTo(s, os);
|
|
-}
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-#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_INTERNAL_HAS_STRING_VIEW
|
|
-
|
|
-inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
|
|
-
|
|
-#if GTEST_HAS_RTTI
|
|
-inline void PrintTo(const std::type_info& info, std::ostream* os) {
|
|
- *os << internal::GetTypeName(info);
|
|
-}
|
|
-#endif // GTEST_HAS_RTTI
|
|
-
|
|
-template <typename T>
|
|
-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>
|
|
-void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
|
|
- ::std::ostream*) {}
|
|
-
|
|
-template <typename T, size_t I>
|
|
-void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
|
|
- ::std::ostream* os) {
|
|
- PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
|
|
- GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
|
- if (I > 1) {
|
|
- GTEST_INTENTIONAL_CONST_COND_POP_()
|
|
- *os << ", ";
|
|
- }
|
|
- UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
|
|
- std::get<I - 1>(t), os);
|
|
-}
|
|
-
|
|
-template <typename... Types>
|
|
-void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
|
|
- *os << "(";
|
|
- PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
|
|
- *os << ")";
|
|
-}
|
|
-
|
|
-// Overload for std::pair.
|
|
-template <typename T1, typename T2>
|
|
-void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
|
- *os << '(';
|
|
- // We cannot use UniversalPrint(value.first, os) here, as T1 may be
|
|
- // a reference type. The same for printing value.second.
|
|
- UniversalPrinter<T1>::Print(value.first, os);
|
|
- *os << ", ";
|
|
- UniversalPrinter<T2>::Print(value.second, os);
|
|
- *os << ')';
|
|
-}
|
|
-
|
|
-// Implements printing a non-reference type T by letting the compiler
|
|
-// pick the right overload of PrintTo() for T.
|
|
-template <typename T>
|
|
-class UniversalPrinter {
|
|
- public:
|
|
- // MSVC warns about adding const to a function type, so we want to
|
|
- // disable the warning.
|
|
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
|
-
|
|
- // Note: we deliberately don't call this PrintTo(), as that name
|
|
- // conflicts with ::testing::internal::PrintTo in the body of the
|
|
- // function.
|
|
- static void Print(const T& value, ::std::ostream* os) {
|
|
- // By default, ::testing::internal::PrintTo() is used for printing
|
|
- // the value.
|
|
- //
|
|
- // Thanks to Koenig look-up, if T is a class and has its own
|
|
- // PrintTo() function defined in its namespace, that function will
|
|
- // be visible here. Since it is more specific than the generic ones
|
|
- // in ::testing::internal, it will be picked by the compiler in the
|
|
- // following statement - exactly what we want.
|
|
- PrintTo(value, os);
|
|
- }
|
|
-
|
|
- GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-};
|
|
-
|
|
-// Remove any const-qualifiers before passing a type to UniversalPrinter.
|
|
-template <typename T>
|
|
-class UniversalPrinter<const T> : public UniversalPrinter<T> {};
|
|
-
|
|
-#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<Optional<T>> {
|
|
- public:
|
|
- static void Print(const Optional<T>& value, ::std::ostream* os) {
|
|
- *os << '(';
|
|
- if (!value) {
|
|
- *os << "nullopt";
|
|
- } else {
|
|
- UniversalPrint(*value, os);
|
|
- }
|
|
- *os << ')';
|
|
- }
|
|
-};
|
|
-
|
|
-template <>
|
|
-class UniversalPrinter<decltype(Nullopt())> {
|
|
- public:
|
|
- static void Print(decltype(Nullopt()), ::std::ostream* os) {
|
|
- *os << "(nullopt)";
|
|
- }
|
|
-};
|
|
-
|
|
-#endif // GTEST_INTERNAL_HAS_OPTIONAL
|
|
-
|
|
-#if GTEST_INTERNAL_HAS_VARIANT
|
|
-
|
|
-// Printer for std::variant / absl::variant
|
|
-
|
|
-template <typename... T>
|
|
-class UniversalPrinter<Variant<T...>> {
|
|
- public:
|
|
- static void Print(const Variant<T...>& value, ::std::ostream* os) {
|
|
- *os << '(';
|
|
-#if GTEST_HAS_ABSL
|
|
- absl::visit(Visitor{os, value.index()}, value);
|
|
-#else
|
|
- std::visit(Visitor{os, value.index()}, value);
|
|
-#endif // GTEST_HAS_ABSL
|
|
- *os << ')';
|
|
- }
|
|
-
|
|
- private:
|
|
- struct Visitor {
|
|
- template <typename U>
|
|
- void operator()(const U& u) const {
|
|
- *os << "'" << GetTypeName<U>() << "(index = " << index
|
|
- << ")' with value ";
|
|
- UniversalPrint(u, os);
|
|
- }
|
|
- ::std::ostream* os;
|
|
- std::size_t index;
|
|
- };
|
|
-};
|
|
-
|
|
-#endif // GTEST_INTERNAL_HAS_VARIANT
|
|
-
|
|
-// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
|
-// elements, starting at address 'begin'.
|
|
-template <typename T>
|
|
-void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
|
|
- if (len == 0) {
|
|
- *os << "{}";
|
|
- } else {
|
|
- *os << "{ ";
|
|
- const size_t kThreshold = 18;
|
|
- const size_t kChunkSize = 8;
|
|
- // If the array has more than kThreshold elements, we'll have to
|
|
- // omit some details by printing only the first and the last
|
|
- // kChunkSize elements.
|
|
- if (len <= kThreshold) {
|
|
- PrintRawArrayTo(begin, len, os);
|
|
- } else {
|
|
- PrintRawArrayTo(begin, kChunkSize, os);
|
|
- *os << ", ..., ";
|
|
- PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
|
|
- }
|
|
- *os << " }";
|
|
- }
|
|
-}
|
|
-// This overload prints a (const) char array compactly.
|
|
-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);
|
|
-
|
|
-// Implements printing an array type T[N].
|
|
-template <typename T, size_t N>
|
|
-class UniversalPrinter<T[N]> {
|
|
- public:
|
|
- // Prints the given array, omitting some elements when there are too
|
|
- // many.
|
|
- static void Print(const T (&a)[N], ::std::ostream* os) {
|
|
- UniversalPrintArray(a, N, os);
|
|
- }
|
|
-};
|
|
-
|
|
-// Implements printing a reference type T&.
|
|
-template <typename T>
|
|
-class UniversalPrinter<T&> {
|
|
- public:
|
|
- // MSVC warns about adding const to a function type, so we want to
|
|
- // disable the warning.
|
|
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
|
-
|
|
- static void Print(const T& value, ::std::ostream* os) {
|
|
- // Prints the address of the value. We use reinterpret_cast here
|
|
- // as static_cast doesn't compile when T is a function type.
|
|
- *os << "@" << reinterpret_cast<const void*>(&value) << " ";
|
|
-
|
|
- // Then prints the value itself.
|
|
- UniversalPrint(value, os);
|
|
- }
|
|
-
|
|
- GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-};
|
|
-
|
|
-// Prints a value tersely: for a reference type, the referenced value
|
|
-// (but not the address) is printed; for a (const) char pointer, the
|
|
-// NUL-terminated string (but not the pointer) is printed.
|
|
-
|
|
-template <typename T>
|
|
-class UniversalTersePrinter {
|
|
- public:
|
|
- static void Print(const T& value, ::std::ostream* os) {
|
|
- UniversalPrint(value, os);
|
|
- }
|
|
-};
|
|
-template <typename T>
|
|
-class UniversalTersePrinter<T&> {
|
|
- public:
|
|
- static void Print(const T& value, ::std::ostream* os) {
|
|
- UniversalPrint(value, os);
|
|
- }
|
|
-};
|
|
-template <typename T, size_t N>
|
|
-class UniversalTersePrinter<T[N]> {
|
|
- public:
|
|
- static void Print(const T (&value)[N], ::std::ostream* os) {
|
|
- UniversalPrinter<T[N]>::Print(value, os);
|
|
- }
|
|
-};
|
|
-template <>
|
|
-class UniversalTersePrinter<const char*> {
|
|
- public:
|
|
- static void Print(const char* str, ::std::ostream* os) {
|
|
- if (str == nullptr) {
|
|
- *os << "NULL";
|
|
- } else {
|
|
- UniversalPrint(std::string(str), os);
|
|
- }
|
|
- }
|
|
-};
|
|
-template <>
|
|
-class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
|
|
-};
|
|
-
|
|
-#ifdef __cpp_char8_t
|
|
-template <>
|
|
-class UniversalTersePrinter<const char8_t*> {
|
|
- public:
|
|
- 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 <>
|
|
-class UniversalTersePrinter<const wchar_t*> {
|
|
- public:
|
|
- static void Print(const wchar_t* str, ::std::ostream* os) {
|
|
- if (str == nullptr) {
|
|
- *os << "NULL";
|
|
- } else {
|
|
- UniversalPrint(::std::wstring(str), os);
|
|
- }
|
|
- }
|
|
-};
|
|
-#endif
|
|
-
|
|
-template <>
|
|
-class UniversalTersePrinter<wchar_t*> {
|
|
- public:
|
|
- static void Print(wchar_t* str, ::std::ostream* os) {
|
|
- UniversalTersePrinter<const wchar_t*>::Print(str, os);
|
|
- }
|
|
-};
|
|
-
|
|
-template <typename T>
|
|
-void UniversalTersePrint(const T& value, ::std::ostream* os) {
|
|
- UniversalTersePrinter<T>::Print(value, os);
|
|
-}
|
|
-
|
|
-// Prints a value using the type inferred by the compiler. The
|
|
-// difference between this and UniversalTersePrint() is that for a
|
|
-// (const) char pointer, this prints both the pointer and the
|
|
-// NUL-terminated string.
|
|
-template <typename T>
|
|
-void UniversalPrint(const T& value, ::std::ostream* os) {
|
|
- // A workarond for the bug in VC++ 7.1 that prevents us from instantiating
|
|
- // UniversalPrinter with T directly.
|
|
- typedef T T1;
|
|
- UniversalPrinter<T1>::Print(value, os);
|
|
-}
|
|
-
|
|
-typedef ::std::vector<::std::string> Strings;
|
|
-
|
|
-// Tersely prints the first N fields of a tuple to a string vector,
|
|
-// one element for each field.
|
|
-template <typename Tuple>
|
|
-void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
|
|
- Strings*) {}
|
|
-template <typename Tuple, size_t I>
|
|
-void TersePrintPrefixToStrings(const Tuple& t,
|
|
- std::integral_constant<size_t, I>,
|
|
- Strings* strings) {
|
|
- TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
|
|
- strings);
|
|
- ::std::stringstream ss;
|
|
- UniversalTersePrint(std::get<I - 1>(t), &ss);
|
|
- strings->push_back(ss.str());
|
|
-}
|
|
-
|
|
-// Prints the fields of a tuple tersely to a string vector, one
|
|
-// element for each field. See the comment before
|
|
-// UniversalTersePrint() for how we define "tersely".
|
|
-template <typename Tuple>
|
|
-Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
|
- Strings result;
|
|
- TersePrintPrefixToStrings(
|
|
- value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
|
|
- &result);
|
|
- return result;
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-template <typename T>
|
|
-::std::string PrintToString(const T& value) {
|
|
- ::std::stringstream ss;
|
|
- internal::UniversalTersePrinter<T>::Print(value, &ss);
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-// Include any custom printer added by the local installation.
|
|
-// We must include this header at the end to make sure it can use the
|
|
-// declarations from this file.
|
|
-#include "gtest/internal/custom/gtest-printers.h"
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-spi.h b/vendor/gtest/include/gtest/gtest-spi.h
|
|
deleted file mode 100644
|
|
index bec8c4810..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-spi.h
|
|
+++ /dev/null
|
|
@@ -1,248 +0,0 @@
|
|
-// Copyright 2007, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// Utilities for testing Google Test itself and code that uses Google Test
|
|
-// (e.g. frameworks built on top of Google Test).
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// This helper class can be used to mock out Google Test failure reporting
|
|
-// so that we can test Google Test or code that builds on Google Test.
|
|
-//
|
|
-// An object of this class appends a TestPartResult object to the
|
|
-// TestPartResultArray object given in the constructor whenever a Google Test
|
|
-// failure is reported. It can either intercept only failures that are
|
|
-// generated in the same thread that created this object or it can intercept
|
|
-// all generated failures. The scope of this mock object can be controlled with
|
|
-// the second argument to the two arguments constructor.
|
|
-class GTEST_API_ ScopedFakeTestPartResultReporter
|
|
- : public TestPartResultReporterInterface {
|
|
- public:
|
|
- // The two possible mocking modes of this object.
|
|
- enum InterceptMode {
|
|
- INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
|
- INTERCEPT_ALL_THREADS // Intercepts all failures.
|
|
- };
|
|
-
|
|
- // The c'tor sets this object as the test part result reporter used
|
|
- // by Google Test. The 'result' parameter specifies where to report the
|
|
- // results. This reporter will only catch failures generated in the current
|
|
- // thread. DEPRECATED
|
|
- explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
|
|
-
|
|
- // Same as above, but you can choose the interception scope of this object.
|
|
- ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
|
|
- TestPartResultArray* result);
|
|
-
|
|
- // The d'tor restores the previous test part result reporter.
|
|
- ~ScopedFakeTestPartResultReporter() override;
|
|
-
|
|
- // Appends the TestPartResult object to the TestPartResultArray
|
|
- // received in the constructor.
|
|
- //
|
|
- // This method is from the TestPartResultReporterInterface
|
|
- // interface.
|
|
- void ReportTestPartResult(const TestPartResult& result) override;
|
|
-
|
|
- private:
|
|
- void Init();
|
|
-
|
|
- const InterceptMode intercept_mode_;
|
|
- TestPartResultReporterInterface* old_reporter_;
|
|
- TestPartResultArray* const result_;
|
|
-
|
|
- ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =
|
|
- delete;
|
|
- ScopedFakeTestPartResultReporter& operator=(
|
|
- const ScopedFakeTestPartResultReporter&) = delete;
|
|
-};
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
|
-// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
|
-// TestPartResultArray contains exactly one failure that has the given
|
|
-// type and contains the given substring. If that's not the case, a
|
|
-// non-fatal failure will be generated.
|
|
-class GTEST_API_ SingleFailureChecker {
|
|
- public:
|
|
- // The constructor remembers the arguments.
|
|
- SingleFailureChecker(const TestPartResultArray* results,
|
|
- TestPartResult::Type type, const std::string& substr);
|
|
- ~SingleFailureChecker();
|
|
-
|
|
- private:
|
|
- const TestPartResultArray* const results_;
|
|
- const TestPartResult::Type type_;
|
|
- const std::string substr_;
|
|
-
|
|
- SingleFailureChecker(const SingleFailureChecker&) = delete;
|
|
- SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-// A set of macros for testing Google Test assertions or code that's expected
|
|
-// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but
|
|
-// not a non-fatal failure, as from EXPECT_EQ). It verifies that the given
|
|
-// statement will cause exactly one fatal Google Test failure with 'substr'
|
|
-// being part of the failure message.
|
|
-//
|
|
-// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
|
-// affects and considers failures generated in the current thread and
|
|
-// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
|
-//
|
|
-// The verification of the assertion is done correctly even when the statement
|
|
-// throws an exception or aborts the current function.
|
|
-//
|
|
-// Known restrictions:
|
|
-// - 'statement' cannot reference local non-static variables or
|
|
-// non-static members of the current object.
|
|
-// - 'statement' cannot return a value.
|
|
-// - You cannot stream a failure message to this macro.
|
|
-//
|
|
-// Note that even though the implementations of the following two
|
|
-// macros are much alike, we cannot refactor them to use a common
|
|
-// helper macro, due to some peculiarity in how the preprocessor
|
|
-// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
|
-// gtest_unittest.cc will fail to compile if we do that.
|
|
-#define EXPECT_FATAL_FAILURE(statement, substr) \
|
|
- do { \
|
|
- class GTestExpectFatalFailureHelper { \
|
|
- public: \
|
|
- static void Execute() { statement; } \
|
|
- }; \
|
|
- ::testing::TestPartResultArray gtest_failures; \
|
|
- ::testing::internal::SingleFailureChecker gtest_checker( \
|
|
- >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
|
|
- { \
|
|
- ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
|
- ::testing::ScopedFakeTestPartResultReporter:: \
|
|
- INTERCEPT_ONLY_CURRENT_THREAD, \
|
|
- >est_failures); \
|
|
- GTestExpectFatalFailureHelper::Execute(); \
|
|
- } \
|
|
- } while (::testing::internal::AlwaysFalse())
|
|
-
|
|
-#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
|
- do { \
|
|
- class GTestExpectFatalFailureHelper { \
|
|
- public: \
|
|
- static void Execute() { statement; } \
|
|
- }; \
|
|
- ::testing::TestPartResultArray gtest_failures; \
|
|
- ::testing::internal::SingleFailureChecker gtest_checker( \
|
|
- >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
|
|
- { \
|
|
- ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
|
- ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
|
- >est_failures); \
|
|
- GTestExpectFatalFailureHelper::Execute(); \
|
|
- } \
|
|
- } while (::testing::internal::AlwaysFalse())
|
|
-
|
|
-// A macro for testing Google Test assertions or code that's expected to
|
|
-// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,
|
|
-// but not from an ASSERT_EQ). It asserts that the given statement will cause
|
|
-// exactly one non-fatal Google Test failure with 'substr' being part of the
|
|
-// failure message.
|
|
-//
|
|
-// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
|
-// affects and considers failures generated in the current thread and
|
|
-// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
|
-//
|
|
-// 'statement' is allowed to reference local variables and members of
|
|
-// the current object.
|
|
-//
|
|
-// The verification of the assertion is done correctly even when the statement
|
|
-// throws an exception or aborts the current function.
|
|
-//
|
|
-// Known restrictions:
|
|
-// - You cannot stream a failure message to this macro.
|
|
-//
|
|
-// Note that even though the implementations of the following two
|
|
-// macros are much alike, we cannot refactor them to use a common
|
|
-// helper macro, due to some peculiarity in how the preprocessor
|
|
-// works. If we do that, the code won't compile when the user gives
|
|
-// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
|
-// expands to code containing an unprotected comma. The
|
|
-// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
|
-// catches that.
|
|
-//
|
|
-// For the same reason, we have to write
|
|
-// if (::testing::internal::AlwaysTrue()) { statement; }
|
|
-// instead of
|
|
-// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
|
-// to avoid an MSVC warning on unreachable code.
|
|
-#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
|
- do { \
|
|
- ::testing::TestPartResultArray gtest_failures; \
|
|
- ::testing::internal::SingleFailureChecker gtest_checker( \
|
|
- >est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
|
- (substr)); \
|
|
- { \
|
|
- ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
|
- ::testing::ScopedFakeTestPartResultReporter:: \
|
|
- INTERCEPT_ONLY_CURRENT_THREAD, \
|
|
- >est_failures); \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- statement; \
|
|
- } \
|
|
- } \
|
|
- } while (::testing::internal::AlwaysFalse())
|
|
-
|
|
-#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
|
- do { \
|
|
- ::testing::TestPartResultArray gtest_failures; \
|
|
- ::testing::internal::SingleFailureChecker gtest_checker( \
|
|
- >est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
|
- (substr)); \
|
|
- { \
|
|
- ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
|
- ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
|
- >est_failures); \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- statement; \
|
|
- } \
|
|
- } \
|
|
- } while (::testing::internal::AlwaysFalse())
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-test-part.h b/vendor/gtest/include/gtest/gtest-test-part.h
|
|
deleted file mode 100644
|
|
index 09cc8c34f..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-test-part.h
|
|
+++ /dev/null
|
|
@@ -1,190 +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.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
|
-
|
|
-#include <iosfwd>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// A copyable object representing the result of a test part (i.e. an
|
|
-// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
|
-//
|
|
-// Don't inherit from TestPartResult as its destructor is not virtual.
|
|
-class GTEST_API_ TestPartResult {
|
|
- public:
|
|
- // The possible outcomes of a test part (i.e. an assertion or an
|
|
- // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
|
- enum Type {
|
|
- kSuccess, // Succeeded.
|
|
- kNonFatalFailure, // Failed but the test can continue.
|
|
- kFatalFailure, // Failed and the test should be terminated.
|
|
- kSkip // Skipped.
|
|
- };
|
|
-
|
|
- // C'tor. TestPartResult does NOT have a default constructor.
|
|
- // Always use this constructor (with parameters) to create a
|
|
- // TestPartResult object.
|
|
- TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
|
|
- const char* a_message)
|
|
- : type_(a_type),
|
|
- file_name_(a_file_name == nullptr ? "" : a_file_name),
|
|
- line_number_(a_line_number),
|
|
- summary_(ExtractSummary(a_message)),
|
|
- message_(a_message) {}
|
|
-
|
|
- // Gets the outcome of the test part.
|
|
- Type type() const { return type_; }
|
|
-
|
|
- // Gets the name of the source file where the test part took place, or
|
|
- // NULL if it's unknown.
|
|
- const char* file_name() const {
|
|
- return file_name_.empty() ? nullptr : file_name_.c_str();
|
|
- }
|
|
-
|
|
- // Gets the line in the source file where the test part took place,
|
|
- // or -1 if it's unknown.
|
|
- int line_number() const { return line_number_; }
|
|
-
|
|
- // Gets the summary of the failure message.
|
|
- const char* summary() const { return summary_.c_str(); }
|
|
-
|
|
- // Gets the message associated with the test part.
|
|
- const char* message() const { return message_.c_str(); }
|
|
-
|
|
- // Returns true if and only if the test part was skipped.
|
|
- bool skipped() const { return type_ == kSkip; }
|
|
-
|
|
- // Returns true if and only if the test part passed.
|
|
- bool passed() const { return type_ == kSuccess; }
|
|
-
|
|
- // Returns true if and only if the test part non-fatally failed.
|
|
- bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
|
-
|
|
- // Returns true if and only if the test part fatally failed.
|
|
- bool fatally_failed() const { return type_ == kFatalFailure; }
|
|
-
|
|
- // Returns true if and only if the test part failed.
|
|
- bool failed() const { return fatally_failed() || nonfatally_failed(); }
|
|
-
|
|
- private:
|
|
- Type type_;
|
|
-
|
|
- // Gets the summary of the failure message by omitting the stack
|
|
- // trace in it.
|
|
- static std::string ExtractSummary(const char* message);
|
|
-
|
|
- // The name of the source file where the test part took place, or
|
|
- // "" if the source file is unknown.
|
|
- std::string file_name_;
|
|
- // The line in the source file where the test part took place, or -1
|
|
- // if the line number is unknown.
|
|
- int line_number_;
|
|
- std::string summary_; // The test failure summary.
|
|
- std::string message_; // The test failure message.
|
|
-};
|
|
-
|
|
-// Prints a TestPartResult object.
|
|
-std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
|
-
|
|
-// An array of TestPartResult objects.
|
|
-//
|
|
-// Don't inherit from TestPartResultArray as its destructor is not
|
|
-// virtual.
|
|
-class GTEST_API_ TestPartResultArray {
|
|
- public:
|
|
- TestPartResultArray() {}
|
|
-
|
|
- // Appends the given TestPartResult to the array.
|
|
- void Append(const TestPartResult& result);
|
|
-
|
|
- // Returns the TestPartResult at the given index (0-based).
|
|
- const TestPartResult& GetTestPartResult(int index) const;
|
|
-
|
|
- // Returns the number of TestPartResult objects in the array.
|
|
- int size() const;
|
|
-
|
|
- private:
|
|
- std::vector<TestPartResult> array_;
|
|
-
|
|
- TestPartResultArray(const TestPartResultArray&) = delete;
|
|
- TestPartResultArray& operator=(const TestPartResultArray&) = delete;
|
|
-};
|
|
-
|
|
-// This interface knows how to report a test part result.
|
|
-class GTEST_API_ TestPartResultReporterInterface {
|
|
- public:
|
|
- virtual ~TestPartResultReporterInterface() {}
|
|
-
|
|
- virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
|
-};
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
|
-// statement generates new fatal failures. To do so it registers itself as the
|
|
-// current test part result reporter. Besides checking if fatal failures were
|
|
-// reported, it only delegates the reporting to the former result reporter.
|
|
-// The original result reporter is restored in the destructor.
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-class GTEST_API_ HasNewFatalFailureHelper
|
|
- : public TestPartResultReporterInterface {
|
|
- public:
|
|
- HasNewFatalFailureHelper();
|
|
- ~HasNewFatalFailureHelper() override;
|
|
- void ReportTestPartResult(const TestPartResult& result) override;
|
|
- bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
|
-
|
|
- private:
|
|
- bool has_new_fatal_failure_;
|
|
- TestPartResultReporterInterface* original_reporter_;
|
|
-
|
|
- HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete;
|
|
- HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest-typed-test.h b/vendor/gtest/include/gtest/gtest-typed-test.h
|
|
deleted file mode 100644
|
|
index bd35a3266..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest-typed-test.h
|
|
+++ /dev/null
|
|
@@ -1,331 +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.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#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.
|
|
-
|
|
-// Typed (aka type-driven) tests repeat the same test for types in a
|
|
-// list. You must know which types you want to test with when writing
|
|
-// typed tests. Here's how you do it:
|
|
-
|
|
-#if 0
|
|
-
|
|
-// First, define a fixture class template. It should be parameterized
|
|
-// by a type. Remember to derive it from testing::Test.
|
|
-template <typename T>
|
|
-class FooTest : public testing::Test {
|
|
- public:
|
|
- ...
|
|
- typedef std::list<T> List;
|
|
- static T shared_;
|
|
- T value_;
|
|
-};
|
|
-
|
|
-// Next, associate a list of types with the test suite, which will be
|
|
-// repeated for each type in the list. The typedef is necessary for
|
|
-// the macro to parse correctly.
|
|
-typedef testing::Types<char, int, unsigned int> MyTypes;
|
|
-TYPED_TEST_SUITE(FooTest, MyTypes);
|
|
-
|
|
-// If the type list contains only one type, you can write that type
|
|
-// directly without Types<...>:
|
|
-// TYPED_TEST_SUITE(FooTest, int);
|
|
-
|
|
-// 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 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::
|
|
- // prefix.
|
|
- n += TestFixture::shared_;
|
|
-
|
|
- // To refer to typedefs in the fixture, add the "typename
|
|
- // TestFixture::" prefix.
|
|
- typename TestFixture::List values;
|
|
- values.push_back(n);
|
|
- ...
|
|
-}
|
|
-
|
|
-TYPED_TEST(FooTest, HasPropertyA) { ... }
|
|
-
|
|
-// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
|
|
-// class that generates custom test name suffixes based on the type. This should
|
|
-// be a class which has a static template function GetName(int index) returning
|
|
-// a string for each type. The provided integer index equals the index of the
|
|
-// type in the provided type list. In many cases the index can be ignored.
|
|
-//
|
|
-// For example:
|
|
-// class MyTypeNames {
|
|
-// public:
|
|
-// template <typename T>
|
|
-// static std::string GetName(int) {
|
|
-// if (std::is_same<T, char>()) return "char";
|
|
-// if (std::is_same<T, int>()) return "int";
|
|
-// if (std::is_same<T, unsigned int>()) return "unsignedInt";
|
|
-// }
|
|
-// };
|
|
-// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
|
|
-
|
|
-#endif // 0
|
|
-
|
|
-// Type-parameterized tests are abstract test patterns parameterized
|
|
-// by a type. Compared with typed tests, type-parameterized tests
|
|
-// allow you to define the test pattern without knowing what the type
|
|
-// parameters are. The defined pattern can be instantiated with
|
|
-// different types any number of times, in any number of translation
|
|
-// units.
|
|
-//
|
|
-// If you are designing an interface or concept, you can define a
|
|
-// suite of type-parameterized tests to verify properties that any
|
|
-// valid implementation of the interface/concept should have. Then,
|
|
-// each implementation can easily instantiate the test suite to verify
|
|
-// that it conforms to the requirements, without having to write
|
|
-// similar tests repeatedly. Here's an example:
|
|
-
|
|
-#if 0
|
|
-
|
|
-// First, define a fixture class template. It should be parameterized
|
|
-// by a type. Remember to derive it from testing::Test.
|
|
-template <typename T>
|
|
-class FooTest : public testing::Test {
|
|
- ...
|
|
-};
|
|
-
|
|
-// Next, declare that you will define a type-parameterized test suite
|
|
-// (the _P suffix is for "parameterized" or "pattern", whichever you
|
|
-// prefer):
|
|
-TYPED_TEST_SUITE_P(FooTest);
|
|
-
|
|
-// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
|
-// for this type-parameterized test suite as you want.
|
|
-TYPED_TEST_P(FooTest, DoesBlah) {
|
|
- // Inside a test, refer to TypeParam to get the type parameter.
|
|
- TypeParam n = 0;
|
|
- ...
|
|
-}
|
|
-
|
|
-TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
|
-
|
|
-// Now the tricky part: you need to register all test patterns before
|
|
-// you can instantiate them. The first argument of the macro is the
|
|
-// test suite name; the rest are the names of the tests in this test
|
|
-// case.
|
|
-REGISTER_TYPED_TEST_SUITE_P(FooTest,
|
|
- DoesBlah, HasPropertyA);
|
|
-
|
|
-// Finally, you are free to instantiate the pattern with the types you
|
|
-// want. If you put the above code in a header file, you can #include
|
|
-// it in multiple C++ source files and instantiate it multiple times.
|
|
-//
|
|
-// To distinguish different instances of the pattern, the first
|
|
-// argument to the INSTANTIATE_* macro is a prefix that will be added
|
|
-// to the actual test suite name. Remember to pick unique prefixes for
|
|
-// different instances.
|
|
-typedef testing::Types<char, int, unsigned int> MyTypes;
|
|
-INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
|
-
|
|
-// If the type list contains only one type, you can write that type
|
|
-// directly without Types<...>:
|
|
-// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
|
|
-//
|
|
-// Similar to the optional argument of TYPED_TEST_SUITE above,
|
|
-// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
|
|
-// generate custom names.
|
|
-// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
|
|
-
|
|
-#endif // 0
|
|
-
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-#include "gtest/internal/gtest-type-util.h"
|
|
-
|
|
-// Implements typed tests.
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// Expands to the name of the typedef for the type parameters of the
|
|
-// given test suite.
|
|
-#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
|
|
-
|
|
-// Expands to the name of the typedef for the NameGenerator, responsible for
|
|
-// creating the suffixes of the name.
|
|
-#define GTEST_NAME_GENERATOR_(TestSuiteName) \
|
|
- gtest_type_params_##TestSuiteName##_NameGenerator
|
|
-
|
|
-#define TYPED_TEST_SUITE(CaseName, Types, ...) \
|
|
- typedef ::testing::internal::GenerateTypeList<Types>::type \
|
|
- GTEST_TYPE_PARAMS_(CaseName); \
|
|
- typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
|
- GTEST_NAME_GENERATOR_(CaseName)
|
|
-
|
|
-#define TYPED_TEST(CaseName, TestName) \
|
|
- static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
|
- "test-name must not be empty"); \
|
|
- template <typename gtest_TypeParam_> \
|
|
- class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
|
- : public CaseName<gtest_TypeParam_> { \
|
|
- private: \
|
|
- typedef CaseName<gtest_TypeParam_> TestFixture; \
|
|
- typedef gtest_TypeParam_ TypeParam; \
|
|
- void TestBody() override; \
|
|
- }; \
|
|
- static bool gtest_##CaseName##_##TestName##_registered_ \
|
|
- GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
|
|
- CaseName, \
|
|
- ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
|
- TestName)>, \
|
|
- GTEST_TYPE_PARAMS_( \
|
|
- CaseName)>::Register("", \
|
|
- ::testing::internal::CodeLocation( \
|
|
- __FILE__, __LINE__), \
|
|
- GTEST_STRINGIFY_(CaseName), \
|
|
- GTEST_STRINGIFY_(TestName), 0, \
|
|
- ::testing::internal::GenerateNames< \
|
|
- GTEST_NAME_GENERATOR_(CaseName), \
|
|
- GTEST_TYPE_PARAMS_(CaseName)>()); \
|
|
- template <typename gtest_TypeParam_> \
|
|
- void GTEST_TEST_CLASS_NAME_(CaseName, \
|
|
- TestName)<gtest_TypeParam_>::TestBody()
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-#define TYPED_TEST_CASE \
|
|
- static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
|
|
- TYPED_TEST_SUITE
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-// Implements type-parameterized tests.
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// Expands to the namespace name that the type-parameterized tests for
|
|
-// the given type-parameterized test suite are defined in. The exact
|
|
-// name of the namespace is subject to change without notice.
|
|
-#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// Expands to the name of the variable used to remember the names of
|
|
-// the defined tests in the given test suite.
|
|
-#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
|
|
- gtest_typed_test_suite_p_state_##TestSuiteName##_
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
|
-//
|
|
-// Expands to the name of the variable used to remember the names of
|
|
-// the registered tests in the given test suite.
|
|
-#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
|
|
- gtest_registered_test_names_##TestSuiteName##_
|
|
-
|
|
-// The variables defined in the type-parameterized test macros are
|
|
-// static as typically these macros are used in a .h file that can be
|
|
-// #included in multiple translation units linked together.
|
|
-#define TYPED_TEST_SUITE_P(SuiteName) \
|
|
- static ::testing::internal::TypedTestSuitePState \
|
|
- GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-#define TYPED_TEST_CASE_P \
|
|
- static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
|
|
- TYPED_TEST_SUITE_P
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-#define TYPED_TEST_P(SuiteName, TestName) \
|
|
- namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
|
- template <typename gtest_TypeParam_> \
|
|
- class TestName : public SuiteName<gtest_TypeParam_> { \
|
|
- private: \
|
|
- typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
|
- typedef gtest_TypeParam_ TypeParam; \
|
|
- void TestBody() override; \
|
|
- }; \
|
|
- static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
|
- GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
|
- __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
|
- GTEST_STRINGIFY_(TestName)); \
|
|
- } \
|
|
- template <typename gtest_TypeParam_> \
|
|
- void GTEST_SUITE_NAMESPACE_( \
|
|
- SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
|
-
|
|
-// 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_
|
|
-#define REGISTER_TYPED_TEST_CASE_P \
|
|
- static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
|
|
- ""); \
|
|
- REGISTER_TYPED_TEST_SUITE_P
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
|
- static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
|
- "test-suit-prefix must not be empty"); \
|
|
- static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
|
|
- ::testing::internal::TypeParameterizedTestSuite< \
|
|
- SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
|
- ::testing::internal::GenerateTypeList<Types>::type>:: \
|
|
- Register(GTEST_STRINGIFY_(Prefix), \
|
|
- ::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
|
- >EST_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::GenerateTypeList<Types>::type>())
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-#define INSTANTIATE_TYPED_TEST_CASE_P \
|
|
- static_assert( \
|
|
- ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
|
|
- INSTANTIATE_TYPED_TEST_SUITE_P
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest.h b/vendor/gtest/include/gtest/gtest.h
|
|
deleted file mode 100644
|
|
index d19a587a1..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest.h
|
|
+++ /dev/null
|
|
@@ -1,2297 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file defines the public API for Google Test. It should be
|
|
-// included by any test program that uses Google Test.
|
|
-//
|
|
-// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
|
-// leave some internal implementation details in this header file.
|
|
-// They are clearly marked by comments like this:
|
|
-//
|
|
-// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-//
|
|
-// Such code is NOT meant to be used by a user directly, and is subject
|
|
-// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
|
-// program!
|
|
-//
|
|
-// Acknowledgment: Google Test borrowed the idea of automatic test
|
|
-// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
|
|
-// easyUnit framework.
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
|
-
|
|
-#include <cstddef>
|
|
-#include <limits>
|
|
-#include <memory>
|
|
-#include <ostream>
|
|
-#include <type_traits>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/gtest-assertion-result.h"
|
|
-#include "gtest/gtest-death-test.h"
|
|
-#include "gtest/gtest-matchers.h"
|
|
-#include "gtest/gtest-message.h"
|
|
-#include "gtest/gtest-param-test.h"
|
|
-#include "gtest/gtest-printers.h"
|
|
-#include "gtest/gtest-test-part.h"
|
|
-#include "gtest/gtest-typed-test.h"
|
|
-#include "gtest/gtest_pred_impl.h"
|
|
-#include "gtest/gtest_prod.h"
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-// Declares the flags.
|
|
-
|
|
-// This flag temporary enables the disabled tests.
|
|
-GTEST_DECLARE_bool_(also_run_disabled_tests);
|
|
-
|
|
-// This flag brings the debugger on an assertion failure.
|
|
-GTEST_DECLARE_bool_(break_on_failure);
|
|
-
|
|
-// This flag controls whether Google Test catches all test-thrown exceptions
|
|
-// and logs them as failures.
|
|
-GTEST_DECLARE_bool_(catch_exceptions);
|
|
-
|
|
-// This flag enables using colors in terminal output. Available values are
|
|
-// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
|
|
-// 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);
|
|
-
|
|
-// This flag controls whether Google Test installs a signal handler that dumps
|
|
-// debugging information when fatal signals are raised.
|
|
-GTEST_DECLARE_bool_(install_failure_signal_handler);
|
|
-
|
|
-// This flag causes the Google Test to list tests. None of the tests listed
|
|
-// are actually run if the flag is provided.
|
|
-GTEST_DECLARE_bool_(list_tests);
|
|
-
|
|
-// This flag controls whether Google Test emits a detailed XML report to a file
|
|
-// 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);
|
|
-
|
|
-// This flags control whether Google Test prints UTF8 characters as text.
|
|
-GTEST_DECLARE_bool_(print_utf8);
|
|
-
|
|
-// This flag specifies the random number seed.
|
|
-GTEST_DECLARE_int32_(random_seed);
|
|
-
|
|
-// This flag sets how many times the tests are repeated. The default value
|
|
-// is 1. If the value is -1 the tests are repeating forever.
|
|
-GTEST_DECLARE_int32_(repeat);
|
|
-
|
|
-// This flag controls whether Google Test Environments are recreated for each
|
|
-// repeat of the tests. The default value is true. If set to false the global
|
|
-// test Environment objects are only set up once, for the first iteration, and
|
|
-// only torn down once, for the last.
|
|
-GTEST_DECLARE_bool_(recreate_environments_when_repeating);
|
|
-
|
|
-// This flag controls whether Google Test includes Google Test internal
|
|
-// stack frames in failure stack traces.
|
|
-GTEST_DECLARE_bool_(show_internal_stack_frames);
|
|
-
|
|
-// When this flag is specified, tests' order is randomized on every iteration.
|
|
-GTEST_DECLARE_bool_(shuffle);
|
|
-
|
|
-// This flag specifies the maximum number of stack frames to be
|
|
-// printed in a failure message.
|
|
-GTEST_DECLARE_int32_(stack_trace_depth);
|
|
-
|
|
-// When this flag is specified, a failed assertion will throw an
|
|
-// exception if exceptions are enabled, or exit the program with a
|
|
-// non-zero code otherwise. For use with an external test framework.
|
|
-GTEST_DECLARE_bool_(throw_on_failure);
|
|
-
|
|
-// When this flag is set with a "host:port" string, on supported
|
|
-// platforms test results are streamed to the specified port on
|
|
-// the specified host machine.
|
|
-GTEST_DECLARE_string_(stream_result_to);
|
|
-
|
|
-#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
-GTEST_DECLARE_string_(flagfile);
|
|
-#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// Silence C4100 (unreferenced formal parameter) and 4805
|
|
-// unsafe mix of type 'const int' and type 'const bool'
|
|
-#ifdef _MSC_VER
|
|
-#pragma warning(push)
|
|
-#pragma warning(disable : 4805)
|
|
-#pragma warning(disable : 4100)
|
|
-#endif
|
|
-
|
|
-// The upper limit for valid stack trace depths.
|
|
-const int kMaxStackTraceDepth = 100;
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-class AssertHelper;
|
|
-class DefaultGlobalTestPartResultReporter;
|
|
-class ExecDeathTest;
|
|
-class NoExecDeathTest;
|
|
-class FinalSuccessChecker;
|
|
-class GTestFlagSaver;
|
|
-class StreamingListenerTest;
|
|
-class TestResultAccessor;
|
|
-class TestEventListenersAccessor;
|
|
-class TestEventRepeater;
|
|
-class UnitTestRecordPropertyTestHelper;
|
|
-class WindowsDeathTest;
|
|
-class FuchsiaDeathTest;
|
|
-class UnitTestImpl* GetUnitTestImpl();
|
|
-void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
|
|
- const std::string& message);
|
|
-std::set<std::string>* GetIgnoredParameterizedTestSuites();
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// The friend relationship of some of these classes is cyclic.
|
|
-// If we don't forward declare them the compiler might confuse the classes
|
|
-// in friendship clauses with same named classes on the scope.
|
|
-class Test;
|
|
-class TestSuite;
|
|
-
|
|
-// Old API is still available but deprecated
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-using TestCase = TestSuite;
|
|
-#endif
|
|
-class TestInfo;
|
|
-class UnitTest;
|
|
-
|
|
-// The abstract class that all tests inherit from.
|
|
-//
|
|
-// In Google Test, a unit test program contains one or many TestSuites, and
|
|
-// each TestSuite contains one or many Tests.
|
|
-//
|
|
-// When you define a test using the TEST macro, you don't need to
|
|
-// explicitly derive from Test - the TEST macro automatically does
|
|
-// this for you.
|
|
-//
|
|
-// The only time you derive from Test is when defining a test fixture
|
|
-// to be used in a TEST_F. For example:
|
|
-//
|
|
-// class FooTest : public testing::Test {
|
|
-// protected:
|
|
-// void SetUp() override { ... }
|
|
-// void TearDown() override { ... }
|
|
-// ...
|
|
-// };
|
|
-//
|
|
-// TEST_F(FooTest, Bar) { ... }
|
|
-// TEST_F(FooTest, Baz) { ... }
|
|
-//
|
|
-// Test is not copyable.
|
|
-class GTEST_API_ Test {
|
|
- public:
|
|
- friend class TestInfo;
|
|
-
|
|
- // 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 suite.
|
|
- //
|
|
- // Google Test will call Foo::SetUpTestSuite() before running the first
|
|
- // 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() {}
|
|
-
|
|
- // 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 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. 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 if and only if the current test has a fatal failure.
|
|
- static bool HasFatalFailure();
|
|
-
|
|
- // Returns true if and only if the current test has a non-fatal failure.
|
|
- static bool HasNonfatalFailure();
|
|
-
|
|
- // Returns true if and only if the current test was skipped.
|
|
- static bool IsSkipped();
|
|
-
|
|
- // Returns true if and only if the current test has a (either fatal or
|
|
- // non-fatal) failure.
|
|
- static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
|
|
-
|
|
- // Logs a property for the current test, test suite, or for the entire
|
|
- // invocation of the test program when used outside of the context of a
|
|
- // test suite. Only the last value for a given key is remembered. These
|
|
- // are public static so they can be called from utility functions that are
|
|
- // not members of the test fixture. Calls to RecordProperty made during
|
|
- // lifespan of the test (from the moment its constructor starts to the
|
|
- // moment its destructor finishes) will be output in XML as attributes of
|
|
- // the <testcase> element. Properties recorded from fixture's
|
|
- // SetUpTestSuite or TearDownTestSuite are logged as attributes of the
|
|
- // corresponding <testsuite> element. Calls to RecordProperty made in the
|
|
- // global context (before or after invocation of RUN_ALL_TESTS and from
|
|
- // SetUp/TearDown method of Environment objects registered with Google
|
|
- // Test) will be output as attributes of the <testsuites> element.
|
|
- static void RecordProperty(const std::string& key, const std::string& value);
|
|
- static void RecordProperty(const std::string& key, int value);
|
|
-
|
|
- protected:
|
|
- // Creates a Test object.
|
|
- Test();
|
|
-
|
|
- // Sets up the test fixture.
|
|
- virtual void SetUp();
|
|
-
|
|
- // Tears down the test fixture.
|
|
- virtual void TearDown();
|
|
-
|
|
- private:
|
|
- // 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.
|
|
- //
|
|
- // A sub-class must implement this to define the test logic.
|
|
- //
|
|
- // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.
|
|
- // Instead, use the TEST or TEST_F macro.
|
|
- virtual void TestBody() = 0;
|
|
-
|
|
- // Sets up, executes, and tears down the test.
|
|
- void Run();
|
|
-
|
|
- // Deletes self. We deliberately pick an unusual name for this
|
|
- // internal method to avoid clashing with names used in user TESTs.
|
|
- void DeleteSelf_() { delete this; }
|
|
-
|
|
- const std::unique_ptr<GTEST_FLAG_SAVER_> gtest_flag_saver_;
|
|
-
|
|
- // Often a user misspells SetUp() as Setup() and spends a long time
|
|
- // wondering why it is never called by Google Test. The declaration of
|
|
- // the following method is solely for catching such an error at
|
|
- // compile time:
|
|
- //
|
|
- // - The return type is deliberately chosen to be not void, so it
|
|
- // will be a conflict if void Setup() is declared in the user's
|
|
- // test fixture.
|
|
- //
|
|
- // - This method is private, so it will be another compiler error
|
|
- // if the method is called from the user's test fixture.
|
|
- //
|
|
- // DO NOT OVERRIDE THIS FUNCTION.
|
|
- //
|
|
- // If you see an error about overriding the following function or
|
|
- // about it being private, you have mis-spelled SetUp() as Setup().
|
|
- struct Setup_should_be_spelled_SetUp {};
|
|
- virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
|
|
-
|
|
- // We disallow copying Tests.
|
|
- Test(const Test&) = delete;
|
|
- Test& operator=(const Test&) = delete;
|
|
-};
|
|
-
|
|
-typedef internal::TimeInMillis TimeInMillis;
|
|
-
|
|
-// A copyable object representing a user specified test property which can be
|
|
-// output as a key/value string pair.
|
|
-//
|
|
-// Don't inherit from TestProperty as its destructor is not virtual.
|
|
-class TestProperty {
|
|
- public:
|
|
- // C'tor. TestProperty does NOT have a default constructor.
|
|
- // Always use this constructor (with parameters) to create a
|
|
- // TestProperty object.
|
|
- TestProperty(const std::string& a_key, const std::string& a_value)
|
|
- : key_(a_key), value_(a_value) {}
|
|
-
|
|
- // Gets the user supplied key.
|
|
- const char* key() const { return key_.c_str(); }
|
|
-
|
|
- // Gets the user supplied value.
|
|
- const char* value() const { return value_.c_str(); }
|
|
-
|
|
- // Sets a new value, overriding the one supplied in the constructor.
|
|
- void SetValue(const std::string& new_value) { value_ = new_value; }
|
|
-
|
|
- private:
|
|
- // The key supplied by the user.
|
|
- std::string key_;
|
|
- // The value supplied by the user.
|
|
- std::string value_;
|
|
-};
|
|
-
|
|
-// The result of a single Test. This includes a list of
|
|
-// TestPartResults, a list of TestProperties, a count of how many
|
|
-// death tests there are in the Test, and how much time it took to run
|
|
-// the Test.
|
|
-//
|
|
-// TestResult is not copyable.
|
|
-class GTEST_API_ TestResult {
|
|
- public:
|
|
- // Creates an empty TestResult.
|
|
- TestResult();
|
|
-
|
|
- // D'tor. Do not inherit from TestResult.
|
|
- ~TestResult();
|
|
-
|
|
- // Gets the number of all test parts. This is the sum of the number
|
|
- // of successful test parts and the number of failed test parts.
|
|
- int total_part_count() const;
|
|
-
|
|
- // Returns the number of the test properties.
|
|
- int test_property_count() const;
|
|
-
|
|
- // Returns true if and only if the test passed (i.e. no test part failed).
|
|
- bool Passed() const { return !Skipped() && !Failed(); }
|
|
-
|
|
- // Returns true if and only if the test was skipped.
|
|
- bool Skipped() const;
|
|
-
|
|
- // Returns true if and only if the test failed.
|
|
- bool Failed() const;
|
|
-
|
|
- // Returns true if and only if the test fatally failed.
|
|
- bool HasFatalFailure() const;
|
|
-
|
|
- // 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;
|
|
-
|
|
- // Returns the i-th test property. i can range from 0 to
|
|
- // test_property_count() - 1. If i is not in that range, aborts the
|
|
- // program.
|
|
- const TestProperty& GetTestProperty(int i) const;
|
|
-
|
|
- private:
|
|
- friend class TestInfo;
|
|
- friend class TestSuite;
|
|
- friend class UnitTest;
|
|
- friend class internal::DefaultGlobalTestPartResultReporter;
|
|
- friend class internal::ExecDeathTest;
|
|
- friend class internal::TestResultAccessor;
|
|
- friend class internal::UnitTestImpl;
|
|
- friend class internal::WindowsDeathTest;
|
|
- friend class internal::FuchsiaDeathTest;
|
|
-
|
|
- // Gets the vector of TestPartResults.
|
|
- const std::vector<TestPartResult>& test_part_results() const {
|
|
- return test_part_results_;
|
|
- }
|
|
-
|
|
- // Gets the vector of TestProperties.
|
|
- const std::vector<TestProperty>& test_properties() const {
|
|
- 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; }
|
|
-
|
|
- // Adds a test property to the list. The property is validated and may add
|
|
- // a non-fatal failure if invalid (e.g., if it conflicts with reserved
|
|
- // key names). If a property is already recorded for the same key, the
|
|
- // value will be updated, rather than storing multiple values for the same
|
|
- // key. xml_element specifies the element for which the property is being
|
|
- // recorded and is used for validation.
|
|
- void RecordProperty(const std::string& xml_element,
|
|
- const TestProperty& test_property);
|
|
-
|
|
- // Adds a failure if the key is a reserved attribute of Google Test
|
|
- // testsuite tags. Returns true if the property is valid.
|
|
- // FIXME: Validate attribute names are legal and human readable.
|
|
- static bool ValidateTestProperty(const std::string& xml_element,
|
|
- const TestProperty& test_property);
|
|
-
|
|
- // Adds a test part result to the list.
|
|
- void AddTestPartResult(const TestPartResult& test_part_result);
|
|
-
|
|
- // Returns the death test count.
|
|
- int death_test_count() const { return death_test_count_; }
|
|
-
|
|
- // Increments the death test count, returning the new count.
|
|
- int increment_death_test_count() { return ++death_test_count_; }
|
|
-
|
|
- // Clears the test part results.
|
|
- void ClearTestPartResults();
|
|
-
|
|
- // Clears the object.
|
|
- void Clear();
|
|
-
|
|
- // Protects mutable state of the property vector and of owned
|
|
- // properties, whose values may be updated.
|
|
- internal::Mutex test_properties_mutex_;
|
|
-
|
|
- // The vector of TestPartResults
|
|
- std::vector<TestPartResult> test_part_results_;
|
|
- // The vector of TestProperties
|
|
- 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_;
|
|
-
|
|
- // We disallow copying TestResult.
|
|
- TestResult(const TestResult&) = delete;
|
|
- TestResult& operator=(const TestResult&) = delete;
|
|
-}; // class TestResult
|
|
-
|
|
-// A TestInfo object stores the following information about a test:
|
|
-//
|
|
-// Test suite name
|
|
-// Test name
|
|
-// Whether the test should be run
|
|
-// A function pointer that creates the test object when invoked
|
|
-// Test result
|
|
-//
|
|
-// The constructor of TestInfo registers itself with the UnitTest
|
|
-// singleton such that the RUN_ALL_TESTS() macro knows which tests to
|
|
-// run.
|
|
-class GTEST_API_ TestInfo {
|
|
- public:
|
|
- // Destructs a TestInfo object. This function is not virtual, so
|
|
- // don't inherit from TestInfo.
|
|
- ~TestInfo();
|
|
-
|
|
- // Returns the test suite name.
|
|
- const char* test_suite_name() const { return test_suite_name_.c_str(); }
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- const char* test_case_name() const { return test_suite_name(); }
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Returns the test name.
|
|
- const char* name() const { return name_.c_str(); }
|
|
-
|
|
- // Returns the name of the parameter type, or NULL if this is not a typed
|
|
- // or a type-parameterized test.
|
|
- const char* type_param() const {
|
|
- if (type_param_.get() != nullptr) return type_param_->c_str();
|
|
- return nullptr;
|
|
- }
|
|
-
|
|
- // Returns the text representation of the value parameter, or NULL if this
|
|
- // is not a value-parameterized test.
|
|
- const char* value_param() const {
|
|
- if (value_param_.get() != nullptr) return value_param_->c_str();
|
|
- return nullptr;
|
|
- }
|
|
-
|
|
- // Returns the file name where this test is defined.
|
|
- const char* file() const { return location_.file.c_str(); }
|
|
-
|
|
- // Returns the line where this test is defined.
|
|
- int line() const { return location_.line; }
|
|
-
|
|
- // Return true if this test should not be run because it's in another shard.
|
|
- bool is_in_another_shard() const { return is_in_another_shard_; }
|
|
-
|
|
- // Returns true if this test should run, that is if the test is not
|
|
- // disabled (or it is disabled but the also_run_disabled_tests flag has
|
|
- // been specified) and its full name matches the user-specified filter.
|
|
- //
|
|
- // Google Test allows the user to filter the tests by their full names.
|
|
- // The full name of a test Bar in test suite Foo is defined as
|
|
- // "Foo.Bar". Only the tests that match the filter will run.
|
|
- //
|
|
- // A filter is a colon-separated list of glob (not regex) patterns,
|
|
- // optionally followed by a '-' and a colon-separated list of
|
|
- // negative patterns (tests to exclude). A test is run if it
|
|
- // matches one of the positive patterns and does not match any of
|
|
- // the negative patterns.
|
|
- //
|
|
- // For example, *A*:Foo.* is a filter that matches any string that
|
|
- // contains the character 'A' or starts with "Foo.".
|
|
- bool should_run() const { return should_run_; }
|
|
-
|
|
- // 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.
|
|
- return matches_filter_ && !is_in_another_shard_;
|
|
- }
|
|
-
|
|
- // Returns the result of the test.
|
|
- const TestResult* result() const { return &result_; }
|
|
-
|
|
- private:
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
- friend class internal::DefaultDeathTestFactory;
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
- friend class Test;
|
|
- friend class TestSuite;
|
|
- friend class internal::UnitTestImpl;
|
|
- friend class internal::StreamingListenerTest;
|
|
- friend TestInfo* internal::MakeAndRegisterTestInfo(
|
|
- const char* test_suite_name, const char* name, const char* type_param,
|
|
- const char* value_param, internal::CodeLocation code_location,
|
|
- internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
|
- internal::TearDownTestSuiteFunc tear_down_tc,
|
|
- internal::TestFactoryBase* factory);
|
|
-
|
|
- // Constructs a TestInfo object. The newly constructed instance assumes
|
|
- // ownership of the factory object.
|
|
- TestInfo(const std::string& test_suite_name, const std::string& name,
|
|
- const char* a_type_param, // NULL if not a type-parameterized test
|
|
- const char* a_value_param, // NULL if not a value-parameterized test
|
|
- internal::CodeLocation a_code_location,
|
|
- internal::TypeId fixture_class_id,
|
|
- internal::TestFactoryBase* factory);
|
|
-
|
|
- // Increments the number of death tests encountered in this test so
|
|
- // far.
|
|
- int increment_death_test_count() {
|
|
- return result_.increment_death_test_count();
|
|
- }
|
|
-
|
|
- // Creates the test object, runs it, records its result, and then
|
|
- // 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();
|
|
- }
|
|
-
|
|
- // These fields are immutable properties of the test.
|
|
- const std::string test_suite_name_; // test suite name
|
|
- const std::string name_; // Test name
|
|
- // Name of the parameter type, or NULL if this is not a typed or a
|
|
- // type-parameterized test.
|
|
- const std::unique_ptr<const ::std::string> type_param_;
|
|
- // Text representation of the value parameter, or NULL if this is not a
|
|
- // 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 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
|
|
-
|
|
- // This field is mutable and needs to be reset before running the
|
|
- // test for the second time.
|
|
- TestResult result_;
|
|
-
|
|
- TestInfo(const TestInfo&) = delete;
|
|
- TestInfo& operator=(const TestInfo&) = delete;
|
|
-};
|
|
-
|
|
-// A test suite, which consists of a vector of TestInfos.
|
|
-//
|
|
-// TestSuite is not copyable.
|
|
-class GTEST_API_ TestSuite {
|
|
- public:
|
|
- // Creates a TestSuite with the given name.
|
|
- //
|
|
- // TestSuite does NOT have a default constructor. Always use this
|
|
- // constructor to create a TestSuite object.
|
|
- //
|
|
- // Arguments:
|
|
- //
|
|
- // name: name of the test suite
|
|
- // a_type_param: the name of the test's type parameter, or NULL if
|
|
- // this is not 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(const char* name, const char* a_type_param,
|
|
- internal::SetUpTestSuiteFunc set_up_tc,
|
|
- internal::TearDownTestSuiteFunc tear_down_tc);
|
|
-
|
|
- // Destructor of TestSuite.
|
|
- virtual ~TestSuite();
|
|
-
|
|
- // Gets the name of the TestSuite.
|
|
- const char* name() const { return name_.c_str(); }
|
|
-
|
|
- // Returns the name of the parameter type, or NULL if this is not a
|
|
- // type-parameterized test suite.
|
|
- const char* type_param() const {
|
|
- if (type_param_.get() != nullptr) return type_param_->c_str();
|
|
- return nullptr;
|
|
- }
|
|
-
|
|
- // Returns true if any test in this test suite should run.
|
|
- bool should_run() const { return should_run_; }
|
|
-
|
|
- // Gets the number of successful tests in this test suite.
|
|
- int successful_test_count() const;
|
|
-
|
|
- // Gets the number of skipped tests in this test suite.
|
|
- int skipped_test_count() const;
|
|
-
|
|
- // Gets the number of failed tests in this test suite.
|
|
- int failed_test_count() const;
|
|
-
|
|
- // Gets the number of disabled tests that will be reported in the XML report.
|
|
- int reportable_disabled_test_count() const;
|
|
-
|
|
- // Gets the number of disabled tests in this test suite.
|
|
- int disabled_test_count() const;
|
|
-
|
|
- // Gets the number of tests to be printed in the XML report.
|
|
- int reportable_test_count() const;
|
|
-
|
|
- // Get the number of tests in this test suite that should run.
|
|
- int test_to_run_count() const;
|
|
-
|
|
- // Gets the number of all tests in this test suite.
|
|
- int total_test_count() const;
|
|
-
|
|
- // Returns true if and only if the test suite passed.
|
|
- bool Passed() const { return !Failed(); }
|
|
-
|
|
- // 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;
|
|
-
|
|
- // Returns the TestResult that holds test properties recorded during
|
|
- // execution of SetUpTestSuite and TearDownTestSuite.
|
|
- const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; }
|
|
-
|
|
- private:
|
|
- friend class Test;
|
|
- friend class internal::UnitTestImpl;
|
|
-
|
|
- // Gets the (mutable) vector of TestInfos in this TestSuite.
|
|
- std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
|
|
-
|
|
- // Gets the (immutable) vector of TestInfos in this TestSuite.
|
|
- const std::vector<TestInfo*>& test_info_list() const {
|
|
- return test_info_list_;
|
|
- }
|
|
-
|
|
- // 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.
|
|
- TestInfo* GetMutableTestInfo(int i);
|
|
-
|
|
- // Sets the should_run member.
|
|
- void set_should_run(bool should) { should_run_ = should; }
|
|
-
|
|
- // Adds a TestInfo to this test suite. Will delete the TestInfo upon
|
|
- // destruction of the TestSuite object.
|
|
- void AddTestInfo(TestInfo* test_info);
|
|
-
|
|
- // Clears the results of all tests in this test suite.
|
|
- void ClearResult();
|
|
-
|
|
- // Clears the results of all tests in the given test suite.
|
|
- static void ClearTestSuiteResult(TestSuite* test_suite) {
|
|
- test_suite->ClearResult();
|
|
- }
|
|
-
|
|
- // 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() {
|
|
- if (set_up_tc_ != nullptr) {
|
|
- (*set_up_tc_)();
|
|
- }
|
|
- }
|
|
-
|
|
- // Runs TearDownTestSuite() for this TestSuite. This wrapper is
|
|
- // needed for catching exceptions thrown from TearDownTestSuite().
|
|
- void RunTearDownTestSuite() {
|
|
- if (tear_down_tc_ != nullptr) {
|
|
- (*tear_down_tc_)();
|
|
- }
|
|
- }
|
|
-
|
|
- // 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 if and only if test skipped.
|
|
- static bool TestSkipped(const TestInfo* test_info) {
|
|
- return test_info->should_run() && test_info->result()->Skipped();
|
|
- }
|
|
-
|
|
- // 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 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 if and only if test is disabled.
|
|
- static bool TestDisabled(const TestInfo* test_info) {
|
|
- return test_info->is_disabled_;
|
|
- }
|
|
-
|
|
- // 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();
|
|
- }
|
|
-
|
|
- // Returns true if the given test should run.
|
|
- static bool ShouldRunTest(const TestInfo* test_info) {
|
|
- return test_info->should_run();
|
|
- }
|
|
-
|
|
- // Shuffles the tests in this test suite.
|
|
- void ShuffleTests(internal::Random* random);
|
|
-
|
|
- // Restores the test order to before the first shuffle.
|
|
- void UnshuffleTests();
|
|
-
|
|
- // Name of the test suite.
|
|
- std::string name_;
|
|
- // Name of the parameter type, or NULL if this is not a typed or a
|
|
- // type-parameterized test.
|
|
- const std::unique_ptr<const ::std::string> type_param_;
|
|
- // The vector of TestInfos in their original order. It owns the
|
|
- // elements in the vector.
|
|
- std::vector<TestInfo*> test_info_list_;
|
|
- // Provides a level of indirection for the test list to allow easy
|
|
- // shuffling and restoring the test order. The i-th element in this
|
|
- // vector is the index of the i-th test in the shuffled test list.
|
|
- std::vector<int> test_indices_;
|
|
- // Pointer to the function that sets up the test suite.
|
|
- internal::SetUpTestSuiteFunc set_up_tc_;
|
|
- // Pointer to the function that tears down the test suite.
|
|
- internal::TearDownTestSuiteFunc tear_down_tc_;
|
|
- // 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
|
|
- // TearDownTestSuite.
|
|
- TestResult ad_hoc_test_result_;
|
|
-
|
|
- // We disallow copying TestSuites.
|
|
- TestSuite(const TestSuite&) = delete;
|
|
- TestSuite& operator=(const TestSuite&) = delete;
|
|
-};
|
|
-
|
|
-// An Environment object is capable of setting up and tearing down an
|
|
-// environment. You should subclass this to define your own
|
|
-// environment(s).
|
|
-//
|
|
-// An Environment object does the set-up and tear-down in virtual
|
|
-// methods SetUp() and TearDown() instead of the constructor and the
|
|
-// destructor, as:
|
|
-//
|
|
-// 1. You cannot safely throw from a destructor. This is a problem
|
|
-// as in some cases Google Test is used where exceptions are enabled, and
|
|
-// we may want to implement ASSERT_* using exceptions where they are
|
|
-// available.
|
|
-// 2. You cannot use ASSERT_* directly in a constructor or
|
|
-// destructor.
|
|
-class Environment {
|
|
- public:
|
|
- // The d'tor is virtual as we need to subclass Environment.
|
|
- virtual ~Environment() {}
|
|
-
|
|
- // Override this to define how to set up the environment.
|
|
- virtual void SetUp() {}
|
|
-
|
|
- // Override this to define how to tear down the environment.
|
|
- virtual void TearDown() {}
|
|
-
|
|
- private:
|
|
- // If you see an error about overriding the following function or
|
|
- // about it being private, you have mis-spelled SetUp() as Setup().
|
|
- struct Setup_should_be_spelled_SetUp {};
|
|
- virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
|
|
-};
|
|
-
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-// Exception which can be thrown from TestEventListener::OnTestPartResult.
|
|
-class GTEST_API_ AssertionException
|
|
- : public internal::GoogleTestFailureException {
|
|
- public:
|
|
- explicit AssertionException(const TestPartResult& result)
|
|
- : GoogleTestFailureException(result) {}
|
|
-};
|
|
-
|
|
-#endif // GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-// The interface for tracing execution of tests. The methods are organized in
|
|
-// the order the corresponding events are fired.
|
|
-class TestEventListener {
|
|
- public:
|
|
- virtual ~TestEventListener() {}
|
|
-
|
|
- // Fired before any test activity starts.
|
|
- virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
|
|
-
|
|
- // Fired before each iteration of tests starts. There may be more than
|
|
- // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
|
|
- // index, starting from 0.
|
|
- virtual void OnTestIterationStart(const UnitTest& unit_test,
|
|
- int iteration) = 0;
|
|
-
|
|
- // Fired before environment set-up for each iteration of tests starts.
|
|
- virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
|
|
-
|
|
- // Fired after environment set-up for each iteration of tests ends.
|
|
- virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
|
|
-
|
|
- // Fired before the test suite starts.
|
|
- virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {}
|
|
-
|
|
- // Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Fired before the test starts.
|
|
- virtual void OnTestStart(const TestInfo& test_info) = 0;
|
|
-
|
|
- // Fired when a test is disabled
|
|
- virtual void OnTestDisabled(const TestInfo& /*test_info*/) {}
|
|
-
|
|
- // Fired after a failed assertion or a SUCCEED() invocation.
|
|
- // If you want to throw an exception from this function to skip to the next
|
|
- // TEST, it must be AssertionException defined above, or inherited from it.
|
|
- virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
|
|
-
|
|
- // Fired after the test ends.
|
|
- virtual void OnTestEnd(const TestInfo& test_info) = 0;
|
|
-
|
|
- // Fired after the test suite ends.
|
|
- virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {}
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Fired before environment tear-down for each iteration of tests starts.
|
|
- virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
|
|
-
|
|
- // Fired after environment tear-down for each iteration of tests ends.
|
|
- virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
|
|
-
|
|
- // Fired after each iteration of tests finishes.
|
|
- virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0;
|
|
-
|
|
- // Fired after all test activities have ended.
|
|
- virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
|
|
-};
|
|
-
|
|
-// The convenience class for users who need to override just one or two
|
|
-// methods and are not concerned that a possible change to a signature of
|
|
-// the methods they override will not be caught during the build. For
|
|
-// comments about each method please see the definition of TestEventListener
|
|
-// above.
|
|
-class EmptyTestEventListener : public TestEventListener {
|
|
- public:
|
|
- void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
|
- int /*iteration*/) override {}
|
|
- void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseStart(const TestCase& /*test_case*/) override {}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- void OnTestStart(const TestInfo& /*test_info*/) override {}
|
|
- void OnTestDisabled(const TestInfo& /*test_info*/) override {}
|
|
- void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
|
|
- void OnTestEnd(const TestInfo& /*test_info*/) override {}
|
|
- void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestIterationEnd(const UnitTest& /*unit_test*/,
|
|
- int /*iteration*/) override {}
|
|
- void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
|
|
-};
|
|
-
|
|
-// TestEventListeners lets users add listeners to track events in Google Test.
|
|
-class GTEST_API_ TestEventListeners {
|
|
- public:
|
|
- TestEventListeners();
|
|
- ~TestEventListeners();
|
|
-
|
|
- // Appends an event listener to the end of the list. Google Test assumes
|
|
- // the ownership of the listener (i.e. it will delete the listener when
|
|
- // the test program finishes).
|
|
- void Append(TestEventListener* listener);
|
|
-
|
|
- // Removes the given event listener from the list and returns it. It then
|
|
- // becomes the caller's responsibility to delete the listener. Returns
|
|
- // NULL if the listener is not found in the list.
|
|
- TestEventListener* Release(TestEventListener* listener);
|
|
-
|
|
- // Returns the standard listener responsible for the default console
|
|
- // output. Can be removed from the listeners list to shut down default
|
|
- // console output. Note that removing this object from the listener list
|
|
- // with Release transfers its ownership to the caller and makes this
|
|
- // function return NULL the next time.
|
|
- TestEventListener* default_result_printer() const {
|
|
- return default_result_printer_;
|
|
- }
|
|
-
|
|
- // Returns the standard listener responsible for the default XML output
|
|
- // controlled by the --gtest_output=xml flag. Can be removed from the
|
|
- // listeners list by users who want to shut down the default XML output
|
|
- // controlled by this flag and substitute it with custom one. Note that
|
|
- // removing this object from the listener list with Release transfers its
|
|
- // ownership to the caller and makes this function return NULL the next
|
|
- // time.
|
|
- TestEventListener* default_xml_generator() const {
|
|
- return default_xml_generator_;
|
|
- }
|
|
-
|
|
- private:
|
|
- friend class TestSuite;
|
|
- friend class TestInfo;
|
|
- friend class internal::DefaultGlobalTestPartResultReporter;
|
|
- friend class internal::NoExecDeathTest;
|
|
- friend class internal::TestEventListenersAccessor;
|
|
- friend class internal::UnitTestImpl;
|
|
-
|
|
- // Returns repeater that broadcasts the TestEventListener events to all
|
|
- // subscribers.
|
|
- TestEventListener* repeater();
|
|
-
|
|
- // Sets the default_result_printer attribute to the provided listener.
|
|
- // The listener is also added to the listener list and previous
|
|
- // default_result_printer is removed from it and deleted. The listener can
|
|
- // also be NULL in which case it will not be added to the list. Does
|
|
- // nothing if the previous and the current listener objects are the same.
|
|
- void SetDefaultResultPrinter(TestEventListener* listener);
|
|
-
|
|
- // Sets the default_xml_generator attribute to the provided listener. The
|
|
- // listener is also added to the listener list and previous
|
|
- // default_xml_generator is removed from it and deleted. The listener can
|
|
- // also be NULL in which case it will not be added to the list. Does
|
|
- // nothing if the previous and the current listener objects are the same.
|
|
- void SetDefaultXmlGenerator(TestEventListener* listener);
|
|
-
|
|
- // Controls whether events will be forwarded by the repeater to the
|
|
- // listeners in the list.
|
|
- bool EventForwardingEnabled() const;
|
|
- void SuppressEventForwarding();
|
|
-
|
|
- // The actual list of listeners.
|
|
- internal::TestEventRepeater* repeater_;
|
|
- // Listener responsible for the standard result output.
|
|
- TestEventListener* default_result_printer_;
|
|
- // Listener responsible for the creation of the XML output file.
|
|
- TestEventListener* default_xml_generator_;
|
|
-
|
|
- // We disallow copying TestEventListeners.
|
|
- TestEventListeners(const TestEventListeners&) = delete;
|
|
- TestEventListeners& operator=(const TestEventListeners&) = delete;
|
|
-};
|
|
-
|
|
-// A UnitTest consists of a vector of TestSuites.
|
|
-//
|
|
-// This is a singleton class. The only instance of UnitTest is
|
|
-// created when UnitTest::GetInstance() is first called. This
|
|
-// instance is never deleted.
|
|
-//
|
|
-// UnitTest is not copyable.
|
|
-//
|
|
-// This class is thread-safe as long as the methods are called
|
|
-// according to their specification.
|
|
-class GTEST_API_ UnitTest {
|
|
- public:
|
|
- // Gets the singleton UnitTest object. The first time this method
|
|
- // is called, a UnitTest object is constructed and returned.
|
|
- // Consecutive calls will return the same object.
|
|
- static UnitTest* GetInstance();
|
|
-
|
|
- // Runs all tests in this UnitTest object and prints the result.
|
|
- // Returns 0 if successful, or 1 otherwise.
|
|
- //
|
|
- // This method can only be called from the main thread.
|
|
- //
|
|
- // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
- int Run() GTEST_MUST_USE_RESULT_;
|
|
-
|
|
- // Returns the working directory when the first TEST() or TEST_F()
|
|
- // was executed. The UnitTest object owns the string.
|
|
- const char* original_working_dir() const;
|
|
-
|
|
- // Returns the TestSuite object for the test that's currently running,
|
|
- // or NULL if no test is running.
|
|
- const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-
|
|
-// Legacy API is still available but deprecated
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-#endif
|
|
-
|
|
- // Returns the TestInfo object for the test that's currently running,
|
|
- // or NULL if no test is running.
|
|
- const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-
|
|
- // Returns the random seed used at the start of the current test run.
|
|
- int random_seed() const;
|
|
-
|
|
- // Returns the ParameterizedTestSuiteRegistry object used to keep track of
|
|
- // value-parameterized tests and instantiate and register them.
|
|
- //
|
|
- // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
- internal::ParameterizedTestSuiteRegistry& parameterized_test_registry()
|
|
- GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-
|
|
- // Gets the number of successful test suites.
|
|
- int successful_test_suite_count() const;
|
|
-
|
|
- // Gets the number of failed test suites.
|
|
- int failed_test_suite_count() const;
|
|
-
|
|
- // Gets the number of all test suites.
|
|
- int total_test_suite_count() const;
|
|
-
|
|
- // Gets the number of all test suites that contain at least one test
|
|
- // that should run.
|
|
- int test_suite_to_run_count() const;
|
|
-
|
|
- // Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- int successful_test_case_count() const;
|
|
- int failed_test_case_count() const;
|
|
- int total_test_case_count() const;
|
|
- int test_case_to_run_count() const;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Gets the number of successful tests.
|
|
- int successful_test_count() const;
|
|
-
|
|
- // Gets the number of skipped tests.
|
|
- int skipped_test_count() const;
|
|
-
|
|
- // Gets the number of failed tests.
|
|
- int failed_test_count() const;
|
|
-
|
|
- // Gets the number of disabled tests that will be reported in the XML report.
|
|
- int reportable_disabled_test_count() const;
|
|
-
|
|
- // Gets the number of disabled tests.
|
|
- int disabled_test_count() const;
|
|
-
|
|
- // Gets the number of tests to be printed in the XML report.
|
|
- int reportable_test_count() const;
|
|
-
|
|
- // Gets the number of all tests.
|
|
- int total_test_count() const;
|
|
-
|
|
- // Gets the number of tests that should run.
|
|
- int test_to_run_count() const;
|
|
-
|
|
- // Gets the time of the test program start, in ms from the start of the
|
|
- // UNIX epoch.
|
|
- TimeInMillis start_timestamp() const;
|
|
-
|
|
- // Gets the elapsed time, in milliseconds.
|
|
- TimeInMillis elapsed_time() const;
|
|
-
|
|
- // Returns true if and only if the unit test passed (i.e. all test suites
|
|
- // passed).
|
|
- bool Passed() const;
|
|
-
|
|
- // 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
|
|
- // total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
|
- const TestSuite* GetTestSuite(int i) const;
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- const TestCase* GetTestCase(int i) const;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Returns the TestResult containing information on test failures and
|
|
- // properties logged outside of individual test suites.
|
|
- const TestResult& ad_hoc_test_result() const;
|
|
-
|
|
- // Returns the list of event listeners that can be used to track events
|
|
- // inside Google Test.
|
|
- TestEventListeners& listeners();
|
|
-
|
|
- private:
|
|
- // Registers and returns a global test environment. When a test
|
|
- // program is run, all global test environments will be set-up in
|
|
- // the order they were registered. After all tests in the program
|
|
- // have finished, all global test environments will be torn-down in
|
|
- // the *reverse* order they were registered.
|
|
- //
|
|
- // The UnitTest object takes ownership of the given environment.
|
|
- //
|
|
- // This method can only be called from the main thread.
|
|
- Environment* AddEnvironment(Environment* env);
|
|
-
|
|
- // Adds a TestPartResult to the current TestResult object. All
|
|
- // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
|
|
- // eventually call this to report their results. The user code
|
|
- // should use the assertion macros instead of calling this directly.
|
|
- void AddTestPartResult(TestPartResult::Type result_type,
|
|
- const char* file_name, int line_number,
|
|
- const std::string& message,
|
|
- const std::string& os_stack_trace)
|
|
- GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-
|
|
- // Adds a TestProperty to the current TestResult object when invoked from
|
|
- // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked
|
|
- // from SetUpTestSuite or TearDownTestSuite, or to the global property set
|
|
- // when invoked elsewhere. If the result already contains a property with
|
|
- // the same key, the value will be updated.
|
|
- void RecordProperty(const std::string& key, const std::string& value);
|
|
-
|
|
- // Gets the i-th test suite among all the test suites. i can range from 0 to
|
|
- // total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
|
- TestSuite* GetMutableTestSuite(int i);
|
|
-
|
|
- // Accessors for the implementation object.
|
|
- internal::UnitTestImpl* impl() { return impl_; }
|
|
- const internal::UnitTestImpl* impl() const { return impl_; }
|
|
-
|
|
- // These classes and functions are friends as they need to access private
|
|
- // members of UnitTest.
|
|
- friend class ScopedTrace;
|
|
- friend class Test;
|
|
- friend class internal::AssertHelper;
|
|
- 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, const std::string& message);
|
|
-
|
|
- // Creates an empty UnitTest.
|
|
- UnitTest();
|
|
-
|
|
- // D'tor
|
|
- virtual ~UnitTest();
|
|
-
|
|
- // Pushes a trace defined by SCOPED_TRACE() on to the per-thread
|
|
- // Google Test trace stack.
|
|
- void PushGTestTrace(const internal::TraceInfo& trace)
|
|
- GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-
|
|
- // Pops a trace from the per-thread Google Test trace stack.
|
|
- void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_);
|
|
-
|
|
- // Protects mutable state in *impl_. This is mutable as some const
|
|
- // methods need to lock it too.
|
|
- mutable internal::Mutex mutex_;
|
|
-
|
|
- // Opaque implementation object. This field is never changed once
|
|
- // the object is constructed. We don't mark it as const here, as
|
|
- // doing so will cause a warning in the constructor of UnitTest.
|
|
- // Mutable state in *impl_ is protected by mutex_.
|
|
- internal::UnitTestImpl* impl_;
|
|
-
|
|
- // We disallow copying UnitTest.
|
|
- UnitTest(const UnitTest&) = delete;
|
|
- UnitTest& operator=(const UnitTest&) = delete;
|
|
-};
|
|
-
|
|
-// A convenient wrapper for adding an environment for the test
|
|
-// program.
|
|
-//
|
|
-// You should call this before RUN_ALL_TESTS() is called, probably in
|
|
-// main(). If you use gtest_main, you need to call this before main()
|
|
-// starts for it to take effect. For example, you can define a global
|
|
-// variable like this:
|
|
-//
|
|
-// testing::Environment* const foo_env =
|
|
-// testing::AddGlobalTestEnvironment(new FooEnvironment);
|
|
-//
|
|
-// However, we strongly recommend you to write your own main() and
|
|
-// call AddGlobalTestEnvironment() there, as relying on initialization
|
|
-// of global variables makes the code harder to read and may cause
|
|
-// problems when you register multiple environments from different
|
|
-// translation units and the environments have dependencies among them
|
|
-// (remember that the compiler doesn't guarantee the order in which
|
|
-// global variables from different translation units are initialized).
|
|
-inline Environment* AddGlobalTestEnvironment(Environment* env) {
|
|
- return UnitTest::GetInstance()->AddEnvironment(env);
|
|
-}
|
|
-
|
|
-// Initializes Google Test. This must be called before calling
|
|
-// RUN_ALL_TESTS(). In particular, it parses a command line for the
|
|
-// flags that Google Test recognizes. Whenever a Google Test flag is
|
|
-// seen, it is removed from argv, and *argc is decremented.
|
|
-//
|
|
-// No value is returned. Instead, the Google Test flag variables are
|
|
-// updated.
|
|
-//
|
|
-// Calling the function for the second time has no user-visible effect.
|
|
-GTEST_API_ void InitGoogleTest(int* argc, char** argv);
|
|
-
|
|
-// This overloaded version can be used in Windows programs compiled in
|
|
-// UNICODE mode.
|
|
-GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
|
|
-
|
|
-// This overloaded version can be used on Arduino/embedded platforms where
|
|
-// there is no argc/argv.
|
|
-GTEST_API_ void InitGoogleTest();
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Separate the error generating code from the code path to reduce the stack
|
|
-// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers
|
|
-// when calling EXPECT_* in a tight loop.
|
|
-template <typename T1, typename T2>
|
|
-AssertionResult CmpHelperEQFailure(const char* lhs_expression,
|
|
- const char* rhs_expression, const T1& lhs,
|
|
- const T2& rhs) {
|
|
- return EqFailure(lhs_expression, rhs_expression,
|
|
- FormatForComparisonFailureMessage(lhs, rhs),
|
|
- FormatForComparisonFailureMessage(rhs, lhs), false);
|
|
-}
|
|
-
|
|
-// This block of code defines operator==/!=
|
|
-// to block lexical scope lookup.
|
|
-// It prevents using invalid operator==/!= defined at namespace scope.
|
|
-struct faketype {};
|
|
-inline bool operator==(faketype, faketype) { return true; }
|
|
-inline bool operator!=(faketype, faketype) { return false; }
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_EQ.
|
|
-template <typename T1, typename T2>
|
|
-AssertionResult CmpHelperEQ(const char* lhs_expression,
|
|
- const char* rhs_expression, const T1& lhs,
|
|
- const T2& rhs) {
|
|
- if (lhs == rhs) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
|
|
-}
|
|
-
|
|
-class EqHelper {
|
|
- public:
|
|
- // This templatized version is for the general case.
|
|
- template <
|
|
- typename T1, typename T2,
|
|
- // Disable this overload for cases where one argument is a pointer
|
|
- // and the other is the null pointer constant.
|
|
- typename std::enable_if<!std::is_integral<T1>::value ||
|
|
- !std::is_pointer<T2>::value>::type* = nullptr>
|
|
- static AssertionResult Compare(const char* lhs_expression,
|
|
- const char* rhs_expression, const T1& lhs,
|
|
- const T2& rhs) {
|
|
- return CmpHelperEQ(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.
|
|
- //
|
|
- // Even though its body looks the same as the above version, we
|
|
- // cannot merge the two, as it will make anonymous enums unhappy.
|
|
- static AssertionResult Compare(const char* lhs_expression,
|
|
- const char* rhs_expression, BiggestInt lhs,
|
|
- BiggestInt rhs) {
|
|
- return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
|
|
- }
|
|
-
|
|
- template <typename T>
|
|
- static AssertionResult Compare(
|
|
- const char* lhs_expression, const char* rhs_expression,
|
|
- // Handle cases where '0' is used as a null pointer literal.
|
|
- std::nullptr_t /* lhs */, T* rhs) {
|
|
- // We already know that 'lhs' is a null pointer.
|
|
- return CmpHelperEQ(lhs_expression, rhs_expression, static_cast<T*>(nullptr),
|
|
- rhs);
|
|
- }
|
|
-};
|
|
-
|
|
-// Separate the error generating code from the code path to reduce the stack
|
|
-// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers
|
|
-// when calling EXPECT_OP in a tight loop.
|
|
-template <typename T1, typename T2>
|
|
-AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,
|
|
- const T1& val1, const T2& val2,
|
|
- const char* op) {
|
|
- return AssertionFailure()
|
|
- << "Expected: (" << expr1 << ") " << op << " (" << expr2
|
|
- << "), actual: " << FormatForComparisonFailureMessage(val1, val2)
|
|
- << " vs " << FormatForComparisonFailureMessage(val2, val1);
|
|
-}
|
|
-
|
|
-// A macro for implementing the helper functions needed to implement
|
|
-// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste
|
|
-// of similar code.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-
|
|
-#define GTEST_IMPL_CMP_HELPER_(op_name, op) \
|
|
- template <typename T1, typename T2> \
|
|
- AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
|
|
- const T1& val1, const T2& val2) { \
|
|
- if (val1 op val2) { \
|
|
- return AssertionSuccess(); \
|
|
- } else { \
|
|
- return CmpHelperOpFailure(expr1, expr2, val1, val2, #op); \
|
|
- } \
|
|
- }
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-
|
|
-// Implements the helper function for {ASSERT|EXPECT}_NE
|
|
-GTEST_IMPL_CMP_HELPER_(NE, !=)
|
|
-// Implements the helper function for {ASSERT|EXPECT}_LE
|
|
-GTEST_IMPL_CMP_HELPER_(LE, <=)
|
|
-// Implements the helper function for {ASSERT|EXPECT}_LT
|
|
-GTEST_IMPL_CMP_HELPER_(LT, <)
|
|
-// Implements the helper function for {ASSERT|EXPECT}_GE
|
|
-GTEST_IMPL_CMP_HELPER_(GE, >=)
|
|
-// Implements the helper function for {ASSERT|EXPECT}_GT
|
|
-GTEST_IMPL_CMP_HELPER_(GT, >)
|
|
-
|
|
-#undef GTEST_IMPL_CMP_HELPER_
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STREQ.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,
|
|
- const char* s2_expression,
|
|
- const char* s1, const char* s2);
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression,
|
|
- const char* s2_expression,
|
|
- const char* s1, const char* s2);
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STRNE.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
|
|
- const char* s2_expression,
|
|
- const char* s1, const char* s2);
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STRCASENE.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
|
|
- const char* s2_expression,
|
|
- const char* s1, const char* s2);
|
|
-
|
|
-// Helper function for *_STREQ on wide strings.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,
|
|
- const char* s2_expression,
|
|
- const wchar_t* s1, const wchar_t* s2);
|
|
-
|
|
-// Helper function for *_STRNE on wide strings.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
|
|
- const char* s2_expression,
|
|
- const wchar_t* s1, const wchar_t* s2);
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// IsSubstring() and IsNotSubstring() are intended to be used as the
|
|
-// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by
|
|
-// themselves. They check whether needle is a substring of haystack
|
|
-// (NULL is considered a substring of itself only), and return an
|
|
-// appropriate error message when they fail.
|
|
-//
|
|
-// The {needle,haystack}_expr arguments are the stringified
|
|
-// expressions that generated the two real arguments.
|
|
-GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const char* needle,
|
|
- const char* haystack);
|
|
-GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const wchar_t* needle,
|
|
- const wchar_t* haystack);
|
|
-GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const char* needle,
|
|
- const char* haystack);
|
|
-GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const wchar_t* needle,
|
|
- const wchar_t* haystack);
|
|
-GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const ::std::string& needle,
|
|
- const ::std::string& haystack);
|
|
-GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const ::std::string& needle,
|
|
- const ::std::string& haystack);
|
|
-
|
|
-#if GTEST_HAS_STD_WSTRING
|
|
-GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const ::std::wstring& needle,
|
|
- const ::std::wstring& haystack);
|
|
-GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const ::std::wstring& needle,
|
|
- const ::std::wstring& haystack);
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Helper template function for comparing floating-points.
|
|
-//
|
|
-// Template parameter:
|
|
-//
|
|
-// RawType: the raw floating-point type (either float or double)
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-template <typename RawType>
|
|
-AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
|
|
- const char* rhs_expression,
|
|
- RawType lhs_value, RawType rhs_value) {
|
|
- const FloatingPoint<RawType> lhs(lhs_value), rhs(rhs_value);
|
|
-
|
|
- if (lhs.AlmostEquals(rhs)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- ::std::stringstream lhs_ss;
|
|
- lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
|
- << lhs_value;
|
|
-
|
|
- ::std::stringstream rhs_ss;
|
|
- rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
|
- << rhs_value;
|
|
-
|
|
- return EqFailure(lhs_expression, rhs_expression,
|
|
- StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
|
|
- false);
|
|
-}
|
|
-
|
|
-// Helper function for implementing ASSERT_NEAR.
|
|
-//
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
|
-GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
|
|
- const char* expr2,
|
|
- const char* abs_error_expr,
|
|
- double val1, double val2,
|
|
- double abs_error);
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-// A class that enables one to stream messages to assertion macros
|
|
-class GTEST_API_ AssertHelper {
|
|
- public:
|
|
- // Constructor.
|
|
- AssertHelper(TestPartResult::Type type, const char* file, int line,
|
|
- const char* message);
|
|
- ~AssertHelper();
|
|
-
|
|
- // Message assignment is a semantic trick to enable assertion
|
|
- // streaming; see the GTEST_MESSAGE_ macro below.
|
|
- void operator=(const Message& message) const;
|
|
-
|
|
- private:
|
|
- // We put our data in a struct so that the size of the AssertHelper class can
|
|
- // be as small as possible. This is important because gcc is incapable of
|
|
- // re-using stack space even for temporary variables, so every EXPECT_EQ
|
|
- // reserves stack space for another AssertHelper.
|
|
- struct AssertHelperData {
|
|
- AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,
|
|
- const char* msg)
|
|
- : type(t), file(srcfile), line(line_num), message(msg) {}
|
|
-
|
|
- TestPartResult::Type const type;
|
|
- const char* const file;
|
|
- int const line;
|
|
- std::string const message;
|
|
-
|
|
- private:
|
|
- AssertHelperData(const AssertHelperData&) = delete;
|
|
- AssertHelperData& operator=(const AssertHelperData&) = delete;
|
|
- };
|
|
-
|
|
- AssertHelperData* const data_;
|
|
-
|
|
- AssertHelper(const AssertHelper&) = delete;
|
|
- AssertHelper& operator=(const AssertHelper&) = delete;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// The pure interface class that all value-parameterized tests inherit from.
|
|
-// A value-parameterized class must inherit from both ::testing::Test and
|
|
-// ::testing::WithParamInterface. In most cases that just means inheriting
|
|
-// from ::testing::TestWithParam, but more complicated test hierarchies
|
|
-// may need to inherit from Test and WithParamInterface at different levels.
|
|
-//
|
|
-// This interface has support for accessing the test parameter value via
|
|
-// the GetParam() method.
|
|
-//
|
|
-// Use it with one of the parameter generator defining functions, like Range(),
|
|
-// Values(), ValuesIn(), Bool(), and Combine().
|
|
-//
|
|
-// class FooTest : public ::testing::TestWithParam<int> {
|
|
-// protected:
|
|
-// FooTest() {
|
|
-// // Can use GetParam() here.
|
|
-// }
|
|
-// ~FooTest() override {
|
|
-// // Can use GetParam() here.
|
|
-// }
|
|
-// void SetUp() override {
|
|
-// // Can use GetParam() here.
|
|
-// }
|
|
-// void TearDown override {
|
|
-// // Can use GetParam() here.
|
|
-// }
|
|
-// };
|
|
-// TEST_P(FooTest, DoesBar) {
|
|
-// // Can use GetParam() method here.
|
|
-// Foo foo;
|
|
-// ASSERT_TRUE(foo.DoesBar(GetParam()));
|
|
-// }
|
|
-// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
|
|
-
|
|
-template <typename T>
|
|
-class WithParamInterface {
|
|
- public:
|
|
- typedef T ParamType;
|
|
- virtual ~WithParamInterface() {}
|
|
-
|
|
- // The current parameter value. Is also available in the test fixture's
|
|
- // constructor.
|
|
- static const ParamType& GetParam() {
|
|
- GTEST_CHECK_(parameter_ != nullptr)
|
|
- << "GetParam() can only be called inside a value-parameterized test "
|
|
- << "-- did you intend to write TEST_P instead of TEST_F?";
|
|
- return *parameter_;
|
|
- }
|
|
-
|
|
- private:
|
|
- // Sets parameter value. The caller is responsible for making sure the value
|
|
- // remains alive and unchanged throughout the current test.
|
|
- static void SetParam(const ParamType* parameter) { parameter_ = parameter; }
|
|
-
|
|
- // Static value used for accessing parameter during a test lifetime.
|
|
- static const ParamType* parameter_;
|
|
-
|
|
- // TestClass must be a subclass of WithParamInterface<T> and Test.
|
|
- template <class TestClass>
|
|
- friend class internal::ParameterizedTestFactory;
|
|
-};
|
|
-
|
|
-template <typename T>
|
|
-const T* WithParamInterface<T>::parameter_ = nullptr;
|
|
-
|
|
-// Most value-parameterized classes can ignore the existence of
|
|
-// WithParamInterface, and can just inherit from ::testing::TestWithParam.
|
|
-
|
|
-template <typename T>
|
|
-class TestWithParam : public Test, public WithParamInterface<T> {};
|
|
-
|
|
-// Macros for indicating success/failure in test code.
|
|
-
|
|
-// Skips test in runtime.
|
|
-// Skipping test aborts current function.
|
|
-// Skipped tests are neither successful nor failed.
|
|
-#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
|
|
-// current test successful, as a test is only successful when it has
|
|
-// no failure.
|
|
-//
|
|
-// EXPECT_* verifies that a certain condition is satisfied. If not,
|
|
-// it behaves like ADD_FAILURE. In particular:
|
|
-//
|
|
-// EXPECT_TRUE verifies that a Boolean condition is true.
|
|
-// EXPECT_FALSE verifies that a Boolean condition is false.
|
|
-//
|
|
-// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except
|
|
-// that they will also abort the current function on failure. People
|
|
-// usually want the fail-fast behavior of FAIL and ASSERT_*, but those
|
|
-// writing data-driven tests often find themselves using ADD_FAILURE
|
|
-// and EXPECT_* more.
|
|
-
|
|
-// Generates a nonfatal failure with a generic message.
|
|
-#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")
|
|
-
|
|
-// Generates a nonfatal failure at the given source file location with
|
|
-// a generic message.
|
|
-#define ADD_FAILURE_AT(file, line) \
|
|
- GTEST_MESSAGE_AT_(file, line, "Failed", \
|
|
- ::testing::TestPartResult::kNonFatalFailure)
|
|
-
|
|
-// Generates a fatal failure with a generic message.
|
|
-#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
|
|
-
|
|
-// Like GTEST_FAIL(), but at the given source file location.
|
|
-#define GTEST_FAIL_AT(file, line) \
|
|
- GTEST_MESSAGE_AT_(file, line, "Failed", \
|
|
- ::testing::TestPartResult::kFatalFailure)
|
|
-
|
|
-// Define this macro to 1 to omit the definition of FAIL(), which is a
|
|
-// generic name and clashes with some other libraries.
|
|
-#if !GTEST_DONT_DEFINE_FAIL
|
|
-#define FAIL() GTEST_FAIL()
|
|
-#endif
|
|
-
|
|
-// Generates a success with a generic message.
|
|
-#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
|
|
-
|
|
-// Define this macro to 1 to omit the definition of SUCCEED(), which
|
|
-// is a generic name and clashes with some other libraries.
|
|
-#if !GTEST_DONT_DEFINE_SUCCEED
|
|
-#define SUCCEED() GTEST_SUCCEED()
|
|
-#endif
|
|
-
|
|
-// Macros for testing exceptions.
|
|
-//
|
|
-// * {ASSERT|EXPECT}_THROW(statement, expected_exception):
|
|
-// Tests that the statement throws the expected exception.
|
|
-// * {ASSERT|EXPECT}_NO_THROW(statement):
|
|
-// Tests that the statement doesn't throw any exception.
|
|
-// * {ASSERT|EXPECT}_ANY_THROW(statement):
|
|
-// Tests that the statement throws an exception.
|
|
-
|
|
-#define EXPECT_THROW(statement, expected_exception) \
|
|
- GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_NO_THROW(statement) \
|
|
- GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_ANY_THROW(statement) \
|
|
- GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
|
|
-#define ASSERT_THROW(statement, expected_exception) \
|
|
- GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_NO_THROW(statement) \
|
|
- GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_ANY_THROW(statement) \
|
|
- GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
|
|
-
|
|
-// 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 GTEST_EXPECT_TRUE(condition) \
|
|
- GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
|
|
- GTEST_NONFATAL_FAILURE_)
|
|
-#define GTEST_EXPECT_FALSE(condition) \
|
|
- GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
|
|
- GTEST_NONFATAL_FAILURE_)
|
|
-#define GTEST_ASSERT_TRUE(condition) \
|
|
- GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)
|
|
-#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
|
|
-// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
|
|
-// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2
|
|
-// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2
|
|
-// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2
|
|
-// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2
|
|
-//
|
|
-// When they are not, Google Test prints both the tested expressions and
|
|
-// their actual values. The values must be compatible built-in types,
|
|
-// or you will get a compiler error. By "compatible" we mean that the
|
|
-// values can be compared by the respective operator.
|
|
-//
|
|
-// Note:
|
|
-//
|
|
-// 1. It is possible to make a user-defined type work with
|
|
-// {ASSERT|EXPECT}_??(), but that requires overloading the
|
|
-// comparison operators and is thus discouraged by the Google C++
|
|
-// Usage Guide. Therefore, you are advised to use the
|
|
-// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are
|
|
-// equal.
|
|
-//
|
|
-// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on
|
|
-// pointers (in particular, C strings). Therefore, if you use it
|
|
-// with two C strings, you are testing how their locations in memory
|
|
-// are related, not how their content is related. To compare two C
|
|
-// strings by content, use {ASSERT|EXPECT}_STR*().
|
|
-//
|
|
-// 3. {ASSERT|EXPECT}_EQ(v1, v2) is preferred to
|
|
-// {ASSERT|EXPECT}_TRUE(v1 == v2), as the former tells you
|
|
-// what the actual value is when it fails, and similarly for the
|
|
-// other comparisons.
|
|
-//
|
|
-// 4. Do not depend on the order in which {ASSERT|EXPECT}_??()
|
|
-// evaluate their arguments, which is undefined.
|
|
-//
|
|
-// 5. These macros evaluate their arguments exactly once.
|
|
-//
|
|
-// Examples:
|
|
-//
|
|
-// EXPECT_NE(Foo(), 5);
|
|
-// EXPECT_EQ(a_pointer, NULL);
|
|
-// ASSERT_LT(i, array_size);
|
|
-// ASSERT_GT(records.size(), 0) << "There is no record left.";
|
|
-
|
|
-#define EXPECT_EQ(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
|
|
-#define EXPECT_NE(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
|
|
-#define EXPECT_LE(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
|
|
-#define EXPECT_LT(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
|
|
-#define EXPECT_GE(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
|
|
-#define EXPECT_GT(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
|
|
-
|
|
-#define GTEST_ASSERT_EQ(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
|
|
-#define GTEST_ASSERT_NE(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
|
|
-#define GTEST_ASSERT_LE(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
|
|
-#define GTEST_ASSERT_LT(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
|
|
-#define GTEST_ASSERT_GE(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
|
|
-#define GTEST_ASSERT_GT(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
|
|
-
|
|
-// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of
|
|
-// ASSERT_XY(), which clashes with some users' own code.
|
|
-
|
|
-#if !GTEST_DONT_DEFINE_ASSERT_EQ
|
|
-#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)
|
|
-#endif
|
|
-
|
|
-#if !GTEST_DONT_DEFINE_ASSERT_NE
|
|
-#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)
|
|
-#endif
|
|
-
|
|
-#if !GTEST_DONT_DEFINE_ASSERT_LE
|
|
-#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)
|
|
-#endif
|
|
-
|
|
-#if !GTEST_DONT_DEFINE_ASSERT_LT
|
|
-#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)
|
|
-#endif
|
|
-
|
|
-#if !GTEST_DONT_DEFINE_ASSERT_GE
|
|
-#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)
|
|
-#endif
|
|
-
|
|
-#if !GTEST_DONT_DEFINE_ASSERT_GT
|
|
-#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)
|
|
-#endif
|
|
-
|
|
-// C-string Comparisons. All tests treat NULL and any non-NULL string
|
|
-// as different. Two NULLs are equal.
|
|
-//
|
|
-// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2
|
|
-// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2
|
|
-// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case
|
|
-// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case
|
|
-//
|
|
-// For wide or narrow string objects, you can use the
|
|
-// {ASSERT|EXPECT}_??() macros.
|
|
-//
|
|
-// Don't depend on the order in which the arguments are evaluated,
|
|
-// which is undefined.
|
|
-//
|
|
-// These macros evaluate their arguments exactly once.
|
|
-
|
|
-#define EXPECT_STREQ(s1, s2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2)
|
|
-#define EXPECT_STRNE(s1, s2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
|
|
-#define EXPECT_STRCASEEQ(s1, s2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)
|
|
-#define EXPECT_STRCASENE(s1, s2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
|
|
-
|
|
-#define ASSERT_STREQ(s1, s2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2)
|
|
-#define ASSERT_STRNE(s1, s2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
|
|
-#define ASSERT_STRCASEEQ(s1, s2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)
|
|
-#define ASSERT_STRCASENE(s1, s2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
|
|
-
|
|
-// Macros for comparing floating-point numbers.
|
|
-//
|
|
-// * {ASSERT|EXPECT}_FLOAT_EQ(val1, val2):
|
|
-// Tests that two float values are almost equal.
|
|
-// * {ASSERT|EXPECT}_DOUBLE_EQ(val1, val2):
|
|
-// Tests that two double values are almost equal.
|
|
-// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):
|
|
-// Tests that v1 and v2 are within the given distance to each other.
|
|
-//
|
|
-// Google Test uses ULP-based comparison to automatically pick a default
|
|
-// error bound that is appropriate for the operands. See the
|
|
-// FloatingPoint template class in gtest-internal.h if you are
|
|
-// interested in the implementation details.
|
|
-
|
|
-#define EXPECT_FLOAT_EQ(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
|
|
- val1, val2)
|
|
-
|
|
-#define EXPECT_DOUBLE_EQ(val1, val2) \
|
|
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
|
|
- val1, val2)
|
|
-
|
|
-#define ASSERT_FLOAT_EQ(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
|
|
- val1, val2)
|
|
-
|
|
-#define ASSERT_DOUBLE_EQ(val1, val2) \
|
|
- ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
|
|
- val1, val2)
|
|
-
|
|
-#define EXPECT_NEAR(val1, val2, abs_error) \
|
|
- EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \
|
|
- abs_error)
|
|
-
|
|
-#define ASSERT_NEAR(val1, val2, abs_error) \
|
|
- ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \
|
|
- abs_error)
|
|
-
|
|
-// These predicate format functions work on floating-point values, and
|
|
-// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
|
|
-//
|
|
-// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);
|
|
-
|
|
-// Asserts that val1 is less than, or almost equal to, val2. Fails
|
|
-// otherwise. In particular, it fails if either val1 or val2 is NaN.
|
|
-GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
|
|
- float val1, float val2);
|
|
-GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
|
|
- double val1, double val2);
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-
|
|
-// Macros that test for HRESULT failure and success, these are only useful
|
|
-// on Windows, and rely on Windows SDK macros and APIs to compile.
|
|
-//
|
|
-// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)
|
|
-//
|
|
-// When expr unexpectedly fails or succeeds, Google Test prints the
|
|
-// expected result and the actual result with both a human-readable
|
|
-// string representation of the error, if available, as well as the
|
|
-// hex result code.
|
|
-#define EXPECT_HRESULT_SUCCEEDED(expr) \
|
|
- EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
|
|
-
|
|
-#define ASSERT_HRESULT_SUCCEEDED(expr) \
|
|
- ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
|
|
-
|
|
-#define EXPECT_HRESULT_FAILED(expr) \
|
|
- EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
|
|
-
|
|
-#define ASSERT_HRESULT_FAILED(expr) \
|
|
- ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-// Macros that execute statement and check that it doesn't generate new fatal
|
|
-// failures in the current thread.
|
|
-//
|
|
-// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
|
|
-//
|
|
-// Examples:
|
|
-//
|
|
-// EXPECT_NO_FATAL_FAILURE(Process());
|
|
-// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed";
|
|
-//
|
|
-#define ASSERT_NO_FATAL_FAILURE(statement) \
|
|
- GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)
|
|
-#define EXPECT_NO_FATAL_FAILURE(statement) \
|
|
- GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
|
|
-
|
|
-// Causes a trace (including the given source file path and line number,
|
|
-// and the given message) to be included in every test failure message generated
|
|
-// by code in the scope of the lifetime of an instance of this class. The effect
|
|
-// is undone with the destruction of the instance.
|
|
-//
|
|
-// The message argument can be anything streamable to std::ostream.
|
|
-//
|
|
-// Example:
|
|
-// testing::ScopedTrace trace("file.cc", 123, "message");
|
|
-//
|
|
-class GTEST_API_ ScopedTrace {
|
|
- public:
|
|
- // The c'tor pushes the given source file location and message onto
|
|
- // a trace stack maintained by Google Test.
|
|
-
|
|
- // Template version. Uses Message() to convert the values into strings.
|
|
- // Slow, but flexible.
|
|
- template <typename T>
|
|
- ScopedTrace(const char* file, int line, const T& message) {
|
|
- PushTrace(file, line, (Message() << message).GetString());
|
|
- }
|
|
-
|
|
- // Optimize for some known types.
|
|
- ScopedTrace(const char* file, int line, const char* message) {
|
|
- PushTrace(file, line, message ? message : "(null)");
|
|
- }
|
|
-
|
|
- ScopedTrace(const char* file, int line, const std::string& message) {
|
|
- PushTrace(file, line, message);
|
|
- }
|
|
-
|
|
- // The d'tor pops the info pushed by the c'tor.
|
|
- //
|
|
- // Note that the d'tor is not virtual in order to be efficient.
|
|
- // Don't inherit from ScopedTrace!
|
|
- ~ScopedTrace();
|
|
-
|
|
- private:
|
|
- void PushTrace(const char* file, int line, std::string message);
|
|
-
|
|
- ScopedTrace(const ScopedTrace&) = delete;
|
|
- ScopedTrace& operator=(const ScopedTrace&) = delete;
|
|
-} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
|
|
- // c'tor and d'tor. Therefore it doesn't
|
|
- // need to be used otherwise.
|
|
-
|
|
-// Causes a trace (including the source file path, the current line
|
|
-// number, and the given message) to be included in every test failure
|
|
-// message generated by code in the current scope. The effect is
|
|
-// undone when the control leaves the current scope.
|
|
-//
|
|
-// The message argument can be anything streamable to std::ostream.
|
|
-//
|
|
-// In the implementation, we include the current line number as part
|
|
-// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
|
|
-// to appear in the same block - as long as they are on different
|
|
-// lines.
|
|
-//
|
|
-// Assuming that each thread maintains its own stack of traces.
|
|
-// Therefore, a SCOPED_TRACE() would (correctly) only affect the
|
|
-// assertions in its own thread.
|
|
-#define SCOPED_TRACE(message) \
|
|
- ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \
|
|
- __FILE__, __LINE__, (message))
|
|
-
|
|
-// Compile-time assertion for type equality.
|
|
-// 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
|
|
-// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
|
|
-// defining objects of that type.
|
|
-//
|
|
-// CAVEAT:
|
|
-//
|
|
-// When used inside a method of a class template,
|
|
-// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
|
|
-// instantiated. For example, given:
|
|
-//
|
|
-// template <typename T> class Foo {
|
|
-// public:
|
|
-// void Bar() { testing::StaticAssertTypeEq<int, T>(); }
|
|
-// };
|
|
-//
|
|
-// the code:
|
|
-//
|
|
-// void Test1() { Foo<bool> foo; }
|
|
-//
|
|
-// will NOT generate a compiler error, as Foo<bool>::Bar() is never
|
|
-// actually instantiated. Instead, you need:
|
|
-//
|
|
-// void Test2() { Foo<bool> foo; foo.Bar(); }
|
|
-//
|
|
-// to cause a compiler error.
|
|
-template <typename T1, typename T2>
|
|
-constexpr bool StaticAssertTypeEq() noexcept {
|
|
- static_assert(std::is_same<T1, T2>::value, "T1 and T2 are not the same type");
|
|
- return true;
|
|
-}
|
|
-
|
|
-// Defines a test.
|
|
-//
|
|
-// The first parameter is the name of the test suite, and the second
|
|
-// parameter is the name of the test within the test suite.
|
|
-//
|
|
-// The convention is to end the test suite name with "Test". For
|
|
-// example, a test suite for the Foo class can be named FooTest.
|
|
-//
|
|
-// Test code should appear between braces after an invocation of
|
|
-// this macro. Example:
|
|
-//
|
|
-// TEST(FooTest, InitializesCorrectly) {
|
|
-// Foo foo;
|
|
-// EXPECT_TRUE(foo.StatusIsOK());
|
|
-// }
|
|
-
|
|
-// Note that we call GetTestTypeId() instead of GetTypeId<
|
|
-// ::testing::Test>() here to get the type ID of testing::Test. This
|
|
-// is to work around a suspected linker bug when using Google Test as
|
|
-// a framework on Mac OS X. The bug causes GetTypeId<
|
|
-// ::testing::Test>() to return different values depending on whether
|
|
-// the call is from the Google Test framework itself or from user test
|
|
-// code. GetTestTypeId() is guaranteed to always return the same
|
|
-// value, as it always calls GetTypeId<>() from the Google Test
|
|
-// framework.
|
|
-#define GTEST_TEST(test_suite_name, test_name) \
|
|
- GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \
|
|
- ::testing::internal::GetTestTypeId())
|
|
-
|
|
-// Define this macro to 1 to omit the definition of TEST(), which
|
|
-// is a generic name and clashes with some other libraries.
|
|
-#if !GTEST_DONT_DEFINE_TEST
|
|
-#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
|
|
-#endif
|
|
-
|
|
-// Defines a test that uses a test fixture.
|
|
-//
|
|
-// The first parameter is the name of the test fixture class, which
|
|
-// also doubles as the test suite name. The second parameter is the
|
|
-// name of the test within the test suite.
|
|
-//
|
|
-// A test fixture class must be declared earlier. The user should put
|
|
-// the test code between braces after using this macro. Example:
|
|
-//
|
|
-// class FooTest : public testing::Test {
|
|
-// protected:
|
|
-// void SetUp() override { b_.AddElement(3); }
|
|
-//
|
|
-// Foo a_;
|
|
-// Foo b_;
|
|
-// };
|
|
-//
|
|
-// TEST_F(FooTest, InitializesCorrectly) {
|
|
-// EXPECT_TRUE(a_.StatusIsOK());
|
|
-// }
|
|
-//
|
|
-// TEST_F(FooTest, ReturnsElementCountCorrectly) {
|
|
-// EXPECT_EQ(a_.size(), 0);
|
|
-// EXPECT_EQ(b_.size(), 1);
|
|
-// }
|
|
-#define GTEST_TEST_F(test_fixture, test_name) \
|
|
- GTEST_TEST_(test_fixture, test_name, test_fixture, \
|
|
- ::testing::internal::GetTypeId<test_fixture>())
|
|
-#if !GTEST_DONT_DEFINE_TEST_F
|
|
-#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)
|
|
-#endif
|
|
-
|
|
-// Returns a path to temporary directory.
|
|
-// Tries to determine an appropriate directory for the platform.
|
|
-GTEST_API_ std::string TempDir();
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-#pragma warning(pop)
|
|
-#endif
|
|
-
|
|
-// Dynamically registers a test with the framework.
|
|
-//
|
|
-// This is an advanced API only to be used when the `TEST` macros are
|
|
-// insufficient. The macros should be preferred when possible, as they avoid
|
|
-// most of the complexity of calling this function.
|
|
-//
|
|
-// The `factory` argument is a factory callable (move-constructible) object or
|
|
-// function pointer that creates a new instance of the Test object. It
|
|
-// handles ownership to the caller. The signature of the callable is
|
|
-// `Fixture*()`, where `Fixture` is the test fixture class for the test. All
|
|
-// tests registered with the same `test_suite_name` must return the same
|
|
-// fixture type. This is checked at runtime.
|
|
-//
|
|
-// The framework will infer the fixture class from the factory and will call
|
|
-// the `SetUpTestSuite` and `TearDownTestSuite` for it.
|
|
-//
|
|
-// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is
|
|
-// undefined.
|
|
-//
|
|
-// Use case example:
|
|
-//
|
|
-// class MyFixture : public ::testing::Test {
|
|
-// public:
|
|
-// // All of these optional, just like in regular macro usage.
|
|
-// static void SetUpTestSuite() { ... }
|
|
-// static void TearDownTestSuite() { ... }
|
|
-// void SetUp() override { ... }
|
|
-// void TearDown() override { ... }
|
|
-// };
|
|
-//
|
|
-// class MyTest : public MyFixture {
|
|
-// public:
|
|
-// explicit MyTest(int data) : data_(data) {}
|
|
-// void TestBody() override { ... }
|
|
-//
|
|
-// private:
|
|
-// int data_;
|
|
-// };
|
|
-//
|
|
-// void RegisterMyTests(const std::vector<int>& values) {
|
|
-// for (int v : values) {
|
|
-// ::testing::RegisterTest(
|
|
-// "MyFixture", ("Test" + std::to_string(v)).c_str(), nullptr,
|
|
-// std::to_string(v).c_str(),
|
|
-// __FILE__, __LINE__,
|
|
-// // Important to use the fixture type as the return type here.
|
|
-// [=]() -> MyFixture* { return new MyTest(v); });
|
|
-// }
|
|
-// }
|
|
-// ...
|
|
-// int main(int argc, char** argv) {
|
|
-// ::testing::InitGoogleTest(&argc, argv);
|
|
-// std::vector<int> values_to_test = LoadValuesFromConfig();
|
|
-// RegisterMyTests(values_to_test);
|
|
-// ...
|
|
-// return RUN_ALL_TESTS();
|
|
-// }
|
|
-//
|
|
-template <int&... ExplicitParameterBarrier, typename Factory>
|
|
-TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
|
|
- const char* type_param, const char* value_param,
|
|
- const char* file, int line, Factory factory) {
|
|
- using TestT = typename std::remove_pointer<decltype(factory())>::type;
|
|
-
|
|
- class FactoryImpl : public internal::TestFactoryBase {
|
|
- public:
|
|
- explicit FactoryImpl(Factory f) : factory_(std::move(f)) {}
|
|
- Test* CreateTest() override { return factory_(); }
|
|
-
|
|
- private:
|
|
- Factory factory_;
|
|
- };
|
|
-
|
|
- return internal::MakeAndRegisterTestInfo(
|
|
- test_suite_name, test_name, type_param, value_param,
|
|
- internal::CodeLocation(file, line), internal::GetTypeId<TestT>(),
|
|
- internal::SuiteApiResolver<TestT>::GetSetUpCaseOrSuite(file, line),
|
|
- internal::SuiteApiResolver<TestT>::GetTearDownCaseOrSuite(file, line),
|
|
- new FactoryImpl{std::move(factory)});
|
|
-}
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-// Use this function in main() to run all tests. It returns 0 if all
|
|
-// tests are successful, or 1 otherwise.
|
|
-//
|
|
-// RUN_ALL_TESTS() should be invoked after the command line has been
|
|
-// parsed by InitGoogleTest().
|
|
-//
|
|
-// This function was formerly a macro; thus, it is in the global
|
|
-// namespace and has an all-caps name.
|
|
-int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
|
|
-
|
|
-inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest_pred_impl.h b/vendor/gtest/include/gtest/gtest_pred_impl.h
|
|
deleted file mode 100644
|
|
index 47a24aa68..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest_pred_impl.h
|
|
+++ /dev/null
|
|
@@ -1,279 +0,0 @@
|
|
-// Copyright 2006, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-//
|
|
-// Implements a family of generic predicate assertion macros.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
-
|
|
-#include "gtest/gtest-assertion-result.h"
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// This header implements a family of generic predicate assertion
|
|
-// macros:
|
|
-//
|
|
-// ASSERT_PRED_FORMAT1(pred_format, v1)
|
|
-// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
|
-// ...
|
|
-//
|
|
-// where pred_format is a function or functor that takes n (in the
|
|
-// case of ASSERT_PRED_FORMATn) values and their source expression
|
|
-// text, and returns a testing::AssertionResult. See the definition
|
|
-// of ASSERT_EQ in gtest.h for an example.
|
|
-//
|
|
-// If you don't care about formatting, you can use the more
|
|
-// restrictive version:
|
|
-//
|
|
-// ASSERT_PRED1(pred, v1)
|
|
-// ASSERT_PRED2(pred, v1, v2)
|
|
-// ...
|
|
-//
|
|
-// where pred is an n-ary function or functor that returns bool,
|
|
-// and the values v1, v2, ..., must support the << operator for
|
|
-// streaming to std::ostream.
|
|
-//
|
|
-// We also define the EXPECT_* variations.
|
|
-//
|
|
-// For now we only support predicates whose arity is at most 5.
|
|
-// Please email googletestframework@googlegroups.com if you need
|
|
-// support for higher arities.
|
|
-
|
|
-// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
|
-// in this file reduce. Don't use this in your code.
|
|
-
|
|
-#define GTEST_ASSERT_(expression, on_failure) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (const ::testing::AssertionResult gtest_ar = (expression)) \
|
|
- ; \
|
|
- else \
|
|
- on_failure(gtest_ar.failure_message())
|
|
-
|
|
-// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
|
-// this in your code.
|
|
-template <typename Pred, typename T1>
|
|
-AssertionResult AssertPred1Helper(const char* pred_text, const char* e1,
|
|
- Pred pred, const T1& v1) {
|
|
- if (pred(v1)) return AssertionSuccess();
|
|
-
|
|
- return AssertionFailure()
|
|
- << pred_text << "(" << e1 << ") evaluates to false, where"
|
|
- << "\n"
|
|
- << e1 << " evaluates to " << ::testing::PrintToString(v1);
|
|
-}
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
|
-// Don't use this in your code.
|
|
-#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \
|
|
- GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
|
-// this in your code.
|
|
-#define GTEST_PRED1_(pred, v1, on_failure) \
|
|
- GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)
|
|
-
|
|
-// Unary predicate assertion macros.
|
|
-#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
|
- GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
|
|
-#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
|
- GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
|
|
-
|
|
-// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
|
-// this in your code.
|
|
-template <typename Pred, typename T1, typename T2>
|
|
-AssertionResult AssertPred2Helper(const char* pred_text, const char* e1,
|
|
- const char* e2, Pred pred, const T1& v1,
|
|
- const T2& v2) {
|
|
- if (pred(v1, v2)) return AssertionSuccess();
|
|
-
|
|
- return AssertionFailure()
|
|
- << pred_text << "(" << e1 << ", " << e2
|
|
- << ") evaluates to false, where"
|
|
- << "\n"
|
|
- << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
|
- << e2 << " evaluates to " << ::testing::PrintToString(v2);
|
|
-}
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
|
-// Don't use this in your code.
|
|
-#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \
|
|
- GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
|
-// this in your code.
|
|
-#define GTEST_PRED2_(pred, v1, v2, on_failure) \
|
|
- GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \
|
|
- on_failure)
|
|
-
|
|
-// Binary predicate assertion macros.
|
|
-#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
|
- GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_PRED2(pred, v1, v2) \
|
|
- GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
|
|
-#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
|
|
- GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_PRED2(pred, v1, v2) \
|
|
- GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
|
|
-
|
|
-// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
|
-// this in your code.
|
|
-template <typename Pred, typename T1, typename T2, typename T3>
|
|
-AssertionResult AssertPred3Helper(const char* pred_text, const char* e1,
|
|
- const char* e2, const char* e3, Pred pred,
|
|
- const T1& v1, const T2& v2, const T3& v3) {
|
|
- if (pred(v1, v2, v3)) return AssertionSuccess();
|
|
-
|
|
- return AssertionFailure()
|
|
- << pred_text << "(" << e1 << ", " << e2 << ", " << e3
|
|
- << ") evaluates to false, where"
|
|
- << "\n"
|
|
- << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
|
- << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
|
- << e3 << " evaluates to " << ::testing::PrintToString(v3);
|
|
-}
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
|
-// Don't use this in your code.
|
|
-#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \
|
|
- GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure)
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
|
-// this in your code.
|
|
-#define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \
|
|
- GTEST_ASSERT_( \
|
|
- ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \
|
|
- on_failure)
|
|
-
|
|
-// Ternary predicate assertion macros.
|
|
-#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
|
- GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_PRED3(pred, v1, v2, v3) \
|
|
- GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
|
-#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
|
- GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_PRED3(pred, v1, v2, v3) \
|
|
- GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
|
-
|
|
-// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
|
-// this in your code.
|
|
-template <typename Pred, typename T1, typename T2, typename T3, typename T4>
|
|
-AssertionResult AssertPred4Helper(const char* pred_text, const char* e1,
|
|
- const char* e2, const char* e3,
|
|
- const char* e4, Pred pred, const T1& v1,
|
|
- const T2& v2, const T3& v3, const T4& v4) {
|
|
- if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
|
-
|
|
- return AssertionFailure()
|
|
- << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
|
- << ") evaluates to false, where"
|
|
- << "\n"
|
|
- << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
|
- << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
|
- << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
|
- << e4 << " evaluates to " << ::testing::PrintToString(v4);
|
|
-}
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
|
-// Don't use this in your code.
|
|
-#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \
|
|
- GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
|
-// this in your code.
|
|
-#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \
|
|
- GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \
|
|
- v1, v2, v3, v4), \
|
|
- on_failure)
|
|
-
|
|
-// 4-ary predicate assertion macros.
|
|
-#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
|
- GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
|
|
- GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
|
-#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
|
- GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
|
|
- GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
|
-
|
|
-// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
|
-// this in your code.
|
|
-template <typename Pred, typename T1, typename T2, typename T3, typename T4,
|
|
- typename T5>
|
|
-AssertionResult AssertPred5Helper(const char* pred_text, const char* e1,
|
|
- const char* e2, const char* e3,
|
|
- const char* e4, const char* e5, Pred pred,
|
|
- const T1& v1, const T2& v2, const T3& v3,
|
|
- const T4& v4, const T5& v5) {
|
|
- if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
|
-
|
|
- return AssertionFailure()
|
|
- << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
|
- << ", " << e5 << ") evaluates to false, where"
|
|
- << "\n"
|
|
- << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
|
- << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
|
- << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
|
- << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
|
|
- << e5 << " evaluates to " << ::testing::PrintToString(v5);
|
|
-}
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
|
-// Don't use this in your code.
|
|
-#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \
|
|
- GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
|
|
- on_failure)
|
|
-
|
|
-// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
|
-// this in your code.
|
|
-#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \
|
|
- GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \
|
|
- pred, v1, v2, v3, v4, v5), \
|
|
- on_failure)
|
|
-
|
|
-// 5-ary predicate assertion macros.
|
|
-#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
|
- GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
|
-#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
|
|
- GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
|
-#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
|
- GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
|
-#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
|
|
- GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
|
diff --git a/vendor/gtest/include/gtest/gtest_prod.h b/vendor/gtest/include/gtest/gtest_prod.h
|
|
deleted file mode 100644
|
|
index 1f37dc31c..000000000
|
|
--- a/vendor/gtest/include/gtest/gtest_prod.h
|
|
+++ /dev/null
|
|
@@ -1,60 +0,0 @@
|
|
-// Copyright 2006, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// Google C++ Testing and Mocking Framework definitions useful in production
|
|
-// code.
|
|
-
|
|
-#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
|
|
-// class. For example:
|
|
-//
|
|
-// class MyClass {
|
|
-// private:
|
|
-// void PrivateMethod();
|
|
-// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
|
|
-// };
|
|
-//
|
|
-// class MyClassTest : public testing::Test {
|
|
-// // ...
|
|
-// };
|
|
-//
|
|
-// TEST_F(MyClassTest, PrivateMethodWorks) {
|
|
-// // Can call MyClass::PrivateMethod() here.
|
|
-// }
|
|
-//
|
|
-// Note: The test class must be in the same namespace as the class being tested.
|
|
-// For example, putting MyClassTest in an anonymous namespace will not work.
|
|
-
|
|
-#define FRIEND_TEST(test_case_name, test_name) \
|
|
- friend class test_case_name##_##test_name##_Test
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/custom/README.md b/vendor/gtest/include/gtest/internal/custom/README.md
|
|
deleted file mode 100644
|
|
index cb49e2c75..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/custom/README.md
|
|
+++ /dev/null
|
|
@@ -1,44 +0,0 @@
|
|
-# Customization Points
|
|
-
|
|
-The custom directory is an injection point for custom user configurations.
|
|
-
|
|
-## Header `gtest.h`
|
|
-
|
|
-### The following macros can be defined:
|
|
-
|
|
-* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of
|
|
- `OsStackTraceGetterInterface`.
|
|
-* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See
|
|
- `testing::TempDir` for semantics and signature.
|
|
-
|
|
-## Header `gtest-port.h`
|
|
-
|
|
-The following macros can be defined:
|
|
-
|
|
-### Logging:
|
|
-
|
|
-* `GTEST_LOG_(severity)`
|
|
-* `GTEST_CHECK_(condition)`
|
|
-* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.
|
|
-
|
|
-### Threading:
|
|
-
|
|
-* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.
|
|
-* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`
|
|
- are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`
|
|
- and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`
|
|
-* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`
|
|
-* `GTEST_LOCK_EXCLUDED_(locks)`
|
|
-
|
|
-### Underlying library support features
|
|
-
|
|
-* `GTEST_HAS_CXXABI_H_`
|
|
-
|
|
-### Exporting API symbols:
|
|
-
|
|
-* `GTEST_API_` - Specifier for exported symbols.
|
|
-
|
|
-## Header `gtest-printers.h`
|
|
-
|
|
-* See documentation at `gtest/gtest-printers.h` for details on how to define a
|
|
- custom printer.
|
|
diff --git a/vendor/gtest/include/gtest/internal/custom/gtest-port.h b/vendor/gtest/include/gtest/internal/custom/gtest-port.h
|
|
deleted file mode 100644
|
|
index db02881c0..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/custom/gtest-port.h
|
|
+++ /dev/null
|
|
@@ -1,37 +0,0 @@
|
|
-// Copyright 2015, 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.
|
|
-//
|
|
-// Injection point for custom user configurations. See README for details
|
|
-//
|
|
-// ** Custom implementation starts here **
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/custom/gtest-printers.h b/vendor/gtest/include/gtest/internal/custom/gtest-printers.h
|
|
deleted file mode 100644
|
|
index b9495d837..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/custom/gtest-printers.h
|
|
+++ /dev/null
|
|
@@ -1,42 +0,0 @@
|
|
-// Copyright 2015, 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.
|
|
-//
|
|
-// This file provides an injection point for custom printers in a local
|
|
-// installation of gTest.
|
|
-// It will be included from gtest-printers.h and the overrides in this file
|
|
-// will be visible to everyone.
|
|
-//
|
|
-// Injection point for custom user configurations. See README for details
|
|
-//
|
|
-// ** Custom implementation starts here **
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/custom/gtest.h b/vendor/gtest/include/gtest/internal/custom/gtest.h
|
|
deleted file mode 100644
|
|
index afaaf17ba..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/custom/gtest.h
|
|
+++ /dev/null
|
|
@@ -1,37 +0,0 @@
|
|
-// Copyright 2015, 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.
|
|
-//
|
|
-// Injection point for custom user configurations. See README for details
|
|
-//
|
|
-// ** Custom implementation starts here **
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-death-test-internal.h b/vendor/gtest/include/gtest/internal/gtest-death-test-internal.h
|
|
deleted file mode 100644
|
|
index 45580ae80..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-death-test-internal.h
|
|
+++ /dev/null
|
|
@@ -1,306 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file defines internal utilities needed for implementing
|
|
-// death tests. They are subject to change without notice.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
|
-
|
|
-#include <stdio.h>
|
|
-
|
|
-#include <memory>
|
|
-
|
|
-#include "gtest/gtest-matchers.h"
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-
|
|
-GTEST_DECLARE_string_(internal_run_death_test);
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-// Names of the flags (needed for parsing Google Test flags).
|
|
-const char kDeathTestStyleFlag[] = "death_test_style";
|
|
-const char kDeathTestUseFork[] = "death_test_use_fork";
|
|
-const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-// DeathTest is a class that hides much of the complexity of the
|
|
-// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
|
|
-// returns a concrete class that depends on the prevailing death test
|
|
-// style, as defined by the --gtest_death_test_style and/or
|
|
-// --gtest_internal_run_death_test flags.
|
|
-
|
|
-// In describing the results of death tests, these terms are used with
|
|
-// the corresponding definitions:
|
|
-//
|
|
-// exit status: The integer exit information in the format specified
|
|
-// by wait(2)
|
|
-// exit code: The integer code passed to exit(3), _exit(2), or
|
|
-// returned from main()
|
|
-class GTEST_API_ DeathTest {
|
|
- public:
|
|
- // Create returns false if there was an error determining the
|
|
- // appropriate action to take for the current death test; for example,
|
|
- // if the gtest_death_test_style flag is set to an invalid value.
|
|
- // The LastMessage method will return a more detailed message in that
|
|
- // case. Otherwise, the DeathTest pointer pointed to by the "test"
|
|
- // argument is set. If the death test should be skipped, the pointer
|
|
- // is set to NULL; otherwise, it is set to the address of a new concrete
|
|
- // DeathTest object that controls the execution of the current test.
|
|
- static bool Create(const char* statement, Matcher<const std::string&> matcher,
|
|
- const char* file, int line, DeathTest** test);
|
|
- DeathTest();
|
|
- virtual ~DeathTest() {}
|
|
-
|
|
- // A helper class that aborts a death test when it's deleted.
|
|
- class ReturnSentinel {
|
|
- public:
|
|
- explicit ReturnSentinel(DeathTest* test) : test_(test) {}
|
|
- ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
|
|
-
|
|
- private:
|
|
- DeathTest* const test_;
|
|
- ReturnSentinel(const ReturnSentinel&) = delete;
|
|
- ReturnSentinel& operator=(const ReturnSentinel&) = delete;
|
|
- } GTEST_ATTRIBUTE_UNUSED_;
|
|
-
|
|
- // An enumeration of possible roles that may be taken when a death
|
|
- // test is encountered. EXECUTE means that the death test logic should
|
|
- // be executed immediately. OVERSEE means that the program should prepare
|
|
- // the appropriate environment for a child process to execute the death
|
|
- // test, then wait for it to complete.
|
|
- enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
|
|
-
|
|
- // An enumeration of the three reasons that a test might be aborted.
|
|
- enum AbortReason {
|
|
- TEST_ENCOUNTERED_RETURN_STATEMENT,
|
|
- TEST_THREW_EXCEPTION,
|
|
- TEST_DID_NOT_DIE
|
|
- };
|
|
-
|
|
- // Assumes one of the above roles.
|
|
- virtual TestRole AssumeRole() = 0;
|
|
-
|
|
- // Waits for the death test to finish and returns its status.
|
|
- virtual int Wait() = 0;
|
|
-
|
|
- // Returns true if the death test passed; that is, the test process
|
|
- // exited during the test, its exit status matches a user-supplied
|
|
- // predicate, and its stderr output matches a user-supplied regular
|
|
- // expression.
|
|
- // The user-supplied predicate may be a macro expression rather
|
|
- // than a function pointer or functor, or else Wait and Passed could
|
|
- // be combined.
|
|
- virtual bool Passed(bool exit_status_ok) = 0;
|
|
-
|
|
- // Signals that the death test did not die as expected.
|
|
- virtual void Abort(AbortReason reason) = 0;
|
|
-
|
|
- // Returns a human-readable outcome message regarding the outcome of
|
|
- // the last death test.
|
|
- static const char* LastMessage();
|
|
-
|
|
- static void set_last_death_test_message(const std::string& message);
|
|
-
|
|
- private:
|
|
- // A string containing a description of the outcome of the last death test.
|
|
- static std::string last_death_test_message_;
|
|
-
|
|
- DeathTest(const DeathTest&) = delete;
|
|
- DeathTest& operator=(const DeathTest&) = delete;
|
|
-};
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-// Factory interface for death tests. May be mocked out for testing.
|
|
-class DeathTestFactory {
|
|
- public:
|
|
- virtual ~DeathTestFactory() {}
|
|
- virtual bool Create(const char* statement,
|
|
- Matcher<const std::string&> matcher, const char* file,
|
|
- int line, DeathTest** test) = 0;
|
|
-};
|
|
-
|
|
-// A concrete DeathTestFactory implementation for normal use.
|
|
-class DefaultDeathTestFactory : public DeathTestFactory {
|
|
- public:
|
|
- bool Create(const char* statement, Matcher<const std::string&> matcher,
|
|
- const char* file, int line, DeathTest** test) override;
|
|
-};
|
|
-
|
|
-// Returns true if exit_status describes a process that was terminated
|
|
-// by a signal, or exited normally with a nonzero exit code.
|
|
-GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
|
-
|
|
-// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
|
|
-// and interpreted as a regex (rather than an Eq matcher) for legacy
|
|
-// compatibility.
|
|
-inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|
- ::testing::internal::RE regex) {
|
|
- return ContainsRegex(regex.pattern());
|
|
-}
|
|
-inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
|
|
- return ContainsRegex(regex);
|
|
-}
|
|
-inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|
- const ::std::string& regex) {
|
|
- return ContainsRegex(regex);
|
|
-}
|
|
-
|
|
-// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
|
|
-// used directly.
|
|
-inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
|
- Matcher<const ::std::string&> matcher) {
|
|
- return matcher;
|
|
-}
|
|
-
|
|
-// Traps C++ exceptions escaping statement and reports them as test
|
|
-// failures. Note that trapping SEH exceptions is not implemented here.
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
-#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
|
- try { \
|
|
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
|
- } catch (const ::std::exception& gtest_exception) { \
|
|
- fprintf( \
|
|
- stderr, \
|
|
- "\n%s: Caught std::exception-derived exception escaping the " \
|
|
- "death test statement. Exception message: %s\n", \
|
|
- ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
|
|
- gtest_exception.what()); \
|
|
- fflush(stderr); \
|
|
- death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
|
- } catch (...) { \
|
|
- death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
|
- }
|
|
-
|
|
-#else
|
|
-#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
|
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
|
-
|
|
-#endif
|
|
-
|
|
-// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
|
-// ASSERT_EXIT*, and EXPECT_EXIT*.
|
|
-#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- ::testing::internal::DeathTest* gtest_dt; \
|
|
- if (!::testing::internal::DeathTest::Create( \
|
|
- #statement, \
|
|
- ::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \
|
|
- __FILE__, __LINE__, >est_dt)) { \
|
|
- goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
|
- } \
|
|
- if (gtest_dt != nullptr) { \
|
|
- std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
|
|
- switch (gtest_dt->AssumeRole()) { \
|
|
- case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
|
- if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
|
- goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
|
- } \
|
|
- break; \
|
|
- case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
|
- ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
|
|
- gtest_dt); \
|
|
- GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
|
- gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
|
- break; \
|
|
- } \
|
|
- } \
|
|
- } \
|
|
- } else \
|
|
- GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
|
|
- : fail(::testing::internal::DeathTest::LastMessage())
|
|
-// The symbol "fail" here expands to something into which a message
|
|
-// can be streamed.
|
|
-
|
|
-// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
|
|
-// NDEBUG mode. In this case we need the statements to be executed and the macro
|
|
-// must accept a streamed message even though the message is never printed.
|
|
-// The regex object is not evaluated, but it is used to prevent "unused"
|
|
-// warnings and to avoid an expression that doesn't compile in debug mode.
|
|
-#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
|
- } else if (!::testing::internal::AlwaysTrue()) { \
|
|
- ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
|
- } else \
|
|
- ::testing::Message()
|
|
-
|
|
-// A class representing the parsed contents of the
|
|
-// --gtest_internal_run_death_test flag, as it existed when
|
|
-// RUN_ALL_TESTS was called.
|
|
-class InternalRunDeathTestFlag {
|
|
- public:
|
|
- InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
|
|
- int a_write_fd)
|
|
- : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}
|
|
-
|
|
- ~InternalRunDeathTestFlag() {
|
|
- if (write_fd_ >= 0) posix::Close(write_fd_);
|
|
- }
|
|
-
|
|
- const std::string& file() const { return file_; }
|
|
- int line() const { return line_; }
|
|
- int index() const { return index_; }
|
|
- int write_fd() const { return write_fd_; }
|
|
-
|
|
- private:
|
|
- std::string file_;
|
|
- int line_;
|
|
- int index_;
|
|
- int write_fd_;
|
|
-
|
|
- InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete;
|
|
- InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete;
|
|
-};
|
|
-
|
|
-// Returns a newly created InternalRunDeathTestFlag object with fields
|
|
-// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
|
-// the flag is specified; otherwise returns NULL.
|
|
-InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
|
-
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-filepath.h b/vendor/gtest/include/gtest/internal/gtest-filepath.h
|
|
deleted file mode 100644
|
|
index a2a60a962..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-filepath.h
|
|
+++ /dev/null
|
|
@@ -1,210 +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.
|
|
-
|
|
-// Google Test filepath utilities
|
|
-//
|
|
-// This header file declares classes and functions used internally by
|
|
-// Google Test. They are subject to change without notice.
|
|
-//
|
|
-// This file is #included in gtest/internal/gtest-internal.h.
|
|
-// Do not include this header file separately!
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
|
-
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-// FilePath - a class for file and directory pathname manipulation which
|
|
-// handles platform-specific conventions (like the pathname separator).
|
|
-// Used for helper functions for naming files in a directory for xml output.
|
|
-// Except for Set methods, all methods are const or static, which provides an
|
|
-// "immutable value object" -- useful for peace of mind.
|
|
-// A FilePath with a value ending in a path separator ("like/this/") represents
|
|
-// a directory, otherwise it is assumed to represent a file. In either case,
|
|
-// it may or may not represent an actual file or directory in the file system.
|
|
-// Names are NOT checked for syntax correctness -- no checking for illegal
|
|
-// characters, malformed paths, etc.
|
|
-
|
|
-class GTEST_API_ FilePath {
|
|
- public:
|
|
- FilePath() : pathname_("") {}
|
|
- FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
|
-
|
|
- explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
|
- Normalize();
|
|
- }
|
|
-
|
|
- FilePath& operator=(const FilePath& rhs) {
|
|
- Set(rhs);
|
|
- return *this;
|
|
- }
|
|
-
|
|
- void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
|
-
|
|
- const std::string& string() const { return pathname_; }
|
|
- const char* c_str() const { return pathname_.c_str(); }
|
|
-
|
|
- // Returns the current working directory, or "" if unsuccessful.
|
|
- static FilePath GetCurrentDir();
|
|
-
|
|
- // Given directory = "dir", base_name = "test", number = 0,
|
|
- // extension = "xml", returns "dir/test.xml". If number is greater
|
|
- // than zero (e.g., 12), returns "dir/test_12.xml".
|
|
- // On Windows platform, uses \ as the separator rather than /.
|
|
- static FilePath MakeFileName(const FilePath& directory,
|
|
- const FilePath& base_name, int number,
|
|
- const char* extension);
|
|
-
|
|
- // Given directory = "dir", relative_path = "test.xml",
|
|
- // returns "dir/test.xml".
|
|
- // On Windows, uses \ as the separator rather than /.
|
|
- static FilePath ConcatPaths(const FilePath& directory,
|
|
- const FilePath& relative_path);
|
|
-
|
|
- // Returns a pathname for a file that does not currently exist. The pathname
|
|
- // will be directory/base_name.extension or
|
|
- // directory/base_name_<number>.extension if directory/base_name.extension
|
|
- // already exists. The number will be incremented until a pathname is found
|
|
- // that does not already exist.
|
|
- // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
|
- // There could be a race condition if two or more processes are calling this
|
|
- // function at the same time -- they could both pick the same filename.
|
|
- static FilePath GenerateUniqueFileName(const FilePath& directory,
|
|
- const FilePath& base_name,
|
|
- const char* extension);
|
|
-
|
|
- // 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
|
|
- // the name, otherwise return the name string unmodified.
|
|
- // On Windows platform, uses \ as the separator, other platforms use /.
|
|
- FilePath RemoveTrailingPathSeparator() const;
|
|
-
|
|
- // Returns a copy of the FilePath with the directory part removed.
|
|
- // Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
|
- // FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
|
- // the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
|
- // returns an empty FilePath ("").
|
|
- // On Windows platform, '\' is the path separator, otherwise it is '/'.
|
|
- FilePath RemoveDirectoryName() const;
|
|
-
|
|
- // RemoveFileName returns the directory path with the filename removed.
|
|
- // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
|
- // If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
|
- // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
|
- // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
|
- // On Windows platform, '\' is the path separator, otherwise it is '/'.
|
|
- FilePath RemoveFileName() const;
|
|
-
|
|
- // Returns a copy of the FilePath with the case-insensitive extension removed.
|
|
- // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
|
- // FilePath("dir/file"). If a case-insensitive extension is not
|
|
- // found, returns a copy of the original FilePath.
|
|
- FilePath RemoveExtension(const char* extension) const;
|
|
-
|
|
- // Creates directories so that path exists. Returns true if successful or if
|
|
- // the directories already exist; returns false if unable to create
|
|
- // directories for any reason. Will also return false if the FilePath does
|
|
- // not represent a directory (that is, it doesn't end with a path separator).
|
|
- bool CreateDirectoriesRecursively() const;
|
|
-
|
|
- // Create the directory so that path exists. Returns true if successful or
|
|
- // if the directory already exists; returns false if unable to create the
|
|
- // directory for any reason, including if the parent directory does not
|
|
- // exist. Not named "CreateDirectory" because that's a macro on Windows.
|
|
- bool CreateFolder() const;
|
|
-
|
|
- // Returns true if FilePath describes something in the file-system,
|
|
- // either a file, directory, or whatever, and that something exists.
|
|
- bool FileOrDirectoryExists() const;
|
|
-
|
|
- // Returns true if pathname describes a directory in the file-system
|
|
- // that exists.
|
|
- bool DirectoryExists() const;
|
|
-
|
|
- // Returns true if FilePath ends with a path separator, which indicates that
|
|
- // it is intended to represent a directory. Returns false otherwise.
|
|
- // This does NOT check that a directory (or file) actually exists.
|
|
- bool IsDirectory() const;
|
|
-
|
|
- // Returns true if pathname describes a root directory. (Windows has one
|
|
- // root directory per disk drive.)
|
|
- bool IsRootDirectory() const;
|
|
-
|
|
- // Returns true if pathname describes an absolute path.
|
|
- bool IsAbsolutePath() const;
|
|
-
|
|
- private:
|
|
- // Replaces multiple consecutive separators with a single separator.
|
|
- // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
|
- // redundancies that might be in a pathname involving "." or "..".
|
|
- //
|
|
- // A pathname with multiple consecutive separators may occur either through
|
|
- // user error or as a result of some scripts or APIs that generate a pathname
|
|
- // with a trailing separator. On other platforms the same API or script
|
|
- // may NOT generate a pathname with a trailing "/". Then elsewhere that
|
|
- // pathname may have another "/" and pathname components added to it,
|
|
- // without checking for the separator already being there.
|
|
- // The script language and operating system may allow paths like "foo//bar"
|
|
- // but some of the functions in FilePath will not handle that correctly. In
|
|
- // particular, RemoveTrailingPathSeparator() only removes one separator, and
|
|
- // it is called in CreateDirectoriesRecursively() assuming that it will change
|
|
- // a pathname from directory syntax (trailing separator) to filename syntax.
|
|
- //
|
|
- // On Windows this method also replaces the alternate path separator '/' with
|
|
- // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
|
|
- // "bar\\foo".
|
|
-
|
|
- void Normalize();
|
|
-
|
|
- // 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;
|
|
-
|
|
- std::string pathname_;
|
|
-}; // class FilePath
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-internal.h b/vendor/gtest/include/gtest/internal/gtest-internal.h
|
|
deleted file mode 100644
|
|
index 9b04e4c85..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-internal.h
|
|
+++ /dev/null
|
|
@@ -1,1570 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file declares functions and macros used internally by
|
|
-// Google Test. They are subject to change without notice.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
|
-
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-#if GTEST_OS_LINUX
|
|
-#include <stdlib.h>
|
|
-#include <sys/types.h>
|
|
-#include <sys/wait.h>
|
|
-#include <unistd.h>
|
|
-#endif // GTEST_OS_LINUX
|
|
-
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
-#include <stdexcept>
|
|
-#endif
|
|
-
|
|
-#include <ctype.h>
|
|
-#include <float.h>
|
|
-#include <string.h>
|
|
-
|
|
-#include <cstdint>
|
|
-#include <iomanip>
|
|
-#include <limits>
|
|
-#include <map>
|
|
-#include <set>
|
|
-#include <string>
|
|
-#include <type_traits>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/gtest-message.h"
|
|
-#include "gtest/internal/gtest-filepath.h"
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-#include "gtest/internal/gtest-type-util.h"
|
|
-
|
|
-// Due to C++ preprocessor weirdness, we need double indirection to
|
|
-// concatenate two tokens when one of them is __LINE__. Writing
|
|
-//
|
|
-// foo ## __LINE__
|
|
-//
|
|
-// will result in the token foo__LINE__, instead of foo followed by
|
|
-// the current line number. For more details, see
|
|
-// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
|
-#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
|
|
-#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
|
|
-
|
|
-// Stringifies its argument.
|
|
-// 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 MessageLite;
|
|
-}
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// Forward declarations.
|
|
-
|
|
-class AssertionResult; // Result of an assertion.
|
|
-class Message; // Represents a failure message.
|
|
-class Test; // Represents a test.
|
|
-class TestInfo; // Information about a test.
|
|
-class TestPartResult; // Result of a test part.
|
|
-class UnitTest; // A collection of test suites.
|
|
-
|
|
-template <typename T>
|
|
-::std::string PrintToString(const T& value);
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-struct TraceInfo; // Information about a trace point.
|
|
-class TestInfoImpl; // Opaque implementation of TestInfo
|
|
-class UnitTestImpl; // Opaque implementation of UnitTest
|
|
-
|
|
-// The text used in failure messages to indicate the start of the
|
|
-// stack trace.
|
|
-GTEST_API_ extern const char kStackTraceMarker[];
|
|
-
|
|
-// An IgnoredValue object can be implicitly constructed from ANY value.
|
|
-class IgnoredValue {
|
|
- struct Sink {};
|
|
-
|
|
- public:
|
|
- // This constructor template allows any value to be implicitly
|
|
- // converted to IgnoredValue. The object has no data member and
|
|
- // doesn't try to remember anything about the argument. We
|
|
- // deliberately omit the 'explicit' keyword in order to allow the
|
|
- // conversion to be implicit.
|
|
- // Disable the conversion if T already has a magical conversion operator.
|
|
- // Otherwise we get ambiguity.
|
|
- template <typename T,
|
|
- typename std::enable_if<!std::is_convertible<T, Sink>::value,
|
|
- int>::type = 0>
|
|
- IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
|
-};
|
|
-
|
|
-// Appends the user-supplied message to the Google-Test-generated message.
|
|
-GTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg,
|
|
- const Message& user_msg);
|
|
-
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
|
- 4275 /* an exported class was derived from a class that was not exported */)
|
|
-
|
|
-// This exception is thrown by (and only by) a failed Google Test
|
|
-// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions
|
|
-// are enabled). We derive it from std::runtime_error, which is for
|
|
-// errors presumably detectable only at run time. Since
|
|
-// std::runtime_error inherits from std::exception, many testing
|
|
-// frameworks know how to extract and print the message inside it.
|
|
-class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
|
|
- public:
|
|
- explicit GoogleTestFailureException(const TestPartResult& failure);
|
|
-};
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4275
|
|
-
|
|
-#endif // GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-namespace edit_distance {
|
|
-// Returns the optimal edits to go from 'left' to 'right'.
|
|
-// All edits cost the same, with replace having lower priority than
|
|
-// add/remove.
|
|
-// Simple implementation of the Wagner-Fischer algorithm.
|
|
-// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
|
|
-enum EditType { kMatch, kAdd, kRemove, kReplace };
|
|
-GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
|
- const std::vector<size_t>& left, const std::vector<size_t>& right);
|
|
-
|
|
-// Same as above, but the input is represented as strings.
|
|
-GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
|
|
- const std::vector<std::string>& left,
|
|
- const std::vector<std::string>& right);
|
|
-
|
|
-// Create a diff of the input strings in Unified diff format.
|
|
-GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,
|
|
- const std::vector<std::string>& right,
|
|
- size_t context = 2);
|
|
-
|
|
-} // namespace edit_distance
|
|
-
|
|
-// Constructs and returns the message for an equality assertion
|
|
-// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
|
|
-//
|
|
-// The first four parameters are the expressions used in the assertion
|
|
-// and their values, as strings. For example, for ASSERT_EQ(foo, bar)
|
|
-// where foo is 5 and bar is 6, we have:
|
|
-//
|
|
-// expected_expression: "foo"
|
|
-// actual_expression: "bar"
|
|
-// expected_value: "5"
|
|
-// actual_value: "6"
|
|
-//
|
|
-// 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,
|
|
- const char* actual_expression,
|
|
- const std::string& expected_value,
|
|
- const std::string& actual_value,
|
|
- bool ignoring_case);
|
|
-
|
|
-// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
|
|
-GTEST_API_ std::string GetBoolAssertionFailureMessage(
|
|
- const AssertionResult& assertion_result, const char* expression_text,
|
|
- const char* actual_predicate_value, const char* expected_predicate_value);
|
|
-
|
|
-// This template class represents an IEEE floating-point number
|
|
-// (either single-precision or double-precision, depending on the
|
|
-// template parameters).
|
|
-//
|
|
-// The purpose of this class is to do more sophisticated number
|
|
-// comparison. (Due to round-off error, etc, it's very unlikely that
|
|
-// two floating-points will be equal exactly. Hence a naive
|
|
-// comparison by the == operation often doesn't work.)
|
|
-//
|
|
-// Format of IEEE floating-point:
|
|
-//
|
|
-// The most-significant bit being the leftmost, an IEEE
|
|
-// floating-point looks like
|
|
-//
|
|
-// sign_bit exponent_bits fraction_bits
|
|
-//
|
|
-// Here, sign_bit is a single bit that designates the sign of the
|
|
-// number.
|
|
-//
|
|
-// For float, there are 8 exponent bits and 23 fraction bits.
|
|
-//
|
|
-// For double, there are 11 exponent bits and 52 fraction bits.
|
|
-//
|
|
-// More details can be found at
|
|
-// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
|
|
-//
|
|
-// Template parameter:
|
|
-//
|
|
-// RawType: the raw floating-point type (either float or double)
|
|
-template <typename RawType>
|
|
-class FloatingPoint {
|
|
- public:
|
|
- // Defines the unsigned integer type that has the same size as the
|
|
- // floating point number.
|
|
- typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
|
|
-
|
|
- // Constants.
|
|
-
|
|
- // # of bits in a number.
|
|
- static const size_t kBitCount = 8 * sizeof(RawType);
|
|
-
|
|
- // # of fraction bits in a number.
|
|
- static const size_t kFractionBitCount =
|
|
- std::numeric_limits<RawType>::digits - 1;
|
|
-
|
|
- // # of exponent bits in a number.
|
|
- static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
|
|
-
|
|
- // The mask for the sign bit.
|
|
- static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
|
|
-
|
|
- // The mask for the fraction bits.
|
|
- static const Bits kFractionBitMask = ~static_cast<Bits>(0) >>
|
|
- (kExponentBitCount + 1);
|
|
-
|
|
- // The mask for the exponent bits.
|
|
- static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
|
|
-
|
|
- // How many ULP's (Units in the Last Place) we want to tolerate when
|
|
- // comparing two numbers. The larger the value, the more error we
|
|
- // allow. A 0 value means that two numbers must be exactly the same
|
|
- // to be considered equal.
|
|
- //
|
|
- // The maximum error of a single floating-point operation is 0.5
|
|
- // units in the last place. On Intel CPU's, all floating-point
|
|
- // calculations are done with 80-bit precision, while double has 64
|
|
- // bits. Therefore, 4 should be enough for ordinary use.
|
|
- //
|
|
- // See the following article for more details on ULP:
|
|
- // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
|
- static const uint32_t kMaxUlps = 4;
|
|
-
|
|
- // Constructs a FloatingPoint from a raw floating-point number.
|
|
- //
|
|
- // On an Intel CPU, passing a non-normalized NAN (Not a Number)
|
|
- // around may change its bits, although the new value is guaranteed
|
|
- // to be also a NAN. Therefore, don't expect this constructor to
|
|
- // preserve the bits in x when x is a NAN.
|
|
- explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
|
|
-
|
|
- // Static methods
|
|
-
|
|
- // Reinterprets a bit pattern as a floating-point number.
|
|
- //
|
|
- // This function is needed to test the AlmostEquals() method.
|
|
- static RawType ReinterpretBits(const Bits bits) {
|
|
- FloatingPoint fp(0);
|
|
- fp.u_.bits_ = bits;
|
|
- return fp.u_.value_;
|
|
- }
|
|
-
|
|
- // Returns the floating-point number that represent positive infinity.
|
|
- static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }
|
|
-
|
|
- // Returns the maximum representable finite floating-point number.
|
|
- static RawType Max();
|
|
-
|
|
- // Non-static methods
|
|
-
|
|
- // Returns the bits that represents this number.
|
|
- const Bits& bits() const { return u_.bits_; }
|
|
-
|
|
- // Returns the exponent bits of this number.
|
|
- Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
|
|
-
|
|
- // Returns the fraction bits of this number.
|
|
- Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
|
|
-
|
|
- // Returns the sign bit of this number.
|
|
- Bits sign_bit() const { return kSignBitMask & u_.bits_; }
|
|
-
|
|
- // 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 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.
|
|
- // - thinks +0.0 and -0.0 are 0 DLP's apart.
|
|
- bool AlmostEquals(const FloatingPoint& rhs) const {
|
|
- // The IEEE standard says that any comparison operation involving
|
|
- // a NAN must return false.
|
|
- if (is_nan() || rhs.is_nan()) return false;
|
|
-
|
|
- return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
|
|
- kMaxUlps;
|
|
- }
|
|
-
|
|
- private:
|
|
- // The data type used to store the actual floating-point number.
|
|
- union FloatingPointUnion {
|
|
- RawType value_; // The raw floating-point number.
|
|
- Bits bits_; // The bits that represent the number.
|
|
- };
|
|
-
|
|
- // Converts an integer from the sign-and-magnitude representation to
|
|
- // the biased representation. More precisely, let N be 2 to the
|
|
- // power of (kBitCount - 1), an integer x is represented by the
|
|
- // unsigned number x + N.
|
|
- //
|
|
- // For instance,
|
|
- //
|
|
- // -N + 1 (the most negative number representable using
|
|
- // sign-and-magnitude) is represented by 1;
|
|
- // 0 is represented by N; and
|
|
- // N - 1 (the biggest number representable using
|
|
- // sign-and-magnitude) is represented by 2N - 1.
|
|
- //
|
|
- // Read http://en.wikipedia.org/wiki/Signed_number_representations
|
|
- // for more details on signed number representations.
|
|
- static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
|
- if (kSignBitMask & sam) {
|
|
- // sam represents a negative number.
|
|
- return ~sam + 1;
|
|
- } else {
|
|
- // sam represents a positive number.
|
|
- return kSignBitMask | sam;
|
|
- }
|
|
- }
|
|
-
|
|
- // Given two numbers in the sign-and-magnitude representation,
|
|
- // returns the distance between them as an unsigned number.
|
|
- static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
|
|
- const Bits& sam2) {
|
|
- const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
|
- const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
|
- return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
|
- }
|
|
-
|
|
- FloatingPointUnion u_;
|
|
-};
|
|
-
|
|
-// We cannot use std::numeric_limits<T>::max() as it clashes with the max()
|
|
-// macro defined by <windows.h>.
|
|
-template <>
|
|
-inline float FloatingPoint<float>::Max() {
|
|
- return FLT_MAX;
|
|
-}
|
|
-template <>
|
|
-inline double FloatingPoint<double>::Max() {
|
|
- return DBL_MAX;
|
|
-}
|
|
-
|
|
-// Typedefs the instances of the FloatingPoint template class that we
|
|
-// care to use.
|
|
-typedef FloatingPoint<float> Float;
|
|
-typedef FloatingPoint<double> Double;
|
|
-
|
|
-// In order to catch the mistake of putting tests that use different
|
|
-// test fixture classes in the same test suite, we need to assign
|
|
-// unique IDs to fixture classes and compare them. The TypeId type is
|
|
-// used to hold such IDs. The user should treat TypeId as an opaque
|
|
-// type: the only operation allowed on TypeId values is to compare
|
|
-// them for equality using the == operator.
|
|
-typedef const void* TypeId;
|
|
-
|
|
-template <typename T>
|
|
-class TypeIdHelper {
|
|
- public:
|
|
- // dummy_ must not have a const type. Otherwise an overly eager
|
|
- // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
|
|
- // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
|
|
- static bool dummy_;
|
|
-};
|
|
-
|
|
-template <typename T>
|
|
-bool TypeIdHelper<T>::dummy_ = false;
|
|
-
|
|
-// GetTypeId<T>() returns the ID of type T. Different values will be
|
|
-// returned for different types. Calling the function twice with the
|
|
-// same type argument is guaranteed to return the same ID.
|
|
-template <typename T>
|
|
-TypeId GetTypeId() {
|
|
- // The compiler is required to allocate a different
|
|
- // TypeIdHelper<T>::dummy_ variable for each T used to instantiate
|
|
- // the template. Therefore, the address of dummy_ is guaranteed to
|
|
- // be unique.
|
|
- return &(TypeIdHelper<T>::dummy_);
|
|
-}
|
|
-
|
|
-// Returns the type ID of ::testing::Test. Always call this instead
|
|
-// of GetTypeId< ::testing::Test>() to get the type ID of
|
|
-// ::testing::Test, as the latter may give the wrong result due to a
|
|
-// suspected linker bug when compiling Google Test as a Mac OS X
|
|
-// framework.
|
|
-GTEST_API_ TypeId GetTestTypeId();
|
|
-
|
|
-// Defines the abstract factory interface that creates instances
|
|
-// of a Test object.
|
|
-class TestFactoryBase {
|
|
- public:
|
|
- virtual ~TestFactoryBase() {}
|
|
-
|
|
- // Creates a test instance to run. The instance is both created and destroyed
|
|
- // within TestInfoImpl::Run()
|
|
- virtual Test* CreateTest() = 0;
|
|
-
|
|
- protected:
|
|
- TestFactoryBase() {}
|
|
-
|
|
- private:
|
|
- TestFactoryBase(const TestFactoryBase&) = delete;
|
|
- TestFactoryBase& operator=(const TestFactoryBase&) = delete;
|
|
-};
|
|
-
|
|
-// This class provides implementation of TeastFactoryBase interface.
|
|
-// It is used in TEST and TEST_F macros.
|
|
-template <class TestClass>
|
|
-class TestFactoryImpl : public TestFactoryBase {
|
|
- public:
|
|
- Test* CreateTest() override { return new TestClass; }
|
|
-};
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-
|
|
-// Predicate-formatters for implementing the HRESULT checking macros
|
|
-// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
|
|
-// We pass a long instead of HRESULT to avoid causing an
|
|
-// include dependency for the HRESULT type.
|
|
-GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
|
|
- long hr); // NOLINT
|
|
-GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
|
|
- long hr); // NOLINT
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-// Types of SetUpTestSuite() and TearDownTestSuite() functions.
|
|
-using SetUpTestSuiteFunc = void (*)();
|
|
-using TearDownTestSuiteFunc = void (*)();
|
|
-
|
|
-struct CodeLocation {
|
|
- CodeLocation(const std::string& a_file, int a_line)
|
|
- : file(a_file), line(a_line) {}
|
|
-
|
|
- std::string file;
|
|
- int line;
|
|
-};
|
|
-
|
|
-// Helper to identify which setup function for TestCase / TestSuite to call.
|
|
-// Only one function is allowed, either TestCase or TestSute but not both.
|
|
-
|
|
-// Utility functions to help SuiteApiResolver
|
|
-using SetUpTearDownSuiteFuncType = void (*)();
|
|
-
|
|
-inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
|
|
- SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {
|
|
- return a == def ? nullptr : a;
|
|
-}
|
|
-
|
|
-template <typename T>
|
|
-// Note that SuiteApiResolver inherits from T because
|
|
-// SetUpTestSuite()/TearDownTestSuite() could be protected. This way
|
|
-// SuiteApiResolver can access them.
|
|
-struct SuiteApiResolver : T {
|
|
- // testing::Test is only forward declared at this point. So we make it a
|
|
- // dependent class for the compiler to be OK with it.
|
|
- using Test =
|
|
- typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
|
|
-
|
|
- 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 =
|
|
- GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);
|
|
-
|
|
- GTEST_CHECK_(!test_case_fp || !test_suite_fp)
|
|
- << "Test can not provide both SetUpTestSuite and SetUpTestCase, please "
|
|
- "make sure there is only one present at "
|
|
- << 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 =
|
|
- GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);
|
|
-
|
|
- GTEST_CHECK_(!test_case_fp || !test_suite_fp)
|
|
- << "Test can not provide both TearDownTestSuite and TearDownTestCase,"
|
|
- " please make sure there is only one present at"
|
|
- << filename << ":" << line_num;
|
|
-
|
|
- return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
|
|
-#else
|
|
- (void)(filename);
|
|
- (void)(line_num);
|
|
- return &T::TearDownTestSuite;
|
|
-#endif
|
|
- }
|
|
-};
|
|
-
|
|
-// Creates a new TestInfo object and registers it with Google Test;
|
|
-// returns the created object.
|
|
-//
|
|
-// Arguments:
|
|
-//
|
|
-// 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
|
|
-// this is not a typed or a type-parameterized test.
|
|
-// 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
|
|
-// 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
|
|
-// factory: pointer to the factory that creates a test object.
|
|
-// The newly created TestInfo instance will assume
|
|
-// ownership of the factory object.
|
|
-GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
|
- const char* test_suite_name, const char* name, const char* type_param,
|
|
- const char* value_param, CodeLocation code_location,
|
|
- TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
|
- TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
|
-
|
|
-// If *pstr starts with the given prefix, modifies *pstr to be right
|
|
-// past the prefix and returns true; otherwise leaves *pstr unchanged
|
|
-// and returns false. None of pstr, *pstr, and prefix can be NULL.
|
|
-GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-// State of the definition of a type-parameterized test suite.
|
|
-class GTEST_API_ TypedTestSuitePState {
|
|
- public:
|
|
- TypedTestSuitePState() : registered_(false) {}
|
|
-
|
|
- // Adds the given test name to defined_test_names_ and return true
|
|
- // if the test suite hasn't been registered; otherwise aborts the
|
|
- // program.
|
|
- bool AddTestName(const char* file, int line, const char* case_name,
|
|
- const char* test_name) {
|
|
- if (registered_) {
|
|
- fprintf(stderr,
|
|
- "%s Test %s must be defined before "
|
|
- "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n",
|
|
- FormatFileLocation(file, line).c_str(), test_name, case_name);
|
|
- fflush(stderr);
|
|
- posix::Abort();
|
|
- }
|
|
- registered_tests_.insert(
|
|
- ::std::make_pair(test_name, CodeLocation(file, line)));
|
|
- return true;
|
|
- }
|
|
-
|
|
- bool TestExists(const std::string& test_name) const {
|
|
- return registered_tests_.count(test_name) > 0;
|
|
- }
|
|
-
|
|
- const CodeLocation& GetCodeLocation(const std::string& test_name) const {
|
|
- RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);
|
|
- GTEST_CHECK_(it != registered_tests_.end());
|
|
- return it->second;
|
|
- }
|
|
-
|
|
- // Verifies that registered_tests match the test names in
|
|
- // defined_test_names_; returns registered_tests if successful, or
|
|
- // aborts the program otherwise.
|
|
- 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;
|
|
-
|
|
- bool registered_;
|
|
- RegisteredTestsMap registered_tests_;
|
|
-};
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-using TypedTestCasePState = TypedTestSuitePState;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-// Skips to the first non-space char after the first comma in 'str';
|
|
-// returns NULL if no comma is found in 'str'.
|
|
-inline const char* SkipComma(const char* str) {
|
|
- const char* comma = strchr(str, ',');
|
|
- if (comma == nullptr) {
|
|
- return nullptr;
|
|
- }
|
|
- while (IsSpace(*(++comma))) {
|
|
- }
|
|
- return comma;
|
|
-}
|
|
-
|
|
-// Returns the prefix of 'str' before the first comma in it; returns
|
|
-// the entire string if it contains no comma.
|
|
-inline std::string GetPrefixUntilComma(const char* str) {
|
|
- const char* comma = strchr(str, ',');
|
|
- return comma == nullptr ? str : std::string(str, comma);
|
|
-}
|
|
-
|
|
-// Splits a given string on a given delimiter, populating a given
|
|
-// vector with the fields.
|
|
-void SplitString(const ::std::string& str, char delimiter,
|
|
- ::std::vector<::std::string>* dest);
|
|
-
|
|
-// The default argument to the template below for the case when the user does
|
|
-// not provide a name generator.
|
|
-struct DefaultNameGenerator {
|
|
- template <typename T>
|
|
- static std::string GetName(int i) {
|
|
- return StreamableToString(i);
|
|
- }
|
|
-};
|
|
-
|
|
-template <typename Provided = DefaultNameGenerator>
|
|
-struct NameGeneratorSelector {
|
|
- typedef Provided type;
|
|
-};
|
|
-
|
|
-template <typename NameGenerator>
|
|
-void GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}
|
|
-
|
|
-template <typename NameGenerator, typename Types>
|
|
-void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
|
|
- result->push_back(NameGenerator::template GetName<typename Types::Head>(i));
|
|
- GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,
|
|
- i + 1);
|
|
-}
|
|
-
|
|
-template <typename NameGenerator, typename Types>
|
|
-std::vector<std::string> GenerateNames() {
|
|
- std::vector<std::string> result;
|
|
- GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);
|
|
- return result;
|
|
-}
|
|
-
|
|
-// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
|
|
-// registers a list of type-parameterized tests with Google Test. The
|
|
-// return value is insignificant - we just need to return something
|
|
-// such that we can call this function in a namespace scope.
|
|
-//
|
|
-// Implementation note: The GTEST_TEMPLATE_ macro declares a template
|
|
-// template parameter. It's defined in gtest-type-util.h.
|
|
-template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
|
|
-class TypeParameterizedTest {
|
|
- public:
|
|
- // 'index' is the index of the test in the type list 'Types'
|
|
- // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
|
- // Types). Valid values for 'index' are [0, N - 1] where N is the
|
|
- // length of Types.
|
|
- static bool Register(const char* prefix, const CodeLocation& code_location,
|
|
- const char* case_name, const char* test_names, int index,
|
|
- const std::vector<std::string>& type_names =
|
|
- GenerateNames<DefaultNameGenerator, Types>()) {
|
|
- typedef typename Types::Head Type;
|
|
- typedef Fixture<Type> FixtureClass;
|
|
- typedef typename GTEST_BIND_(TestSel, Type) TestClass;
|
|
-
|
|
- // First, registers the first type-parameterized test in the type
|
|
- // list.
|
|
- MakeAndRegisterTestInfo(
|
|
- (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
|
- "/" + type_names[static_cast<size_t>(index)])
|
|
- .c_str(),
|
|
- StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
|
- GetTypeName<Type>().c_str(),
|
|
- nullptr, // No value parameter.
|
|
- code_location, GetTypeId<FixtureClass>(),
|
|
- SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(
|
|
- code_location.file.c_str(), code_location.line),
|
|
- SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(
|
|
- code_location.file.c_str(), code_location.line),
|
|
- new TestFactoryImpl<TestClass>);
|
|
-
|
|
- // Next, recurses (at compile time) with the tail of the type list.
|
|
- return TypeParameterizedTest<Fixture, TestSel,
|
|
- typename Types::Tail>::Register(prefix,
|
|
- code_location,
|
|
- case_name,
|
|
- test_names,
|
|
- index + 1,
|
|
- type_names);
|
|
- }
|
|
-};
|
|
-
|
|
-// The base case for the compile time recursion.
|
|
-template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
|
-class TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
|
- public:
|
|
- static bool Register(const char* /*prefix*/, const CodeLocation&,
|
|
- const char* /*case_name*/, const char* /*test_names*/,
|
|
- int /*index*/,
|
|
- const std::vector<std::string>& =
|
|
- std::vector<std::string>() /*type_names*/) {
|
|
- return true;
|
|
- }
|
|
-};
|
|
-
|
|
-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
|
|
-// something such that we can call this function in a namespace scope.
|
|
-template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
|
|
-class TypeParameterizedTestSuite {
|
|
- public:
|
|
- static bool Register(const char* prefix, CodeLocation code_location,
|
|
- const TypedTestSuitePState* state, const char* case_name,
|
|
- 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)) {
|
|
- fprintf(stderr, "Failed to get code location for test %s.%s at %s.",
|
|
- case_name, test_name.c_str(),
|
|
- FormatFileLocation(code_location.file.c_str(), code_location.line)
|
|
- .c_str());
|
|
- fflush(stderr);
|
|
- posix::Abort();
|
|
- }
|
|
- const CodeLocation& test_location = state->GetCodeLocation(test_name);
|
|
-
|
|
- typedef typename Tests::Head Head;
|
|
-
|
|
- // First, register the first test in 'Test' for each type in 'Types'.
|
|
- TypeParameterizedTest<Fixture, Head, Types>::Register(
|
|
- prefix, test_location, case_name, test_names, 0, type_names);
|
|
-
|
|
- // Next, recurses (at compile time) with the tail of the test list.
|
|
- return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
|
- Types>::Register(prefix, code_location,
|
|
- state, case_name,
|
|
- SkipComma(test_names),
|
|
- type_names);
|
|
- }
|
|
-};
|
|
-
|
|
-// The base case for the compile time recursion.
|
|
-template <GTEST_TEMPLATE_ Fixture, typename Types>
|
|
-class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
|
|
- public:
|
|
- static bool Register(const char* /*prefix*/, const CodeLocation&,
|
|
- const TypedTestSuitePState* /*state*/,
|
|
- const char* /*case_name*/, const char* /*test_names*/,
|
|
- const std::vector<std::string>& =
|
|
- std::vector<std::string>() /*type_names*/) {
|
|
- return true;
|
|
- }
|
|
-};
|
|
-
|
|
-// Returns the current OS stack trace as an std::string.
|
|
-//
|
|
-// The maximum number of stack frames to be included is specified by
|
|
-// the gtest_stack_trace_depth flag. The skip_count parameter
|
|
-// specifies the number of top frames to be skipped, which doesn't
|
|
-// count against the number of frames to be included.
|
|
-//
|
|
-// For example, if Foo() calls Bar(), which in turn calls
|
|
-// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
|
|
-// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
|
-GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
|
|
- int skip_count);
|
|
-
|
|
-// Helpers for suppressing warnings on unreachable code or constant
|
|
-// condition.
|
|
-
|
|
-// Always returns true.
|
|
-GTEST_API_ bool AlwaysTrue();
|
|
-
|
|
-// Always returns false.
|
|
-inline bool AlwaysFalse() { return !AlwaysTrue(); }
|
|
-
|
|
-// Helper for suppressing false warning from Clang on a const char*
|
|
-// variable declared in a conditional expression always being NULL in
|
|
-// the else branch.
|
|
-struct GTEST_API_ ConstCharPtr {
|
|
- ConstCharPtr(const char* str) : value(str) {}
|
|
- operator bool() const { return true; }
|
|
- 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
|
|
-// code). Unlike rand_r(), it's portable. An LCG isn't very random,
|
|
-// but it's good enough for our purposes.
|
|
-class GTEST_API_ Random {
|
|
- public:
|
|
- static const uint32_t kMaxRange = 1u << 31;
|
|
-
|
|
- explicit Random(uint32_t 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_t Generate(uint32_t range);
|
|
-
|
|
- private:
|
|
- uint32_t state_;
|
|
- Random(const Random&) = delete;
|
|
- Random& operator=(const Random&) = delete;
|
|
-};
|
|
-
|
|
-// Turns const U&, U&, const U, and U all into U.
|
|
-#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
|
|
- typename std::remove_const<typename std::remove_reference<T>::type>::type
|
|
-
|
|
-// 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>
|
|
-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
|
|
-// valid types and NULL can be implicitly converted to them). It will
|
|
-// be picked over the second overload as 'int' is a perfect match for
|
|
-// the type of argument 0. If C::iterator or C::const_iterator is not
|
|
-// a valid type, the first overload is not viable, and the second
|
|
-// overload will be picked. Therefore, we can determine whether C is
|
|
-// a container class by checking the type of IsContainerTest<C>(0).
|
|
-// The value of the expression is insignificant.
|
|
-//
|
|
-// In C++11 mode we check the existence of a const_iterator and that an
|
|
-// iterator is properly implemented for the container.
|
|
-//
|
|
-// For pre-C++11 that we look for both C::iterator and C::const_iterator.
|
|
-// The reason is that C++ injects the name of a class as a member of the
|
|
-// class itself (e.g. you can refer to class iterator as either
|
|
-// 'iterator' or 'iterator::iterator'). If we look for C::iterator
|
|
-// only, for example, we would mistakenly think that a class named
|
|
-// iterator is an STL container.
|
|
-//
|
|
-// Also note that the simpler approach of overloading
|
|
-// IsContainerTest(typename C::const_iterator*) and
|
|
-// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
|
|
-typedef int IsContainer;
|
|
-template <class C,
|
|
- class Iterator = decltype(::std::declval<const C&>().begin()),
|
|
- class = decltype(::std::declval<const C&>().end()),
|
|
- class = decltype(++::std::declval<Iterator&>()),
|
|
- class = decltype(*::std::declval<Iterator>()),
|
|
- class = typename C::const_iterator>
|
|
-IsContainer IsContainerTest(int /* dummy */) {
|
|
- return 0;
|
|
-}
|
|
-
|
|
-typedef char IsNotContainer;
|
|
-template <class C>
|
|
-IsNotContainer IsContainerTest(long /* dummy */) {
|
|
- return '\0';
|
|
-}
|
|
-
|
|
-// Trait to detect whether a type T is a hash table.
|
|
-// The heuristic used is that the type contains an inner type `hasher` and does
|
|
-// not contain an inner type `reverse_iterator`.
|
|
-// If the container is iterable in reverse, then order might actually matter.
|
|
-template <typename T>
|
|
-struct IsHashTable {
|
|
- private:
|
|
- template <typename U>
|
|
- static char test(typename U::hasher*, typename U::reverse_iterator*);
|
|
- template <typename U>
|
|
- static int test(typename U::hasher*, ...);
|
|
- template <typename U>
|
|
- static char test(...);
|
|
-
|
|
- public:
|
|
- static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);
|
|
-};
|
|
-
|
|
-template <typename T>
|
|
-const bool IsHashTable<T>::value;
|
|
-
|
|
-template <typename C,
|
|
- bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>
|
|
-struct IsRecursiveContainerImpl;
|
|
-
|
|
-template <typename C>
|
|
-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
|
|
-// something is a container is relying on only const_iterator in C++11 and
|
|
-// is relying on both const_iterator and iterator otherwise
|
|
-template <typename C>
|
|
-struct IsRecursiveContainerImpl<C, true> {
|
|
- using value_type = decltype(*std::declval<typename C::const_iterator>());
|
|
- using type =
|
|
- 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
|
|
-// evaluates whether C is a recursive container type. A recursive container
|
|
-// type is a container type whose value_type is equal to the container type
|
|
-// itself. An example for a recursive container type is
|
|
-// boost::filesystem::path, whose iterator has a value_type that is equal to
|
|
-// boost::filesystem::path.
|
|
-template <typename C>
|
|
-struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
|
|
-
|
|
-// Utilities for native arrays.
|
|
-
|
|
-// ArrayEq() compares two k-dimensional native arrays using the
|
|
-// elements' operator==, where k can be any integer >= 0. When k is
|
|
-// 0, ArrayEq() degenerates into comparing a single pair of values.
|
|
-
|
|
-template <typename T, typename U>
|
|
-bool ArrayEq(const T* lhs, size_t size, const U* rhs);
|
|
-
|
|
-// This generic version is used when k is 0.
|
|
-template <typename T, typename U>
|
|
-inline bool ArrayEq(const T& lhs, const U& rhs) {
|
|
- return lhs == rhs;
|
|
-}
|
|
-
|
|
-// This overload is used when k >= 1.
|
|
-template <typename T, typename U, size_t N>
|
|
-inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {
|
|
- return internal::ArrayEq(lhs, N, rhs);
|
|
-}
|
|
-
|
|
-// This helper reduces code bloat. If we instead put its logic inside
|
|
-// the previous ArrayEq() function, arrays with different sizes would
|
|
-// lead to different copies of the template code.
|
|
-template <typename T, typename U>
|
|
-bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
|
|
- for (size_t i = 0; i != size; i++) {
|
|
- if (!internal::ArrayEq(lhs[i], rhs[i])) return false;
|
|
- }
|
|
- return true;
|
|
-}
|
|
-
|
|
-// Finds the first element in the iterator range [begin, end) that
|
|
-// equals elem. Element may be a native array type itself.
|
|
-template <typename Iter, typename Element>
|
|
-Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {
|
|
- for (Iter it = begin; it != end; ++it) {
|
|
- if (internal::ArrayEq(*it, elem)) return it;
|
|
- }
|
|
- return end;
|
|
-}
|
|
-
|
|
-// CopyArray() copies a k-dimensional native array using the elements'
|
|
-// operator=, where k can be any integer >= 0. When k is 0,
|
|
-// CopyArray() degenerates into copying a single value.
|
|
-
|
|
-template <typename T, typename U>
|
|
-void CopyArray(const T* from, size_t size, U* to);
|
|
-
|
|
-// This generic version is used when k is 0.
|
|
-template <typename T, typename U>
|
|
-inline void CopyArray(const T& from, U* to) {
|
|
- *to = from;
|
|
-}
|
|
-
|
|
-// This overload is used when k >= 1.
|
|
-template <typename T, typename U, size_t N>
|
|
-inline void CopyArray(const T (&from)[N], U (*to)[N]) {
|
|
- internal::CopyArray(from, N, *to);
|
|
-}
|
|
-
|
|
-// This helper reduces code bloat. If we instead put its logic inside
|
|
-// the previous CopyArray() function, arrays with different sizes
|
|
-// would lead to different copies of the template code.
|
|
-template <typename T, typename U>
|
|
-void CopyArray(const T* from, size_t size, U* to) {
|
|
- for (size_t i = 0; i != size; i++) {
|
|
- internal::CopyArray(from[i], to + i);
|
|
- }
|
|
-}
|
|
-
|
|
-// The relation between an NativeArray object (see below) and the
|
|
-// native array it represents.
|
|
-// We use 2 different structs to allow non-copyable types to be used, as long
|
|
-// as RelationToSourceReference() is passed.
|
|
-struct RelationToSourceReference {};
|
|
-struct RelationToSourceCopy {};
|
|
-
|
|
-// Adapts a native array to a read-only STL-style container. Instead
|
|
-// of the complete STL container concept, this adaptor only implements
|
|
-// members useful for Google Mock's container matchers. New members
|
|
-// should be added as needed. To simplify the implementation, we only
|
|
-// support Element being a raw type (i.e. having no top-level const or
|
|
-// reference modifier). It's the client's responsibility to satisfy
|
|
-// this requirement. Element can be an array type itself (hence
|
|
-// multi-dimensional arrays are supported).
|
|
-template <typename Element>
|
|
-class NativeArray {
|
|
- public:
|
|
- // STL-style container typedefs.
|
|
- typedef Element value_type;
|
|
- typedef Element* iterator;
|
|
- typedef const Element* const_iterator;
|
|
-
|
|
- // Constructs from a native array. References the source.
|
|
- NativeArray(const Element* array, size_t count, RelationToSourceReference) {
|
|
- InitRef(array, count);
|
|
- }
|
|
-
|
|
- // Constructs from a native array. Copies the source.
|
|
- NativeArray(const Element* array, size_t count, RelationToSourceCopy) {
|
|
- InitCopy(array, count);
|
|
- }
|
|
-
|
|
- // Copy constructor.
|
|
- NativeArray(const NativeArray& rhs) {
|
|
- (this->*rhs.clone_)(rhs.array_, rhs.size_);
|
|
- }
|
|
-
|
|
- ~NativeArray() {
|
|
- if (clone_ != &NativeArray::InitRef) delete[] array_;
|
|
- }
|
|
-
|
|
- // STL-style container methods.
|
|
- size_t size() const { return size_; }
|
|
- const_iterator begin() const { return array_; }
|
|
- const_iterator end() const { return array_ + size_; }
|
|
- bool operator==(const NativeArray& rhs) const {
|
|
- return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin());
|
|
- }
|
|
-
|
|
- private:
|
|
- 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) {
|
|
- Element* const copy = new Element[a_size];
|
|
- CopyArray(array, a_size, copy);
|
|
- array_ = copy;
|
|
- size_ = a_size;
|
|
- clone_ = &NativeArray::InitCopy;
|
|
- }
|
|
-
|
|
- // Initializes this object with a reference of the input.
|
|
- void InitRef(const Element* array, size_t a_size) {
|
|
- array_ = array;
|
|
- size_ = a_size;
|
|
- clone_ = &NativeArray::InitRef;
|
|
- }
|
|
-
|
|
- const Element* array_;
|
|
- size_t size_;
|
|
- void (NativeArray::*clone_)(const Element*, size_t);
|
|
-};
|
|
-
|
|
-// Backport of std::index_sequence.
|
|
-template <size_t... Is>
|
|
-struct IndexSequence {
|
|
- using type = IndexSequence;
|
|
-};
|
|
-
|
|
-// Double the IndexSequence, and one if plus_one is true.
|
|
-template <bool plus_one, typename T, size_t sizeofT>
|
|
-struct DoubleSequence;
|
|
-template <size_t... I, size_t sizeofT>
|
|
-struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
|
|
- using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
|
|
-};
|
|
-template <size_t... I, size_t sizeofT>
|
|
-struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
|
|
- using type = IndexSequence<I..., (sizeofT + I)...>;
|
|
-};
|
|
-
|
|
-// Backport of std::make_index_sequence.
|
|
-// It uses O(ln(N)) instantiation depth.
|
|
-template <size_t N>
|
|
-struct MakeIndexSequenceImpl
|
|
- : DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
|
|
- N / 2>::type {};
|
|
-
|
|
-template <>
|
|
-struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
|
|
-
|
|
-template <size_t N>
|
|
-using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
|
|
-
|
|
-template <typename... T>
|
|
-using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
|
|
-
|
|
-template <size_t>
|
|
-struct Ignore {
|
|
- Ignore(...); // NOLINT
|
|
-};
|
|
-
|
|
-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, typename... T>
|
|
-struct ElemFromList {
|
|
- using type =
|
|
- decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
|
|
- static_cast<T (*)()>(nullptr)...));
|
|
-};
|
|
-
|
|
-struct FlatTupleConstructTag {};
|
|
-
|
|
-template <typename... T>
|
|
-class FlatTuple;
|
|
-
|
|
-template <typename Derived, size_t I>
|
|
-struct FlatTupleElemBase;
|
|
-
|
|
-template <typename... T, size_t I>
|
|
-struct FlatTupleElemBase<FlatTuple<T...>, I> {
|
|
- using value_type = typename ElemFromList<I, T...>::type;
|
|
- FlatTupleElemBase() = default;
|
|
- template <typename Arg>
|
|
- explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)
|
|
- : value(std::forward<Arg>(t)) {}
|
|
- value_type value;
|
|
-};
|
|
-
|
|
-template <typename Derived, typename Idx>
|
|
-struct FlatTupleBase;
|
|
-
|
|
-template <size_t... Idx, typename... T>
|
|
-struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
|
- : FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
|
- using Indices = IndexSequence<Idx...>;
|
|
- FlatTupleBase() = default;
|
|
- 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 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
|
|
-// regardless of T...
|
|
-// MakeIndexSequence, on the other hand, it is recursive but with an
|
|
-// instantiation depth of O(ln(N)).
|
|
-template <typename... T>
|
|
-class FlatTuple
|
|
- : private FlatTupleBase<FlatTuple<T...>,
|
|
- typename MakeIndexSequence<sizeof...(T)>::type> {
|
|
- using Indices = typename FlatTupleBase<
|
|
- FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
|
|
-
|
|
- public:
|
|
- FlatTuple() = default;
|
|
- template <typename... Args>
|
|
- explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)
|
|
- : FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}
|
|
-
|
|
- using FlatTuple::FlatTupleBase::Apply;
|
|
- using FlatTuple::FlatTupleBase::Get;
|
|
-};
|
|
-
|
|
-// Utility functions to be called with static_assert to induce deprecation
|
|
-// warnings.
|
|
-GTEST_INTERNAL_DEPRECATED(
|
|
- "INSTANTIATE_TEST_CASE_P is deprecated, please use "
|
|
- "INSTANTIATE_TEST_SUITE_P")
|
|
-constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
|
|
-
|
|
-GTEST_INTERNAL_DEPRECATED(
|
|
- "TYPED_TEST_CASE_P is deprecated, please use "
|
|
- "TYPED_TEST_SUITE_P")
|
|
-constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
|
|
-
|
|
-GTEST_INTERNAL_DEPRECATED(
|
|
- "TYPED_TEST_CASE is deprecated, please use "
|
|
- "TYPED_TEST_SUITE")
|
|
-constexpr bool TypedTestCaseIsDeprecated() { return true; }
|
|
-
|
|
-GTEST_INTERNAL_DEPRECATED(
|
|
- "REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
|
|
- "REGISTER_TYPED_TEST_SUITE_P")
|
|
-constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
|
|
-
|
|
-GTEST_INTERNAL_DEPRECATED(
|
|
- "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
|
|
- "INSTANTIATE_TYPED_TEST_SUITE_P")
|
|
-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()
|
|
-
|
|
-#define GTEST_MESSAGE_(message, result_type) \
|
|
- GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
|
|
-
|
|
-#define GTEST_FATAL_FAILURE_(message) \
|
|
- return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
|
|
-
|
|
-#define GTEST_NONFATAL_FAILURE_(message) \
|
|
- GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
|
|
-
|
|
-#define GTEST_SUCCESS_(message) \
|
|
- GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
|
|
-
|
|
-#define GTEST_SKIP_(message) \
|
|
- return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
|
|
-
|
|
-// 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; \
|
|
- } else /* NOLINT */ \
|
|
- static_assert(true, "") // User must have a semicolon after expansion.
|
|
-
|
|
-#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::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: " + \
|
|
- gtest_msg.value) \
|
|
- .c_str())
|
|
-
|
|
-#define GTEST_TEST_ANY_THROW_(statement, fail) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- bool gtest_caught_any = false; \
|
|
- try { \
|
|
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
|
- } catch (...) { \
|
|
- gtest_caught_any = true; \
|
|
- } \
|
|
- if (!gtest_caught_any) { \
|
|
- goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
|
|
- } \
|
|
- } else \
|
|
- GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) \
|
|
- : fail("Expected: " #statement \
|
|
- " throws an exception.\n" \
|
|
- " Actual: it doesn't.")
|
|
-
|
|
-// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
|
|
-// either a boolean expression or an AssertionResult. text is a textual
|
|
-// 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_ = \
|
|
- ::testing::AssertionResult(expression)) \
|
|
- ; \
|
|
- else \
|
|
- fail(::testing::internal::GetBoolAssertionFailureMessage( \
|
|
- gtest_ar_, text, #actual, #expected) \
|
|
- .c_str())
|
|
-
|
|
-#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (::testing::internal::AlwaysTrue()) { \
|
|
- ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
|
|
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
|
- if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
|
|
- goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
|
|
- } \
|
|
- } else \
|
|
- GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \
|
|
- : fail("Expected: " #statement \
|
|
- " doesn't generate new fatal " \
|
|
- "failures in the current thread.\n" \
|
|
- " Actual: it does.")
|
|
-
|
|
-// Expands to the name of the class that implements the given test.
|
|
-#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
|
- test_suite_name##_##test_name##_Test
|
|
-
|
|
-// 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)() = default; \
|
|
- ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
|
- (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
|
|
- const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
|
- test_name) &) = delete; /* NOLINT */ \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
|
- (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
|
|
- GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
|
- test_name) &&) noexcept = delete; /* NOLINT */ \
|
|
- \
|
|
- private: \
|
|
- void TestBody() override; \
|
|
- static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
|
|
- }; \
|
|
- \
|
|
- ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
|
- test_name)::test_info_ = \
|
|
- ::testing::internal::MakeAndRegisterTestInfo( \
|
|
- #test_suite_name, #test_name, nullptr, nullptr, \
|
|
- ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
|
|
- ::testing::internal::SuiteApiResolver< \
|
|
- parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
|
|
- ::testing::internal::SuiteApiResolver< \
|
|
- parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
|
|
- new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
|
|
- test_suite_name, test_name)>); \
|
|
- void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-param-util.h b/vendor/gtest/include/gtest/internal/gtest-param-util.h
|
|
deleted file mode 100644
|
|
index e7af2f904..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-param-util.h
|
|
+++ /dev/null
|
|
@@ -1,956 +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.
|
|
-
|
|
-// Type and function utilities for implementing parameterized tests.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
|
-
|
|
-#include <ctype.h>
|
|
-
|
|
-#include <cassert>
|
|
-#include <iterator>
|
|
-#include <memory>
|
|
-#include <set>
|
|
-#include <tuple>
|
|
-#include <type_traits>
|
|
-#include <utility>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/gtest-printers.h"
|
|
-#include "gtest/gtest-test-part.h"
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-namespace testing {
|
|
-// Input to a parameterized test name generator, describing a test parameter.
|
|
-// Consists of the parameter value and the integer parameter index.
|
|
-template <class ParamType>
|
|
-struct TestParamInfo {
|
|
- TestParamInfo(const ParamType& a_param, size_t an_index)
|
|
- : param(a_param), index(an_index) {}
|
|
- ParamType param;
|
|
- size_t index;
|
|
-};
|
|
-
|
|
-// A builtin parameterized test name generator which returns the result of
|
|
-// testing::PrintToString.
|
|
-struct PrintToStringParamName {
|
|
- template <class ParamType>
|
|
- std::string operator()(const TestParamInfo<ParamType>& info) const {
|
|
- return PrintToString(info.param);
|
|
- }
|
|
-};
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-// Utility Functions
|
|
-
|
|
-// Outputs a message explaining invalid registration of different
|
|
-// fixture class for the same test suite. This may happen when
|
|
-// TEST_P macro is used to define two tests with the same name
|
|
-// but in different namespaces.
|
|
-GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
|
- CodeLocation code_location);
|
|
-
|
|
-template <typename>
|
|
-class ParamGeneratorInterface;
|
|
-template <typename>
|
|
-class ParamGenerator;
|
|
-
|
|
-// Interface for iterating over elements provided by an implementation
|
|
-// of ParamGeneratorInterface<T>.
|
|
-template <typename T>
|
|
-class ParamIteratorInterface {
|
|
- public:
|
|
- virtual ~ParamIteratorInterface() {}
|
|
- // A pointer to the base generator instance.
|
|
- // Used only for the purposes of iterator comparison
|
|
- // to make sure that two iterators belong to the same generator.
|
|
- virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
|
|
- // Advances iterator to point to the next element
|
|
- // provided by the generator. The caller is responsible
|
|
- // for not calling Advance() on an iterator equal to
|
|
- // BaseGenerator()->End().
|
|
- virtual void Advance() = 0;
|
|
- // Clones the iterator object. Used for implementing copy semantics
|
|
- // of ParamIterator<T>.
|
|
- virtual ParamIteratorInterface* Clone() const = 0;
|
|
- // Dereferences the current iterator and provides (read-only) access
|
|
- // to the pointed value. It is the caller's responsibility not to call
|
|
- // Current() on an iterator equal to BaseGenerator()->End().
|
|
- // Used for implementing ParamGenerator<T>::operator*().
|
|
- virtual const T* Current() const = 0;
|
|
- // Determines whether the given iterator and other point to the same
|
|
- // element in the sequence generated by the generator.
|
|
- // Used for implementing ParamGenerator<T>::operator==().
|
|
- virtual bool Equals(const ParamIteratorInterface& other) const = 0;
|
|
-};
|
|
-
|
|
-// Class iterating over elements provided by an implementation of
|
|
-// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
|
|
-// and implements the const forward iterator concept.
|
|
-template <typename T>
|
|
-class ParamIterator {
|
|
- public:
|
|
- typedef T value_type;
|
|
- typedef const T& reference;
|
|
- typedef ptrdiff_t difference_type;
|
|
-
|
|
- // ParamIterator assumes ownership of the impl_ pointer.
|
|
- ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
|
|
- ParamIterator& operator=(const ParamIterator& other) {
|
|
- if (this != &other) impl_.reset(other.impl_->Clone());
|
|
- return *this;
|
|
- }
|
|
-
|
|
- const T& operator*() const { return *impl_->Current(); }
|
|
- const T* operator->() const { return impl_->Current(); }
|
|
- // Prefix version of operator++.
|
|
- ParamIterator& operator++() {
|
|
- impl_->Advance();
|
|
- return *this;
|
|
- }
|
|
- // Postfix version of operator++.
|
|
- ParamIterator operator++(int /*unused*/) {
|
|
- ParamIteratorInterface<T>* clone = impl_->Clone();
|
|
- impl_->Advance();
|
|
- return ParamIterator(clone);
|
|
- }
|
|
- bool operator==(const ParamIterator& other) const {
|
|
- return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
|
|
- }
|
|
- bool operator!=(const ParamIterator& other) const {
|
|
- return !(*this == other);
|
|
- }
|
|
-
|
|
- private:
|
|
- friend class ParamGenerator<T>;
|
|
- explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
|
|
- std::unique_ptr<ParamIteratorInterface<T>> impl_;
|
|
-};
|
|
-
|
|
-// ParamGeneratorInterface<T> is the binary interface to access generators
|
|
-// defined in other translation units.
|
|
-template <typename T>
|
|
-class ParamGeneratorInterface {
|
|
- public:
|
|
- typedef T ParamType;
|
|
-
|
|
- virtual ~ParamGeneratorInterface() {}
|
|
-
|
|
- // Generator interface definition
|
|
- virtual ParamIteratorInterface<T>* Begin() const = 0;
|
|
- virtual ParamIteratorInterface<T>* End() const = 0;
|
|
-};
|
|
-
|
|
-// Wraps ParamGeneratorInterface<T> and provides general generator syntax
|
|
-// compatible with the STL Container concept.
|
|
-// This class implements copy initialization semantics and the contained
|
|
-// ParamGeneratorInterface<T> instance is shared among all copies
|
|
-// of the original object. This is possible because that instance is immutable.
|
|
-template <typename T>
|
|
-class ParamGenerator {
|
|
- public:
|
|
- typedef ParamIterator<T> iterator;
|
|
-
|
|
- explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
|
|
- ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
|
|
-
|
|
- ParamGenerator& operator=(const ParamGenerator& other) {
|
|
- impl_ = other.impl_;
|
|
- return *this;
|
|
- }
|
|
-
|
|
- iterator begin() const { return iterator(impl_->Begin()); }
|
|
- iterator end() const { return iterator(impl_->End()); }
|
|
-
|
|
- private:
|
|
- std::shared_ptr<const ParamGeneratorInterface<T>> impl_;
|
|
-};
|
|
-
|
|
-// Generates values from a range of two comparable values. Can be used to
|
|
-// generate sequences of user-defined types that implement operator+() and
|
|
-// operator<().
|
|
-// This class is used in the Range() function.
|
|
-template <typename T, typename IncrementT>
|
|
-class RangeGenerator : public ParamGeneratorInterface<T> {
|
|
- public:
|
|
- RangeGenerator(T begin, T end, IncrementT step)
|
|
- : begin_(begin),
|
|
- end_(end),
|
|
- step_(step),
|
|
- end_index_(CalculateEndIndex(begin, end, step)) {}
|
|
- ~RangeGenerator() override {}
|
|
-
|
|
- ParamIteratorInterface<T>* Begin() const override {
|
|
- return new Iterator(this, begin_, 0, step_);
|
|
- }
|
|
- ParamIteratorInterface<T>* End() const override {
|
|
- return new Iterator(this, end_, end_index_, step_);
|
|
- }
|
|
-
|
|
- private:
|
|
- class Iterator : public ParamIteratorInterface<T> {
|
|
- public:
|
|
- Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
|
|
- IncrementT step)
|
|
- : base_(base), value_(value), index_(index), step_(step) {}
|
|
- ~Iterator() override {}
|
|
-
|
|
- const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
|
- return base_;
|
|
- }
|
|
- void Advance() override {
|
|
- value_ = static_cast<T>(value_ + step_);
|
|
- index_++;
|
|
- }
|
|
- ParamIteratorInterface<T>* Clone() const override {
|
|
- return new Iterator(*this);
|
|
- }
|
|
- const T* Current() const override { return &value_; }
|
|
- bool Equals(const ParamIteratorInterface<T>& other) const override {
|
|
- // Having the same base generator guarantees that the other
|
|
- // iterator is of the same type and we can downcast.
|
|
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
|
- << "The program attempted to compare iterators "
|
|
- << "from different generators." << std::endl;
|
|
- const int other_index =
|
|
- CheckedDowncastToActualType<const Iterator>(&other)->index_;
|
|
- return index_ == other_index;
|
|
- }
|
|
-
|
|
- private:
|
|
- Iterator(const Iterator& other)
|
|
- : ParamIteratorInterface<T>(),
|
|
- base_(other.base_),
|
|
- value_(other.value_),
|
|
- index_(other.index_),
|
|
- step_(other.step_) {}
|
|
-
|
|
- // No implementation - assignment is unsupported.
|
|
- void operator=(const Iterator& other);
|
|
-
|
|
- const ParamGeneratorInterface<T>* const base_;
|
|
- T value_;
|
|
- int index_;
|
|
- const IncrementT step_;
|
|
- }; // class RangeGenerator::Iterator
|
|
-
|
|
- static int CalculateEndIndex(const T& begin, const T& end,
|
|
- const IncrementT& step) {
|
|
- int end_index = 0;
|
|
- for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;
|
|
- return end_index;
|
|
- }
|
|
-
|
|
- // No implementation - assignment is unsupported.
|
|
- void operator=(const RangeGenerator& other);
|
|
-
|
|
- const T begin_;
|
|
- const T end_;
|
|
- const IncrementT step_;
|
|
- // The index for the end() iterator. All the elements in the generated
|
|
- // sequence are indexed (0-based) to aid iterator comparison.
|
|
- const int end_index_;
|
|
-}; // class RangeGenerator
|
|
-
|
|
-// Generates values from a pair of STL-style iterators. Used in the
|
|
-// ValuesIn() function. The elements are copied from the source range
|
|
-// since the source can be located on the stack, and the generator
|
|
-// is likely to persist beyond that stack frame.
|
|
-template <typename T>
|
|
-class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|
- public:
|
|
- template <typename ForwardIterator>
|
|
- ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
|
|
- : container_(begin, end) {}
|
|
- ~ValuesInIteratorRangeGenerator() override {}
|
|
-
|
|
- ParamIteratorInterface<T>* Begin() const override {
|
|
- return new Iterator(this, container_.begin());
|
|
- }
|
|
- ParamIteratorInterface<T>* End() const override {
|
|
- return new Iterator(this, container_.end());
|
|
- }
|
|
-
|
|
- private:
|
|
- typedef typename ::std::vector<T> ContainerType;
|
|
-
|
|
- class Iterator : public ParamIteratorInterface<T> {
|
|
- public:
|
|
- Iterator(const ParamGeneratorInterface<T>* base,
|
|
- typename ContainerType::const_iterator iterator)
|
|
- : base_(base), iterator_(iterator) {}
|
|
- ~Iterator() override {}
|
|
-
|
|
- const ParamGeneratorInterface<T>* BaseGenerator() const override {
|
|
- return base_;
|
|
- }
|
|
- void Advance() override {
|
|
- ++iterator_;
|
|
- value_.reset();
|
|
- }
|
|
- ParamIteratorInterface<T>* Clone() const override {
|
|
- return new Iterator(*this);
|
|
- }
|
|
- // We need to use cached value referenced by iterator_ because *iterator_
|
|
- // can return a temporary object (and of type other then T), so just
|
|
- // having "return &*iterator_;" doesn't work.
|
|
- // value_ is updated here and not in Advance() because Advance()
|
|
- // can advance iterator_ beyond the end of the range, and we cannot
|
|
- // detect that fact. The client code, on the other hand, is
|
|
- // responsible for not calling Current() on an out-of-range iterator.
|
|
- const T* Current() const override {
|
|
- if (value_.get() == nullptr) value_.reset(new T(*iterator_));
|
|
- return value_.get();
|
|
- }
|
|
- bool Equals(const ParamIteratorInterface<T>& other) const override {
|
|
- // Having the same base generator guarantees that the other
|
|
- // iterator is of the same type and we can downcast.
|
|
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
|
- << "The program attempted to compare iterators "
|
|
- << "from different generators." << std::endl;
|
|
- return iterator_ ==
|
|
- CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
|
|
- }
|
|
-
|
|
- private:
|
|
- Iterator(const Iterator& other)
|
|
- // The explicit constructor call suppresses a false warning
|
|
- // emitted by gcc when supplied with the -Wextra option.
|
|
- : ParamIteratorInterface<T>(),
|
|
- base_(other.base_),
|
|
- iterator_(other.iterator_) {}
|
|
-
|
|
- const ParamGeneratorInterface<T>* const base_;
|
|
- typename ContainerType::const_iterator iterator_;
|
|
- // A cached value of *iterator_. We keep it here to allow access by
|
|
- // pointer in the wrapping iterator's operator->().
|
|
- // value_ needs to be mutable to be accessed in Current().
|
|
- // Use of std::unique_ptr helps manage cached value's lifetime,
|
|
- // which is bound by the lifespan of the iterator itself.
|
|
- mutable std::unique_ptr<const T> value_;
|
|
- }; // class ValuesInIteratorRangeGenerator::Iterator
|
|
-
|
|
- // No implementation - assignment is unsupported.
|
|
- void operator=(const ValuesInIteratorRangeGenerator& other);
|
|
-
|
|
- const ContainerType container_;
|
|
-}; // class ValuesInIteratorRangeGenerator
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// Default parameterized test name generator, returns a string containing the
|
|
-// integer test parameter index.
|
|
-template <class ParamType>
|
|
-std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
|
- Message name_stream;
|
|
- name_stream << info.index;
|
|
- return name_stream.GetString();
|
|
-}
|
|
-
|
|
-template <typename T = int>
|
|
-void TestNotEmpty() {
|
|
- static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
|
|
-}
|
|
-template <typename T = int>
|
|
-void TestNotEmpty(const T&) {}
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// Stores a parameter value and later creates tests parameterized with that
|
|
-// value.
|
|
-template <class TestClass>
|
|
-class ParameterizedTestFactory : public TestFactoryBase {
|
|
- public:
|
|
- typedef typename TestClass::ParamType ParamType;
|
|
- explicit ParameterizedTestFactory(ParamType parameter)
|
|
- : parameter_(parameter) {}
|
|
- Test* CreateTest() override {
|
|
- TestClass::SetParam(¶meter_);
|
|
- return new TestClass();
|
|
- }
|
|
-
|
|
- private:
|
|
- const ParamType parameter_;
|
|
-
|
|
- ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;
|
|
- ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;
|
|
-};
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// TestMetaFactoryBase is a base class for meta-factories that create
|
|
-// test factories for passing into MakeAndRegisterTestInfo function.
|
|
-template <class ParamType>
|
|
-class TestMetaFactoryBase {
|
|
- public:
|
|
- virtual ~TestMetaFactoryBase() {}
|
|
-
|
|
- virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
|
|
-};
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// TestMetaFactory creates test factories for passing into
|
|
-// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
|
|
-// ownership of test factory pointer, same factory object cannot be passed
|
|
-// into that method twice. But ParameterizedTestSuiteInfo is going to call
|
|
-// it for each Test/Parameter value combination. Thus it needs meta factory
|
|
-// creator class.
|
|
-template <class TestSuite>
|
|
-class TestMetaFactory
|
|
- : public TestMetaFactoryBase<typename TestSuite::ParamType> {
|
|
- public:
|
|
- using ParamType = typename TestSuite::ParamType;
|
|
-
|
|
- TestMetaFactory() {}
|
|
-
|
|
- TestFactoryBase* CreateTestFactory(ParamType parameter) override {
|
|
- return new ParameterizedTestFactory<TestSuite>(parameter);
|
|
- }
|
|
-
|
|
- private:
|
|
- TestMetaFactory(const TestMetaFactory&) = delete;
|
|
- TestMetaFactory& operator=(const TestMetaFactory&) = delete;
|
|
-};
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// ParameterizedTestSuiteInfoBase is a generic interface
|
|
-// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
|
|
-// accumulates test information provided by TEST_P macro invocations
|
|
-// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
|
|
-// and uses that information to register all resulting test instances
|
|
-// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
|
|
-// a collection of pointers to the ParameterizedTestSuiteInfo objects
|
|
-// and calls RegisterTests() on each of them when asked.
|
|
-class ParameterizedTestSuiteInfoBase {
|
|
- public:
|
|
- virtual ~ParameterizedTestSuiteInfoBase() {}
|
|
-
|
|
- // Base part of test suite name for display purposes.
|
|
- virtual const std::string& GetTestSuiteName() const = 0;
|
|
- // 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.
|
|
- // This method should not be called more than once on any single
|
|
- // instance of a ParameterizedTestSuiteInfoBase derived class.
|
|
- virtual void RegisterTests() = 0;
|
|
-
|
|
- protected:
|
|
- ParameterizedTestSuiteInfoBase() {}
|
|
-
|
|
- private:
|
|
- ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =
|
|
- delete;
|
|
- ParameterizedTestSuiteInfoBase& operator=(
|
|
- const ParameterizedTestSuiteInfoBase&) = delete;
|
|
-};
|
|
-
|
|
-// 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
|
|
-// macro invocations for a particular test suite and generators
|
|
-// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
|
|
-// test suite. It registers tests with all values generated by all
|
|
-// generators when asked.
|
|
-template <class TestSuite>
|
|
-class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|
- public:
|
|
- // ParamType and GeneratorCreationFunc are private types but are required
|
|
- // for declarations of public methods AddTestPattern() and
|
|
- // AddTestSuiteInstantiation().
|
|
- using ParamType = typename TestSuite::ParamType;
|
|
- // A function that returns an instance of appropriate generator type.
|
|
- typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
|
- using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
|
-
|
|
- explicit ParameterizedTestSuiteInfo(const char* name,
|
|
- CodeLocation code_location)
|
|
- : test_suite_name_(name), code_location_(code_location) {}
|
|
-
|
|
- // Test suite base name for display purposes.
|
|
- const std::string& GetTestSuiteName() const override {
|
|
- return test_suite_name_;
|
|
- }
|
|
- // 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.
|
|
- // test_suite_name is the base name of the test suite (without invocation
|
|
- // prefix). test_base_name is the name of an individual test without
|
|
- // 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,
|
|
- 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.
|
|
- int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
|
- GeneratorCreationFunc* func,
|
|
- ParamNameGeneratorFunc* name_func,
|
|
- const char* file, int line) {
|
|
- instantiations_.push_back(
|
|
- InstantiationInfo(instantiation_name, func, name_func, file, line));
|
|
- return 0; // Return value used only to run this method in namespace scope.
|
|
- }
|
|
- // UnitTest class invokes this method to register tests in this test suite
|
|
- // 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;
|
|
- for (typename InstantiationContainer::iterator gen_it =
|
|
- instantiations_.begin();
|
|
- gen_it != instantiations_.end(); ++gen_it) {
|
|
- const std::string& instantiation_name = gen_it->name;
|
|
- ParamGenerator<ParamType> generator((*gen_it->generator)());
|
|
- ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
|
- const char* file = gen_it->file;
|
|
- int line = gen_it->line;
|
|
-
|
|
- std::string test_suite_name;
|
|
- if (!instantiation_name.empty())
|
|
- test_suite_name = instantiation_name + "/";
|
|
- test_suite_name += test_info->test_suite_base_name;
|
|
-
|
|
- size_t i = 0;
|
|
- std::set<std::string> test_param_names;
|
|
- 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(TestParamInfo<ParamType>(*param_it, i));
|
|
-
|
|
- GTEST_CHECK_(IsValidParamName(param_name))
|
|
- << "Parameterized test name '" << param_name
|
|
- << "' is invalid, in " << file << " line " << line << std::endl;
|
|
-
|
|
- GTEST_CHECK_(test_param_names.count(param_name) == 0)
|
|
- << "Duplicate parameterized test name '" << param_name << "', in "
|
|
- << file << " line " << line << std::endl;
|
|
-
|
|
- test_param_names.insert(param_name);
|
|
-
|
|
- 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(), test_info->code_location,
|
|
- GetTestSuiteTypeId(),
|
|
- SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
|
- SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
|
- test_info->test_meta_factory->CreateTestFactory(*param_it));
|
|
- } // 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:
|
|
- // LocalTestInfo structure keeps information about a single test registered
|
|
- // 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,
|
|
- 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),
|
|
- 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:
|
|
- // <Instantiation name, Sequence generator creation function,
|
|
- // Name generator function, Source file, Source line>
|
|
- struct InstantiationInfo {
|
|
- InstantiationInfo(const std::string& name_in,
|
|
- GeneratorCreationFunc* generator_in,
|
|
- ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
|
- int line_in)
|
|
- : name(name_in),
|
|
- generator(generator_in),
|
|
- name_func(name_func_in),
|
|
- file(file_in),
|
|
- line(line_in) {}
|
|
-
|
|
- std::string name;
|
|
- GeneratorCreationFunc* generator;
|
|
- ParamNameGeneratorFunc* name_func;
|
|
- const char* file;
|
|
- int line;
|
|
- };
|
|
- typedef ::std::vector<InstantiationInfo> InstantiationContainer;
|
|
-
|
|
- static bool IsValidParamName(const std::string& name) {
|
|
- // Check for empty string
|
|
- if (name.empty()) return false;
|
|
-
|
|
- // Check for invalid characters
|
|
- for (std::string::size_type index = 0; index < name.size(); ++index) {
|
|
- if (!IsAlNum(name[index]) && name[index] != '_') return false;
|
|
- }
|
|
-
|
|
- return true;
|
|
- }
|
|
-
|
|
- const std::string test_suite_name_;
|
|
- CodeLocation code_location_;
|
|
- TestInfoContainer tests_;
|
|
- InstantiationContainer instantiations_;
|
|
-
|
|
- ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;
|
|
- ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =
|
|
- delete;
|
|
-}; // class ParameterizedTestSuiteInfo
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-template <class TestCase>
|
|
-using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// ParameterizedTestSuiteRegistry contains a map of
|
|
-// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
|
|
-// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
|
|
-// ParameterizedTestSuiteInfo descriptors.
|
|
-class ParameterizedTestSuiteRegistry {
|
|
- public:
|
|
- ParameterizedTestSuiteRegistry() {}
|
|
- ~ParameterizedTestSuiteRegistry() {
|
|
- for (auto& test_suite_info : test_suite_infos_) {
|
|
- delete test_suite_info;
|
|
- }
|
|
- }
|
|
-
|
|
- // Looks up or creates and returns a structure containing information about
|
|
- // tests and instantiations of a particular test suite.
|
|
- template <class TestSuite>
|
|
- ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
|
- const char* test_suite_name, CodeLocation code_location) {
|
|
- ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
|
- for (auto& test_suite_info : test_suite_infos_) {
|
|
- if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
|
- if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
|
- // Complain about incorrect usage of Google Test facilities
|
|
- // and terminate the program since we cannot guaranty correct
|
|
- // test suite setup and tear-down in this case.
|
|
- ReportInvalidTestSuiteType(test_suite_name, code_location);
|
|
- posix::Abort();
|
|
- } else {
|
|
- // At this point we are sure that the object we found is of the same
|
|
- // type we are looking for, so we downcast it to that type
|
|
- // without further checks.
|
|
- typed_test_info = CheckedDowncastToActualType<
|
|
- ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- if (typed_test_info == nullptr) {
|
|
- typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
|
- test_suite_name, code_location);
|
|
- test_suite_infos_.push_back(typed_test_info);
|
|
- }
|
|
- return typed_test_info;
|
|
- }
|
|
- void RegisterTests() {
|
|
- for (auto& test_suite_info : test_suite_infos_) {
|
|
- test_suite_info->RegisterTests();
|
|
- }
|
|
- }
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- template <class TestCase>
|
|
- ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
|
- const char* test_case_name, CodeLocation code_location) {
|
|
- return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
|
- }
|
|
-
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- private:
|
|
- using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
|
-
|
|
- TestSuiteInfoContainer test_suite_infos_;
|
|
-
|
|
- ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
|
- delete;
|
|
- ParameterizedTestSuiteRegistry& operator=(
|
|
- const ParameterizedTestSuiteRegistry&) = delete;
|
|
-};
|
|
-
|
|
-// Keep track of what type-parameterized test suite are defined and
|
|
-// where as well as which are intatiated. This allows susequently
|
|
-// identifying suits that are defined but never used.
|
|
-class TypeParameterizedTestSuiteRegistry {
|
|
- public:
|
|
- // Add a suite definition
|
|
- void RegisterTestSuite(const char* test_suite_name,
|
|
- CodeLocation code_location);
|
|
-
|
|
- // Add an instantiation of a suit.
|
|
- void RegisterInstantiation(const char* test_suite_name);
|
|
-
|
|
- // For each suit repored as defined but not reported as instantiation,
|
|
- // emit a test that reports that fact (configurably, as an error).
|
|
- void CheckForInstantiations();
|
|
-
|
|
- private:
|
|
- struct TypeParameterizedTestSuiteInfo {
|
|
- explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
|
- : code_location(c), instantiated(false) {}
|
|
-
|
|
- CodeLocation code_location;
|
|
- bool instantiated;
|
|
- };
|
|
-
|
|
- std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Forward declarations of ValuesIn(), which is implemented in
|
|
-// include/gtest/gtest-param-test.h.
|
|
-template <class Container>
|
|
-internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
|
- const Container& container);
|
|
-
|
|
-namespace internal {
|
|
-// Used in the Values() function to provide polymorphic capabilities.
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-#pragma warning(push)
|
|
-#pragma warning(disable : 4100)
|
|
-#endif
|
|
-
|
|
-template <typename... Ts>
|
|
-class ValueArray {
|
|
- public:
|
|
- explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
|
|
-
|
|
- template <typename T>
|
|
- operator ParamGenerator<T>() const { // NOLINT
|
|
- return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
|
|
- }
|
|
-
|
|
- private:
|
|
- template <typename T, size_t... I>
|
|
- std::vector<T> MakeVector(IndexSequence<I...>) const {
|
|
- return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
|
|
- }
|
|
-
|
|
- FlatTuple<Ts...> v_;
|
|
-};
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-#pragma warning(pop)
|
|
-#endif
|
|
-
|
|
-template <typename... T>
|
|
-class CartesianProductGenerator
|
|
- : public ParamGeneratorInterface<::std::tuple<T...>> {
|
|
- public:
|
|
- typedef ::std::tuple<T...> ParamType;
|
|
-
|
|
- CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
|
|
- : generators_(g) {}
|
|
- ~CartesianProductGenerator() override {}
|
|
-
|
|
- ParamIteratorInterface<ParamType>* Begin() const override {
|
|
- return new Iterator(this, generators_, false);
|
|
- }
|
|
- ParamIteratorInterface<ParamType>* End() const override {
|
|
- return new Iterator(this, generators_, true);
|
|
- }
|
|
-
|
|
- private:
|
|
- template <class I>
|
|
- class IteratorImpl;
|
|
- template <size_t... I>
|
|
- class IteratorImpl<IndexSequence<I...>>
|
|
- : public ParamIteratorInterface<ParamType> {
|
|
- public:
|
|
- IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
|
|
- const std::tuple<ParamGenerator<T>...>& generators,
|
|
- bool is_end)
|
|
- : base_(base),
|
|
- begin_(std::get<I>(generators).begin()...),
|
|
- end_(std::get<I>(generators).end()...),
|
|
- current_(is_end ? end_ : begin_) {
|
|
- ComputeCurrentValue();
|
|
- }
|
|
- ~IteratorImpl() override {}
|
|
-
|
|
- const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
|
|
- return base_;
|
|
- }
|
|
- // Advance should not be called on beyond-of-range iterators
|
|
- // so no component iterators must be beyond end of range, either.
|
|
- void Advance() override {
|
|
- assert(!AtEnd());
|
|
- // Advance the last iterator.
|
|
- ++std::get<sizeof...(T) - 1>(current_);
|
|
- // if that reaches end, propagate that up.
|
|
- AdvanceIfEnd<sizeof...(T) - 1>();
|
|
- ComputeCurrentValue();
|
|
- }
|
|
- ParamIteratorInterface<ParamType>* Clone() const override {
|
|
- return new IteratorImpl(*this);
|
|
- }
|
|
-
|
|
- const ParamType* Current() const override { return current_value_.get(); }
|
|
-
|
|
- bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
|
|
- // Having the same base generator guarantees that the other
|
|
- // iterator is of the same type and we can downcast.
|
|
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
|
- << "The program attempted to compare iterators "
|
|
- << "from different generators." << std::endl;
|
|
- const IteratorImpl* typed_other =
|
|
- CheckedDowncastToActualType<const IteratorImpl>(&other);
|
|
-
|
|
- // We must report iterators equal if they both point beyond their
|
|
- // respective ranges. That can happen in a variety of fashions,
|
|
- // so we have to consult AtEnd().
|
|
- if (AtEnd() && typed_other->AtEnd()) return true;
|
|
-
|
|
- bool same = true;
|
|
- bool dummy[] = {
|
|
- (same = same && std::get<I>(current_) ==
|
|
- std::get<I>(typed_other->current_))...};
|
|
- (void)dummy;
|
|
- return same;
|
|
- }
|
|
-
|
|
- private:
|
|
- template <size_t ThisI>
|
|
- void AdvanceIfEnd() {
|
|
- if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
|
|
-
|
|
- bool last = ThisI == 0;
|
|
- if (last) {
|
|
- // We are done. Nothing else to propagate.
|
|
- return;
|
|
- }
|
|
-
|
|
- constexpr size_t NextI = ThisI - (ThisI != 0);
|
|
- std::get<ThisI>(current_) = std::get<ThisI>(begin_);
|
|
- ++std::get<NextI>(current_);
|
|
- AdvanceIfEnd<NextI>();
|
|
- }
|
|
-
|
|
- void ComputeCurrentValue() {
|
|
- if (!AtEnd())
|
|
- current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
|
|
- }
|
|
- bool AtEnd() const {
|
|
- bool at_end = false;
|
|
- bool dummy[] = {
|
|
- (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
|
|
- (void)dummy;
|
|
- return at_end;
|
|
- }
|
|
-
|
|
- const ParamGeneratorInterface<ParamType>* const base_;
|
|
- std::tuple<typename ParamGenerator<T>::iterator...> begin_;
|
|
- std::tuple<typename ParamGenerator<T>::iterator...> end_;
|
|
- std::tuple<typename ParamGenerator<T>::iterator...> current_;
|
|
- std::shared_ptr<ParamType> current_value_;
|
|
- };
|
|
-
|
|
- using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
|
|
-
|
|
- std::tuple<ParamGenerator<T>...> generators_;
|
|
-};
|
|
-
|
|
-template <class... Gen>
|
|
-class CartesianProductHolder {
|
|
- public:
|
|
- CartesianProductHolder(const Gen&... g) : generators_(g...) {}
|
|
- template <typename... T>
|
|
- operator ParamGenerator<::std::tuple<T...>>() const {
|
|
- return ParamGenerator<::std::tuple<T...>>(
|
|
- new CartesianProductGenerator<T...>(generators_));
|
|
- }
|
|
-
|
|
- private:
|
|
- std::tuple<Gen...> generators_;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-port-arch.h b/vendor/gtest/include/gtest/internal/gtest-port-arch.h
|
|
deleted file mode 100644
|
|
index f025db76a..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-port-arch.h
|
|
+++ /dev/null
|
|
@@ -1,116 +0,0 @@
|
|
-// Copyright 2015, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file defines the GTEST_OS_* macro.
|
|
-// It is separate from gtest-port.h so that custom/gtest-port.h can include it.
|
|
-
|
|
-#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__
|
|
-#define GTEST_OS_CYGWIN 1
|
|
-#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
|
|
-#define GTEST_OS_WINDOWS_MINGW 1
|
|
-#define GTEST_OS_WINDOWS 1
|
|
-#elif defined _WIN32
|
|
-#define GTEST_OS_WINDOWS 1
|
|
-#ifdef _WIN32_WCE
|
|
-#define GTEST_OS_WINDOWS_MOBILE 1
|
|
-#elif defined(WINAPI_FAMILY)
|
|
-#include <winapifamily.h>
|
|
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
-#define GTEST_OS_WINDOWS_DESKTOP 1
|
|
-#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
|
-#define GTEST_OS_WINDOWS_PHONE 1
|
|
-#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
|
-#define GTEST_OS_WINDOWS_RT 1
|
|
-#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
|
-#define GTEST_OS_WINDOWS_PHONE 1
|
|
-#define GTEST_OS_WINDOWS_TV_TITLE 1
|
|
-#else
|
|
-// WINAPI_FAMILY defined but no known partition matched.
|
|
-// Default to desktop.
|
|
-#define GTEST_OS_WINDOWS_DESKTOP 1
|
|
-#endif
|
|
-#else
|
|
-#define GTEST_OS_WINDOWS_DESKTOP 1
|
|
-#endif // _WIN32_WCE
|
|
-#elif defined __OS2__
|
|
-#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
|
|
-#elif defined __DragonFly__
|
|
-#define GTEST_OS_DRAGONFLY 1
|
|
-#elif defined __FreeBSD__
|
|
-#define GTEST_OS_FREEBSD 1
|
|
-#elif defined __Fuchsia__
|
|
-#define GTEST_OS_FUCHSIA 1
|
|
-#elif defined(__GNU__)
|
|
-#define GTEST_OS_GNU_HURD 1
|
|
-#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
|
-#define GTEST_OS_GNU_KFREEBSD 1
|
|
-#elif defined __linux__
|
|
-#define GTEST_OS_LINUX 1
|
|
-#if defined __ANDROID__
|
|
-#define GTEST_OS_LINUX_ANDROID 1
|
|
-#endif
|
|
-#elif defined __MVS__
|
|
-#define GTEST_OS_ZOS 1
|
|
-#elif defined(__sun) && defined(__SVR4)
|
|
-#define GTEST_OS_SOLARIS 1
|
|
-#elif defined(_AIX)
|
|
-#define GTEST_OS_AIX 1
|
|
-#elif defined(__hpux)
|
|
-#define GTEST_OS_HPUX 1
|
|
-#elif defined __native_client__
|
|
-#define GTEST_OS_NACL 1
|
|
-#elif defined __NetBSD__
|
|
-#define GTEST_OS_NETBSD 1
|
|
-#elif defined __OpenBSD__
|
|
-#define GTEST_OS_OPENBSD 1
|
|
-#elif defined __QNX__
|
|
-#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 // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-port.h b/vendor/gtest/include/gtest/internal/gtest-port.h
|
|
deleted file mode 100644
|
|
index f909c6af3..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-port.h
|
|
+++ /dev/null
|
|
@@ -1,2413 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// Low-level types and utilities for porting Google Test to various
|
|
-// platforms. All macros ending with _ and symbols defined in an
|
|
-// internal namespace are subject to change without notice. Code
|
|
-// outside Google Test MUST NOT USE THEM DIRECTLY. Macros that don't
|
|
-// end with _ are part of Google Test's public API and can be used by
|
|
-// code outside Google Test.
|
|
-//
|
|
-// This file is fundamental to Google Test. All other Google Test source
|
|
-// files are expected to #include this. Therefore, it cannot #include
|
|
-// any other Google Test header.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
|
-#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
|
-
|
|
-// Environment-describing macros
|
|
-// -----------------------------
|
|
-//
|
|
-// Google Test can be used in many different environments. Macros in
|
|
-// this section tell Google Test what kind of environment it is being
|
|
-// used in, such that Google Test can provide environment-specific
|
|
-// features and implementations.
|
|
-//
|
|
-// Google Test tries to automatically detect the properties of its
|
|
-// environment, so users usually don't need to worry about these
|
|
-// macros. However, the automatic detection is not perfect.
|
|
-// Sometimes it's necessary for a user to define some of the following
|
|
-// macros in the build script to override Google Test's decisions.
|
|
-//
|
|
-// If the user doesn't define a macro in the list, Google Test will
|
|
-// provide a default definition. After this header is #included, all
|
|
-// macros in this list will be defined to either 1 or 0.
|
|
-//
|
|
-// Notes to maintainers:
|
|
-// - Each macro here is a user-tweakable knob; do not grow the list
|
|
-// lightly.
|
|
-// - Use #if to key off these macros. Don't use #ifdef or "#if
|
|
-// defined(...)", which will not work as these macros are ALWAYS
|
|
-// defined.
|
|
-//
|
|
-// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2)
|
|
-// is/isn't available.
|
|
-// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
|
|
-// are enabled.
|
|
-// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular
|
|
-// expressions are/aren't available.
|
|
-// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
|
|
-// is/isn't available.
|
|
-// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't
|
|
-// enabled.
|
|
-// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
|
|
-// std::wstring does/doesn't work (Google Test can
|
|
-// be used where std::wstring is unavailable).
|
|
-// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
|
|
-// compiler supports Microsoft's "Structured
|
|
-// Exception Handling".
|
|
-// GTEST_HAS_STREAM_REDIRECTION
|
|
-// - Define it to 1/0 to indicate whether the
|
|
-// platform supports I/O stream redirection using
|
|
-// dup() and dup2().
|
|
-// GTEST_LINKED_AS_SHARED_LIBRARY
|
|
-// - Define to 1 when compiling tests that use
|
|
-// Google Test as a shared library (known as
|
|
-// DLL on Windows).
|
|
-// GTEST_CREATE_SHARED_LIBRARY
|
|
-// - Define to 1 when compiling Google Test itself
|
|
-// as a shared library.
|
|
-// GTEST_DEFAULT_DEATH_TEST_STYLE
|
|
-// - The default value of --gtest_death_test_style.
|
|
-// The legacy default has been "fast" in the open
|
|
-// source version since 2008. The recommended value
|
|
-// is "threadsafe", and can be set in
|
|
-// custom/gtest-port.h.
|
|
-
|
|
-// Platform-indicating macros
|
|
-// --------------------------
|
|
-//
|
|
-// Macros indicating the platform on which Google Test is being used
|
|
-// (a macro is defined to 1 if compiled on the given platform;
|
|
-// otherwise UNDEFINED -- it's never defined to 0.). Google Test
|
|
-// defines these macros automatically. Code outside Google Test MUST
|
|
-// NOT define them.
|
|
-//
|
|
-// GTEST_OS_AIX - IBM AIX
|
|
-// GTEST_OS_CYGWIN - Cygwin
|
|
-// GTEST_OS_DRAGONFLY - DragonFlyBSD
|
|
-// GTEST_OS_FREEBSD - FreeBSD
|
|
-// GTEST_OS_FUCHSIA - Fuchsia
|
|
-// GTEST_OS_GNU_HURD - GNU/Hurd
|
|
-// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
|
|
-// GTEST_OS_HAIKU - Haiku
|
|
-// GTEST_OS_HPUX - HP-UX
|
|
-// GTEST_OS_LINUX - Linux
|
|
-// GTEST_OS_LINUX_ANDROID - Google Android
|
|
-// GTEST_OS_MAC - Mac OS X
|
|
-// GTEST_OS_IOS - iOS
|
|
-// GTEST_OS_NACL - Google Native Client (NaCl)
|
|
-// GTEST_OS_NETBSD - NetBSD
|
|
-// GTEST_OS_OPENBSD - OpenBSD
|
|
-// GTEST_OS_OS2 - OS/2
|
|
-// GTEST_OS_QNX - QNX
|
|
-// GTEST_OS_SOLARIS - Sun Solaris
|
|
-// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
|
|
-// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
|
|
-// GTEST_OS_WINDOWS_MINGW - MinGW
|
|
-// GTEST_OS_WINDOWS_MOBILE - Windows Mobile
|
|
-// GTEST_OS_WINDOWS_PHONE - Windows Phone
|
|
-// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT
|
|
-// GTEST_OS_ZOS - z/OS
|
|
-//
|
|
-// Among the platforms, Cygwin, Linux, Mac OS X, and Windows have the
|
|
-// most stable support. Since core members of the Google Test project
|
|
-// don't have access to other platforms, support for them may be less
|
|
-// stable. If you notice any problems on your platform, please notify
|
|
-// googletestframework@googlegroups.com (patches for fixing them are
|
|
-// even more welcome!).
|
|
-//
|
|
-// It is possible that none of the GTEST_OS_* macros are defined.
|
|
-
|
|
-// Feature-indicating macros
|
|
-// -------------------------
|
|
-//
|
|
-// Macros indicating which Google Test features are available (a macro
|
|
-// is defined to 1 if the corresponding feature is supported;
|
|
-// otherwise UNDEFINED -- it's never defined to 0.). Google Test
|
|
-// defines these macros automatically. Code outside Google Test MUST
|
|
-// NOT define them.
|
|
-//
|
|
-// These macros are public so that portable tests can be written.
|
|
-// Such tests typically surround code using a feature with an #if
|
|
-// which controls that code. For example:
|
|
-//
|
|
-// #if GTEST_HAS_DEATH_TEST
|
|
-// EXPECT_DEATH(DoSomethingDeadly());
|
|
-// #endif
|
|
-//
|
|
-// GTEST_HAS_DEATH_TEST - death tests
|
|
-// GTEST_HAS_TYPED_TEST - typed tests
|
|
-// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
|
|
-// GTEST_IS_THREADSAFE - Google Test is thread-safe.
|
|
-// GTEST_USES_RE2 - the RE2 regular expression library is used
|
|
-// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
|
-// GTEST_HAS_POSIX_RE (see above) which users can
|
|
-// define themselves.
|
|
-// GTEST_USES_SIMPLE_RE - our own simple regex is used;
|
|
-// the above RE\b(s) are mutually exclusive.
|
|
-
|
|
-// Misc public macros
|
|
-// ------------------
|
|
-//
|
|
-// GTEST_FLAG(flag_name) - references the variable corresponding to
|
|
-// the given Google Test flag.
|
|
-
|
|
-// Internal utilities
|
|
-// ------------------
|
|
-//
|
|
-// The following macros and utilities are for Google Test's INTERNAL
|
|
-// use only. Code outside Google Test MUST NOT USE THEM DIRECTLY.
|
|
-//
|
|
-// Macros for basic C++ coding:
|
|
-// 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_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.
|
|
-//
|
|
-// Regular expressions:
|
|
-// RE - a simple regular expression class using
|
|
-// 1) the RE2 syntax on all platforms when built with RE2
|
|
-// and Abseil as dependencies
|
|
-// 2) the POSIX Extended Regular Expression syntax on
|
|
-// UNIX-like platforms,
|
|
-// 3) A reduced regular exception syntax on other platforms,
|
|
-// including Windows.
|
|
-// Logging:
|
|
-// GTEST_LOG_() - logs messages at the specified severity level.
|
|
-// LogToStderr() - directs all log messages to stderr.
|
|
-// FlushInfoLog() - flushes informational log messages.
|
|
-//
|
|
-// Stdout and stderr capturing:
|
|
-// CaptureStdout() - starts capturing stdout.
|
|
-// GetCapturedStdout() - stops capturing stdout and returns the captured
|
|
-// string.
|
|
-// CaptureStderr() - starts capturing stderr.
|
|
-// GetCapturedStderr() - stops capturing stderr and returns the captured
|
|
-// string.
|
|
-//
|
|
-// Integer types:
|
|
-// TypeWithSize - maps an integer to a int type.
|
|
-// TimeInMillis - integers of known sizes.
|
|
-// BiggestInt - the biggest signed integer type.
|
|
-//
|
|
-// Command-line utilities:
|
|
-// GetInjectableArgvs() - returns the command line as a vector of strings.
|
|
-//
|
|
-// Environment variable utilities:
|
|
-// GetEnv() - gets the value of an environment variable.
|
|
-// BoolFromGTestEnv() - parses a bool environment variable.
|
|
-// Int32FromGTestEnv() - parses an int32_t environment variable.
|
|
-// StringFromGTestEnv() - parses a string environment variable.
|
|
-//
|
|
-// Deprecation warnings:
|
|
-// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as
|
|
-// deprecated; calling a marked function
|
|
-// should generate a compiler warning
|
|
-
|
|
-#include <ctype.h> // for isspace, etc
|
|
-#include <stddef.h> // for ptrdiff_t
|
|
-#include <stdio.h>
|
|
-#include <stdlib.h>
|
|
-#include <string.h>
|
|
-
|
|
-#include <cerrno>
|
|
-// #include <condition_variable> // Guarded by GTEST_IS_THREADSAFE below
|
|
-#include <cstdint>
|
|
-#include <iostream>
|
|
-#include <limits>
|
|
-#include <locale>
|
|
-#include <memory>
|
|
-#include <string>
|
|
-// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
|
|
-#include <tuple>
|
|
-#include <type_traits>
|
|
-#include <vector>
|
|
-
|
|
-#ifndef _WIN32_WCE
|
|
-#include <sys/stat.h>
|
|
-#include <sys/types.h>
|
|
-#endif // !_WIN32_WCE
|
|
-
|
|
-#if defined __APPLE__
|
|
-#include <AvailabilityMacros.h>
|
|
-#include <TargetConditionals.h>
|
|
-#endif
|
|
-
|
|
-#include "gtest/internal/custom/gtest-port.h"
|
|
-#include "gtest/internal/gtest-port-arch.h"
|
|
-
|
|
-#if GTEST_HAS_ABSL
|
|
-#include "absl/flags/declare.h"
|
|
-#include "absl/flags/flag.h"
|
|
-#include "absl/flags/reflection.h"
|
|
-#endif
|
|
-
|
|
-#if !defined(GTEST_DEV_EMAIL_)
|
|
-#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
|
|
-#define GTEST_FLAG_PREFIX_ "gtest_"
|
|
-#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
|
|
-#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
|
|
-#define GTEST_NAME_ "Google Test"
|
|
-#define GTEST_PROJECT_URL_ "https://github.com/google/googletest/"
|
|
-#endif // !defined(GTEST_DEV_EMAIL_)
|
|
-
|
|
-#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_)
|
|
-#define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest"
|
|
-#endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_)
|
|
-
|
|
-// Determines the version of gcc that is used to compile this.
|
|
-#ifdef __GNUC__
|
|
-// 40302 means version 4.3.2.
|
|
-#define GTEST_GCC_VER_ \
|
|
- (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
|
-#endif // __GNUC__
|
|
-
|
|
-// Macros for disabling Microsoft Visual C++ warnings.
|
|
-//
|
|
-// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
|
|
-// /* code that triggers warnings C4800 and C4385 */
|
|
-// GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-#if defined(_MSC_VER)
|
|
-#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \
|
|
- __pragma(warning(push)) __pragma(warning(disable : warnings))
|
|
-#define GTEST_DISABLE_MSC_WARNINGS_POP_() __pragma(warning(pop))
|
|
-#else
|
|
-// Not all compilers are MSVC
|
|
-#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)
|
|
-#define GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-#endif
|
|
-
|
|
-// Clang on Windows does not understand MSVC's pragma warning.
|
|
-// We need clang-specific way to disable function deprecation warning.
|
|
-#ifdef __clang__
|
|
-#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
|
|
- _Pragma("clang diagnostic push") \
|
|
- _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \
|
|
- _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"")
|
|
-#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma("clang diagnostic pop")
|
|
-#else
|
|
-#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
|
|
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
|
|
-#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-#endif
|
|
-
|
|
-// Brings in definitions for functions used in the testing::internal::posix
|
|
-// namespace (read, write, close, chdir, isatty, stat). We do not currently
|
|
-// use them on Windows Mobile.
|
|
-#if GTEST_OS_WINDOWS
|
|
-#if !GTEST_OS_WINDOWS_MOBILE
|
|
-#include <direct.h>
|
|
-#include <io.h>
|
|
-#endif
|
|
-// In order to avoid having to include <windows.h>, use forward declaration
|
|
-#if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR)
|
|
-// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two
|
|
-// separate (equivalent) structs, instead of using typedef
|
|
-typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
|
-#else
|
|
-// Assume CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.
|
|
-// This assumption is verified by
|
|
-// 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
|
|
-// mentioned above.
|
|
-#include <strings.h>
|
|
-#include <unistd.h>
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-#if GTEST_OS_LINUX_ANDROID
|
|
-// Used to define __ANDROID_API__ matching the target NDK API level.
|
|
-#include <android/api-level.h> // NOLINT
|
|
-#endif
|
|
-
|
|
-// 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 && !GTEST_OS_XTENSA)
|
|
-#endif
|
|
-#endif
|
|
-
|
|
-// Select the regular expression implementation.
|
|
-#if GTEST_HAS_ABSL
|
|
-// When using Abseil, RE2 is required.
|
|
-#include "absl/strings/string_view.h"
|
|
-#include "re2/re2.h"
|
|
-#define GTEST_USES_RE2 1
|
|
-#elif GTEST_HAS_POSIX_RE
|
|
-#include <regex.h> // NOLINT
|
|
-#define GTEST_USES_POSIX_RE 1
|
|
-#else
|
|
-// Use our own simple regex implementation.
|
|
-#define GTEST_USES_SIMPLE_RE 1
|
|
-#endif
|
|
-
|
|
-#ifndef GTEST_HAS_EXCEPTIONS
|
|
-// 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 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
|
|
-// macro to enable exceptions, so we'll do the same.
|
|
-// Assumes that exceptions are enabled by default.
|
|
-#ifndef _HAS_EXCEPTIONS
|
|
-#define _HAS_EXCEPTIONS 1
|
|
-#endif // _HAS_EXCEPTIONS
|
|
-#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
|
|
-#elif defined(__clang__)
|
|
-// 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 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
|
|
-// detecting whether they are enabled or not. Therefore, we assume that
|
|
-// they are enabled unless the user tells us otherwise.
|
|
-#define GTEST_HAS_EXCEPTIONS 1
|
|
-#elif defined(__IBMCPP__) && __EXCEPTIONS
|
|
-// 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
|
|
-// be turned of by +noeh compiler option if desired.
|
|
-#define GTEST_HAS_EXCEPTIONS 1
|
|
-#else
|
|
-// For other compilers, we assume exceptions are disabled to be
|
|
-// conservative.
|
|
-#define GTEST_HAS_EXCEPTIONS 0
|
|
-#endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
|
-#endif // GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-#ifndef GTEST_HAS_STD_WSTRING
|
|
-// The user didn't tell us whether ::std::wstring is available, so we need
|
|
-// to figure it out.
|
|
-// Cygwin 1.7 and below doesn't support ::std::wstring.
|
|
-// Solaris' libc++ doesn't support it either. Android has
|
|
-// 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_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA))
|
|
-
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-// Determines whether RTTI is available.
|
|
-#ifndef GTEST_HAS_RTTI
|
|
-// The user didn't tell us whether RTTI is enabled, so we need to
|
|
-// figure it out.
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-
|
|
-#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 if and only if RTTI is
|
|
-// enabled.
|
|
-#elif defined(__GNUC__)
|
|
-
|
|
-#ifdef __GXX_RTTI
|
|
-// When building against STLport with the Android NDK and with
|
|
-// -frtti -fno-exceptions, the build fails at link time with undefined
|
|
-// references to __cxa_bad_typeid. Note sure if STL or toolchain bug,
|
|
-// so disable RTTI when detected.
|
|
-#if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && !defined(__EXCEPTIONS)
|
|
-#define GTEST_HAS_RTTI 0
|
|
-#else
|
|
-#define GTEST_HAS_RTTI 1
|
|
-#endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS
|
|
-#else
|
|
-#define GTEST_HAS_RTTI 0
|
|
-#endif // __GXX_RTTI
|
|
-
|
|
-// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends
|
|
-// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the
|
|
-// first version with C++ support.
|
|
-#elif defined(__clang__)
|
|
-
|
|
-#define GTEST_HAS_RTTI __has_feature(cxx_rtti)
|
|
-
|
|
-// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
|
|
-// both the typeid and dynamic_cast features are present.
|
|
-#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
|
|
-
|
|
-#ifdef __RTTI_ALL__
|
|
-#define GTEST_HAS_RTTI 1
|
|
-#else
|
|
-#define GTEST_HAS_RTTI 0
|
|
-#endif
|
|
-
|
|
-#else
|
|
-
|
|
-// For all other compilers, we assume RTTI is enabled.
|
|
-#define GTEST_HAS_RTTI 1
|
|
-
|
|
-#endif // _MSC_VER
|
|
-
|
|
-#endif // GTEST_HAS_RTTI
|
|
-
|
|
-// It's this header's responsibility to #include <typeinfo> when RTTI
|
|
-// is enabled.
|
|
-#if GTEST_HAS_RTTI
|
|
-#include <typeinfo>
|
|
-#endif
|
|
-
|
|
-// Determines whether Google Test can use the pthreads library.
|
|
-#ifndef GTEST_HAS_PTHREAD
|
|
-// The user didn't tell us explicitly, so we make reasonable assumptions about
|
|
-// which platforms have pthreads support.
|
|
-//
|
|
-// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
|
|
-// to your compiler flags.
|
|
-#define GTEST_HAS_PTHREAD \
|
|
- (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
|
|
- GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
|
- GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \
|
|
- GTEST_OS_HAIKU || GTEST_OS_GNU_HURD)
|
|
-#endif // GTEST_HAS_PTHREAD
|
|
-
|
|
-#if GTEST_HAS_PTHREAD
|
|
-// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
|
|
-// true.
|
|
-#include <pthread.h> // NOLINT
|
|
-
|
|
-// For timespec and nanosleep, used below.
|
|
-#include <time.h> // NOLINT
|
|
-#endif
|
|
-
|
|
-// Determines whether clone(2) is supported.
|
|
-// Usually it will only be available on Linux, excluding
|
|
-// Linux on the Itanium architecture.
|
|
-// Also see http://linux.die.net/man/2/clone.
|
|
-#ifndef GTEST_HAS_CLONE
|
|
-// The user didn't tell us, so we need to figure it out.
|
|
-
|
|
-#if GTEST_OS_LINUX && !defined(__ia64__)
|
|
-#if GTEST_OS_LINUX_ANDROID
|
|
-// On Android, clone() became available at different API levels for each 32-bit
|
|
-// architecture.
|
|
-#if defined(__LP64__) || (defined(__arm__) && __ANDROID_API__ >= 9) || \
|
|
- (defined(__mips__) && __ANDROID_API__ >= 12) || \
|
|
- (defined(__i386__) && __ANDROID_API__ >= 17)
|
|
-#define GTEST_HAS_CLONE 1
|
|
-#else
|
|
-#define GTEST_HAS_CLONE 0
|
|
-#endif
|
|
-#else
|
|
-#define GTEST_HAS_CLONE 1
|
|
-#endif
|
|
-#else
|
|
-#define GTEST_HAS_CLONE 0
|
|
-#endif // GTEST_OS_LINUX && !defined(__ia64__)
|
|
-
|
|
-#endif // GTEST_HAS_CLONE
|
|
-
|
|
-// Determines whether to support stream redirection. This is used to test
|
|
-// output correctness and to implement death tests.
|
|
-#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 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
|
|
-#define GTEST_HAS_STREAM_REDIRECTION 0
|
|
-#else
|
|
-#define GTEST_HAS_STREAM_REDIRECTION 1
|
|
-#endif // !GTEST_OS_WINDOWS_MOBILE
|
|
-#endif // GTEST_HAS_STREAM_REDIRECTION
|
|
-
|
|
-// Determines whether to support death tests.
|
|
-// pops up a dialog window that cannot be suppressed programmatically.
|
|
-#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
|
|
- (GTEST_OS_MAC && !GTEST_OS_IOS) || \
|
|
- (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \
|
|
- GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \
|
|
- GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
|
|
- GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \
|
|
- GTEST_OS_GNU_HURD)
|
|
-#define GTEST_HAS_DEATH_TEST 1
|
|
-#endif
|
|
-
|
|
-// Determines whether to support type-driven tests.
|
|
-
|
|
-// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
|
|
-// Sun Pro CC, IBM Visual Age, and HP aCC support.
|
|
-#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \
|
|
- defined(__IBMCPP__) || defined(__HP_aCC)
|
|
-#define GTEST_HAS_TYPED_TEST 1
|
|
-#define GTEST_HAS_TYPED_TEST_P 1
|
|
-#endif
|
|
-
|
|
-// Determines whether the system compiler uses UTF-16 for encoding wide strings.
|
|
-#define GTEST_WIDE_STRING_USES_UTF16_ \
|
|
- (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_AIX || GTEST_OS_OS2)
|
|
-
|
|
-// Determines whether test results can be streamed to a socket.
|
|
-#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
|
|
- GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD || \
|
|
- GTEST_OS_GNU_HURD
|
|
-#define GTEST_CAN_STREAM_RESULTS_ 1
|
|
-#endif
|
|
-
|
|
-// Defines some utility macros.
|
|
-
|
|
-// The GNU compiler emits a warning if nested "if" statements are followed by
|
|
-// an "else" statement and braces are not used to explicitly disambiguate the
|
|
-// "else" binding. This leads to problems with code like:
|
|
-//
|
|
-// if (gate)
|
|
-// ASSERT_*(condition) << "Some message";
|
|
-//
|
|
-// The "switch (0) case 0:" idiom is used to suppress this.
|
|
-#ifdef __INTEL_COMPILER
|
|
-#define GTEST_AMBIGUOUS_ELSE_BLOCKER_
|
|
-#else
|
|
-#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- switch (0) \
|
|
- case 0: \
|
|
- default: // NOLINT
|
|
-#endif
|
|
-
|
|
-// Use this annotation at the end of a struct/class definition to
|
|
-// prevent the compiler from optimizing away instances that are never
|
|
-// used. This is useful when all interesting logic happens inside the
|
|
-// c'tor and / or d'tor. Example:
|
|
-//
|
|
-// struct Foo {
|
|
-// Foo() { ... }
|
|
-// } GTEST_ATTRIBUTE_UNUSED_;
|
|
-//
|
|
-// Also use it after a variable or parameter declaration to tell the
|
|
-// compiler the variable/parameter does not have to be used.
|
|
-#if defined(__GNUC__) && !defined(COMPILER_ICC)
|
|
-#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
|
|
-#elif defined(__clang__)
|
|
-#if __has_attribute(unused)
|
|
-#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
|
|
-#endif
|
|
-#endif
|
|
-#ifndef GTEST_ATTRIBUTE_UNUSED_
|
|
-#define GTEST_ATTRIBUTE_UNUSED_
|
|
-#endif
|
|
-
|
|
-// Use this annotation before a function that takes a printf format string.
|
|
-#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC)
|
|
-#if defined(__MINGW_PRINTF_FORMAT)
|
|
-// MinGW has two different printf implementations. Ensure the format macro
|
|
-// matches the selected implementation. See
|
|
-// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
|
|
-#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
|
|
- __attribute__(( \
|
|
- __format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
|
|
- __attribute__((__format__(__printf__, string_index, first_to_check)))
|
|
-#endif
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
|
|
-#endif
|
|
-
|
|
-// Tell the compiler to warn about unused return values for functions declared
|
|
-// with this macro. The macro should be used on function declarations
|
|
-// following the argument list:
|
|
-//
|
|
-// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
|
|
-#if defined(__GNUC__) && !defined(COMPILER_ICC)
|
|
-#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))
|
|
-#else
|
|
-#define GTEST_MUST_USE_RESULT_
|
|
-#endif // __GNUC__ && !COMPILER_ICC
|
|
-
|
|
-// MS C++ compiler emits warning when a conditional expression is compile time
|
|
-// constant. In some contexts this warning is false positive and needs to be
|
|
-// suppressed. Use the following two macros in such cases:
|
|
-//
|
|
-// GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
|
-// while (true) {
|
|
-// GTEST_INTENTIONAL_CONST_COND_POP_()
|
|
-// }
|
|
-#define GTEST_INTENTIONAL_CONST_COND_PUSH_() \
|
|
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127)
|
|
-#define GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
-
|
|
-// Determine whether the compiler supports Microsoft's Structured Exception
|
|
-// Handling. This is supported by several Windows compilers but generally
|
|
-// does not exist on any other system.
|
|
-#ifndef GTEST_HAS_SEH
|
|
-// The user didn't tell us, so we need to figure it out.
|
|
-
|
|
-#if defined(_MSC_VER) || defined(__BORLANDC__)
|
|
-// These two compilers are known to support SEH.
|
|
-#define GTEST_HAS_SEH 1
|
|
-#else
|
|
-// Assume no SEH.
|
|
-#define GTEST_HAS_SEH 0
|
|
-#endif
|
|
-
|
|
-#endif // GTEST_HAS_SEH
|
|
-
|
|
-#ifndef GTEST_IS_THREADSAFE
|
|
-
|
|
-#define GTEST_IS_THREADSAFE \
|
|
- (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ || \
|
|
- (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) || \
|
|
- GTEST_HAS_PTHREAD)
|
|
-
|
|
-#endif // GTEST_IS_THREADSAFE
|
|
-
|
|
-#if GTEST_IS_THREADSAFE
|
|
-// Some platforms don't support including these threading related headers.
|
|
-#include <condition_variable> // NOLINT
|
|
-#include <mutex> // NOLINT
|
|
-#endif // GTEST_IS_THREADSAFE
|
|
-
|
|
-// GTEST_API_ qualifies all symbols that must be exported. The definitions below
|
|
-// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
|
|
-// gtest/internal/custom/gtest-port.h
|
|
-#ifndef GTEST_API_
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-#if GTEST_LINKED_AS_SHARED_LIBRARY
|
|
-#define GTEST_API_ __declspec(dllimport)
|
|
-#elif GTEST_CREATE_SHARED_LIBRARY
|
|
-#define GTEST_API_ __declspec(dllexport)
|
|
-#endif
|
|
-#elif __GNUC__ >= 4 || defined(__clang__)
|
|
-#define GTEST_API_ __attribute__((visibility("default")))
|
|
-#endif // _MSC_VER
|
|
-
|
|
-#endif // GTEST_API_
|
|
-
|
|
-#ifndef GTEST_API_
|
|
-#define GTEST_API_
|
|
-#endif // GTEST_API_
|
|
-
|
|
-#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE
|
|
-#define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
|
|
-#endif // GTEST_DEFAULT_DEATH_TEST_STYLE
|
|
-
|
|
-#ifdef __GNUC__
|
|
-// Ask the compiler to never inline a given function.
|
|
-#define GTEST_NO_INLINE_ __attribute__((noinline))
|
|
-#else
|
|
-#define GTEST_NO_INLINE_
|
|
-#endif
|
|
-
|
|
-#if defined(__clang__)
|
|
-// Nested ifs to avoid triggering MSVC warning.
|
|
-#if __has_attribute(disable_tail_calls)
|
|
-// Ask the compiler not to perform tail call optimization inside
|
|
-// the marked function.
|
|
-#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))
|
|
-#endif
|
|
-#elif __GNUC__
|
|
-#define GTEST_NO_TAIL_CALL_ \
|
|
- __attribute__((optimize("no-optimize-sibling-calls")))
|
|
-#else
|
|
-#define GTEST_NO_TAIL_CALL_
|
|
-#endif
|
|
-
|
|
-// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
|
|
-#if !defined(GTEST_HAS_CXXABI_H_)
|
|
-#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
|
|
-#define GTEST_HAS_CXXABI_H_ 1
|
|
-#else
|
|
-#define GTEST_HAS_CXXABI_H_ 0
|
|
-#endif
|
|
-#endif
|
|
-
|
|
-// A function level attribute to disable checking for use of uninitialized
|
|
-// memory when built with MemorySanitizer.
|
|
-#if defined(__clang__)
|
|
-#if __has_feature(memory_sanitizer)
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
-#endif // __has_feature(memory_sanitizer)
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
-#endif // __clang__
|
|
-
|
|
-// A function level attribute to disable AddressSanitizer instrumentation.
|
|
-#if defined(__clang__)
|
|
-#if __has_feature(address_sanitizer)
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \
|
|
- __attribute__((no_sanitize_address))
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
-#endif // __has_feature(address_sanitizer)
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
-#endif // __clang__
|
|
-
|
|
-// A function level attribute to disable HWAddressSanitizer instrumentation.
|
|
-#if defined(__clang__)
|
|
-#if __has_feature(hwaddress_sanitizer)
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \
|
|
- __attribute__((no_sanitize("hwaddress")))
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
|
-#endif // __has_feature(hwaddress_sanitizer)
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
|
-#endif // __clang__
|
|
-
|
|
-// A function level attribute to disable ThreadSanitizer instrumentation.
|
|
-#if defined(__clang__)
|
|
-#if __has_feature(thread_sanitizer)
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread))
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
-#endif // __has_feature(thread_sanitizer)
|
|
-#else
|
|
-#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
-#endif // __clang__
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-class Message;
|
|
-
|
|
-// Legacy imports for backwards compatibility.
|
|
-// New code should use std:: names directly.
|
|
-using std::get;
|
|
-using std::make_tuple;
|
|
-using std::tuple;
|
|
-using std::tuple_element;
|
|
-using std::tuple_size;
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// A secret type that Google Test users don't know about. It has no
|
|
-// definition on purpose. Therefore it's impossible to create a
|
|
-// Secret object, which is what we want.
|
|
-class Secret;
|
|
-
|
|
-// A helper for suppressing warnings on constant condition. It just
|
|
-// returns 'condition'.
|
|
-GTEST_API_ bool IsTrue(bool condition);
|
|
-
|
|
-// Defines RE.
|
|
-
|
|
-#if GTEST_USES_RE2
|
|
-
|
|
-// This is almost `using RE = ::RE2`, except it is copy-constructible, and it
|
|
-// needs to disambiguate the `std::string`, `absl::string_view`, and `const
|
|
-// char*` constructors.
|
|
-class GTEST_API_ RE {
|
|
- public:
|
|
- RE(absl::string_view regex) : regex_(regex) {} // NOLINT
|
|
- RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT
|
|
- RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT
|
|
- RE(const RE& other) : RE(other.pattern()) {}
|
|
-
|
|
- const std::string& pattern() const { return regex_.pattern(); }
|
|
-
|
|
- static bool FullMatch(absl::string_view str, const RE& re) {
|
|
- return RE2::FullMatch(str, re.regex_);
|
|
- }
|
|
- static bool PartialMatch(absl::string_view str, const RE& re) {
|
|
- return RE2::PartialMatch(str, re.regex_);
|
|
- }
|
|
-
|
|
- private:
|
|
- RE2 regex_;
|
|
-};
|
|
-
|
|
-#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE
|
|
-
|
|
-// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
|
|
-// Regular Expression syntax.
|
|
-class GTEST_API_ RE {
|
|
- public:
|
|
- // A copy constructor is required by the Standard to initialize object
|
|
- // references from r-values.
|
|
- RE(const RE& other) { Init(other.pattern()); }
|
|
-
|
|
- // Constructs an RE from a string.
|
|
- RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
|
|
-
|
|
- RE(const char* regex) { Init(regex); } // NOLINT
|
|
- ~RE();
|
|
-
|
|
- // Returns the string representation of the regex.
|
|
- const char* pattern() const { return pattern_; }
|
|
-
|
|
- // 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);
|
|
- }
|
|
- static bool PartialMatch(const ::std::string& str, const RE& re) {
|
|
- return PartialMatch(str.c_str(), re);
|
|
- }
|
|
-
|
|
- static bool FullMatch(const char* str, const RE& re);
|
|
- static bool PartialMatch(const char* str, const RE& re);
|
|
-
|
|
- private:
|
|
- void Init(const char* regex);
|
|
- const char* pattern_;
|
|
- bool is_valid_;
|
|
-
|
|
-#if GTEST_USES_POSIX_RE
|
|
-
|
|
- regex_t full_regex_; // For FullMatch().
|
|
- regex_t partial_regex_; // For PartialMatch().
|
|
-
|
|
-#else // GTEST_USES_SIMPLE_RE
|
|
-
|
|
- const char* full_pattern_; // For FullMatch();
|
|
-
|
|
-#endif
|
|
-};
|
|
-
|
|
-#endif // ::testing::internal::RE implementation
|
|
-
|
|
-// Formats a source file path and a line number as they would appear
|
|
-// in an error message from the compiler used to compile this code.
|
|
-GTEST_API_ ::std::string FormatFileLocation(const char* file, int line);
|
|
-
|
|
-// Formats a file location for compiler-independent XML output.
|
|
-// Although this function is not platform dependent, we put it next to
|
|
-// FormatFileLocation in order to contrast the two functions.
|
|
-GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,
|
|
- int line);
|
|
-
|
|
-// Defines logging utilities:
|
|
-// GTEST_LOG_(severity) - logs messages at the specified severity level. The
|
|
-// message itself is streamed into the macro.
|
|
-// LogToStderr() - directs all log messages to stderr.
|
|
-// FlushInfoLog() - flushes informational log messages.
|
|
-
|
|
-enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };
|
|
-
|
|
-// Formats log entry severity, provides a stream object for streaming the
|
|
-// log message, and terminates the message with a newline when going out of
|
|
-// scope.
|
|
-class GTEST_API_ GTestLog {
|
|
- public:
|
|
- GTestLog(GTestLogSeverity severity, const char* file, int line);
|
|
-
|
|
- // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
|
|
- ~GTestLog();
|
|
-
|
|
- ::std::ostream& GetStream() { return ::std::cerr; }
|
|
-
|
|
- private:
|
|
- const GTestLogSeverity severity_;
|
|
-
|
|
- GTestLog(const GTestLog&) = delete;
|
|
- GTestLog& operator=(const GTestLog&) = delete;
|
|
-};
|
|
-
|
|
-#if !defined(GTEST_LOG_)
|
|
-
|
|
-#define GTEST_LOG_(severity) \
|
|
- ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
|
|
- __FILE__, __LINE__) \
|
|
- .GetStream()
|
|
-
|
|
-inline void LogToStderr() {}
|
|
-inline void FlushInfoLog() { fflush(nullptr); }
|
|
-
|
|
-#endif // !defined(GTEST_LOG_)
|
|
-
|
|
-#if !defined(GTEST_CHECK_)
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE.
|
|
-//
|
|
-// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
|
-// is not satisfied.
|
|
-// Synopsis:
|
|
-// GTEST_CHECK_(boolean_condition);
|
|
-// or
|
|
-// GTEST_CHECK_(boolean_condition) << "Additional message";
|
|
-//
|
|
-// This checks the condition and if the condition is not satisfied
|
|
-// it prints message about the condition violation, including the
|
|
-// condition itself, plus additional message streamed into it, if any,
|
|
-// and then it aborts the program. It aborts the program irrespective of
|
|
-// whether it is built in the debug mode or not.
|
|
-#define GTEST_CHECK_(condition) \
|
|
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
|
- if (::testing::internal::IsTrue(condition)) \
|
|
- ; \
|
|
- else \
|
|
- GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
|
|
-#endif // !defined(GTEST_CHECK_)
|
|
-
|
|
-// An all-mode assert to verify that the given POSIX-style function
|
|
-// call returns 0 (indicating success). Known limitation: this
|
|
-// doesn't expand to a balanced 'if' statement, so enclose the macro
|
|
-// in {} if you need to use it as the only statement in an 'if'
|
|
-// branch.
|
|
-#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
|
|
- if (const int gtest_error = (posix_call)) \
|
|
- GTEST_LOG_(FATAL) << #posix_call << "failed with error " << gtest_error
|
|
-
|
|
-// 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:
|
|
-//
|
|
-// char ==> const char&
|
|
-// const char ==> const char&
|
|
-// char& ==> char&
|
|
-// const char& ==> const char&
|
|
-//
|
|
-// Note that the non-const reference will not have "const" added. This is
|
|
-// standard, and necessary so that "T" can always bind to "const T&".
|
|
-template <typename T>
|
|
-struct ConstRef {
|
|
- typedef const T& type;
|
|
-};
|
|
-template <typename T>
|
|
-struct ConstRef<T&> {
|
|
- typedef T& type;
|
|
-};
|
|
-
|
|
-// The argument T must depend on some template parameters.
|
|
-#define GTEST_REFERENCE_TO_CONST_(T) \
|
|
- typename ::testing::internal::ConstRef<T>::type
|
|
-
|
|
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
|
-//
|
|
-// Use ImplicitCast_ as a safe version of static_cast for upcasting in
|
|
-// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a
|
|
-// const Foo*). When you use ImplicitCast_, the compiler checks that
|
|
-// the cast is safe. Such explicit ImplicitCast_s are necessary in
|
|
-// surprisingly many situations where C++ demands an exact type match
|
|
-// instead of an argument type convertible to a target type.
|
|
-//
|
|
-// The syntax for using ImplicitCast_ is the same as for static_cast:
|
|
-//
|
|
-// ImplicitCast_<ToType>(expr)
|
|
-//
|
|
-// ImplicitCast_ would have been part of the C++ standard library,
|
|
-// but the proposal was submitted too late. It will probably make
|
|
-// its way into the language in the future.
|
|
-//
|
|
-// This relatively ugly name is intentional. It prevents clashes with
|
|
-// similar functions users may have (e.g., implicit_cast). The internal
|
|
-// namespace alone is not enough because the function can be found by ADL.
|
|
-template <typename To>
|
|
-inline To ImplicitCast_(To x) {
|
|
- return x;
|
|
-}
|
|
-
|
|
-// When you upcast (that is, cast a pointer from type Foo to type
|
|
-// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts
|
|
-// always succeed. When you downcast (that is, cast a pointer from
|
|
-// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
|
|
-// how do you know the pointer is really of type SubclassOfFoo? It
|
|
-// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
|
|
-// when you downcast, you should use this macro. In debug mode, we
|
|
-// use dynamic_cast<> to double-check the downcast is legal (we die
|
|
-// if it's not). In normal mode, we do the efficient static_cast<>
|
|
-// instead. Thus, it's important to test in debug mode to make sure
|
|
-// the cast is legal!
|
|
-// This is the only place in the code we should use dynamic_cast<>.
|
|
-// In particular, you SHOULDN'T be using dynamic_cast<> in order to
|
|
-// do RTTI (eg code like this:
|
|
-// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
|
|
-// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
|
|
-// You should design the code some other way not to need this.
|
|
-//
|
|
-// This relatively ugly name is intentional. It prevents clashes with
|
|
-// similar functions users may have (e.g., down_cast). The internal
|
|
-// namespace alone is not enough because the function can be found by ADL.
|
|
-template <typename To, typename From> // use like this: DownCast_<T*>(foo);
|
|
-inline To DownCast_(From* f) { // so we only accept pointers
|
|
- // Ensures that To is a sub-type of From *. This test is here only
|
|
- // for compile-time type checking, and has no overhead in an
|
|
- // optimized build at run-time, as it will be optimized away
|
|
- // completely.
|
|
- GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
|
- if (false) {
|
|
- GTEST_INTENTIONAL_CONST_COND_POP_()
|
|
- const To to = nullptr;
|
|
- ::testing::internal::ImplicitCast_<From*>(to);
|
|
- }
|
|
-
|
|
-#if GTEST_HAS_RTTI
|
|
- // RTTI: debug mode only!
|
|
- GTEST_CHECK_(f == nullptr || dynamic_cast<To>(f) != nullptr);
|
|
-#endif
|
|
- return static_cast<To>(f);
|
|
-}
|
|
-
|
|
-// Downcasts the pointer of type Base to Derived.
|
|
-// Derived must be a subclass of Base. The parameter MUST
|
|
-// point to a class of type Derived, not any subclass of it.
|
|
-// When RTTI is available, the function performs a runtime
|
|
-// check to enforce this.
|
|
-template <class Derived, class Base>
|
|
-Derived* CheckedDowncastToActualType(Base* base) {
|
|
-#if GTEST_HAS_RTTI
|
|
- GTEST_CHECK_(typeid(*base) == typeid(Derived));
|
|
-#endif
|
|
-
|
|
-#if GTEST_HAS_DOWNCAST_
|
|
- return ::down_cast<Derived*>(base);
|
|
-#elif GTEST_HAS_RTTI
|
|
- return dynamic_cast<Derived*>(base); // NOLINT
|
|
-#else
|
|
- return static_cast<Derived*>(base); // Poor man's downcast.
|
|
-#endif
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_STREAM_REDIRECTION
|
|
-
|
|
-// Defines the stderr capturer:
|
|
-// CaptureStdout - starts capturing stdout.
|
|
-// GetCapturedStdout - stops capturing stdout and returns the captured string.
|
|
-// CaptureStderr - starts capturing stderr.
|
|
-// GetCapturedStderr - stops capturing stderr and returns the captured string.
|
|
-//
|
|
-GTEST_API_ void CaptureStdout();
|
|
-GTEST_API_ std::string GetCapturedStdout();
|
|
-GTEST_API_ void CaptureStderr();
|
|
-GTEST_API_ std::string GetCapturedStderr();
|
|
-
|
|
-#endif // GTEST_HAS_STREAM_REDIRECTION
|
|
-// Returns the size (in bytes) of a file.
|
|
-GTEST_API_ size_t GetFileSize(FILE* file);
|
|
-
|
|
-// Reads the entire content of a file as a string.
|
|
-GTEST_API_ std::string ReadEntireFile(FILE* file);
|
|
-
|
|
-// All command line arguments.
|
|
-GTEST_API_ std::vector<std::string> GetArgvs();
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-
|
|
-std::vector<std::string> GetInjectableArgvs();
|
|
-// Deprecated: pass the args vector by value instead.
|
|
-void SetInjectableArgvs(const std::vector<std::string>* new_argvs);
|
|
-void SetInjectableArgvs(const std::vector<std::string>& new_argvs);
|
|
-void ClearInjectableArgvs();
|
|
-
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-// Defines synchronization primitives.
|
|
-#if GTEST_IS_THREADSAFE
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-// Provides leak-safe Windows kernel handle ownership.
|
|
-// Used in death tests and in threading support.
|
|
-class GTEST_API_ AutoHandle {
|
|
- public:
|
|
- // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
|
|
- // avoid including <windows.h> in this header file. Including <windows.h> is
|
|
- // undesirable because it defines a lot of symbols and macros that tend to
|
|
- // conflict with client code. This assumption is verified by
|
|
- // WindowsTypesTest.HANDLEIsVoidStar.
|
|
- typedef void* Handle;
|
|
- AutoHandle();
|
|
- explicit AutoHandle(Handle handle);
|
|
-
|
|
- ~AutoHandle();
|
|
-
|
|
- Handle Get() const;
|
|
- void Reset();
|
|
- void Reset(Handle handle);
|
|
-
|
|
- private:
|
|
- // Returns true if and only if the handle is a valid handle object that can be
|
|
- // closed.
|
|
- bool IsCloseable() const;
|
|
-
|
|
- Handle handle_;
|
|
-
|
|
- AutoHandle(const AutoHandle&) = delete;
|
|
- AutoHandle& operator=(const AutoHandle&) = delete;
|
|
-};
|
|
-#endif
|
|
-
|
|
-#if GTEST_HAS_NOTIFICATION_
|
|
-// Notification has already been imported into the namespace.
|
|
-// Nothing to do here.
|
|
-
|
|
-#else
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-// Allows a controller thread to pause execution of newly created
|
|
-// threads until notified. Instances of this class must be created
|
|
-// and destroyed in the controller thread.
|
|
-//
|
|
-// This class is only for testing Google Test's own constructs. Do not
|
|
-// use it in user tests, either directly or indirectly.
|
|
-// TODO(b/203539622): Replace unconditionally with absl::Notification.
|
|
-class GTEST_API_ Notification {
|
|
- public:
|
|
- Notification() : notified_(false) {}
|
|
- Notification(const Notification&) = delete;
|
|
- Notification& operator=(const Notification&) = delete;
|
|
-
|
|
- // Notifies all threads created with this notification to start. Must
|
|
- // be called from the controller thread.
|
|
- void Notify() {
|
|
- std::lock_guard<std::mutex> lock(mu_);
|
|
- notified_ = true;
|
|
- cv_.notify_all();
|
|
- }
|
|
-
|
|
- // Blocks until the controller thread notifies. Must be called from a test
|
|
- // thread.
|
|
- void WaitForNotification() {
|
|
- std::unique_lock<std::mutex> lock(mu_);
|
|
- cv_.wait(lock, [this]() { return notified_; });
|
|
- }
|
|
-
|
|
- private:
|
|
- std::mutex mu_;
|
|
- std::condition_variable cv_;
|
|
- bool notified_;
|
|
-};
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-#endif // GTEST_HAS_NOTIFICATION_
|
|
-
|
|
-// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
|
|
-// defined, but we don't want to use MinGW's pthreads implementation, which
|
|
-// has conformance problems with some versions of the POSIX standard.
|
|
-#if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS
|
|
-
|
|
-// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
|
|
-// Consequently, it cannot select a correct instantiation of ThreadWithParam
|
|
-// in order to call its Run(). Introducing ThreadWithParamBase as a
|
|
-// non-templated base class for ThreadWithParam allows us to bypass this
|
|
-// problem.
|
|
-class ThreadWithParamBase {
|
|
- public:
|
|
- virtual ~ThreadWithParamBase() {}
|
|
- virtual void Run() = 0;
|
|
-};
|
|
-
|
|
-// pthread_create() accepts a pointer to a function type with the C linkage.
|
|
-// According to the Standard (7.5/1), function types with different linkages
|
|
-// are different even if they are otherwise identical. Some compilers (for
|
|
-// example, SunStudio) treat them as different types. Since class methods
|
|
-// cannot be defined with C-linkage we need to define a free C-function to
|
|
-// pass into pthread_create().
|
|
-extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
|
|
- static_cast<ThreadWithParamBase*>(thread)->Run();
|
|
- return nullptr;
|
|
-}
|
|
-
|
|
-// Helper class for testing Google Test's multi-threading constructs.
|
|
-// To use it, write:
|
|
-//
|
|
-// void ThreadFunc(int param) { /* Do things with param */ }
|
|
-// Notification thread_can_start;
|
|
-// ...
|
|
-// // The thread_can_start parameter is optional; you can supply NULL.
|
|
-// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
|
|
-// thread_can_start.Notify();
|
|
-//
|
|
-// These classes are only for testing Google Test's own constructs. Do
|
|
-// not use them in user tests, either directly or indirectly.
|
|
-template <typename T>
|
|
-class ThreadWithParam : public ThreadWithParamBase {
|
|
- public:
|
|
- typedef void UserThreadFunc(T);
|
|
-
|
|
- ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
|
- : func_(func),
|
|
- param_(param),
|
|
- thread_can_start_(thread_can_start),
|
|
- finished_(false) {
|
|
- ThreadWithParamBase* const base = this;
|
|
- // The thread can be created only after all fields except thread_
|
|
- // have been initialized.
|
|
- GTEST_CHECK_POSIX_SUCCESS_(
|
|
- pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base));
|
|
- }
|
|
- ~ThreadWithParam() override { Join(); }
|
|
-
|
|
- void Join() {
|
|
- if (!finished_) {
|
|
- GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr));
|
|
- finished_ = true;
|
|
- }
|
|
- }
|
|
-
|
|
- void Run() override {
|
|
- if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification();
|
|
- func_(param_);
|
|
- }
|
|
-
|
|
- private:
|
|
- UserThreadFunc* const func_; // User-supplied thread function.
|
|
- const T param_; // User-supplied parameter to the thread function.
|
|
- // When non-NULL, used to block execution until the controller thread
|
|
- // notifies.
|
|
- Notification* const thread_can_start_;
|
|
- bool finished_; // true if and only if we know that the thread function has
|
|
- // finished.
|
|
- pthread_t thread_; // The native thread object.
|
|
-
|
|
- ThreadWithParam(const ThreadWithParam&) = delete;
|
|
- ThreadWithParam& operator=(const ThreadWithParam&) = delete;
|
|
-};
|
|
-#endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD ||
|
|
- // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
|
|
-
|
|
-#if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
|
|
-// Mutex and ThreadLocal have already been imported into the namespace.
|
|
-// Nothing to do here.
|
|
-
|
|
-#elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
|
-
|
|
-// Mutex implements mutex on Windows platforms. It is used in conjunction
|
|
-// with class MutexLock:
|
|
-//
|
|
-// Mutex mutex;
|
|
-// ...
|
|
-// MutexLock lock(&mutex); // Acquires the mutex and releases it at the
|
|
-// // end of the current scope.
|
|
-//
|
|
-// A static Mutex *must* be defined or declared using one of the following
|
|
-// macros:
|
|
-// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
|
|
-// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
|
-//
|
|
-// (A non-static Mutex is defined/declared in the usual way).
|
|
-class GTEST_API_ Mutex {
|
|
- public:
|
|
- enum MutexType { kStatic = 0, kDynamic = 1 };
|
|
- // We rely on kStaticMutex being 0 as it is to what the linker initializes
|
|
- // type_ in static mutexes. critical_section_ will be initialized lazily
|
|
- // in ThreadSafeLazyInit().
|
|
- enum StaticConstructorSelector { kStaticMutex = 0 };
|
|
-
|
|
- // This constructor intentionally does nothing. It relies on type_ being
|
|
- // statically initialized to 0 (effectively setting it to kStatic) and on
|
|
- // ThreadSafeLazyInit() to lazily initialize the rest of the members.
|
|
- explicit Mutex(StaticConstructorSelector /*dummy*/) {}
|
|
-
|
|
- Mutex();
|
|
- ~Mutex();
|
|
-
|
|
- void Lock();
|
|
-
|
|
- void Unlock();
|
|
-
|
|
- // Does nothing if the current thread holds the mutex. Otherwise, crashes
|
|
- // with high probability.
|
|
- void AssertHeld();
|
|
-
|
|
- private:
|
|
- // Initializes owner_thread_id_ and critical_section_ in static mutexes.
|
|
- void ThreadSafeLazyInit();
|
|
-
|
|
- // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503,
|
|
- // we assume that 0 is an invalid value for thread IDs.
|
|
- unsigned int owner_thread_id_;
|
|
-
|
|
- // For static mutexes, we rely on these members being initialized to zeros
|
|
- // by the linker.
|
|
- MutexType type_;
|
|
- long critical_section_init_phase_; // NOLINT
|
|
- GTEST_CRITICAL_SECTION* critical_section_;
|
|
-
|
|
- Mutex(const Mutex&) = delete;
|
|
- Mutex& operator=(const Mutex&) = delete;
|
|
-};
|
|
-
|
|
-#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
|
- extern ::testing::internal::Mutex mutex
|
|
-
|
|
-#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
|
- ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex)
|
|
-
|
|
-// We cannot name this class MutexLock because the ctor declaration would
|
|
-// conflict with a macro named MutexLock, which is defined on some
|
|
-// platforms. That macro is used as a defensive measure to prevent against
|
|
-// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
|
-// "MutexLock l(&mu)". Hence the typedef trick below.
|
|
-class GTestMutexLock {
|
|
- public:
|
|
- explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
|
-
|
|
- ~GTestMutexLock() { mutex_->Unlock(); }
|
|
-
|
|
- private:
|
|
- Mutex* const mutex_;
|
|
-
|
|
- GTestMutexLock(const GTestMutexLock&) = delete;
|
|
- GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
|
-};
|
|
-
|
|
-typedef GTestMutexLock MutexLock;
|
|
-
|
|
-// Base class for ValueHolder<T>. Allows a caller to hold and delete a value
|
|
-// without knowing its type.
|
|
-class ThreadLocalValueHolderBase {
|
|
- public:
|
|
- virtual ~ThreadLocalValueHolderBase() {}
|
|
-};
|
|
-
|
|
-// Provides a way for a thread to send notifications to a ThreadLocal
|
|
-// regardless of its parameter type.
|
|
-class ThreadLocalBase {
|
|
- public:
|
|
- // Creates a new ValueHolder<T> object holding a default value passed to
|
|
- // this ThreadLocal<T>'s constructor and returns it. It is the caller's
|
|
- // responsibility not to call this when the ThreadLocal<T> instance already
|
|
- // has a value on the current thread.
|
|
- virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
|
|
-
|
|
- protected:
|
|
- ThreadLocalBase() {}
|
|
- virtual ~ThreadLocalBase() {}
|
|
-
|
|
- private:
|
|
- ThreadLocalBase(const ThreadLocalBase&) = delete;
|
|
- ThreadLocalBase& operator=(const ThreadLocalBase&) = delete;
|
|
-};
|
|
-
|
|
-// Maps a thread to a set of ThreadLocals that have values instantiated on that
|
|
-// thread and notifies them when the thread exits. A ThreadLocal instance is
|
|
-// expected to persist until all threads it has values on have terminated.
|
|
-class GTEST_API_ ThreadLocalRegistry {
|
|
- public:
|
|
- // Registers thread_local_instance as having value on the current thread.
|
|
- // Returns a value that can be used to identify the thread from other threads.
|
|
- static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
|
|
- const ThreadLocalBase* thread_local_instance);
|
|
-
|
|
- // Invoked when a ThreadLocal instance is destroyed.
|
|
- static void OnThreadLocalDestroyed(
|
|
- const ThreadLocalBase* thread_local_instance);
|
|
-};
|
|
-
|
|
-class GTEST_API_ ThreadWithParamBase {
|
|
- public:
|
|
- void Join();
|
|
-
|
|
- protected:
|
|
- class Runnable {
|
|
- public:
|
|
- virtual ~Runnable() {}
|
|
- virtual void Run() = 0;
|
|
- };
|
|
-
|
|
- ThreadWithParamBase(Runnable* runnable, Notification* thread_can_start);
|
|
- virtual ~ThreadWithParamBase();
|
|
-
|
|
- private:
|
|
- AutoHandle thread_;
|
|
-};
|
|
-
|
|
-// Helper class for testing Google Test's multi-threading constructs.
|
|
-template <typename T>
|
|
-class ThreadWithParam : public ThreadWithParamBase {
|
|
- public:
|
|
- typedef void UserThreadFunc(T);
|
|
-
|
|
- ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
|
- : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
|
|
- virtual ~ThreadWithParam() {}
|
|
-
|
|
- private:
|
|
- class RunnableImpl : public Runnable {
|
|
- public:
|
|
- RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
|
|
- virtual ~RunnableImpl() {}
|
|
- virtual void Run() { func_(param_); }
|
|
-
|
|
- private:
|
|
- UserThreadFunc* const func_;
|
|
- const T param_;
|
|
-
|
|
- RunnableImpl(const RunnableImpl&) = delete;
|
|
- RunnableImpl& operator=(const RunnableImpl&) = delete;
|
|
- };
|
|
-
|
|
- ThreadWithParam(const ThreadWithParam&) = delete;
|
|
- ThreadWithParam& operator=(const ThreadWithParam&) = delete;
|
|
-};
|
|
-
|
|
-// Implements thread-local storage on Windows systems.
|
|
-//
|
|
-// // Thread 1
|
|
-// ThreadLocal<int> tl(100); // 100 is the default value for each thread.
|
|
-//
|
|
-// // Thread 2
|
|
-// tl.set(150); // Changes the value for thread 2 only.
|
|
-// EXPECT_EQ(150, tl.get());
|
|
-//
|
|
-// // Thread 1
|
|
-// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value.
|
|
-// tl.set(200);
|
|
-// EXPECT_EQ(200, tl.get());
|
|
-//
|
|
-// The template type argument T must have a public copy constructor.
|
|
-// In addition, the default ThreadLocal constructor requires T to have
|
|
-// a public default constructor.
|
|
-//
|
|
-// The users of a TheadLocal instance have to make sure that all but one
|
|
-// threads (including the main one) using that instance have exited before
|
|
-// destroying it. Otherwise, the per-thread objects managed for them by the
|
|
-// ThreadLocal instance are not guaranteed to be destroyed on all platforms.
|
|
-//
|
|
-// Google Test only uses global ThreadLocal objects. That means they
|
|
-// will die after main() has returned. Therefore, no per-thread
|
|
-// object managed by Google Test will be leaked as long as all threads
|
|
-// using Google Test have exited when main() returns.
|
|
-template <typename T>
|
|
-class ThreadLocal : public ThreadLocalBase {
|
|
- public:
|
|
- ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
|
|
- explicit ThreadLocal(const T& value)
|
|
- : default_factory_(new InstanceValueHolderFactory(value)) {}
|
|
-
|
|
- ~ThreadLocal() override { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }
|
|
-
|
|
- T* pointer() { return GetOrCreateValue(); }
|
|
- const T* pointer() const { return GetOrCreateValue(); }
|
|
- const T& get() const { return *pointer(); }
|
|
- void set(const T& value) { *pointer() = value; }
|
|
-
|
|
- private:
|
|
- // Holds a value of T. Can be deleted via its base class without the caller
|
|
- // knowing the type of T.
|
|
- class ValueHolder : public ThreadLocalValueHolderBase {
|
|
- public:
|
|
- ValueHolder() : value_() {}
|
|
- explicit ValueHolder(const T& value) : value_(value) {}
|
|
-
|
|
- T* pointer() { return &value_; }
|
|
-
|
|
- private:
|
|
- T value_;
|
|
- ValueHolder(const ValueHolder&) = delete;
|
|
- ValueHolder& operator=(const ValueHolder&) = delete;
|
|
- };
|
|
-
|
|
- T* GetOrCreateValue() const {
|
|
- return static_cast<ValueHolder*>(
|
|
- ThreadLocalRegistry::GetValueOnCurrentThread(this))
|
|
- ->pointer();
|
|
- }
|
|
-
|
|
- ThreadLocalValueHolderBase* NewValueForCurrentThread() const override {
|
|
- return default_factory_->MakeNewHolder();
|
|
- }
|
|
-
|
|
- class ValueHolderFactory {
|
|
- public:
|
|
- ValueHolderFactory() {}
|
|
- virtual ~ValueHolderFactory() {}
|
|
- virtual ValueHolder* MakeNewHolder() const = 0;
|
|
-
|
|
- private:
|
|
- ValueHolderFactory(const ValueHolderFactory&) = delete;
|
|
- ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;
|
|
- };
|
|
-
|
|
- class DefaultValueHolderFactory : public ValueHolderFactory {
|
|
- public:
|
|
- DefaultValueHolderFactory() {}
|
|
- ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
|
|
-
|
|
- private:
|
|
- DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;
|
|
- DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =
|
|
- delete;
|
|
- };
|
|
-
|
|
- class InstanceValueHolderFactory : public ValueHolderFactory {
|
|
- public:
|
|
- explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
|
|
- ValueHolder* MakeNewHolder() const override {
|
|
- return new ValueHolder(value_);
|
|
- }
|
|
-
|
|
- private:
|
|
- const T value_; // The value for each thread.
|
|
-
|
|
- InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;
|
|
- InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =
|
|
- delete;
|
|
- };
|
|
-
|
|
- std::unique_ptr<ValueHolderFactory> default_factory_;
|
|
-
|
|
- ThreadLocal(const ThreadLocal&) = delete;
|
|
- ThreadLocal& operator=(const ThreadLocal&) = delete;
|
|
-};
|
|
-
|
|
-#elif GTEST_HAS_PTHREAD
|
|
-
|
|
-// MutexBase and Mutex implement mutex on pthreads-based platforms.
|
|
-class MutexBase {
|
|
- public:
|
|
- // Acquires this mutex.
|
|
- void Lock() {
|
|
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
|
|
- owner_ = pthread_self();
|
|
- has_owner_ = true;
|
|
- }
|
|
-
|
|
- // Releases this mutex.
|
|
- void Unlock() {
|
|
- // Since the lock is being released the owner_ field should no longer be
|
|
- // considered valid. We don't protect writing to has_owner_ here, as it's
|
|
- // the caller's responsibility to ensure that the current thread holds the
|
|
- // mutex when this is called.
|
|
- has_owner_ = false;
|
|
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
|
|
- }
|
|
-
|
|
- // Does nothing if the current thread holds the mutex. Otherwise, crashes
|
|
- // with high probability.
|
|
- void AssertHeld() const {
|
|
- GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))
|
|
- << "The current thread is not holding the mutex @" << this;
|
|
- }
|
|
-
|
|
- // A static mutex may be used before main() is entered. It may even
|
|
- // be used before the dynamic initialization stage. Therefore we
|
|
- // must be able to initialize a static mutex object at link time.
|
|
- // This means MutexBase has to be a POD and its member variables
|
|
- // have to be public.
|
|
- public:
|
|
- pthread_mutex_t mutex_; // The underlying pthread mutex.
|
|
- // has_owner_ indicates whether the owner_ field below contains a valid thread
|
|
- // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All
|
|
- // accesses to the owner_ field should be protected by a check of this field.
|
|
- // An alternative might be to memset() owner_ to all zeros, but there's no
|
|
- // guarantee that a zero'd pthread_t is necessarily invalid or even different
|
|
- // from pthread_self().
|
|
- bool has_owner_;
|
|
- pthread_t owner_; // The thread holding the mutex.
|
|
-};
|
|
-
|
|
-// Forward-declares a static mutex.
|
|
-#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
|
- extern ::testing::internal::MutexBase mutex
|
|
-
|
|
-// Defines and statically (i.e. at link time) initializes a static mutex.
|
|
-// The initialization list here does not explicitly initialize each field,
|
|
-// instead relying on default initialization for the unspecified fields. In
|
|
-// particular, the owner_ field (a pthread_t) is not explicitly initialized.
|
|
-// This allows initialization to work whether pthread_t is a scalar or struct.
|
|
-// The flag -Wmissing-field-initializers must not be specified for this to work.
|
|
-#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
|
- ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}
|
|
-
|
|
-// The Mutex class can only be used for mutexes created at runtime. It
|
|
-// shares its API with MutexBase otherwise.
|
|
-class Mutex : public MutexBase {
|
|
- public:
|
|
- Mutex() {
|
|
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
|
|
- has_owner_ = false;
|
|
- }
|
|
- ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); }
|
|
-
|
|
- private:
|
|
- Mutex(const Mutex&) = delete;
|
|
- Mutex& operator=(const Mutex&) = delete;
|
|
-};
|
|
-
|
|
-// We cannot name this class MutexLock because the ctor declaration would
|
|
-// conflict with a macro named MutexLock, which is defined on some
|
|
-// platforms. That macro is used as a defensive measure to prevent against
|
|
-// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
|
-// "MutexLock l(&mu)". Hence the typedef trick below.
|
|
-class GTestMutexLock {
|
|
- public:
|
|
- explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
|
|
-
|
|
- ~GTestMutexLock() { mutex_->Unlock(); }
|
|
-
|
|
- private:
|
|
- MutexBase* const mutex_;
|
|
-
|
|
- GTestMutexLock(const GTestMutexLock&) = delete;
|
|
- GTestMutexLock& operator=(const GTestMutexLock&) = delete;
|
|
-};
|
|
-
|
|
-typedef GTestMutexLock MutexLock;
|
|
-
|
|
-// Helpers for ThreadLocal.
|
|
-
|
|
-// pthread_key_create() requires DeleteThreadLocalValue() to have
|
|
-// C-linkage. Therefore it cannot be templatized to access
|
|
-// ThreadLocal<T>. Hence the need for class
|
|
-// ThreadLocalValueHolderBase.
|
|
-class ThreadLocalValueHolderBase {
|
|
- public:
|
|
- virtual ~ThreadLocalValueHolderBase() {}
|
|
-};
|
|
-
|
|
-// Called by pthread to delete thread-local data stored by
|
|
-// pthread_setspecific().
|
|
-extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
|
|
- delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
|
|
-}
|
|
-
|
|
-// Implements thread-local storage on pthreads-based systems.
|
|
-template <typename T>
|
|
-class GTEST_API_ ThreadLocal {
|
|
- public:
|
|
- ThreadLocal()
|
|
- : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
|
|
- explicit ThreadLocal(const T& value)
|
|
- : key_(CreateKey()),
|
|
- default_factory_(new InstanceValueHolderFactory(value)) {}
|
|
-
|
|
- ~ThreadLocal() {
|
|
- // Destroys the managed object for the current thread, if any.
|
|
- DeleteThreadLocalValue(pthread_getspecific(key_));
|
|
-
|
|
- // Releases resources associated with the key. This will *not*
|
|
- // delete managed objects for other threads.
|
|
- GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
|
|
- }
|
|
-
|
|
- T* pointer() { return GetOrCreateValue(); }
|
|
- const T* pointer() const { return GetOrCreateValue(); }
|
|
- const T& get() const { return *pointer(); }
|
|
- void set(const T& value) { *pointer() = value; }
|
|
-
|
|
- private:
|
|
- // Holds a value of type T.
|
|
- class ValueHolder : public ThreadLocalValueHolderBase {
|
|
- public:
|
|
- ValueHolder() : value_() {}
|
|
- explicit ValueHolder(const T& value) : value_(value) {}
|
|
-
|
|
- T* pointer() { return &value_; }
|
|
-
|
|
- private:
|
|
- T value_;
|
|
- ValueHolder(const ValueHolder&) = delete;
|
|
- ValueHolder& operator=(const ValueHolder&) = delete;
|
|
- };
|
|
-
|
|
- static pthread_key_t CreateKey() {
|
|
- pthread_key_t key;
|
|
- // When a thread exits, DeleteThreadLocalValue() will be called on
|
|
- // the object managed for that thread.
|
|
- GTEST_CHECK_POSIX_SUCCESS_(
|
|
- pthread_key_create(&key, &DeleteThreadLocalValue));
|
|
- return key;
|
|
- }
|
|
-
|
|
- T* GetOrCreateValue() const {
|
|
- ThreadLocalValueHolderBase* const holder =
|
|
- static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
|
|
- if (holder != nullptr) {
|
|
- return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
|
|
- }
|
|
-
|
|
- ValueHolder* const new_holder = default_factory_->MakeNewHolder();
|
|
- ThreadLocalValueHolderBase* const holder_base = new_holder;
|
|
- GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
|
|
- return new_holder->pointer();
|
|
- }
|
|
-
|
|
- class ValueHolderFactory {
|
|
- public:
|
|
- ValueHolderFactory() {}
|
|
- virtual ~ValueHolderFactory() {}
|
|
- virtual ValueHolder* MakeNewHolder() const = 0;
|
|
-
|
|
- private:
|
|
- ValueHolderFactory(const ValueHolderFactory&) = delete;
|
|
- ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;
|
|
- };
|
|
-
|
|
- class DefaultValueHolderFactory : public ValueHolderFactory {
|
|
- public:
|
|
- DefaultValueHolderFactory() {}
|
|
- ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
|
|
-
|
|
- private:
|
|
- DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;
|
|
- DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =
|
|
- delete;
|
|
- };
|
|
-
|
|
- class InstanceValueHolderFactory : public ValueHolderFactory {
|
|
- public:
|
|
- explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
|
|
- ValueHolder* MakeNewHolder() const override {
|
|
- return new ValueHolder(value_);
|
|
- }
|
|
-
|
|
- private:
|
|
- const T value_; // The value for each thread.
|
|
-
|
|
- InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;
|
|
- InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =
|
|
- delete;
|
|
- };
|
|
-
|
|
- // A key pthreads uses for looking up per-thread values.
|
|
- const pthread_key_t key_;
|
|
- std::unique_ptr<ValueHolderFactory> default_factory_;
|
|
-
|
|
- ThreadLocal(const ThreadLocal&) = delete;
|
|
- ThreadLocal& operator=(const ThreadLocal&) = delete;
|
|
-};
|
|
-
|
|
-#endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
|
|
-
|
|
-#else // GTEST_IS_THREADSAFE
|
|
-
|
|
-// A dummy implementation of synchronization primitives (mutex, lock,
|
|
-// and thread-local variable). Necessary for compiling Google Test where
|
|
-// mutex is not supported - using Google Test in multiple threads is not
|
|
-// supported on such platforms.
|
|
-
|
|
-class Mutex {
|
|
- public:
|
|
- Mutex() {}
|
|
- void Lock() {}
|
|
- void Unlock() {}
|
|
- void AssertHeld() const {}
|
|
-};
|
|
-
|
|
-#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
|
- extern ::testing::internal::Mutex mutex
|
|
-
|
|
-#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
|
|
-
|
|
-// We cannot name this class MutexLock because the ctor declaration would
|
|
-// conflict with a macro named MutexLock, which is defined on some
|
|
-// platforms. That macro is used as a defensive measure to prevent against
|
|
-// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
|
-// "MutexLock l(&mu)". Hence the typedef trick below.
|
|
-class GTestMutexLock {
|
|
- public:
|
|
- explicit GTestMutexLock(Mutex*) {} // NOLINT
|
|
-};
|
|
-
|
|
-typedef GTestMutexLock MutexLock;
|
|
-
|
|
-template <typename T>
|
|
-class GTEST_API_ ThreadLocal {
|
|
- public:
|
|
- ThreadLocal() : value_() {}
|
|
- explicit ThreadLocal(const T& value) : value_(value) {}
|
|
- T* pointer() { return &value_; }
|
|
- const T* pointer() const { return &value_; }
|
|
- const T& get() const { return value_; }
|
|
- void set(const T& value) { value_ = value; }
|
|
-
|
|
- private:
|
|
- T value_;
|
|
-};
|
|
-
|
|
-#endif // GTEST_IS_THREADSAFE
|
|
-
|
|
-// Returns the number of threads running in the process, or 0 to indicate that
|
|
-// we cannot detect it.
|
|
-GTEST_API_ size_t GetThreadCount();
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-#define GTEST_PATH_SEP_ "\\"
|
|
-#define GTEST_HAS_ALT_PATH_SEP_ 1
|
|
-#else
|
|
-#define GTEST_PATH_SEP_ "/"
|
|
-#define GTEST_HAS_ALT_PATH_SEP_ 0
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-// Utilities for char.
|
|
-
|
|
-// isspace(int ch) and friends accept an unsigned char or EOF. char
|
|
-// may be signed, depending on the compiler (or compiler flags).
|
|
-// Therefore we need to cast a char to unsigned char before calling
|
|
-// isspace(), etc.
|
|
-
|
|
-inline bool IsAlpha(char ch) {
|
|
- return isalpha(static_cast<unsigned char>(ch)) != 0;
|
|
-}
|
|
-inline bool IsAlNum(char ch) {
|
|
- return isalnum(static_cast<unsigned char>(ch)) != 0;
|
|
-}
|
|
-inline bool IsDigit(char ch) {
|
|
- return isdigit(static_cast<unsigned char>(ch)) != 0;
|
|
-}
|
|
-inline bool IsLower(char ch) {
|
|
- return islower(static_cast<unsigned char>(ch)) != 0;
|
|
-}
|
|
-inline bool IsSpace(char ch) {
|
|
- return isspace(static_cast<unsigned char>(ch)) != 0;
|
|
-}
|
|
-inline bool IsUpper(char ch) {
|
|
- return isupper(static_cast<unsigned char>(ch)) != 0;
|
|
-}
|
|
-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;
|
|
-}
|
|
-
|
|
-inline char ToLower(char ch) {
|
|
- return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
|
|
-}
|
|
-inline char ToUpper(char ch) {
|
|
- return static_cast<char>(toupper(static_cast<unsigned char>(ch)));
|
|
-}
|
|
-
|
|
-inline std::string StripTrailingSpaces(std::string str) {
|
|
- std::string::iterator it = str.end();
|
|
- while (it != str.begin() && IsSpace(*--it)) it = str.erase(it);
|
|
- return str;
|
|
-}
|
|
-
|
|
-// The testing::internal::posix namespace holds wrappers for common
|
|
-// POSIX functions. These wrappers hide the differences between
|
|
-// Windows/MSVC and POSIX systems. Since some compilers define these
|
|
-// standard functions as macros, the wrapper cannot have the same name
|
|
-// as the wrapped function.
|
|
-
|
|
-namespace posix {
|
|
-
|
|
-// Functions with a different name on Windows.
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-
|
|
-typedef struct _stat StatStruct;
|
|
-
|
|
-#ifdef __BORLANDC__
|
|
-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 || GTEST_OS_ZOS || GTEST_OS_IOS || \
|
|
- GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM)
|
|
-inline int DoIsATTY(int /* fd */) { return 0; }
|
|
-#else
|
|
-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);
|
|
-}
|
|
-inline char* StrDup(const char* src) { return _strdup(src); }
|
|
-#endif // __BORLANDC__
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
-inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
|
|
-// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
|
|
-// time and thus not defined there.
|
|
-#else
|
|
-inline int FileNo(FILE* file) { return _fileno(file); }
|
|
-inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
|
|
-inline int RmDir(const char* dir) { return _rmdir(dir); }
|
|
-inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
|
|
-#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 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);
|
|
-}
|
|
-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); }
|
|
-
|
|
-#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_()
|
|
-
|
|
-// 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 && !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) {
|
|
- return freopen(path, mode, stream);
|
|
-}
|
|
-inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
|
|
-#endif
|
|
-inline int FClose(FILE* fp) { return fclose(fp); }
|
|
-#if !GTEST_OS_WINDOWS_MOBILE
|
|
-inline int Read(int fd, void* buf, unsigned int count) {
|
|
- return static_cast<int>(read(fd, buf, count));
|
|
-}
|
|
-inline int Write(int fd, const void* buf, unsigned int count) {
|
|
- return static_cast<int>(write(fd, buf, count));
|
|
-}
|
|
-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 || 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)
|
|
- // Environment variables which we programmatically clear will be set to the
|
|
- // empty string rather than unset (NULL). Handle that case.
|
|
- const char* const env = getenv(name);
|
|
- return (env != nullptr && env[0] != '\0') ? env : nullptr;
|
|
-#else
|
|
- return getenv(name);
|
|
-#endif
|
|
-}
|
|
-
|
|
-GTEST_DISABLE_MSC_DEPRECATED_POP_()
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
-// Windows CE has no C library. The abort() function is used in
|
|
-// several places in Google Test. This implementation provides a reasonable
|
|
-// imitation of standard behaviour.
|
|
-[[noreturn]] void Abort();
|
|
-#else
|
|
-[[noreturn]] inline void Abort() { abort(); }
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
-} // namespace posix
|
|
-
|
|
-// MSVC "deprecates" snprintf and issues warnings wherever it is used. In
|
|
-// order to avoid these warnings, we need to use _snprintf or _snprintf_s on
|
|
-// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate
|
|
-// function in order to achieve that. We use macro definition here because
|
|
-// snprintf is a variadic function.
|
|
-#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE
|
|
-// MSVC 2005 and above support variadic macros.
|
|
-#define GTEST_SNPRINTF_(buffer, size, format, ...) \
|
|
- _snprintf_s(buffer, size, size, format, __VA_ARGS__)
|
|
-#elif defined(_MSC_VER)
|
|
-// Windows CE does not define _snprintf_s
|
|
-#define GTEST_SNPRINTF_ _snprintf
|
|
-#else
|
|
-#define GTEST_SNPRINTF_ snprintf
|
|
-#endif
|
|
-
|
|
-// The biggest signed integer type the compiler supports.
|
|
-//
|
|
-// 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
|
|
-// size. e.g.
|
|
-//
|
|
-// TypeWithSize<4>::UInt
|
|
-//
|
|
-// is typedef-ed to be unsigned int (unsigned integer made up of 4
|
|
-// bytes).
|
|
-//
|
|
-// Such functionality should belong to STL, but I cannot find it
|
|
-// there.
|
|
-//
|
|
-// Google Test uses this class in the implementation of floating-point
|
|
-// comparison.
|
|
-//
|
|
-// For now it only handles UInt (unsigned int) as that's all Google Test
|
|
-// needs. Other types can be easily added in the future if need
|
|
-// arises.
|
|
-template <size_t size>
|
|
-class TypeWithSize {
|
|
- public:
|
|
- // This prevents the user from using TypeWithSize<N> with incorrect
|
|
- // values of N.
|
|
- using UInt = void;
|
|
-};
|
|
-
|
|
-// The specialization for size 4.
|
|
-template <>
|
|
-class TypeWithSize<4> {
|
|
- public:
|
|
- using Int = std::int32_t;
|
|
- using UInt = std::uint32_t;
|
|
-};
|
|
-
|
|
-// The specialization for size 8.
|
|
-template <>
|
|
-class TypeWithSize<8> {
|
|
- public:
|
|
- using Int = std::int64_t;
|
|
- using UInt = std::uint64_t;
|
|
-};
|
|
-
|
|
-// Integer types of known sizes.
|
|
-using TimeInMillis = int64_t; // Represents time in milliseconds.
|
|
-
|
|
-// Utilities for command line flags and environment variables.
|
|
-
|
|
-// Macro for referencing flags.
|
|
-#if !defined(GTEST_FLAG)
|
|
-#define GTEST_FLAG_NAME_(name) gtest_##name
|
|
-#define GTEST_FLAG(name) FLAGS_gtest_##name
|
|
-#endif // !defined(GTEST_FLAG)
|
|
-
|
|
-// Pick a command line flags implementation.
|
|
-#if GTEST_HAS_ABSL
|
|
-
|
|
-// Macros for defining flags.
|
|
-#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
|
- ABSL_FLAG(bool, GTEST_FLAG_NAME_(name), default_val, doc)
|
|
-#define GTEST_DEFINE_int32_(name, default_val, doc) \
|
|
- ABSL_FLAG(int32_t, GTEST_FLAG_NAME_(name), default_val, doc)
|
|
-#define GTEST_DEFINE_string_(name, default_val, doc) \
|
|
- ABSL_FLAG(std::string, GTEST_FLAG_NAME_(name), default_val, doc)
|
|
-
|
|
-// Macros for declaring flags.
|
|
-#define GTEST_DECLARE_bool_(name) \
|
|
- ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
|
|
-#define GTEST_DECLARE_int32_(name) \
|
|
- ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
|
|
-#define GTEST_DECLARE_string_(name) \
|
|
- ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
|
|
-
|
|
-#define GTEST_FLAG_SAVER_ ::absl::FlagSaver
|
|
-
|
|
-#define GTEST_FLAG_GET(name) ::absl::GetFlag(GTEST_FLAG(name))
|
|
-#define GTEST_FLAG_SET(name, value) \
|
|
- (void)(::absl::SetFlag(>EST_FLAG(name), value))
|
|
-#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
|
|
-
|
|
-#else // GTEST_HAS_ABSL
|
|
-
|
|
-// Macros for defining flags.
|
|
-#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
|
- namespace testing { \
|
|
- GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
|
|
- } \
|
|
- static_assert(true, "no-op to require trailing semicolon")
|
|
-#define GTEST_DEFINE_int32_(name, default_val, doc) \
|
|
- namespace testing { \
|
|
- GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
|
|
- } \
|
|
- static_assert(true, "no-op to require trailing semicolon")
|
|
-#define GTEST_DEFINE_string_(name, default_val, doc) \
|
|
- namespace testing { \
|
|
- GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
|
|
- } \
|
|
- static_assert(true, "no-op to require trailing semicolon")
|
|
-
|
|
-// Macros for declaring flags.
|
|
-#define GTEST_DECLARE_bool_(name) \
|
|
- namespace testing { \
|
|
- GTEST_API_ extern bool GTEST_FLAG(name); \
|
|
- } \
|
|
- static_assert(true, "no-op to require trailing semicolon")
|
|
-#define GTEST_DECLARE_int32_(name) \
|
|
- namespace testing { \
|
|
- GTEST_API_ extern std::int32_t GTEST_FLAG(name); \
|
|
- } \
|
|
- static_assert(true, "no-op to require trailing semicolon")
|
|
-#define GTEST_DECLARE_string_(name) \
|
|
- namespace testing { \
|
|
- GTEST_API_ extern ::std::string GTEST_FLAG(name); \
|
|
- } \
|
|
- static_assert(true, "no-op to require trailing semicolon")
|
|
-
|
|
-#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
|
|
-
|
|
-#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name)
|
|
-#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
|
|
-#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
|
|
-
|
|
-#endif // GTEST_HAS_ABSL
|
|
-
|
|
-// Thread annotations
|
|
-#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
|
-#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
|
-#define GTEST_LOCK_EXCLUDED_(locks)
|
|
-#endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
|
|
-
|
|
-// Parses 'str' for a 32-bit signed integer. If successful, writes the result
|
|
-// to *value and returns true; otherwise leaves *value unchanged and returns
|
|
-// false.
|
|
-GTEST_API_ bool ParseInt32(const Message& src_text, const char* str,
|
|
- int32_t* value);
|
|
-
|
|
-// 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_t Int32FromGTestEnv(const char* flag, int32_t default_val);
|
|
-std::string OutputFlagAlsoCheckEnvVar();
|
|
-const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-#if !defined(GTEST_INTERNAL_DEPRECATED)
|
|
-
|
|
-// Internal Macro to mark an API deprecated, for googletest usage only
|
|
-// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or
|
|
-// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of
|
|
-// a deprecated entity will trigger a warning when compiled with
|
|
-// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).
|
|
-// For msvc /W3 option will need to be used
|
|
-// Note that for 'other' compilers this macro evaluates to nothing to prevent
|
|
-// compilations errors.
|
|
-#if defined(_MSC_VER)
|
|
-#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))
|
|
-#elif defined(__GNUC__)
|
|
-#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))
|
|
-#else
|
|
-#define GTEST_INTERNAL_DEPRECATED(message)
|
|
-#endif
|
|
-
|
|
-#endif // !defined(GTEST_INTERNAL_DEPRECATED)
|
|
-
|
|
-#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>;
|
|
-inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
|
|
-} // 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>;
|
|
-inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
|
|
-} // 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_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-string.h b/vendor/gtest/include/gtest/internal/gtest-string.h
|
|
deleted file mode 100644
|
|
index cca2e1f2a..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-string.h
|
|
+++ /dev/null
|
|
@@ -1,177 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This header file declares the String class and functions used internally by
|
|
-// Google Test. They are subject to change without notice. They should not used
|
|
-// by code external to Google Test.
|
|
-//
|
|
-// This header file is #included by gtest-internal.h.
|
|
-// It should not be #included by other files.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#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.
|
|
-#include <mem.h>
|
|
-#endif
|
|
-
|
|
-#include <string.h>
|
|
-
|
|
-#include <cstdint>
|
|
-#include <string>
|
|
-
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-// String - an abstract class holding static string utilities.
|
|
-class GTEST_API_ String {
|
|
- public:
|
|
- // Static utility methods
|
|
-
|
|
- // Clones a 0-terminated C string, allocating memory using new. The
|
|
- // caller is responsible for deleting the return value using
|
|
- // delete[]. Returns the cloned string, or NULL if the input is
|
|
- // NULL.
|
|
- //
|
|
- // This is different from strdup() in string.h, which allocates
|
|
- // memory using malloc().
|
|
- static const char* CloneCString(const char* c_str);
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
- // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
|
- // able to pass strings to Win32 APIs on CE we need to convert them
|
|
- // to 'Unicode', UTF-16.
|
|
-
|
|
- // Creates a UTF-16 wide string from the given ANSI string, allocating
|
|
- // memory using new. The caller is responsible for deleting the return
|
|
- // value using delete[]. Returns the wide string, or NULL if the
|
|
- // input is NULL.
|
|
- //
|
|
- // The wide string is created using the ANSI codepage (CP_ACP) to
|
|
- // match the behaviour of the ANSI versions of Win32 calls and the
|
|
- // C runtime.
|
|
- static LPCWSTR AnsiToUtf16(const char* c_str);
|
|
-
|
|
- // Creates an ANSI string from the given wide string, allocating
|
|
- // memory using new. The caller is responsible for deleting the return
|
|
- // value using delete[]. Returns the ANSI string, or NULL if the
|
|
- // input is NULL.
|
|
- //
|
|
- // The returned string is created using the ANSI codepage (CP_ACP) to
|
|
- // match the behaviour of the ANSI versions of Win32 calls and the
|
|
- // C runtime.
|
|
- static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
|
-#endif
|
|
-
|
|
- // 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,
|
|
- // including the empty string.
|
|
- static bool CStringEquals(const char* lhs, const char* rhs);
|
|
-
|
|
- // Converts a wide C string to a String using the UTF-8 encoding.
|
|
- // NULL will be converted to "(null)". If an error occurred during
|
|
- // the conversion, "(failed to convert from wide string)" is
|
|
- // returned.
|
|
- static std::string ShowWideCString(const wchar_t* wide_c_str);
|
|
-
|
|
- // 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 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,
|
|
- // including the empty string.
|
|
- static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs);
|
|
-
|
|
- // 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,
|
|
- // including the empty string.
|
|
- // NB: The implementations on different platforms slightly differ.
|
|
- // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
|
- // environment variable. On GNU platform this method uses wcscasecmp
|
|
- // which compares according to LC_CTYPE category of the current locale.
|
|
- // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
|
- // current locale.
|
|
- static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
|
- const wchar_t* rhs);
|
|
-
|
|
- // 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_t value);
|
|
-
|
|
- // Formats a byte as "%02X".
|
|
- static std::string FormatByte(unsigned char value);
|
|
-
|
|
- private:
|
|
- String(); // Not meant to be instantiated.
|
|
-}; // class String
|
|
-
|
|
-// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
|
-// character in the buffer is replaced with "\\0".
|
|
-GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
|
diff --git a/vendor/gtest/include/gtest/internal/gtest-type-util.h b/vendor/gtest/include/gtest/internal/gtest-type-util.h
|
|
deleted file mode 100644
|
|
index 6bc02a7de..000000000
|
|
--- a/vendor/gtest/include/gtest/internal/gtest-type-util.h
|
|
+++ /dev/null
|
|
@@ -1,186 +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.
|
|
-
|
|
-// Type utilities needed for implementing typed and type-parameterized
|
|
-// tests.
|
|
-
|
|
-// IWYU pragma: private, include "gtest/gtest.h"
|
|
-// IWYU pragma: friend gtest/.*
|
|
-// IWYU pragma: friend gmock/.*
|
|
-
|
|
-#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
|
-#define GOOGLETEST_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;
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_RTTI
|
|
-// GetTypeName(const std::type_info&) returns a human-readable name of type T.
|
|
-inline std::string GetTypeName(const std::type_info& type) {
|
|
- const char* const name = type.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
|
|
-}
|
|
-#endif // GTEST_HAS_RTTI
|
|
-
|
|
-// GetTypeName<T>() returns a human-readable name of type T if and only if
|
|
-// RTTI is enabled, otherwise it returns a dummy type name.
|
|
-// 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
|
|
- return GetTypeName(typeid(T));
|
|
-#else
|
|
- return "<type>";
|
|
-#endif // GTEST_HAS_RTTI
|
|
-}
|
|
-
|
|
-// A unique type indicating an empty node
|
|
-struct None {};
|
|
-
|
|
-#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
|
|
-
|
|
-template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
|
|
-struct Templates {
|
|
- using Head = TemplateSel<Head_>;
|
|
- using Tail = Templates<Tail_...>;
|
|
-};
|
|
-
|
|
-template <GTEST_TEMPLATE_ Head_>
|
|
-struct Templates<Head_> {
|
|
- using Head = TemplateSel<Head_>;
|
|
- using Tail = None;
|
|
-};
|
|
-
|
|
-// Tuple-like type lists
|
|
-template <typename Head_, typename... Tail_>
|
|
-struct Types {
|
|
- using Head = Head_;
|
|
- using Tail = Types<Tail_...>;
|
|
-};
|
|
-
|
|
-template <typename Head_>
|
|
-struct Types<Head_> {
|
|
- using Head = Head_;
|
|
- using Tail = None;
|
|
-};
|
|
-
|
|
-// Helper metafunctions to tell apart a single type from types
|
|
-// generated by ::testing::Types
|
|
-template <typename... Ts>
|
|
-struct ProxyTypeList {
|
|
- using type = Types<Ts...>;
|
|
-};
|
|
-
|
|
-template <typename>
|
|
-struct is_proxy_type_list : std::false_type {};
|
|
-
|
|
-template <typename... Ts>
|
|
-struct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};
|
|
-
|
|
-// Generator which conditionally creates type lists.
|
|
-// It recognizes if a requested type list should be created
|
|
-// and prevents creating a new type list nested within another one.
|
|
-template <typename T>
|
|
-struct GenerateTypeList {
|
|
- private:
|
|
- using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,
|
|
- ProxyTypeList<T>>::type;
|
|
-
|
|
- public:
|
|
- using type = typename proxy::type;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-template <typename... Ts>
|
|
-using Types = internal::ProxyTypeList<Ts...>;
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
|
diff --git a/vendor/gtest/samples/prime_tables.h b/vendor/gtest/samples/prime_tables.h
|
|
deleted file mode 100644
|
|
index 7c0286e1a..000000000
|
|
--- a/vendor/gtest/samples/prime_tables.h
|
|
+++ /dev/null
|
|
@@ -1,124 +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.
|
|
-
|
|
-// This provides interface PrimeTable that determines whether a number is a
|
|
-// prime and determines a next prime number. This interface is used
|
|
-// in Google Test samples demonstrating use of parameterized tests.
|
|
-
|
|
-#ifndef GOOGLETEST_SAMPLES_PRIME_TABLES_H_
|
|
-#define GOOGLETEST_SAMPLES_PRIME_TABLES_H_
|
|
-
|
|
-#include <algorithm>
|
|
-
|
|
-// The prime table interface.
|
|
-class PrimeTable {
|
|
- public:
|
|
- virtual ~PrimeTable() {}
|
|
-
|
|
- // 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
|
|
- // if the next prime is beyond the capacity of the table.
|
|
- virtual int GetNextPrime(int p) const = 0;
|
|
-};
|
|
-
|
|
-// Implementation #1 calculates the primes on-the-fly.
|
|
-class OnTheFlyPrimeTable : public PrimeTable {
|
|
- public:
|
|
- bool IsPrime(int n) const override {
|
|
- if (n <= 1) return false;
|
|
-
|
|
- for (int i = 2; i * i <= n; i++) {
|
|
- // n is divisible by an integer other than 1 and itself.
|
|
- if ((n % i) == 0) return false;
|
|
- }
|
|
-
|
|
- return true;
|
|
- }
|
|
-
|
|
- int GetNextPrime(int p) const override {
|
|
- if (p < 0) return -1;
|
|
-
|
|
- for (int n = p + 1;; n++) {
|
|
- if (IsPrime(n)) return n;
|
|
- }
|
|
- }
|
|
-};
|
|
-
|
|
-// Implementation #2 pre-calculates the primes and stores the result
|
|
-// in an array.
|
|
-class PreCalculatedPrimeTable : public PrimeTable {
|
|
- public:
|
|
- // 'max' specifies the maximum number the prime table holds.
|
|
- explicit PreCalculatedPrimeTable(int max)
|
|
- : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
|
|
- CalculatePrimesUpTo(max);
|
|
- }
|
|
- ~PreCalculatedPrimeTable() override { delete[] is_prime_; }
|
|
-
|
|
- bool IsPrime(int n) const override {
|
|
- return 0 <= n && n < is_prime_size_ && is_prime_[n];
|
|
- }
|
|
-
|
|
- int GetNextPrime(int p) const override {
|
|
- for (int n = p + 1; n < is_prime_size_; n++) {
|
|
- if (is_prime_[n]) return n;
|
|
- }
|
|
-
|
|
- return -1;
|
|
- }
|
|
-
|
|
- private:
|
|
- void CalculatePrimesUpTo(int max) {
|
|
- ::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
|
|
- is_prime_[0] = is_prime_[1] = false;
|
|
-
|
|
- // Checks every candidate for prime number (we know that 2 is the only even
|
|
- // prime).
|
|
- for (int i = 2; i * i <= max; i += i % 2 + 1) {
|
|
- if (!is_prime_[i]) continue;
|
|
-
|
|
- // Marks all multiples of i (except i itself) as non-prime.
|
|
- // We are starting here from i-th multiplier, because all smaller
|
|
- // complex numbers were already marked.
|
|
- for (int j = i * i; j <= max; j += i) {
|
|
- is_prime_[j] = false;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- const int is_prime_size_;
|
|
- bool* const is_prime_;
|
|
-
|
|
- // Disables compiler warning "assignment operator could not be generated."
|
|
- void operator=(const PreCalculatedPrimeTable& rhs);
|
|
-};
|
|
-
|
|
-#endif // GOOGLETEST_SAMPLES_PRIME_TABLES_H_
|
|
diff --git a/vendor/gtest/samples/sample1.cc b/vendor/gtest/samples/sample1.cc
|
|
deleted file mode 100644
|
|
index 80b69f415..000000000
|
|
--- a/vendor/gtest/samples/sample1.cc
|
|
+++ /dev/null
|
|
@@ -1,66 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-#include "sample1.h"
|
|
-
|
|
-// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
|
|
-int Factorial(int n) {
|
|
- int result = 1;
|
|
- for (int i = 1; i <= n; i++) {
|
|
- result *= i;
|
|
- }
|
|
-
|
|
- return result;
|
|
-}
|
|
-
|
|
-// 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;
|
|
-
|
|
- // Trivial case 2: even numbers
|
|
- if (n % 2 == 0) return n == 2;
|
|
-
|
|
- // Now, we have that n is odd and n >= 3.
|
|
-
|
|
- // Try to divide n by every odd number i, starting from 3
|
|
- for (int i = 3;; i += 2) {
|
|
- // We only have to try i up to the square root of n
|
|
- if (i > n / i) break;
|
|
-
|
|
- // Now, we have i <= n/i < n.
|
|
- // If n is divisible by i, n is not prime.
|
|
- if (n % i == 0) return false;
|
|
- }
|
|
-
|
|
- // n has no integer factor in the range (1, n), and thus is prime.
|
|
- return true;
|
|
-}
|
|
diff --git a/vendor/gtest/samples/sample1.h b/vendor/gtest/samples/sample1.h
|
|
deleted file mode 100644
|
|
index ba392cfbd..000000000
|
|
--- a/vendor/gtest/samples/sample1.h
|
|
+++ /dev/null
|
|
@@ -1,41 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-#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 if and only if n is a prime number.
|
|
-bool IsPrime(int n);
|
|
-
|
|
-#endif // GOOGLETEST_SAMPLES_SAMPLE1_H_
|
|
diff --git a/vendor/gtest/samples/sample10_unittest.cc b/vendor/gtest/samples/sample10_unittest.cc
|
|
deleted file mode 100644
|
|
index 95b4811b8..000000000
|
|
--- a/vendor/gtest/samples/sample10_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,139 +0,0 @@
|
|
-// Copyright 2009 Google Inc. All Rights Reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// This sample shows how to use Google Test listener API to implement
|
|
-// a primitive leak checker.
|
|
-
|
|
-#include <stdio.h>
|
|
-#include <stdlib.h>
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-using ::testing::EmptyTestEventListener;
|
|
-using ::testing::InitGoogleTest;
|
|
-using ::testing::Test;
|
|
-using ::testing::TestEventListeners;
|
|
-using ::testing::TestInfo;
|
|
-using ::testing::TestPartResult;
|
|
-using ::testing::UnitTest;
|
|
-
|
|
-namespace {
|
|
-// We will track memory used by this class.
|
|
-class Water {
|
|
- public:
|
|
- // Normal Water declarations go here.
|
|
-
|
|
- // operator new and operator delete help us control water allocation.
|
|
- void* operator new(size_t allocation_size) {
|
|
- allocated_++;
|
|
- return malloc(allocation_size);
|
|
- }
|
|
-
|
|
- void operator delete(void* block, size_t /* allocation_size */) {
|
|
- allocated_--;
|
|
- free(block);
|
|
- }
|
|
-
|
|
- static int allocated() { return allocated_; }
|
|
-
|
|
- private:
|
|
- static int allocated_;
|
|
-};
|
|
-
|
|
-int Water::allocated_ = 0;
|
|
-
|
|
-// This event listener monitors how many Water objects are created and
|
|
-// destroyed by each test, and reports a failure if a test leaks some Water
|
|
-// objects. It does this by comparing the number of live Water objects at
|
|
-// the beginning of a test and at the end of a test.
|
|
-class LeakChecker : public EmptyTestEventListener {
|
|
- private:
|
|
- // Called before a test starts.
|
|
- void OnTestStart(const TestInfo& /* test_info */) override {
|
|
- initially_allocated_ = Water::allocated();
|
|
- }
|
|
-
|
|
- // Called after a test ends.
|
|
- void OnTestEnd(const TestInfo& /* test_info */) override {
|
|
- int difference = Water::allocated() - initially_allocated_;
|
|
-
|
|
- // You can generate a failure in any event handler except
|
|
- // OnTestPartResult. Just use an appropriate Google Test assertion to do
|
|
- // it.
|
|
- EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
|
|
- }
|
|
-
|
|
- int initially_allocated_;
|
|
-};
|
|
-
|
|
-TEST(ListenersTest, DoesNotLeak) {
|
|
- Water* water = new Water;
|
|
- delete water;
|
|
-}
|
|
-
|
|
-// This should fail when the --check_for_leaks command line flag is
|
|
-// specified.
|
|
-TEST(ListenersTest, LeaksWater) {
|
|
- Water* water = new Water;
|
|
- EXPECT_TRUE(water != nullptr);
|
|
-}
|
|
-} // namespace
|
|
-
|
|
-int main(int argc, char** argv) {
|
|
- InitGoogleTest(&argc, argv);
|
|
-
|
|
- bool check_for_leaks = false;
|
|
- if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0)
|
|
- check_for_leaks = true;
|
|
- else
|
|
- printf("%s\n",
|
|
- "Run this program with --check_for_leaks to enable "
|
|
- "custom leak checking in the tests.");
|
|
-
|
|
- // If we are given the --check_for_leaks command line flag, installs the
|
|
- // leak checker.
|
|
- if (check_for_leaks) {
|
|
- TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
|
|
-
|
|
- // Adds the leak checker to the end of the test event listener list,
|
|
- // after the default text output printer and the default XML report
|
|
- // generator.
|
|
- //
|
|
- // The order is important - it ensures that failures generated in the
|
|
- // leak checker's OnTestEnd() method are processed by the text and XML
|
|
- // printers *before* their OnTestEnd() methods are called, such that
|
|
- // they are attributed to the right test. Remember that a listener
|
|
- // receives an OnXyzStart event *after* listeners preceding it in the
|
|
- // list received that event, and receives an OnXyzEnd event *before*
|
|
- // listeners preceding it.
|
|
- //
|
|
- // We don't need to worry about deleting the new listener later, as
|
|
- // Google Test will do it.
|
|
- listeners.Append(new LeakChecker);
|
|
- }
|
|
- return RUN_ALL_TESTS();
|
|
-}
|
|
diff --git a/vendor/gtest/samples/sample1_unittest.cc b/vendor/gtest/samples/sample1_unittest.cc
|
|
deleted file mode 100644
|
|
index 60f2770ca..000000000
|
|
--- a/vendor/gtest/samples/sample1_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,148 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-// This sample shows how to write a simple unit test for a function,
|
|
-// using Google C++ testing framework.
|
|
-//
|
|
-// Writing a unit test using Google C++ testing framework is easy as 1-2-3:
|
|
-
|
|
-// Step 1. Include necessary header files such that the stuff your
|
|
-// test logic needs is declared.
|
|
-//
|
|
-// Don't forget gtest.h, which declares the testing framework.
|
|
-
|
|
-#include "sample1.h"
|
|
-
|
|
-#include <limits.h>
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-
|
|
-// Step 2. Use the TEST macro to define your tests.
|
|
-//
|
|
-// TEST has two parameters: the test case name and the test name.
|
|
-// After using the macro, you should define your test logic between a
|
|
-// pair of braces. You can use a bunch of macros to indicate the
|
|
-// success or failure of a test. EXPECT_TRUE and EXPECT_EQ are
|
|
-// examples of such macros. For a complete list, see gtest.h.
|
|
-//
|
|
-// <TechnicalDetails>
|
|
-//
|
|
-// In Google Test, tests are grouped into test cases. This is how we
|
|
-// keep test code organized. You should put logically related tests
|
|
-// into the same test case.
|
|
-//
|
|
-// The test case name and the test name should both be valid C++
|
|
-// identifiers. And you should not use underscore (_) in the names.
|
|
-//
|
|
-// Google Test guarantees that each test you define is run exactly
|
|
-// once, but it makes no guarantee on the order the tests are
|
|
-// executed. Therefore, you should write your tests in such a way
|
|
-// that their results don't depend on their order.
|
|
-//
|
|
-// </TechnicalDetails>
|
|
-
|
|
-// Tests Factorial().
|
|
-
|
|
-// Tests factorial of negative numbers.
|
|
-TEST(FactorialTest, Negative) {
|
|
- // This test is named "Negative", and belongs to the "FactorialTest"
|
|
- // test case.
|
|
- EXPECT_EQ(1, Factorial(-5));
|
|
- EXPECT_EQ(1, Factorial(-1));
|
|
- EXPECT_GT(Factorial(-10), 0);
|
|
-
|
|
- // <TechnicalDetails>
|
|
- //
|
|
- // EXPECT_EQ(expected, actual) is the same as
|
|
- //
|
|
- // EXPECT_TRUE((expected) == (actual))
|
|
- //
|
|
- // except that it will print both the expected value and the actual
|
|
- // value when the assertion fails. This is very helpful for
|
|
- // debugging. Therefore in this case EXPECT_EQ is preferred.
|
|
- //
|
|
- // On the other hand, EXPECT_TRUE accepts any Boolean expression,
|
|
- // and is thus more general.
|
|
- //
|
|
- // </TechnicalDetails>
|
|
-}
|
|
-
|
|
-// Tests factorial of 0.
|
|
-TEST(FactorialTest, Zero) { EXPECT_EQ(1, Factorial(0)); }
|
|
-
|
|
-// Tests factorial of positive numbers.
|
|
-TEST(FactorialTest, Positive) {
|
|
- EXPECT_EQ(1, Factorial(1));
|
|
- EXPECT_EQ(2, Factorial(2));
|
|
- EXPECT_EQ(6, Factorial(3));
|
|
- EXPECT_EQ(40320, Factorial(8));
|
|
-}
|
|
-
|
|
-// Tests IsPrime()
|
|
-
|
|
-// Tests negative input.
|
|
-TEST(IsPrimeTest, Negative) {
|
|
- // This test belongs to the IsPrimeTest test case.
|
|
-
|
|
- EXPECT_FALSE(IsPrime(-1));
|
|
- EXPECT_FALSE(IsPrime(-2));
|
|
- EXPECT_FALSE(IsPrime(INT_MIN));
|
|
-}
|
|
-
|
|
-// Tests some trivial cases.
|
|
-TEST(IsPrimeTest, Trivial) {
|
|
- EXPECT_FALSE(IsPrime(0));
|
|
- EXPECT_FALSE(IsPrime(1));
|
|
- EXPECT_TRUE(IsPrime(2));
|
|
- EXPECT_TRUE(IsPrime(3));
|
|
-}
|
|
-
|
|
-// Tests positive input.
|
|
-TEST(IsPrimeTest, Positive) {
|
|
- EXPECT_FALSE(IsPrime(4));
|
|
- EXPECT_TRUE(IsPrime(5));
|
|
- EXPECT_FALSE(IsPrime(6));
|
|
- EXPECT_TRUE(IsPrime(23));
|
|
-}
|
|
-} // namespace
|
|
-
|
|
-// Step 3. Call RUN_ALL_TESTS() in main().
|
|
-//
|
|
-// We do this by linking in src/gtest_main.cc file, which consists of
|
|
-// a main() function which calls RUN_ALL_TESTS() for us.
|
|
-//
|
|
-// This runs all the tests you've defined, prints the result, and
|
|
-// returns 0 if successful, or 1 otherwise.
|
|
-//
|
|
-// Did you notice that we didn't register the tests? The
|
|
-// RUN_ALL_TESTS() macro magically knows about all the tests we
|
|
-// defined. Isn't this convenient?
|
|
diff --git a/vendor/gtest/samples/sample2.cc b/vendor/gtest/samples/sample2.cc
|
|
deleted file mode 100644
|
|
index be7c4c994..000000000
|
|
--- a/vendor/gtest/samples/sample2.cc
|
|
+++ /dev/null
|
|
@@ -1,54 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-#include "sample2.h"
|
|
-
|
|
-#include <string.h>
|
|
-
|
|
-// Clones a 0-terminated C string, allocating memory using new.
|
|
-const char* MyString::CloneCString(const char* a_c_string) {
|
|
- if (a_c_string == nullptr) return nullptr;
|
|
-
|
|
- const size_t len = strlen(a_c_string);
|
|
- char* const clone = new char[len + 1];
|
|
- memcpy(clone, a_c_string, len + 1);
|
|
-
|
|
- return clone;
|
|
-}
|
|
-
|
|
-// Sets the 0-terminated C string this MyString object
|
|
-// represents.
|
|
-void MyString::Set(const char* a_c_string) {
|
|
- // Makes sure this works when c_string == c_string_
|
|
- const char* const temp = MyString::CloneCString(a_c_string);
|
|
- delete[] c_string_;
|
|
- c_string_ = temp;
|
|
-}
|
|
diff --git a/vendor/gtest/samples/sample2.h b/vendor/gtest/samples/sample2.h
|
|
deleted file mode 100644
|
|
index 15a1ce778..000000000
|
|
--- a/vendor/gtest/samples/sample2.h
|
|
+++ /dev/null
|
|
@@ -1,79 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-#ifndef GOOGLETEST_SAMPLES_SAMPLE2_H_
|
|
-#define GOOGLETEST_SAMPLES_SAMPLE2_H_
|
|
-
|
|
-#include <string.h>
|
|
-
|
|
-// A simple string class.
|
|
-class MyString {
|
|
- private:
|
|
- const char* c_string_;
|
|
- const MyString& operator=(const MyString& rhs);
|
|
-
|
|
- public:
|
|
- // Clones a 0-terminated C string, allocating memory using new.
|
|
- static const char* CloneCString(const char* a_c_string);
|
|
-
|
|
- ////////////////////////////////////////////////////////////
|
|
- //
|
|
- // C'tors
|
|
-
|
|
- // The default c'tor constructs a NULL string.
|
|
- MyString() : c_string_(nullptr) {}
|
|
-
|
|
- // Constructs a MyString by cloning a 0-terminated C string.
|
|
- explicit MyString(const char* a_c_string) : c_string_(nullptr) {
|
|
- Set(a_c_string);
|
|
- }
|
|
-
|
|
- // Copy c'tor
|
|
- MyString(const MyString& string) : c_string_(nullptr) {
|
|
- Set(string.c_string_);
|
|
- }
|
|
-
|
|
- ////////////////////////////////////////////////////////////
|
|
- //
|
|
- // D'tor. MyString is intended to be a final class, so the d'tor
|
|
- // doesn't need to be virtual.
|
|
- ~MyString() { delete[] c_string_; }
|
|
-
|
|
- // Gets the 0-terminated C string this MyString object represents.
|
|
- const char* c_string() const { return c_string_; }
|
|
-
|
|
- size_t Length() const { return c_string_ == nullptr ? 0 : strlen(c_string_); }
|
|
-
|
|
- // Sets the 0-terminated C string this MyString object represents.
|
|
- void Set(const char* c_string);
|
|
-};
|
|
-
|
|
-#endif // GOOGLETEST_SAMPLES_SAMPLE2_H_
|
|
diff --git a/vendor/gtest/samples/sample2_unittest.cc b/vendor/gtest/samples/sample2_unittest.cc
|
|
deleted file mode 100644
|
|
index cd734f943..000000000
|
|
--- a/vendor/gtest/samples/sample2_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,107 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-// This sample shows how to write a more complex unit test for a class
|
|
-// that has multiple member functions.
|
|
-//
|
|
-// Usually, it's a good idea to have one test for each method in your
|
|
-// class. You don't have to do that exactly, but it helps to keep
|
|
-// your tests organized. You may also throw in additional tests as
|
|
-// needed.
|
|
-
|
|
-#include "sample2.h"
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-// In this example, we test the MyString class (a simple string).
|
|
-
|
|
-// Tests the default c'tor.
|
|
-TEST(MyString, DefaultConstructor) {
|
|
- const MyString s;
|
|
-
|
|
- // Asserts that s.c_string() returns NULL.
|
|
- //
|
|
- // <TechnicalDetails>
|
|
- //
|
|
- // If we write NULL instead of
|
|
- //
|
|
- // static_cast<const char *>(NULL)
|
|
- //
|
|
- // in this assertion, it will generate a warning on gcc 3.4. The
|
|
- // reason is that EXPECT_EQ needs to know the types of its
|
|
- // arguments in order to print them when it fails. Since NULL is
|
|
- // #defined as 0, the compiler will use the formatter function for
|
|
- // int to print it. However, gcc thinks that NULL should be used as
|
|
- // a pointer, not an int, and therefore complains.
|
|
- //
|
|
- // The root of the problem is C++'s lack of distinction between the
|
|
- // integer number 0 and the null pointer constant. Unfortunately,
|
|
- // we have to live with this fact.
|
|
- //
|
|
- // </TechnicalDetails>
|
|
- EXPECT_STREQ(nullptr, s.c_string());
|
|
-
|
|
- EXPECT_EQ(0u, s.Length());
|
|
-}
|
|
-
|
|
-const char kHelloString[] = "Hello, world!";
|
|
-
|
|
-// Tests the c'tor that accepts a C string.
|
|
-TEST(MyString, ConstructorFromCString) {
|
|
- const MyString s(kHelloString);
|
|
- EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
|
|
- EXPECT_EQ(sizeof(kHelloString) / sizeof(kHelloString[0]) - 1, s.Length());
|
|
-}
|
|
-
|
|
-// Tests the copy c'tor.
|
|
-TEST(MyString, CopyConstructor) {
|
|
- const MyString s1(kHelloString);
|
|
- const MyString s2 = s1;
|
|
- EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
|
|
-}
|
|
-
|
|
-// Tests the Set method.
|
|
-TEST(MyString, Set) {
|
|
- MyString s;
|
|
-
|
|
- s.Set(kHelloString);
|
|
- EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
|
|
-
|
|
- // Set should work when the input pointer is the same as the one
|
|
- // already in the MyString object.
|
|
- s.Set(s.c_string());
|
|
- EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
|
|
-
|
|
- // Can we set the MyString to NULL?
|
|
- s.Set(nullptr);
|
|
- EXPECT_STREQ(nullptr, s.c_string());
|
|
-}
|
|
-} // namespace
|
|
diff --git a/vendor/gtest/samples/sample3-inl.h b/vendor/gtest/samples/sample3-inl.h
|
|
deleted file mode 100644
|
|
index bc3ffb9c4..000000000
|
|
--- a/vendor/gtest/samples/sample3-inl.h
|
|
+++ /dev/null
|
|
@@ -1,171 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-#ifndef GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
|
|
-#define GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
|
|
-
|
|
-#include <stddef.h>
|
|
-
|
|
-// Queue is a simple queue implemented as a singled-linked list.
|
|
-//
|
|
-// The element type must support copy constructor.
|
|
-template <typename E> // E is the element type
|
|
-class Queue;
|
|
-
|
|
-// QueueNode is a node in a Queue, which consists of an element of
|
|
-// type E and a pointer to the next node.
|
|
-template <typename E> // E is the element type
|
|
-class QueueNode {
|
|
- friend class Queue<E>;
|
|
-
|
|
- public:
|
|
- // Gets the element in this node.
|
|
- const E& element() const { return element_; }
|
|
-
|
|
- // Gets the next node in the queue.
|
|
- QueueNode* next() { return next_; }
|
|
- const QueueNode* next() const { return next_; }
|
|
-
|
|
- private:
|
|
- // Creates a node with a given element value. The next pointer is
|
|
- // set to NULL.
|
|
- explicit QueueNode(const E& an_element)
|
|
- : element_(an_element), next_(nullptr) {}
|
|
-
|
|
- // We disable the default assignment operator and copy c'tor.
|
|
- const QueueNode& operator=(const QueueNode&);
|
|
- QueueNode(const QueueNode&);
|
|
-
|
|
- E element_;
|
|
- QueueNode* next_;
|
|
-};
|
|
-
|
|
-template <typename E> // E is the element type.
|
|
-class Queue {
|
|
- public:
|
|
- // Creates an empty queue.
|
|
- Queue() : head_(nullptr), last_(nullptr), size_(0) {}
|
|
-
|
|
- // D'tor. Clears the queue.
|
|
- ~Queue() { Clear(); }
|
|
-
|
|
- // Clears the queue.
|
|
- void Clear() {
|
|
- if (size_ > 0) {
|
|
- // 1. Deletes every node.
|
|
- QueueNode<E>* node = head_;
|
|
- QueueNode<E>* next = node->next();
|
|
- for (;;) {
|
|
- delete node;
|
|
- node = next;
|
|
- if (node == nullptr) break;
|
|
- next = node->next();
|
|
- }
|
|
-
|
|
- // 2. Resets the member variables.
|
|
- head_ = last_ = nullptr;
|
|
- size_ = 0;
|
|
- }
|
|
- }
|
|
-
|
|
- // Gets the number of elements.
|
|
- size_t Size() const { return size_; }
|
|
-
|
|
- // Gets the first element of the queue, or NULL if the queue is empty.
|
|
- QueueNode<E>* Head() { return head_; }
|
|
- const QueueNode<E>* Head() const { return head_; }
|
|
-
|
|
- // Gets the last element of the queue, or NULL if the queue is empty.
|
|
- QueueNode<E>* Last() { return last_; }
|
|
- const QueueNode<E>* Last() const { return last_; }
|
|
-
|
|
- // Adds an element to the end of the queue. A copy of the element is
|
|
- // created using the copy constructor, and then stored in the queue.
|
|
- // Changes made to the element in the queue doesn't affect the source
|
|
- // object, and vice versa.
|
|
- void Enqueue(const E& element) {
|
|
- QueueNode<E>* new_node = new QueueNode<E>(element);
|
|
-
|
|
- if (size_ == 0) {
|
|
- head_ = last_ = new_node;
|
|
- size_ = 1;
|
|
- } else {
|
|
- last_->next_ = new_node;
|
|
- last_ = new_node;
|
|
- size_++;
|
|
- }
|
|
- }
|
|
-
|
|
- // Removes the head of the queue and returns it. Returns NULL if
|
|
- // the queue is empty.
|
|
- E* Dequeue() {
|
|
- if (size_ == 0) {
|
|
- return nullptr;
|
|
- }
|
|
-
|
|
- const QueueNode<E>* const old_head = head_;
|
|
- head_ = head_->next_;
|
|
- size_--;
|
|
- if (size_ == 0) {
|
|
- last_ = nullptr;
|
|
- }
|
|
-
|
|
- E* element = new E(old_head->element());
|
|
- delete old_head;
|
|
-
|
|
- return element;
|
|
- }
|
|
-
|
|
- // Applies a function/functor on each element of the queue, and
|
|
- // returns the result in a new queue. The original queue is not
|
|
- // affected.
|
|
- template <typename F>
|
|
- Queue* Map(F function) const {
|
|
- Queue* new_queue = new Queue();
|
|
- for (const QueueNode<E>* node = head_; node != nullptr;
|
|
- node = node->next_) {
|
|
- new_queue->Enqueue(function(node->element()));
|
|
- }
|
|
-
|
|
- return new_queue;
|
|
- }
|
|
-
|
|
- private:
|
|
- QueueNode<E>* head_; // The first node of the queue.
|
|
- QueueNode<E>* last_; // The last node of the queue.
|
|
- size_t size_; // The number of elements in the queue.
|
|
-
|
|
- // We disallow copying a queue.
|
|
- Queue(const Queue&);
|
|
- const Queue& operator=(const Queue&);
|
|
-};
|
|
-
|
|
-#endif // GOOGLETEST_SAMPLES_SAMPLE3_INL_H_
|
|
diff --git a/vendor/gtest/samples/sample3_unittest.cc b/vendor/gtest/samples/sample3_unittest.cc
|
|
deleted file mode 100644
|
|
index 71609c6a0..000000000
|
|
--- a/vendor/gtest/samples/sample3_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,146 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-// In this example, we use a more advanced feature of Google Test called
|
|
-// test fixture.
|
|
-//
|
|
-// A test fixture is a place to hold objects and functions shared by
|
|
-// all tests in a test case. Using a test fixture avoids duplicating
|
|
-// the test code necessary to initialize and cleanup those common
|
|
-// objects for each test. It is also useful for defining sub-routines
|
|
-// that your tests need to invoke a lot.
|
|
-//
|
|
-// <TechnicalDetails>
|
|
-//
|
|
-// The tests share the test fixture in the sense of code sharing, not
|
|
-// data sharing. Each test is given its own fresh copy of the
|
|
-// fixture. You cannot expect the data modified by one test to be
|
|
-// passed on to another test, which is a bad idea.
|
|
-//
|
|
-// The reason for this design is that tests should be independent and
|
|
-// repeatable. In particular, a test should not fail as the result of
|
|
-// another test's failure. If one test depends on info produced by
|
|
-// another test, then the two tests should really be one big test.
|
|
-//
|
|
-// The macros for indicating the success/failure of a test
|
|
-// (EXPECT_TRUE, FAIL, etc) need to know what the current test is
|
|
-// (when Google Test prints the test result, it tells you which test
|
|
-// each failure belongs to). Technically, these macros invoke a
|
|
-// member function of the Test class. Therefore, you cannot use them
|
|
-// in a global function. That's why you should put test sub-routines
|
|
-// in a test fixture.
|
|
-//
|
|
-// </TechnicalDetails>
|
|
-
|
|
-#include "sample3-inl.h"
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-// To use a test fixture, derive a class from testing::Test.
|
|
-class QueueTestSmpl3 : public testing::Test {
|
|
- protected: // You should make the members protected s.t. they can be
|
|
- // accessed from sub-classes.
|
|
- // virtual void SetUp() will be called before each test is run. You
|
|
- // should define it if you need to initialize the variables.
|
|
- // Otherwise, this can be skipped.
|
|
- void SetUp() override {
|
|
- q1_.Enqueue(1);
|
|
- q2_.Enqueue(2);
|
|
- q2_.Enqueue(3);
|
|
- }
|
|
-
|
|
- // virtual void TearDown() will be called after each test is run.
|
|
- // You should define it if there is cleanup work to do. Otherwise,
|
|
- // you don't have to provide it.
|
|
- //
|
|
- // virtual void TearDown() {
|
|
- // }
|
|
-
|
|
- // A helper function that some test uses.
|
|
- static int Double(int n) { return 2 * n; }
|
|
-
|
|
- // A helper function for testing Queue::Map().
|
|
- void MapTester(const Queue<int>* q) {
|
|
- // Creates a new queue, where each element is twice as big as the
|
|
- // corresponding one in q.
|
|
- const Queue<int>* const new_q = q->Map(Double);
|
|
-
|
|
- // Verifies that the new queue has the same size as q.
|
|
- ASSERT_EQ(q->Size(), new_q->Size());
|
|
-
|
|
- // Verifies the relationship between the elements of the two queues.
|
|
- for (const QueueNode<int>*n1 = q->Head(), *n2 = new_q->Head();
|
|
- n1 != nullptr; n1 = n1->next(), n2 = n2->next()) {
|
|
- EXPECT_EQ(2 * n1->element(), n2->element());
|
|
- }
|
|
-
|
|
- delete new_q;
|
|
- }
|
|
-
|
|
- // Declares the variables your tests want to use.
|
|
- Queue<int> q0_;
|
|
- Queue<int> q1_;
|
|
- Queue<int> q2_;
|
|
-};
|
|
-
|
|
-// When you have a test fixture, you define a test using TEST_F
|
|
-// instead of TEST.
|
|
-
|
|
-// Tests the default c'tor.
|
|
-TEST_F(QueueTestSmpl3, DefaultConstructor) {
|
|
- // You can access data in the test fixture here.
|
|
- EXPECT_EQ(0u, q0_.Size());
|
|
-}
|
|
-
|
|
-// Tests Dequeue().
|
|
-TEST_F(QueueTestSmpl3, Dequeue) {
|
|
- int* n = q0_.Dequeue();
|
|
- EXPECT_TRUE(n == nullptr);
|
|
-
|
|
- n = q1_.Dequeue();
|
|
- ASSERT_TRUE(n != nullptr);
|
|
- EXPECT_EQ(1, *n);
|
|
- EXPECT_EQ(0u, q1_.Size());
|
|
- delete n;
|
|
-
|
|
- n = q2_.Dequeue();
|
|
- ASSERT_TRUE(n != nullptr);
|
|
- EXPECT_EQ(2, *n);
|
|
- EXPECT_EQ(1u, q2_.Size());
|
|
- delete n;
|
|
-}
|
|
-
|
|
-// Tests the Queue::Map() function.
|
|
-TEST_F(QueueTestSmpl3, Map) {
|
|
- MapTester(&q0_);
|
|
- MapTester(&q1_);
|
|
- MapTester(&q2_);
|
|
-}
|
|
-} // namespace
|
|
diff --git a/vendor/gtest/samples/sample4.cc b/vendor/gtest/samples/sample4.cc
|
|
deleted file mode 100644
|
|
index 489c89b0d..000000000
|
|
--- a/vendor/gtest/samples/sample4.cc
|
|
+++ /dev/null
|
|
@@ -1,50 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-
|
|
-#include "sample4.h"
|
|
-
|
|
-#include <stdio.h>
|
|
-
|
|
-// Returns the current counter value, and increments it.
|
|
-int Counter::Increment() { return counter_++; }
|
|
-
|
|
-// Returns the current counter value, and decrements it.
|
|
-// counter can not be less than 0, return 0 in this case
|
|
-int Counter::Decrement() {
|
|
- if (counter_ == 0) {
|
|
- return counter_;
|
|
- } else {
|
|
- return counter_--;
|
|
- }
|
|
-}
|
|
-
|
|
-// Prints the current counter value to STDOUT.
|
|
-void Counter::Print() const { printf("%d", counter_); }
|
|
diff --git a/vendor/gtest/samples/sample4.h b/vendor/gtest/samples/sample4.h
|
|
deleted file mode 100644
|
|
index 0c4ed92e7..000000000
|
|
--- a/vendor/gtest/samples/sample4.h
|
|
+++ /dev/null
|
|
@@ -1,53 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// A sample program demonstrating using Google C++ testing framework.
|
|
-#ifndef GOOGLETEST_SAMPLES_SAMPLE4_H_
|
|
-#define GOOGLETEST_SAMPLES_SAMPLE4_H_
|
|
-
|
|
-// A simple monotonic counter.
|
|
-class Counter {
|
|
- private:
|
|
- int counter_;
|
|
-
|
|
- public:
|
|
- // Creates a counter that starts at 0.
|
|
- Counter() : counter_(0) {}
|
|
-
|
|
- // Returns the current counter value, and increments it.
|
|
- int Increment();
|
|
-
|
|
- // Returns the current counter value, and decrements it.
|
|
- int Decrement();
|
|
-
|
|
- // Prints the current counter value to STDOUT.
|
|
- void Print() const;
|
|
-};
|
|
-
|
|
-#endif // GOOGLETEST_SAMPLES_SAMPLE4_H_
|
|
diff --git a/vendor/gtest/samples/sample4_unittest.cc b/vendor/gtest/samples/sample4_unittest.cc
|
|
deleted file mode 100644
|
|
index fb9973fe6..000000000
|
|
--- a/vendor/gtest/samples/sample4_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,53 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-#include "sample4.h"
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-namespace {
|
|
-// Tests the Increment() method.
|
|
-
|
|
-TEST(Counter, Increment) {
|
|
- Counter c;
|
|
-
|
|
- // Test that counter 0 returns 0
|
|
- EXPECT_EQ(0, c.Decrement());
|
|
-
|
|
- // EXPECT_EQ() evaluates its arguments exactly once, so they
|
|
- // can have side effects.
|
|
-
|
|
- EXPECT_EQ(0, c.Increment());
|
|
- EXPECT_EQ(1, c.Increment());
|
|
- EXPECT_EQ(2, c.Increment());
|
|
-
|
|
- EXPECT_EQ(3, c.Decrement());
|
|
-}
|
|
-
|
|
-} // namespace
|
|
diff --git a/vendor/gtest/samples/sample5_unittest.cc b/vendor/gtest/samples/sample5_unittest.cc
|
|
deleted file mode 100644
|
|
index cc8c0f012..000000000
|
|
--- a/vendor/gtest/samples/sample5_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,189 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// This sample teaches how to reuse a test fixture in multiple test
|
|
-// cases by deriving sub-fixtures from it.
|
|
-//
|
|
-// When you define a test fixture, you specify the name of the test
|
|
-// case that will use this fixture. Therefore, a test fixture can
|
|
-// be used by only one test case.
|
|
-//
|
|
-// Sometimes, more than one test cases may want to use the same or
|
|
-// slightly different test fixtures. For example, you may want to
|
|
-// make sure that all tests for a GUI library don't leak important
|
|
-// system resources like fonts and brushes. In Google Test, you do
|
|
-// this by putting the shared logic in a super (as in "super class")
|
|
-// test fixture, and then have each test case use a fixture derived
|
|
-// from this super fixture.
|
|
-
|
|
-#include <limits.h>
|
|
-#include <time.h>
|
|
-
|
|
-#include "sample1.h"
|
|
-#include "sample3-inl.h"
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-// In this sample, we want to ensure that every test finishes within
|
|
-// ~5 seconds. If a test takes longer to run, we consider it a
|
|
-// failure.
|
|
-//
|
|
-// We put the code for timing a test in a test fixture called
|
|
-// "QuickTest". QuickTest is intended to be the super fixture that
|
|
-// other fixtures derive from, therefore there is no test case with
|
|
-// the name "QuickTest". This is OK.
|
|
-//
|
|
-// Later, we will derive multiple test fixtures from QuickTest.
|
|
-class QuickTest : public testing::Test {
|
|
- protected:
|
|
- // Remember that SetUp() is run immediately before a test starts.
|
|
- // This is a good place to record the start time.
|
|
- void SetUp() override { start_time_ = time(nullptr); }
|
|
-
|
|
- // TearDown() is invoked immediately after a test finishes. Here we
|
|
- // check if the test was too slow.
|
|
- void TearDown() override {
|
|
- // Gets the time when the test finishes
|
|
- const time_t end_time = time(nullptr);
|
|
-
|
|
- // Asserts that the test took no more than ~5 seconds. Did you
|
|
- // know that you can use assertions in SetUp() and TearDown() as
|
|
- // well?
|
|
- EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
|
|
- }
|
|
-
|
|
- // The UTC time (in seconds) when the test starts
|
|
- time_t start_time_;
|
|
-};
|
|
-
|
|
-// We derive a fixture named IntegerFunctionTest from the QuickTest
|
|
-// fixture. All tests using this fixture will be automatically
|
|
-// required to be quick.
|
|
-class IntegerFunctionTest : public QuickTest {
|
|
- // We don't need any more logic than already in the QuickTest fixture.
|
|
- // Therefore the body is empty.
|
|
-};
|
|
-
|
|
-// Now we can write tests in the IntegerFunctionTest test case.
|
|
-
|
|
-// Tests Factorial()
|
|
-TEST_F(IntegerFunctionTest, Factorial) {
|
|
- // Tests factorial of negative numbers.
|
|
- EXPECT_EQ(1, Factorial(-5));
|
|
- EXPECT_EQ(1, Factorial(-1));
|
|
- EXPECT_GT(Factorial(-10), 0);
|
|
-
|
|
- // Tests factorial of 0.
|
|
- EXPECT_EQ(1, Factorial(0));
|
|
-
|
|
- // Tests factorial of positive numbers.
|
|
- EXPECT_EQ(1, Factorial(1));
|
|
- EXPECT_EQ(2, Factorial(2));
|
|
- EXPECT_EQ(6, Factorial(3));
|
|
- EXPECT_EQ(40320, Factorial(8));
|
|
-}
|
|
-
|
|
-// Tests IsPrime()
|
|
-TEST_F(IntegerFunctionTest, IsPrime) {
|
|
- // Tests negative input.
|
|
- EXPECT_FALSE(IsPrime(-1));
|
|
- EXPECT_FALSE(IsPrime(-2));
|
|
- EXPECT_FALSE(IsPrime(INT_MIN));
|
|
-
|
|
- // Tests some trivial cases.
|
|
- EXPECT_FALSE(IsPrime(0));
|
|
- EXPECT_FALSE(IsPrime(1));
|
|
- EXPECT_TRUE(IsPrime(2));
|
|
- EXPECT_TRUE(IsPrime(3));
|
|
-
|
|
- // Tests positive input.
|
|
- EXPECT_FALSE(IsPrime(4));
|
|
- EXPECT_TRUE(IsPrime(5));
|
|
- EXPECT_FALSE(IsPrime(6));
|
|
- EXPECT_TRUE(IsPrime(23));
|
|
-}
|
|
-
|
|
-// The next test case (named "QueueTest") also needs to be quick, so
|
|
-// we derive another fixture from QuickTest.
|
|
-//
|
|
-// The QueueTest test fixture has some logic and shared objects in
|
|
-// addition to what's in QuickTest already. We define the additional
|
|
-// stuff inside the body of the test fixture, as usual.
|
|
-class QueueTest : public QuickTest {
|
|
- protected:
|
|
- void SetUp() override {
|
|
- // First, we need to set up the super fixture (QuickTest).
|
|
- QuickTest::SetUp();
|
|
-
|
|
- // Second, some additional setup for this fixture.
|
|
- q1_.Enqueue(1);
|
|
- q2_.Enqueue(2);
|
|
- q2_.Enqueue(3);
|
|
- }
|
|
-
|
|
- // By default, TearDown() inherits the behavior of
|
|
- // QuickTest::TearDown(). As we have no additional cleaning work
|
|
- // for QueueTest, we omit it here.
|
|
- //
|
|
- // virtual void TearDown() {
|
|
- // QuickTest::TearDown();
|
|
- // }
|
|
-
|
|
- Queue<int> q0_;
|
|
- Queue<int> q1_;
|
|
- Queue<int> q2_;
|
|
-};
|
|
-
|
|
-// Now, let's write tests using the QueueTest fixture.
|
|
-
|
|
-// Tests the default constructor.
|
|
-TEST_F(QueueTest, DefaultConstructor) { EXPECT_EQ(0u, q0_.Size()); }
|
|
-
|
|
-// Tests Dequeue().
|
|
-TEST_F(QueueTest, Dequeue) {
|
|
- int* n = q0_.Dequeue();
|
|
- EXPECT_TRUE(n == nullptr);
|
|
-
|
|
- n = q1_.Dequeue();
|
|
- EXPECT_TRUE(n != nullptr);
|
|
- EXPECT_EQ(1, *n);
|
|
- EXPECT_EQ(0u, q1_.Size());
|
|
- delete n;
|
|
-
|
|
- n = q2_.Dequeue();
|
|
- EXPECT_TRUE(n != nullptr);
|
|
- EXPECT_EQ(2, *n);
|
|
- EXPECT_EQ(1u, q2_.Size());
|
|
- delete n;
|
|
-}
|
|
-} // namespace
|
|
-// If necessary, you can derive further test fixtures from a derived
|
|
-// fixture itself. For example, you can derive another fixture from
|
|
-// QueueTest. Google Test imposes no limit on how deep the hierarchy
|
|
-// can be. In practice, however, you probably don't want it to be too
|
|
-// deep as to be confusing.
|
|
diff --git a/vendor/gtest/samples/sample6_unittest.cc b/vendor/gtest/samples/sample6_unittest.cc
|
|
deleted file mode 100644
|
|
index cf576f0a5..000000000
|
|
--- a/vendor/gtest/samples/sample6_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,214 +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.
|
|
-
|
|
-// This sample shows how to test common properties of multiple
|
|
-// implementations of the same interface (aka interface tests).
|
|
-
|
|
-// The interface and its implementations are in this header.
|
|
-#include "prime_tables.h"
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-// First, we define some factory functions for creating instances of
|
|
-// the implementations. You may be able to skip this step if all your
|
|
-// implementations can be constructed the same way.
|
|
-
|
|
-template <class T>
|
|
-PrimeTable* CreatePrimeTable();
|
|
-
|
|
-template <>
|
|
-PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() {
|
|
- return new OnTheFlyPrimeTable;
|
|
-}
|
|
-
|
|
-template <>
|
|
-PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() {
|
|
- return new PreCalculatedPrimeTable(10000);
|
|
-}
|
|
-
|
|
-// Then we define a test fixture class template.
|
|
-template <class T>
|
|
-class PrimeTableTest : public testing::Test {
|
|
- protected:
|
|
- // The ctor calls the factory function to create a prime table
|
|
- // implemented by T.
|
|
- PrimeTableTest() : table_(CreatePrimeTable<T>()) {}
|
|
-
|
|
- ~PrimeTableTest() override { delete table_; }
|
|
-
|
|
- // Note that we test an implementation via the base interface
|
|
- // instead of the actual implementation class. This is important
|
|
- // for keeping the tests close to the real world scenario, where the
|
|
- // implementation is invoked via the base interface. It avoids
|
|
- // got-yas where the implementation class has a method that shadows
|
|
- // a method with the same name (but slightly different argument
|
|
- // types) in the base interface, for example.
|
|
- PrimeTable* const table_;
|
|
-};
|
|
-
|
|
-using testing::Types;
|
|
-
|
|
-// Google Test offers two ways for reusing tests for different types.
|
|
-// The first is called "typed tests". You should use it if you
|
|
-// already know *all* the types you are gonna exercise when you write
|
|
-// the tests.
|
|
-
|
|
-// To write a typed test case, first use
|
|
-//
|
|
-// TYPED_TEST_SUITE(TestCaseName, TypeList);
|
|
-//
|
|
-// to declare it and specify the type parameters. As with TEST_F,
|
|
-// TestCaseName must match the test fixture name.
|
|
-
|
|
-// The list of types we want to test.
|
|
-typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;
|
|
-
|
|
-TYPED_TEST_SUITE(PrimeTableTest, Implementations);
|
|
-
|
|
-// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
|
|
-// similar to TEST_F.
|
|
-TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) {
|
|
- // Inside the test body, you can refer to the type parameter by
|
|
- // TypeParam, and refer to the fixture class by TestFixture. We
|
|
- // don't need them in this example.
|
|
-
|
|
- // Since we are in the template world, C++ requires explicitly
|
|
- // writing 'this->' when referring to members of the fixture class.
|
|
- // This is something you have to learn to live with.
|
|
- EXPECT_FALSE(this->table_->IsPrime(-5));
|
|
- EXPECT_FALSE(this->table_->IsPrime(0));
|
|
- EXPECT_FALSE(this->table_->IsPrime(1));
|
|
- EXPECT_FALSE(this->table_->IsPrime(4));
|
|
- EXPECT_FALSE(this->table_->IsPrime(6));
|
|
- EXPECT_FALSE(this->table_->IsPrime(100));
|
|
-}
|
|
-
|
|
-TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) {
|
|
- EXPECT_TRUE(this->table_->IsPrime(2));
|
|
- EXPECT_TRUE(this->table_->IsPrime(3));
|
|
- EXPECT_TRUE(this->table_->IsPrime(5));
|
|
- EXPECT_TRUE(this->table_->IsPrime(7));
|
|
- EXPECT_TRUE(this->table_->IsPrime(11));
|
|
- EXPECT_TRUE(this->table_->IsPrime(131));
|
|
-}
|
|
-
|
|
-TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
|
|
- EXPECT_EQ(2, this->table_->GetNextPrime(0));
|
|
- EXPECT_EQ(3, this->table_->GetNextPrime(2));
|
|
- EXPECT_EQ(5, this->table_->GetNextPrime(3));
|
|
- EXPECT_EQ(7, this->table_->GetNextPrime(5));
|
|
- EXPECT_EQ(11, this->table_->GetNextPrime(7));
|
|
- EXPECT_EQ(131, this->table_->GetNextPrime(128));
|
|
-}
|
|
-
|
|
-// That's it! Google Test will repeat each TYPED_TEST for each type
|
|
-// in the type list specified in TYPED_TEST_SUITE. Sit back and be
|
|
-// happy that you don't have to define them multiple times.
|
|
-
|
|
-using testing::Types;
|
|
-
|
|
-// Sometimes, however, you don't yet know all the types that you want
|
|
-// to test when you write the tests. For example, if you are the
|
|
-// author of an interface and expect other people to implement it, you
|
|
-// might want to write a set of tests to make sure each implementation
|
|
-// conforms to some basic requirements, but you don't know what
|
|
-// implementations will be written in the future.
|
|
-//
|
|
-// How can you write the tests without committing to the type
|
|
-// parameters? That's what "type-parameterized tests" can do for you.
|
|
-// It is a bit more involved than typed tests, but in return you get a
|
|
-// test pattern that can be reused in many contexts, which is a big
|
|
-// win. Here's how you do it:
|
|
-
|
|
-// First, define a test fixture class template. Here we just reuse
|
|
-// the PrimeTableTest fixture defined earlier:
|
|
-
|
|
-template <class T>
|
|
-class PrimeTableTest2 : public PrimeTableTest<T> {};
|
|
-
|
|
-// Then, declare the test case. The argument is the name of the test
|
|
-// fixture, and also the name of the test case (as usual). The _P
|
|
-// suffix is for "parameterized" or "pattern".
|
|
-TYPED_TEST_SUITE_P(PrimeTableTest2);
|
|
-
|
|
-// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
|
|
-// similar to what you do with TEST_F.
|
|
-TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) {
|
|
- EXPECT_FALSE(this->table_->IsPrime(-5));
|
|
- EXPECT_FALSE(this->table_->IsPrime(0));
|
|
- EXPECT_FALSE(this->table_->IsPrime(1));
|
|
- EXPECT_FALSE(this->table_->IsPrime(4));
|
|
- EXPECT_FALSE(this->table_->IsPrime(6));
|
|
- EXPECT_FALSE(this->table_->IsPrime(100));
|
|
-}
|
|
-
|
|
-TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) {
|
|
- EXPECT_TRUE(this->table_->IsPrime(2));
|
|
- EXPECT_TRUE(this->table_->IsPrime(3));
|
|
- EXPECT_TRUE(this->table_->IsPrime(5));
|
|
- EXPECT_TRUE(this->table_->IsPrime(7));
|
|
- EXPECT_TRUE(this->table_->IsPrime(11));
|
|
- EXPECT_TRUE(this->table_->IsPrime(131));
|
|
-}
|
|
-
|
|
-TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) {
|
|
- EXPECT_EQ(2, this->table_->GetNextPrime(0));
|
|
- EXPECT_EQ(3, this->table_->GetNextPrime(2));
|
|
- EXPECT_EQ(5, this->table_->GetNextPrime(3));
|
|
- EXPECT_EQ(7, this->table_->GetNextPrime(5));
|
|
- EXPECT_EQ(11, this->table_->GetNextPrime(7));
|
|
- EXPECT_EQ(131, this->table_->GetNextPrime(128));
|
|
-}
|
|
-
|
|
-// Type-parameterized tests involve one extra step: you have to
|
|
-// enumerate the tests you defined:
|
|
-REGISTER_TYPED_TEST_SUITE_P(
|
|
- PrimeTableTest2, // The first argument is the test case name.
|
|
- // The rest of the arguments are the test names.
|
|
- ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);
|
|
-
|
|
-// At this point the test pattern is done. However, you don't have
|
|
-// any real test yet as you haven't said which types you want to run
|
|
-// the tests with.
|
|
-
|
|
-// To turn the abstract test pattern into real tests, you instantiate
|
|
-// it with a list of types. Usually the test pattern will be defined
|
|
-// in a .h file, and anyone can #include and instantiate it. You can
|
|
-// even instantiate it more than once in the same program. To tell
|
|
-// different instances apart, you give each of them a name, which will
|
|
-// become part of the test case name and can be used in test filters.
|
|
-
|
|
-// The list of types we want to test. Note that it doesn't have to be
|
|
-// defined at the time we write the TYPED_TEST_P()s.
|
|
-typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>
|
|
- PrimeTableImplementations;
|
|
-INSTANTIATE_TYPED_TEST_SUITE_P(OnTheFlyAndPreCalculated, // Instance name
|
|
- PrimeTableTest2, // Test case name
|
|
- PrimeTableImplementations); // Type list
|
|
-
|
|
-} // namespace
|
|
diff --git a/vendor/gtest/samples/sample7_unittest.cc b/vendor/gtest/samples/sample7_unittest.cc
|
|
deleted file mode 100644
|
|
index 3ad22cab8..000000000
|
|
--- a/vendor/gtest/samples/sample7_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,113 +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.
|
|
-
|
|
-// This sample shows how to test common properties of multiple
|
|
-// implementations of an interface (aka interface tests) using
|
|
-// value-parameterized tests. Each test in the test case has
|
|
-// a parameter that is an interface pointer to an implementation
|
|
-// tested.
|
|
-
|
|
-// The interface and its implementations are in this header.
|
|
-#include "prime_tables.h"
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-
|
|
-using ::testing::TestWithParam;
|
|
-using ::testing::Values;
|
|
-
|
|
-// As a general rule, to prevent a test from affecting the tests that come
|
|
-// after it, you should create and destroy the tested objects for each test
|
|
-// instead of reusing them. In this sample we will define a simple factory
|
|
-// function for PrimeTable objects. We will instantiate objects in test's
|
|
-// SetUp() method and delete them in TearDown() method.
|
|
-typedef PrimeTable* CreatePrimeTableFunc();
|
|
-
|
|
-PrimeTable* CreateOnTheFlyPrimeTable() { return new OnTheFlyPrimeTable(); }
|
|
-
|
|
-template <size_t max_precalculated>
|
|
-PrimeTable* CreatePreCalculatedPrimeTable() {
|
|
- return new PreCalculatedPrimeTable(max_precalculated);
|
|
-}
|
|
-
|
|
-// Inside the test body, fixture constructor, SetUp(), and TearDown() you
|
|
-// can refer to the test parameter by GetParam(). In this case, the test
|
|
-// parameter is a factory function which we call in fixture's SetUp() to
|
|
-// create and store an instance of PrimeTable.
|
|
-class PrimeTableTestSmpl7 : public TestWithParam<CreatePrimeTableFunc*> {
|
|
- public:
|
|
- ~PrimeTableTestSmpl7() override { delete table_; }
|
|
- void SetUp() override { table_ = (*GetParam())(); }
|
|
- void TearDown() override {
|
|
- delete table_;
|
|
- table_ = nullptr;
|
|
- }
|
|
-
|
|
- protected:
|
|
- PrimeTable* table_;
|
|
-};
|
|
-
|
|
-TEST_P(PrimeTableTestSmpl7, ReturnsFalseForNonPrimes) {
|
|
- EXPECT_FALSE(table_->IsPrime(-5));
|
|
- EXPECT_FALSE(table_->IsPrime(0));
|
|
- EXPECT_FALSE(table_->IsPrime(1));
|
|
- EXPECT_FALSE(table_->IsPrime(4));
|
|
- EXPECT_FALSE(table_->IsPrime(6));
|
|
- EXPECT_FALSE(table_->IsPrime(100));
|
|
-}
|
|
-
|
|
-TEST_P(PrimeTableTestSmpl7, ReturnsTrueForPrimes) {
|
|
- EXPECT_TRUE(table_->IsPrime(2));
|
|
- EXPECT_TRUE(table_->IsPrime(3));
|
|
- EXPECT_TRUE(table_->IsPrime(5));
|
|
- EXPECT_TRUE(table_->IsPrime(7));
|
|
- EXPECT_TRUE(table_->IsPrime(11));
|
|
- EXPECT_TRUE(table_->IsPrime(131));
|
|
-}
|
|
-
|
|
-TEST_P(PrimeTableTestSmpl7, CanGetNextPrime) {
|
|
- EXPECT_EQ(2, table_->GetNextPrime(0));
|
|
- EXPECT_EQ(3, table_->GetNextPrime(2));
|
|
- EXPECT_EQ(5, table_->GetNextPrime(3));
|
|
- EXPECT_EQ(7, table_->GetNextPrime(5));
|
|
- EXPECT_EQ(11, table_->GetNextPrime(7));
|
|
- EXPECT_EQ(131, table_->GetNextPrime(128));
|
|
-}
|
|
-
|
|
-// In order to run value-parameterized tests, you need to instantiate them,
|
|
-// or bind them to a list of values which will be used as test parameters.
|
|
-// You can instantiate them in a different translation module, or even
|
|
-// instantiate them several times.
|
|
-//
|
|
-// Here, we instantiate our tests with a list of two PrimeTable object
|
|
-// factory functions:
|
|
-INSTANTIATE_TEST_SUITE_P(OnTheFlyAndPreCalculated, PrimeTableTestSmpl7,
|
|
- Values(&CreateOnTheFlyPrimeTable,
|
|
- &CreatePreCalculatedPrimeTable<1000>));
|
|
-
|
|
-} // namespace
|
|
diff --git a/vendor/gtest/samples/sample8_unittest.cc b/vendor/gtest/samples/sample8_unittest.cc
|
|
deleted file mode 100644
|
|
index 9717e2860..000000000
|
|
--- a/vendor/gtest/samples/sample8_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,152 +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.
|
|
-
|
|
-// This sample shows how to test code relying on some global flag variables.
|
|
-// Combine() helps with generating all possible combinations of such flags,
|
|
-// and each test is given one combination as a parameter.
|
|
-
|
|
-// Use class definitions to test from this header.
|
|
-#include "prime_tables.h"
|
|
-#include "gtest/gtest.h"
|
|
-namespace {
|
|
-
|
|
-// Suppose we want to introduce a new, improved implementation of PrimeTable
|
|
-// which combines speed of PrecalcPrimeTable and versatility of
|
|
-// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
|
|
-// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
|
|
-// appropriate under the circumstances. But in low memory conditions, it can be
|
|
-// told to instantiate without PrecalcPrimeTable instance at all and use only
|
|
-// OnTheFlyPrimeTable.
|
|
-class HybridPrimeTable : public PrimeTable {
|
|
- public:
|
|
- HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
|
|
- : on_the_fly_impl_(new OnTheFlyPrimeTable),
|
|
- precalc_impl_(force_on_the_fly
|
|
- ? nullptr
|
|
- : new PreCalculatedPrimeTable(max_precalculated)),
|
|
- max_precalculated_(max_precalculated) {}
|
|
- ~HybridPrimeTable() override {
|
|
- delete on_the_fly_impl_;
|
|
- delete precalc_impl_;
|
|
- }
|
|
-
|
|
- bool IsPrime(int n) const override {
|
|
- if (precalc_impl_ != nullptr && n < max_precalculated_)
|
|
- return precalc_impl_->IsPrime(n);
|
|
- else
|
|
- return on_the_fly_impl_->IsPrime(n);
|
|
- }
|
|
-
|
|
- int GetNextPrime(int p) const override {
|
|
- int next_prime = -1;
|
|
- if (precalc_impl_ != nullptr && p < max_precalculated_)
|
|
- next_prime = precalc_impl_->GetNextPrime(p);
|
|
-
|
|
- return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
|
|
- }
|
|
-
|
|
- private:
|
|
- OnTheFlyPrimeTable* on_the_fly_impl_;
|
|
- PreCalculatedPrimeTable* precalc_impl_;
|
|
- int max_precalculated_;
|
|
-};
|
|
-
|
|
-using ::testing::Bool;
|
|
-using ::testing::Combine;
|
|
-using ::testing::TestWithParam;
|
|
-using ::testing::Values;
|
|
-
|
|
-// To test all code paths for HybridPrimeTable we must test it with numbers
|
|
-// both within and outside PreCalculatedPrimeTable's capacity and also with
|
|
-// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
|
|
-// accept different combinations of parameters for instantiating a
|
|
-// HybridPrimeTable instance.
|
|
-class PrimeTableTest : public TestWithParam< ::std::tuple<bool, int> > {
|
|
- protected:
|
|
- void SetUp() override {
|
|
- bool force_on_the_fly;
|
|
- int max_precalculated;
|
|
- std::tie(force_on_the_fly, max_precalculated) = GetParam();
|
|
- table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
|
|
- }
|
|
- void TearDown() override {
|
|
- delete table_;
|
|
- table_ = nullptr;
|
|
- }
|
|
- HybridPrimeTable* table_;
|
|
-};
|
|
-
|
|
-TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
|
|
- // Inside the test body, you can refer to the test parameter by GetParam().
|
|
- // In this case, the test parameter is a PrimeTable interface pointer which
|
|
- // we can use directly.
|
|
- // Please note that you can also save it in the fixture's SetUp() method
|
|
- // or constructor and use saved copy in the tests.
|
|
-
|
|
- EXPECT_FALSE(table_->IsPrime(-5));
|
|
- EXPECT_FALSE(table_->IsPrime(0));
|
|
- EXPECT_FALSE(table_->IsPrime(1));
|
|
- EXPECT_FALSE(table_->IsPrime(4));
|
|
- EXPECT_FALSE(table_->IsPrime(6));
|
|
- EXPECT_FALSE(table_->IsPrime(100));
|
|
-}
|
|
-
|
|
-TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
|
|
- EXPECT_TRUE(table_->IsPrime(2));
|
|
- EXPECT_TRUE(table_->IsPrime(3));
|
|
- EXPECT_TRUE(table_->IsPrime(5));
|
|
- EXPECT_TRUE(table_->IsPrime(7));
|
|
- EXPECT_TRUE(table_->IsPrime(11));
|
|
- EXPECT_TRUE(table_->IsPrime(131));
|
|
-}
|
|
-
|
|
-TEST_P(PrimeTableTest, CanGetNextPrime) {
|
|
- EXPECT_EQ(2, table_->GetNextPrime(0));
|
|
- EXPECT_EQ(3, table_->GetNextPrime(2));
|
|
- EXPECT_EQ(5, table_->GetNextPrime(3));
|
|
- EXPECT_EQ(7, table_->GetNextPrime(5));
|
|
- EXPECT_EQ(11, table_->GetNextPrime(7));
|
|
- EXPECT_EQ(131, table_->GetNextPrime(128));
|
|
-}
|
|
-
|
|
-// In order to run value-parameterized tests, you need to instantiate them,
|
|
-// or bind them to a list of values which will be used as test parameters.
|
|
-// You can instantiate them in a different translation module, or even
|
|
-// instantiate them several times.
|
|
-//
|
|
-// Here, we instantiate our tests with a list of parameters. We must combine
|
|
-// all variations of the boolean flag suppressing PrecalcPrimeTable and some
|
|
-// meaningful values for tests. We choose a small value (1), and a value that
|
|
-// will put some of the tested numbers beyond the capability of the
|
|
-// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
|
|
-// possible combinations.
|
|
-INSTANTIATE_TEST_SUITE_P(MeaningfulTestParameters, PrimeTableTest,
|
|
- Combine(Bool(), Values(1, 10)));
|
|
-
|
|
-} // namespace
|
|
diff --git a/vendor/gtest/samples/sample9_unittest.cc b/vendor/gtest/samples/sample9_unittest.cc
|
|
deleted file mode 100644
|
|
index d627ea7d5..000000000
|
|
--- a/vendor/gtest/samples/sample9_unittest.cc
|
|
+++ /dev/null
|
|
@@ -1,149 +0,0 @@
|
|
-// Copyright 2009 Google Inc. All Rights Reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// This sample shows how to use Google Test listener API to implement
|
|
-// an alternative console output and how to use the UnitTest reflection API
|
|
-// to enumerate test suites and tests and to inspect their results.
|
|
-
|
|
-#include <stdio.h>
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-using ::testing::EmptyTestEventListener;
|
|
-using ::testing::InitGoogleTest;
|
|
-using ::testing::Test;
|
|
-using ::testing::TestEventListeners;
|
|
-using ::testing::TestInfo;
|
|
-using ::testing::TestPartResult;
|
|
-using ::testing::TestSuite;
|
|
-using ::testing::UnitTest;
|
|
-namespace {
|
|
-// Provides alternative output mode which produces minimal amount of
|
|
-// information about tests.
|
|
-class TersePrinter : public EmptyTestEventListener {
|
|
- private:
|
|
- // Called before any test activity starts.
|
|
- void OnTestProgramStart(const UnitTest& /* unit_test */) override {}
|
|
-
|
|
- // Called after all test activities have ended.
|
|
- void OnTestProgramEnd(const UnitTest& unit_test) override {
|
|
- fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED");
|
|
- fflush(stdout);
|
|
- }
|
|
-
|
|
- // Called before a test starts.
|
|
- void OnTestStart(const TestInfo& test_info) override {
|
|
- fprintf(stdout, "*** Test %s.%s starting.\n", test_info.test_suite_name(),
|
|
- test_info.name());
|
|
- fflush(stdout);
|
|
- }
|
|
-
|
|
- // Called after a failed assertion or a SUCCEED() invocation.
|
|
- void OnTestPartResult(const TestPartResult& test_part_result) override {
|
|
- fprintf(stdout, "%s in %s:%d\n%s\n",
|
|
- test_part_result.failed() ? "*** Failure" : "Success",
|
|
- test_part_result.file_name(), test_part_result.line_number(),
|
|
- test_part_result.summary());
|
|
- fflush(stdout);
|
|
- }
|
|
-
|
|
- // Called after a test ends.
|
|
- void OnTestEnd(const TestInfo& test_info) override {
|
|
- fprintf(stdout, "*** Test %s.%s ending.\n", test_info.test_suite_name(),
|
|
- test_info.name());
|
|
- fflush(stdout);
|
|
- }
|
|
-}; // class TersePrinter
|
|
-
|
|
-TEST(CustomOutputTest, PrintsMessage) {
|
|
- printf("Printing something from the test body...\n");
|
|
-}
|
|
-
|
|
-TEST(CustomOutputTest, Succeeds) {
|
|
- SUCCEED() << "SUCCEED() has been invoked from here";
|
|
-}
|
|
-
|
|
-TEST(CustomOutputTest, Fails) {
|
|
- EXPECT_EQ(1, 2)
|
|
- << "This test fails in order to demonstrate alternative failure messages";
|
|
-}
|
|
-} // namespace
|
|
-
|
|
-int main(int argc, char** argv) {
|
|
- InitGoogleTest(&argc, argv);
|
|
-
|
|
- bool terse_output = false;
|
|
- if (argc > 1 && strcmp(argv[1], "--terse_output") == 0)
|
|
- terse_output = true;
|
|
- else
|
|
- printf("%s\n",
|
|
- "Run this program with --terse_output to change the way "
|
|
- "it prints its output.");
|
|
-
|
|
- UnitTest& unit_test = *UnitTest::GetInstance();
|
|
-
|
|
- // If we are given the --terse_output command line flag, suppresses the
|
|
- // standard output and attaches own result printer.
|
|
- if (terse_output) {
|
|
- TestEventListeners& listeners = unit_test.listeners();
|
|
-
|
|
- // Removes the default console output listener from the list so it will
|
|
- // not receive events from Google Test and won't print any output. Since
|
|
- // this operation transfers ownership of the listener to the caller we
|
|
- // have to delete it as well.
|
|
- delete listeners.Release(listeners.default_result_printer());
|
|
-
|
|
- // Adds the custom output listener to the list. It will now receive
|
|
- // events from Google Test and print the alternative output. We don't
|
|
- // have to worry about deleting it since Google Test assumes ownership
|
|
- // over it after adding it to the list.
|
|
- listeners.Append(new TersePrinter);
|
|
- }
|
|
- int ret_val = RUN_ALL_TESTS();
|
|
-
|
|
- // 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_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() &&
|
|
- strcmp(test_info.name(), "Fails") != 0) {
|
|
- unexpectedly_failed_tests++;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- // Test that were meant to fail should not affect the test program outcome.
|
|
- if (unexpectedly_failed_tests == 0) ret_val = 0;
|
|
-
|
|
- return ret_val;
|
|
-}
|
|
diff --git a/vendor/gtest/src/gtest-all.cc b/vendor/gtest/src/gtest-all.cc
|
|
deleted file mode 100644
|
|
index 2a70ed88c..000000000
|
|
--- a/vendor/gtest/src/gtest-all.cc
|
|
+++ /dev/null
|
|
@@ -1,49 +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.
|
|
-
|
|
-//
|
|
-// Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// Sometimes it's desirable to build Google Test by compiling a single file.
|
|
-// This file serves this purpose.
|
|
-
|
|
-// This line ensures that gtest.h can be compiled on its own, even
|
|
-// when it's fused.
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-// The following lines pull in the real gtest *.cc files.
|
|
-#include "src/gtest-assertion-result.cc"
|
|
-#include "src/gtest-death-test.cc"
|
|
-#include "src/gtest-filepath.cc"
|
|
-#include "src/gtest-matchers.cc"
|
|
-#include "src/gtest-port.cc"
|
|
-#include "src/gtest-printers.cc"
|
|
-#include "src/gtest-test-part.cc"
|
|
-#include "src/gtest-typed-test.cc"
|
|
-#include "src/gtest.cc"
|
|
diff --git a/vendor/gtest/src/gtest-assertion-result.cc b/vendor/gtest/src/gtest-assertion-result.cc
|
|
deleted file mode 100644
|
|
index f1c0b10dc..000000000
|
|
--- a/vendor/gtest/src/gtest-assertion-result.cc
|
|
+++ /dev/null
|
|
@@ -1,77 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This file defines the AssertionResult type.
|
|
-
|
|
-#include "gtest/gtest-assertion-result.h"
|
|
-
|
|
-#include <string>
|
|
-#include <utility>
|
|
-
|
|
-#include "gtest/gtest-message.h"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// AssertionResult constructors.
|
|
-// Used in EXPECT_TRUE/FALSE(assertion_result).
|
|
-AssertionResult::AssertionResult(const AssertionResult& other)
|
|
- : success_(other.success_),
|
|
- message_(other.message_.get() != nullptr
|
|
- ? new ::std::string(*other.message_)
|
|
- : static_cast< ::std::string*>(nullptr)) {}
|
|
-
|
|
-// Swaps two AssertionResults.
|
|
-void AssertionResult::swap(AssertionResult& other) {
|
|
- using std::swap;
|
|
- swap(success_, other.success_);
|
|
- swap(message_, other.message_);
|
|
-}
|
|
-
|
|
-// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
|
|
-AssertionResult AssertionResult::operator!() const {
|
|
- AssertionResult negation(!success_);
|
|
- if (message_.get() != nullptr) negation << *message_;
|
|
- return negation;
|
|
-}
|
|
-
|
|
-// Makes a successful assertion result.
|
|
-AssertionResult AssertionSuccess() { return AssertionResult(true); }
|
|
-
|
|
-// Makes a failed assertion result.
|
|
-AssertionResult AssertionFailure() { return AssertionResult(false); }
|
|
-
|
|
-// Makes a failed assertion result with the given failure message.
|
|
-// Deprecated; use AssertionFailure() << message.
|
|
-AssertionResult AssertionFailure(const Message& message) {
|
|
- return AssertionFailure() << message;
|
|
-}
|
|
-
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-death-test.cc b/vendor/gtest/src/gtest-death-test.cc
|
|
deleted file mode 100644
|
|
index e6abc6278..000000000
|
|
--- a/vendor/gtest/src/gtest-death-test.cc
|
|
+++ /dev/null
|
|
@@ -1,1620 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-//
|
|
-// This file implements death tests.
|
|
-
|
|
-#include "gtest/gtest-death-test.h"
|
|
-
|
|
-#include <functional>
|
|
-#include <utility>
|
|
-
|
|
-#include "gtest/internal/custom/gtest.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-
|
|
-#if GTEST_OS_MAC
|
|
-#include <crt_externs.h>
|
|
-#endif // GTEST_OS_MAC
|
|
-
|
|
-#include <errno.h>
|
|
-#include <fcntl.h>
|
|
-#include <limits.h>
|
|
-
|
|
-#if GTEST_OS_LINUX
|
|
-#include <signal.h>
|
|
-#endif // GTEST_OS_LINUX
|
|
-
|
|
-#include <stdarg.h>
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-#include <windows.h>
|
|
-#else
|
|
-#include <sys/mman.h>
|
|
-#include <sys/wait.h>
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-#if GTEST_OS_QNX
|
|
-#include <spawn.h>
|
|
-#endif // GTEST_OS_QNX
|
|
-
|
|
-#if GTEST_OS_FUCHSIA
|
|
-#include <lib/fdio/fd.h>
|
|
-#include <lib/fdio/io.h>
|
|
-#include <lib/fdio/spawn.h>
|
|
-#include <lib/zx/channel.h>
|
|
-#include <lib/zx/port.h>
|
|
-#include <lib/zx/process.h>
|
|
-#include <lib/zx/socket.h>
|
|
-#include <zircon/processargs.h>
|
|
-#include <zircon/syscalls.h>
|
|
-#include <zircon/syscalls/policy.h>
|
|
-#include <zircon/syscalls/port.h>
|
|
-#endif // GTEST_OS_FUCHSIA
|
|
-
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-#include "gtest/gtest-message.h"
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-#include "src/gtest-internal-inl.h"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// Constants.
|
|
-
|
|
-// The default death test style.
|
|
-//
|
|
-// This is defined in internal/gtest-port.h as "fast", but can be overridden by
|
|
-// a definition in internal/custom/gtest-port.h. The recommended value, which is
|
|
-// used internally at Google, is "threadsafe".
|
|
-static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DEFINE_string_(
|
|
- death_test_style,
|
|
- testing::internal::StringFromGTestEnv("death_test_style",
|
|
- testing::kDefaultDeathTestStyle),
|
|
- "Indicates how to run a death test in a forked child process: "
|
|
- "\"threadsafe\" (child process re-executes the test binary "
|
|
- "from the beginning, running only the specific death test) or "
|
|
- "\"fast\" (child process runs the death test immediately "
|
|
- "after forking).");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- death_test_use_fork,
|
|
- testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
|
|
- "Instructs to use fork()/_exit() instead of clone() in death tests. "
|
|
- "Ignored and always uses fork() on POSIX systems where clone() is not "
|
|
- "implemented. Useful when running under valgrind or similar tools if "
|
|
- "those do not support clone(). Valgrind 3.3.1 will just fail if "
|
|
- "it sees an unsupported combination of clone() flags. "
|
|
- "It is not recommended to use this flag w/o valgrind though it will "
|
|
- "work in 99% of the cases. Once valgrind is fixed, this flag will "
|
|
- "most likely be removed.");
|
|
-
|
|
-GTEST_DEFINE_string_(
|
|
- internal_run_death_test, "",
|
|
- "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 "
|
|
- "death test. FOR INTERNAL USE ONLY.");
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Valid only for fast death tests. Indicates the code is running in the
|
|
-// child process of a fast style death test.
|
|
-#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
|
-static bool g_in_fast_death_test_child = false;
|
|
-#endif
|
|
-
|
|
-// Returns a Boolean value indicating whether the caller is currently
|
|
-// executing in the context of the death test child process. Tools such as
|
|
-// Valgrind heap checkers may need this to modify their behavior in death
|
|
-// tests. IMPORTANT: This is an internal utility. Using it may break the
|
|
-// implementation of death tests. User code MUST NOT use it.
|
|
-bool InDeathTestChild() {
|
|
-#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
|
-
|
|
- // On Windows and Fuchsia, death tests are thread-safe regardless of the value
|
|
- // of the death_test_style flag.
|
|
- return !GTEST_FLAG_GET(internal_run_death_test).empty();
|
|
-
|
|
-#else
|
|
-
|
|
- if (GTEST_FLAG_GET(death_test_style) == "threadsafe")
|
|
- return !GTEST_FLAG_GET(internal_run_death_test).empty();
|
|
- else
|
|
- return g_in_fast_death_test_child;
|
|
-#endif
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// ExitedWithCode constructor.
|
|
-ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {}
|
|
-
|
|
-// ExitedWithCode function-call operator.
|
|
-bool ExitedWithCode::operator()(int exit_status) const {
|
|
-#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
|
-
|
|
- return exit_status == exit_code_;
|
|
-
|
|
-#else
|
|
-
|
|
- return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
|
-}
|
|
-
|
|
-#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
|
-// KilledBySignal constructor.
|
|
-KilledBySignal::KilledBySignal(int signum) : signum_(signum) {}
|
|
-
|
|
-// KilledBySignal function-call operator.
|
|
-bool KilledBySignal::operator()(int exit_status) const {
|
|
-#if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
|
|
- {
|
|
- bool result;
|
|
- if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) {
|
|
- return result;
|
|
- }
|
|
- }
|
|
-#endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
|
|
- return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
|
|
-}
|
|
-#endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Utilities needed for death tests.
|
|
-
|
|
-// Generates a textual description of a given exit code, in the format
|
|
-// specified by wait(2).
|
|
-static std::string ExitSummary(int exit_code) {
|
|
- Message m;
|
|
-
|
|
-#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
|
-
|
|
- m << "Exited with exit status " << exit_code;
|
|
-
|
|
-#else
|
|
-
|
|
- if (WIFEXITED(exit_code)) {
|
|
- m << "Exited with exit status " << WEXITSTATUS(exit_code);
|
|
- } else if (WIFSIGNALED(exit_code)) {
|
|
- m << "Terminated by signal " << WTERMSIG(exit_code);
|
|
- }
|
|
-#ifdef WCOREDUMP
|
|
- if (WCOREDUMP(exit_code)) {
|
|
- m << " (core dumped)";
|
|
- }
|
|
-#endif
|
|
-#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
|
|
-
|
|
- return m.GetString();
|
|
-}
|
|
-
|
|
-// Returns true if exit_status describes a process that was terminated
|
|
-// by a signal, or exited normally with a nonzero exit code.
|
|
-bool ExitedUnsuccessfully(int exit_status) {
|
|
- return !ExitedWithCode(0)(exit_status);
|
|
-}
|
|
-
|
|
-#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
|
-// Generates a textual failure message when a death test finds more than
|
|
-// one thread running, or cannot determine the number of threads, prior
|
|
-// to executing the given statement. It is the responsibility of the
|
|
-// caller not to pass a thread_count of 1.
|
|
-static std::string DeathTestThreadWarning(size_t thread_count) {
|
|
- Message msg;
|
|
- msg << "Death tests use fork(), which is unsafe particularly"
|
|
- << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
|
|
- if (thread_count == 0) {
|
|
- msg << "couldn't detect the number of threads.";
|
|
- } else {
|
|
- msg << "detected " << thread_count << " threads.";
|
|
- }
|
|
- msg << " See "
|
|
- "https://github.com/google/googletest/blob/master/docs/"
|
|
- "advanced.md#death-tests-and-threads"
|
|
- << " for more explanation and suggested solutions, especially if"
|
|
- << " this is the last message you see before your test times out.";
|
|
- return msg.GetString();
|
|
-}
|
|
-#endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
|
|
-
|
|
-// Flag characters for reporting a death test that did not die.
|
|
-static const char kDeathTestLived = 'L';
|
|
-static const char kDeathTestReturned = 'R';
|
|
-static const char kDeathTestThrew = 'T';
|
|
-static const char kDeathTestInternalError = 'I';
|
|
-
|
|
-#if GTEST_OS_FUCHSIA
|
|
-
|
|
-// File descriptor used for the pipe in the child process.
|
|
-static const int kFuchsiaReadPipeFd = 3;
|
|
-
|
|
-#endif
|
|
-
|
|
-// An enumeration describing all of the possible ways that a death test can
|
|
-// conclude. DIED means that the process died while executing the test
|
|
-// code; LIVED means that process lived beyond the end of the test code;
|
|
-// RETURNED means that the test statement attempted to execute a return
|
|
-// statement, which is not allowed; THREW means that the test statement
|
|
-// returned control by throwing an exception. IN_PROGRESS means the test
|
|
-// has not yet concluded.
|
|
-enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
|
|
-
|
|
-// Routine for aborting the program which is safe to call from an
|
|
-// exec-style death test child process, in which case the error
|
|
-// message is propagated back to the parent process. Otherwise, the
|
|
-// message is simply printed to stderr. In either case, the program
|
|
-// then exits with status 1.
|
|
-static void DeathTestAbort(const std::string& message) {
|
|
- // On a POSIX system, this function may be called from a threadsafe-style
|
|
- // death test child process, which operates on a very small stack. Use
|
|
- // the heap for any additional non-minuscule memory requirements.
|
|
- const InternalRunDeathTestFlag* const flag =
|
|
- GetUnitTestImpl()->internal_run_death_test_flag();
|
|
- if (flag != nullptr) {
|
|
- FILE* parent = posix::FDOpen(flag->write_fd(), "w");
|
|
- fputc(kDeathTestInternalError, parent);
|
|
- fprintf(parent, "%s", message.c_str());
|
|
- fflush(parent);
|
|
- _exit(1);
|
|
- } else {
|
|
- fprintf(stderr, "%s", message.c_str());
|
|
- fflush(stderr);
|
|
- posix::Abort();
|
|
- }
|
|
-}
|
|
-
|
|
-// A replacement for CHECK that calls DeathTestAbort if the assertion
|
|
-// fails.
|
|
-#define GTEST_DEATH_TEST_CHECK_(expression) \
|
|
- do { \
|
|
- if (!::testing::internal::IsTrue(expression)) { \
|
|
- DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \
|
|
- ", line " + \
|
|
- ::testing::internal::StreamableToString(__LINE__) + \
|
|
- ": " + #expression); \
|
|
- } \
|
|
- } while (::testing::internal::AlwaysFalse())
|
|
-
|
|
-// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
|
|
-// evaluating any system call that fulfills two conditions: it must return
|
|
-// -1 on failure, and set errno to EINTR when it is interrupted and
|
|
-// should be tried again. The macro expands to a loop that repeatedly
|
|
-// evaluates the expression as long as it evaluates to -1 and sets
|
|
-// errno to EINTR. If the expression evaluates to -1 but errno is
|
|
-// something other than EINTR, DeathTestAbort is called.
|
|
-#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \
|
|
- do { \
|
|
- int gtest_retval; \
|
|
- do { \
|
|
- gtest_retval = (expression); \
|
|
- } while (gtest_retval == -1 && errno == EINTR); \
|
|
- if (gtest_retval == -1) { \
|
|
- DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \
|
|
- ", line " + \
|
|
- ::testing::internal::StreamableToString(__LINE__) + \
|
|
- ": " + #expression + " != -1"); \
|
|
- } \
|
|
- } while (::testing::internal::AlwaysFalse())
|
|
-
|
|
-// Returns the message describing the last system error in errno.
|
|
-std::string GetLastErrnoDescription() {
|
|
- return errno == 0 ? "" : posix::StrError(errno);
|
|
-}
|
|
-
|
|
-// This is called from a death test parent process to read a failure
|
|
-// message from the death test child process and log it with the FATAL
|
|
-// severity. On Windows, the message is read from a pipe handle. On other
|
|
-// platforms, it is read from a file descriptor.
|
|
-static void FailFromInternalError(int fd) {
|
|
- Message error;
|
|
- char buffer[256];
|
|
- int num_read;
|
|
-
|
|
- do {
|
|
- while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
|
|
- buffer[num_read] = '\0';
|
|
- error << buffer;
|
|
- }
|
|
- } while (num_read == -1 && errno == EINTR);
|
|
-
|
|
- if (num_read == 0) {
|
|
- GTEST_LOG_(FATAL) << error.GetString();
|
|
- } else {
|
|
- const int last_error = errno;
|
|
- GTEST_LOG_(FATAL) << "Error while reading death test internal: "
|
|
- << GetLastErrnoDescription() << " [" << last_error << "]";
|
|
- }
|
|
-}
|
|
-
|
|
-// Death test constructor. Increments the running death test count
|
|
-// for the current test.
|
|
-DeathTest::DeathTest() {
|
|
- TestInfo* const info = GetUnitTestImpl()->current_test_info();
|
|
- if (info == nullptr) {
|
|
- DeathTestAbort(
|
|
- "Cannot run a death test outside of a TEST or "
|
|
- "TEST_F construct");
|
|
- }
|
|
-}
|
|
-
|
|
-// Creates and returns a death test by dispatching to the current
|
|
-// death test factory.
|
|
-bool DeathTest::Create(const char* statement,
|
|
- Matcher<const std::string&> matcher, const char* file,
|
|
- int line, DeathTest** test) {
|
|
- return GetUnitTestImpl()->death_test_factory()->Create(
|
|
- statement, std::move(matcher), file, line, test);
|
|
-}
|
|
-
|
|
-const char* DeathTest::LastMessage() {
|
|
- return last_death_test_message_.c_str();
|
|
-}
|
|
-
|
|
-void DeathTest::set_last_death_test_message(const std::string& message) {
|
|
- last_death_test_message_ = message;
|
|
-}
|
|
-
|
|
-std::string DeathTest::last_death_test_message_;
|
|
-
|
|
-// Provides cross platform implementation for some death functionality.
|
|
-class DeathTestImpl : public DeathTest {
|
|
- protected:
|
|
- DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher)
|
|
- : statement_(a_statement),
|
|
- matcher_(std::move(matcher)),
|
|
- spawned_(false),
|
|
- status_(-1),
|
|
- outcome_(IN_PROGRESS),
|
|
- read_fd_(-1),
|
|
- write_fd_(-1) {}
|
|
-
|
|
- // read_fd_ is expected to be closed and cleared by a derived class.
|
|
- ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
|
|
-
|
|
- void Abort(AbortReason reason) override;
|
|
- bool Passed(bool status_ok) override;
|
|
-
|
|
- const char* statement() const { return statement_; }
|
|
- bool spawned() const { return spawned_; }
|
|
- void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
|
|
- int status() const { return status_; }
|
|
- void set_status(int a_status) { status_ = a_status; }
|
|
- DeathTestOutcome outcome() const { return outcome_; }
|
|
- void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
|
|
- int read_fd() const { return read_fd_; }
|
|
- void set_read_fd(int fd) { read_fd_ = fd; }
|
|
- int write_fd() const { return write_fd_; }
|
|
- void set_write_fd(int fd) { write_fd_ = fd; }
|
|
-
|
|
- // Called in the parent process only. Reads the result code of the death
|
|
- // test child process via a pipe, interprets it to set the outcome_
|
|
- // member, and closes read_fd_. Outputs diagnostics and terminates in
|
|
- // case of unexpected codes.
|
|
- void ReadAndInterpretStatusByte();
|
|
-
|
|
- // Returns stderr output from the child process.
|
|
- virtual std::string GetErrorLogs();
|
|
-
|
|
- private:
|
|
- // The textual content of the code this object is testing. This class
|
|
- // doesn't own this string and should not attempt to delete it.
|
|
- const char* const statement_;
|
|
- // A matcher that's expected to match the stderr output by the child process.
|
|
- Matcher<const std::string&> matcher_;
|
|
- // True if the death test child process has been successfully spawned.
|
|
- bool spawned_;
|
|
- // The exit status of the child process.
|
|
- int status_;
|
|
- // How the death test concluded.
|
|
- DeathTestOutcome outcome_;
|
|
- // Descriptor to the read end of the pipe to the child process. It is
|
|
- // always -1 in the child process. The child keeps its write end of the
|
|
- // pipe in write_fd_.
|
|
- int read_fd_;
|
|
- // Descriptor to the child's write end of the pipe to the parent process.
|
|
- // It is always -1 in the parent process. The parent keeps its end of the
|
|
- // pipe in read_fd_.
|
|
- int write_fd_;
|
|
-};
|
|
-
|
|
-// Called in the parent process only. Reads the result code of the death
|
|
-// test child process via a pipe, interprets it to set the outcome_
|
|
-// member, and closes read_fd_. Outputs diagnostics and terminates in
|
|
-// case of unexpected codes.
|
|
-void DeathTestImpl::ReadAndInterpretStatusByte() {
|
|
- char flag;
|
|
- int bytes_read;
|
|
-
|
|
- // The read() here blocks until data is available (signifying the
|
|
- // failure of the death test) or until the pipe is closed (signifying
|
|
- // its success), so it's okay to call this in the parent before
|
|
- // the child process has exited.
|
|
- do {
|
|
- bytes_read = posix::Read(read_fd(), &flag, 1);
|
|
- } while (bytes_read == -1 && errno == EINTR);
|
|
-
|
|
- if (bytes_read == 0) {
|
|
- set_outcome(DIED);
|
|
- } else if (bytes_read == 1) {
|
|
- switch (flag) {
|
|
- case kDeathTestReturned:
|
|
- set_outcome(RETURNED);
|
|
- break;
|
|
- case kDeathTestThrew:
|
|
- set_outcome(THREW);
|
|
- break;
|
|
- case kDeathTestLived:
|
|
- set_outcome(LIVED);
|
|
- break;
|
|
- case kDeathTestInternalError:
|
|
- FailFromInternalError(read_fd()); // Does not return.
|
|
- break;
|
|
- default:
|
|
- GTEST_LOG_(FATAL) << "Death test child process reported "
|
|
- << "unexpected status byte ("
|
|
- << static_cast<unsigned int>(flag) << ")";
|
|
- }
|
|
- } else {
|
|
- GTEST_LOG_(FATAL) << "Read from death test child process failed: "
|
|
- << GetLastErrnoDescription();
|
|
- }
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
|
|
- set_read_fd(-1);
|
|
-}
|
|
-
|
|
-std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
|
|
-
|
|
-// Signals that the death test code which should have exited, didn't.
|
|
-// Should be called only in a death test child process.
|
|
-// Writes a status byte to the child's status file descriptor, then
|
|
-// calls _exit(1).
|
|
-void DeathTestImpl::Abort(AbortReason reason) {
|
|
- // The parent process considers the death test to be a failure if
|
|
- // it finds any data in our pipe. So, here we write a single flag byte
|
|
- // to the pipe, then exit.
|
|
- const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived
|
|
- : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew
|
|
- : kDeathTestReturned;
|
|
-
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
|
|
- // We are leaking the descriptor here because on some platforms (i.e.,
|
|
- // when built as Windows DLL), destructors of global objects will still
|
|
- // run after calling _exit(). On such systems, write_fd_ will be
|
|
- // indirectly closed from the destructor of UnitTestImpl, causing double
|
|
- // close if it is also closed here. On debug configurations, double close
|
|
- // may assert. As there are no in-process buffers to flush here, we are
|
|
- // relying on the OS to close the descriptor after the process terminates
|
|
- // when the destructors are not run.
|
|
- _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
|
-}
|
|
-
|
|
-// Returns an indented copy of stderr output for a death test.
|
|
-// This makes distinguishing death test output lines from regular log lines
|
|
-// much easier.
|
|
-static ::std::string FormatDeathTestOutput(const ::std::string& output) {
|
|
- ::std::string ret;
|
|
- for (size_t at = 0;;) {
|
|
- const size_t line_end = output.find('\n', at);
|
|
- ret += "[ DEATH ] ";
|
|
- if (line_end == ::std::string::npos) {
|
|
- ret += output.substr(at);
|
|
- break;
|
|
- }
|
|
- ret += output.substr(at, line_end + 1 - at);
|
|
- at = line_end + 1;
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
-// Assesses the success or failure of a death test, using both private
|
|
-// members which have previously been set, and one argument:
|
|
-//
|
|
-// Private data members:
|
|
-// outcome: An enumeration describing how the death test
|
|
-// concluded: DIED, LIVED, THREW, or RETURNED. The death test
|
|
-// fails in the latter three cases.
|
|
-// status: The exit status of the child process. On *nix, it is in the
|
|
-// in the format specified by wait(2). On Windows, this is the
|
|
-// value supplied to the ExitProcess() API or a numeric code
|
|
-// of the exception that terminated the program.
|
|
-// matcher_: A matcher that's expected to match the stderr output by the child
|
|
-// process.
|
|
-//
|
|
-// Argument:
|
|
-// status_ok: true if exit_status is acceptable in the context of
|
|
-// this particular death test, which fails if it is false
|
|
-//
|
|
-// 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()) return false;
|
|
-
|
|
- const std::string error_message = GetErrorLogs();
|
|
-
|
|
- bool success = false;
|
|
- Message buffer;
|
|
-
|
|
- buffer << "Death test: " << statement() << "\n";
|
|
- switch (outcome()) {
|
|
- case LIVED:
|
|
- buffer << " Result: failed to die.\n"
|
|
- << " Error msg:\n"
|
|
- << FormatDeathTestOutput(error_message);
|
|
- break;
|
|
- case THREW:
|
|
- buffer << " Result: threw an exception.\n"
|
|
- << " Error msg:\n"
|
|
- << FormatDeathTestOutput(error_message);
|
|
- break;
|
|
- case RETURNED:
|
|
- buffer << " Result: illegal return in test statement.\n"
|
|
- << " Error msg:\n"
|
|
- << FormatDeathTestOutput(error_message);
|
|
- break;
|
|
- case DIED:
|
|
- if (status_ok) {
|
|
- if (matcher_.Matches(error_message)) {
|
|
- success = true;
|
|
- } else {
|
|
- std::ostringstream stream;
|
|
- matcher_.DescribeTo(&stream);
|
|
- buffer << " Result: died but not with expected error.\n"
|
|
- << " Expected: " << stream.str() << "\n"
|
|
- << "Actual msg:\n"
|
|
- << FormatDeathTestOutput(error_message);
|
|
- }
|
|
- } else {
|
|
- buffer << " Result: died but not with expected exit code:\n"
|
|
- << " " << ExitSummary(status()) << "\n"
|
|
- << "Actual msg:\n"
|
|
- << FormatDeathTestOutput(error_message);
|
|
- }
|
|
- break;
|
|
- case IN_PROGRESS:
|
|
- default:
|
|
- GTEST_LOG_(FATAL)
|
|
- << "DeathTest::Passed somehow called before conclusion of test";
|
|
- }
|
|
-
|
|
- DeathTest::set_last_death_test_message(buffer.GetString());
|
|
- return success;
|
|
-}
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-// WindowsDeathTest implements death tests on Windows. Due to the
|
|
-// specifics of starting new processes on Windows, death tests there are
|
|
-// always threadsafe, and Google Test considers the
|
|
-// --gtest_death_test_style=fast setting to be equivalent to
|
|
-// --gtest_death_test_style=threadsafe there.
|
|
-//
|
|
-// A few implementation notes: Like the Linux version, the Windows
|
|
-// implementation uses pipes for child-to-parent communication. But due to
|
|
-// the specifics of pipes on Windows, some extra steps are required:
|
|
-//
|
|
-// 1. The parent creates a communication pipe and stores handles to both
|
|
-// ends of it.
|
|
-// 2. The parent starts the child and provides it with the information
|
|
-// necessary to acquire the handle to the write end of the pipe.
|
|
-// 3. The child acquires the write end of the pipe and signals the parent
|
|
-// using a Windows event.
|
|
-// 4. Now the parent can release the write end of the pipe on its side. If
|
|
-// this is done before step 3, the object's reference count goes down to
|
|
-// 0 and it is destroyed, preventing the child from acquiring it. The
|
|
-// parent now has to release it, or read operations on the read end of
|
|
-// the pipe will not return when the child terminates.
|
|
-// 5. The parent reads child's output through the pipe (outcome code and
|
|
-// any possible error messages) from the pipe, and its stderr and then
|
|
-// determines whether to fail the test.
|
|
-//
|
|
-// Note: to distinguish Win32 API calls from the local method and function
|
|
-// calls, the former are explicitly resolved in the global namespace.
|
|
-//
|
|
-class WindowsDeathTest : public DeathTestImpl {
|
|
- public:
|
|
- WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
|
|
- const char* file, int line)
|
|
- : DeathTestImpl(a_statement, std::move(matcher)),
|
|
- file_(file),
|
|
- line_(line) {}
|
|
-
|
|
- // All of these virtual functions are inherited from DeathTest.
|
|
- virtual int Wait();
|
|
- virtual TestRole AssumeRole();
|
|
-
|
|
- private:
|
|
- // The name of the file in which the death test is located.
|
|
- const char* const file_;
|
|
- // The line number on which the death test is located.
|
|
- const int line_;
|
|
- // Handle to the write end of the pipe to the child process.
|
|
- AutoHandle write_handle_;
|
|
- // Child process handle.
|
|
- AutoHandle child_handle_;
|
|
- // Event the child process uses to signal the parent that it has
|
|
- // acquired the handle to the write end of the pipe. After seeing this
|
|
- // event the parent can release its own handles to make sure its
|
|
- // ReadFile() calls return when the child terminates.
|
|
- AutoHandle event_handle_;
|
|
-};
|
|
-
|
|
-// Waits for the child in a death test to exit, returning its exit
|
|
-// status, or 0 if no child process exists. As a side effect, sets the
|
|
-// outcome data member.
|
|
-int WindowsDeathTest::Wait() {
|
|
- if (!spawned()) return 0;
|
|
-
|
|
- // Wait until the child either signals that it has acquired the write end
|
|
- // of the pipe or it dies.
|
|
- const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()};
|
|
- switch (::WaitForMultipleObjects(2, wait_handles,
|
|
- FALSE, // Waits for any of the handles.
|
|
- INFINITE)) {
|
|
- case WAIT_OBJECT_0:
|
|
- case WAIT_OBJECT_0 + 1:
|
|
- break;
|
|
- default:
|
|
- GTEST_DEATH_TEST_CHECK_(false); // Should not get here.
|
|
- }
|
|
-
|
|
- // The child has acquired the write end of the pipe or exited.
|
|
- // We release the handle on our side and continue.
|
|
- write_handle_.Reset();
|
|
- event_handle_.Reset();
|
|
-
|
|
- ReadAndInterpretStatusByte();
|
|
-
|
|
- // Waits for the child process to exit if it haven't already. This
|
|
- // returns immediately if the child has already exited, regardless of
|
|
- // whether previous calls to WaitForMultipleObjects synchronized on this
|
|
- // handle or not.
|
|
- GTEST_DEATH_TEST_CHECK_(WAIT_OBJECT_0 ==
|
|
- ::WaitForSingleObject(child_handle_.Get(), INFINITE));
|
|
- DWORD status_code;
|
|
- GTEST_DEATH_TEST_CHECK_(
|
|
- ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);
|
|
- child_handle_.Reset();
|
|
- set_status(static_cast<int>(status_code));
|
|
- return status();
|
|
-}
|
|
-
|
|
-// The AssumeRole process for a Windows death test. It creates a child
|
|
-// process with the same executable as the current process to run the
|
|
-// death test. The child process is given the --gtest_filter and
|
|
-// --gtest_internal_run_death_test flags such that it knows to run the
|
|
-// current death test only.
|
|
-DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
|
- const UnitTestImpl* const impl = GetUnitTestImpl();
|
|
- const InternalRunDeathTestFlag* const flag =
|
|
- impl->internal_run_death_test_flag();
|
|
- const TestInfo* const info = impl->current_test_info();
|
|
- const int death_test_index = info->result()->death_test_count();
|
|
-
|
|
- if (flag != nullptr) {
|
|
- // ParseInternalRunDeathTestFlag() has performed all the necessary
|
|
- // processing.
|
|
- set_write_fd(flag->write_fd());
|
|
- return EXECUTE_TEST;
|
|
- }
|
|
-
|
|
- // WindowsDeathTest uses an anonymous pipe to communicate results of
|
|
- // a death test.
|
|
- SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),
|
|
- nullptr, TRUE};
|
|
- HANDLE read_handle, write_handle;
|
|
- GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle,
|
|
- &handles_are_inheritable,
|
|
- 0) // Default buffer size.
|
|
- != FALSE);
|
|
- set_read_fd(
|
|
- ::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), O_RDONLY));
|
|
- write_handle_.Reset(write_handle);
|
|
- event_handle_.Reset(::CreateEvent(
|
|
- &handles_are_inheritable,
|
|
- TRUE, // The event will automatically reset to non-signaled state.
|
|
- FALSE, // The initial state is non-signalled.
|
|
- nullptr)); // The even is unnamed.
|
|
- GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
|
|
- const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
|
- "filter=" + info->test_suite_name() + "." +
|
|
- info->name();
|
|
- const std::string internal_flag =
|
|
- std::string("--") + GTEST_FLAG_PREFIX_ +
|
|
- "internal_run_death_test=" + file_ + "|" + StreamableToString(line_) +
|
|
- "|" + StreamableToString(death_test_index) + "|" +
|
|
- StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
|
|
- // size_t has the same width as pointers on both 32-bit and 64-bit
|
|
- // Windows platforms.
|
|
- // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
|
|
- "|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
|
|
- StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
|
|
-
|
|
- char executable_path[_MAX_PATH + 1]; // NOLINT
|
|
- GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
|
|
- executable_path,
|
|
- _MAX_PATH));
|
|
-
|
|
- std::string command_line = std::string(::GetCommandLineA()) + " " +
|
|
- filter_flag + " \"" + internal_flag + "\"";
|
|
-
|
|
- DeathTest::set_last_death_test_message("");
|
|
-
|
|
- CaptureStderr();
|
|
- // Flush the log buffers since the log streams are shared with the child.
|
|
- FlushInfoLog();
|
|
-
|
|
- // The child process will share the standard handles with the parent.
|
|
- STARTUPINFOA startup_info;
|
|
- memset(&startup_info, 0, sizeof(STARTUPINFO));
|
|
- startup_info.dwFlags = STARTF_USESTDHANDLES;
|
|
- startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
|
|
- startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
|
- startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
|
|
-
|
|
- PROCESS_INFORMATION process_info;
|
|
- GTEST_DEATH_TEST_CHECK_(
|
|
- ::CreateProcessA(
|
|
- executable_path, const_cast<char*>(command_line.c_str()),
|
|
- nullptr, // Returned process handle is not inheritable.
|
|
- nullptr, // Returned thread handle is not inheritable.
|
|
- TRUE, // Child inherits all inheritable handles (for write_handle_).
|
|
- 0x0, // Default creation flags.
|
|
- nullptr, // Inherit the parent's environment.
|
|
- UnitTest::GetInstance()->original_working_dir(), &startup_info,
|
|
- &process_info) != FALSE);
|
|
- child_handle_.Reset(process_info.hProcess);
|
|
- ::CloseHandle(process_info.hThread);
|
|
- set_spawned(true);
|
|
- return OVERSEE_TEST;
|
|
-}
|
|
-
|
|
-#elif GTEST_OS_FUCHSIA
|
|
-
|
|
-class FuchsiaDeathTest : public DeathTestImpl {
|
|
- public:
|
|
- FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
|
|
- const char* file, int line)
|
|
- : DeathTestImpl(a_statement, std::move(matcher)),
|
|
- file_(file),
|
|
- line_(line) {}
|
|
-
|
|
- // All of these virtual functions are inherited from DeathTest.
|
|
- int Wait() override;
|
|
- TestRole AssumeRole() override;
|
|
- std::string GetErrorLogs() override;
|
|
-
|
|
- private:
|
|
- // The name of the file in which the death test is located.
|
|
- const char* const file_;
|
|
- // The line number on which the death test is located.
|
|
- const int line_;
|
|
- // The stderr data captured by the child process.
|
|
- std::string captured_stderr_;
|
|
-
|
|
- zx::process child_process_;
|
|
- zx::channel exception_channel_;
|
|
- zx::socket stderr_socket_;
|
|
-};
|
|
-
|
|
-// Utility class for accumulating command-line arguments.
|
|
-class Arguments {
|
|
- public:
|
|
- Arguments() { args_.push_back(nullptr); }
|
|
-
|
|
- ~Arguments() {
|
|
- for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
|
|
- ++i) {
|
|
- free(*i);
|
|
- }
|
|
- }
|
|
- void AddArgument(const char* argument) {
|
|
- args_.insert(args_.end() - 1, posix::StrDup(argument));
|
|
- }
|
|
-
|
|
- template <typename Str>
|
|
- void AddArguments(const ::std::vector<Str>& arguments) {
|
|
- for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
|
|
- i != arguments.end(); ++i) {
|
|
- args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
|
|
- }
|
|
- }
|
|
- char* const* Argv() { return &args_[0]; }
|
|
-
|
|
- int size() { return static_cast<int>(args_.size()) - 1; }
|
|
-
|
|
- private:
|
|
- std::vector<char*> args_;
|
|
-};
|
|
-
|
|
-// Waits for the child in a death test to exit, returning its exit
|
|
-// status, or 0 if no child process exists. As a side effect, sets the
|
|
-// outcome data member.
|
|
-int FuchsiaDeathTest::Wait() {
|
|
- const int kProcessKey = 0;
|
|
- const int kSocketKey = 1;
|
|
- const int kExceptionKey = 2;
|
|
-
|
|
- if (!spawned()) return 0;
|
|
-
|
|
- // Create a port to wait for socket/task/exception events.
|
|
- zx_status_t status_zx;
|
|
- zx::port port;
|
|
- status_zx = zx::port::create(0, &port);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
-
|
|
- // Register to wait for the child process to terminate.
|
|
- status_zx =
|
|
- child_process_.wait_async(port, kProcessKey, ZX_PROCESS_TERMINATED, 0);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
-
|
|
- // Register to wait for the socket to be readable or closed.
|
|
- status_zx = stderr_socket_.wait_async(
|
|
- port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
-
|
|
- // Register to wait for an exception.
|
|
- status_zx = exception_channel_.wait_async(port, kExceptionKey,
|
|
- ZX_CHANNEL_READABLE, 0);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
-
|
|
- bool process_terminated = false;
|
|
- bool socket_closed = false;
|
|
- do {
|
|
- zx_port_packet_t packet = {};
|
|
- status_zx = port.wait(zx::time::infinite(), &packet);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
-
|
|
- if (packet.key == kExceptionKey) {
|
|
- // Process encountered an exception. Kill it directly rather than
|
|
- // letting other handlers process the event. We will get a kProcessKey
|
|
- // event when the process actually terminates.
|
|
- status_zx = child_process_.kill();
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
- } else if (packet.key == kProcessKey) {
|
|
- // Process terminated.
|
|
- GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
|
|
- GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);
|
|
- process_terminated = true;
|
|
- } else if (packet.key == kSocketKey) {
|
|
- GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
|
|
- if (packet.signal.observed & ZX_SOCKET_READABLE) {
|
|
- // Read data from the socket.
|
|
- constexpr size_t kBufferSize = 1024;
|
|
- do {
|
|
- size_t old_length = captured_stderr_.length();
|
|
- size_t bytes_read = 0;
|
|
- captured_stderr_.resize(old_length + kBufferSize);
|
|
- status_zx =
|
|
- stderr_socket_.read(0, &captured_stderr_.front() + old_length,
|
|
- kBufferSize, &bytes_read);
|
|
- captured_stderr_.resize(old_length + bytes_read);
|
|
- } while (status_zx == ZX_OK);
|
|
- if (status_zx == ZX_ERR_PEER_CLOSED) {
|
|
- socket_closed = true;
|
|
- } else {
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT);
|
|
- status_zx = stderr_socket_.wait_async(
|
|
- port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
- }
|
|
- } else {
|
|
- GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED);
|
|
- socket_closed = true;
|
|
- }
|
|
- }
|
|
- } while (!process_terminated && !socket_closed);
|
|
-
|
|
- ReadAndInterpretStatusByte();
|
|
-
|
|
- zx_info_process_t buffer;
|
|
- status_zx = child_process_.get_info(ZX_INFO_PROCESS, &buffer, sizeof(buffer),
|
|
- nullptr, nullptr);
|
|
- GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
|
|
-
|
|
- GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED);
|
|
- set_status(static_cast<int>(buffer.return_code));
|
|
- return status();
|
|
-}
|
|
-
|
|
-// The AssumeRole process for a Fuchsia death test. It creates a child
|
|
-// process with the same executable as the current process to run the
|
|
-// death test. The child process is given the --gtest_filter and
|
|
-// --gtest_internal_run_death_test flags such that it knows to run the
|
|
-// current death test only.
|
|
-DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
|
|
- const UnitTestImpl* const impl = GetUnitTestImpl();
|
|
- const InternalRunDeathTestFlag* const flag =
|
|
- impl->internal_run_death_test_flag();
|
|
- const TestInfo* const info = impl->current_test_info();
|
|
- const int death_test_index = info->result()->death_test_count();
|
|
-
|
|
- if (flag != nullptr) {
|
|
- // ParseInternalRunDeathTestFlag() has performed all the necessary
|
|
- // processing.
|
|
- set_write_fd(kFuchsiaReadPipeFd);
|
|
- return EXECUTE_TEST;
|
|
- }
|
|
-
|
|
- // Flush the log buffers since the log streams are shared with the child.
|
|
- FlushInfoLog();
|
|
-
|
|
- // Build the child process command line.
|
|
- const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
|
- "filter=" + info->test_suite_name() + "." +
|
|
- info->name();
|
|
- const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
|
- kInternalRunDeathTestFlag + "=" + file_ +
|
|
- "|" + StreamableToString(line_) + "|" +
|
|
- StreamableToString(death_test_index);
|
|
- Arguments args;
|
|
- args.AddArguments(GetInjectableArgvs());
|
|
- args.AddArgument(filter_flag.c_str());
|
|
- args.AddArgument(internal_flag.c_str());
|
|
-
|
|
- // Build the pipe for communication with the child.
|
|
- zx_status_t status;
|
|
- zx_handle_t child_pipe_handle;
|
|
- int child_pipe_fd;
|
|
- status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle);
|
|
- GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
|
- set_read_fd(child_pipe_fd);
|
|
-
|
|
- // Set the pipe handle for the child.
|
|
- fdio_spawn_action_t spawn_actions[2] = {};
|
|
- fdio_spawn_action_t* add_handle_action = &spawn_actions[0];
|
|
- add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;
|
|
- add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd);
|
|
- add_handle_action->h.handle = child_pipe_handle;
|
|
-
|
|
- // Create a socket pair will be used to receive the child process' stderr.
|
|
- zx::socket stderr_producer_socket;
|
|
- status = zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);
|
|
- GTEST_DEATH_TEST_CHECK_(status >= 0);
|
|
- int stderr_producer_fd = -1;
|
|
- status =
|
|
- fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd);
|
|
- GTEST_DEATH_TEST_CHECK_(status >= 0);
|
|
-
|
|
- // Make the stderr socket nonblocking.
|
|
- GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0);
|
|
-
|
|
- fdio_spawn_action_t* add_stderr_action = &spawn_actions[1];
|
|
- add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD;
|
|
- add_stderr_action->fd.local_fd = stderr_producer_fd;
|
|
- add_stderr_action->fd.target_fd = STDERR_FILENO;
|
|
-
|
|
- // Create a child job.
|
|
- zx_handle_t child_job = ZX_HANDLE_INVALID;
|
|
- status = zx_job_create(zx_job_default(), 0, &child_job);
|
|
- GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
|
- zx_policy_basic_t policy;
|
|
- policy.condition = ZX_POL_NEW_ANY;
|
|
- policy.policy = ZX_POL_ACTION_ALLOW;
|
|
- status = zx_job_set_policy(child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC,
|
|
- &policy, 1);
|
|
- GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
|
-
|
|
- // Create an exception channel attached to the |child_job|, to allow
|
|
- // us to suppress the system default exception handler from firing.
|
|
- status = zx_task_create_exception_channel(
|
|
- child_job, 0, exception_channel_.reset_and_get_address());
|
|
- GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
|
-
|
|
- // Spawn the child process.
|
|
- status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0],
|
|
- args.Argv(), nullptr, 2, spawn_actions,
|
|
- child_process_.reset_and_get_address(), nullptr);
|
|
- GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
|
|
-
|
|
- set_spawned(true);
|
|
- return OVERSEE_TEST;
|
|
-}
|
|
-
|
|
-std::string FuchsiaDeathTest::GetErrorLogs() { return captured_stderr_; }
|
|
-
|
|
-#else // We are neither on Windows, nor on Fuchsia.
|
|
-
|
|
-// ForkingDeathTest provides implementations for most of the abstract
|
|
-// methods of the DeathTest interface. Only the AssumeRole method is
|
|
-// left undefined.
|
|
-class ForkingDeathTest : public DeathTestImpl {
|
|
- public:
|
|
- ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher);
|
|
-
|
|
- // All of these virtual functions are inherited from DeathTest.
|
|
- int Wait() override;
|
|
-
|
|
- protected:
|
|
- void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
|
|
-
|
|
- private:
|
|
- // PID of child process during death test; 0 in the child process itself.
|
|
- pid_t child_pid_;
|
|
-};
|
|
-
|
|
-// Constructs a ForkingDeathTest.
|
|
-ForkingDeathTest::ForkingDeathTest(const char* a_statement,
|
|
- Matcher<const std::string&> matcher)
|
|
- : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {}
|
|
-
|
|
-// Waits for the child in a death test to exit, returning its exit
|
|
-// status, or 0 if no child process exists. As a side effect, sets the
|
|
-// outcome data member.
|
|
-int ForkingDeathTest::Wait() {
|
|
- if (!spawned()) return 0;
|
|
-
|
|
- ReadAndInterpretStatusByte();
|
|
-
|
|
- int status_value;
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
|
|
- set_status(status_value);
|
|
- return status_value;
|
|
-}
|
|
-
|
|
-// A concrete death test class that forks, then immediately runs the test
|
|
-// in the child process.
|
|
-class NoExecDeathTest : public ForkingDeathTest {
|
|
- public:
|
|
- NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher)
|
|
- : ForkingDeathTest(a_statement, std::move(matcher)) {}
|
|
- TestRole AssumeRole() override;
|
|
-};
|
|
-
|
|
-// The AssumeRole process for a fork-and-run death test. It implements a
|
|
-// straightforward fork, with a simple pipe to transmit the status byte.
|
|
-DeathTest::TestRole NoExecDeathTest::AssumeRole() {
|
|
- const size_t thread_count = GetThreadCount();
|
|
- if (thread_count != 1) {
|
|
- GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
|
|
- }
|
|
-
|
|
- int pipe_fd[2];
|
|
- GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
|
|
-
|
|
- DeathTest::set_last_death_test_message("");
|
|
- CaptureStderr();
|
|
- // When we fork the process below, the log file buffers are copied, but the
|
|
- // file descriptors are shared. We flush all log files here so that closing
|
|
- // the file descriptors in the child process doesn't throw off the
|
|
- // synchronization between descriptors and buffers in the parent process.
|
|
- // This is as close to the fork as possible to avoid a race condition in case
|
|
- // there are multiple threads running before the death test, and another
|
|
- // thread writes to the log file.
|
|
- FlushInfoLog();
|
|
-
|
|
- const pid_t child_pid = fork();
|
|
- GTEST_DEATH_TEST_CHECK_(child_pid != -1);
|
|
- set_child_pid(child_pid);
|
|
- if (child_pid == 0) {
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));
|
|
- set_write_fd(pipe_fd[1]);
|
|
- // Redirects all logging to stderr in the child process to prevent
|
|
- // concurrent writes to the log files. We capture stderr in the parent
|
|
- // process and append the child process' output to a log.
|
|
- LogToStderr();
|
|
- // Event forwarding to the listeners of event listener API mush be shut
|
|
- // down in death test subprocesses.
|
|
- GetUnitTestImpl()->listeners()->SuppressEventForwarding();
|
|
- g_in_fast_death_test_child = true;
|
|
- return EXECUTE_TEST;
|
|
- } else {
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
|
- set_read_fd(pipe_fd[0]);
|
|
- set_spawned(true);
|
|
- return OVERSEE_TEST;
|
|
- }
|
|
-}
|
|
-
|
|
-// A concrete death test class that forks and re-executes the main
|
|
-// program from the beginning, with command-line flags set that cause
|
|
-// only this specific death test to be run.
|
|
-class ExecDeathTest : public ForkingDeathTest {
|
|
- public:
|
|
- ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
|
|
- const char* file, int line)
|
|
- : ForkingDeathTest(a_statement, std::move(matcher)),
|
|
- file_(file),
|
|
- line_(line) {}
|
|
- TestRole AssumeRole() override;
|
|
-
|
|
- private:
|
|
- static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {
|
|
- ::std::vector<std::string> args = GetInjectableArgvs();
|
|
-#if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
|
|
- ::std::vector<std::string> extra_args =
|
|
- GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();
|
|
- args.insert(args.end(), extra_args.begin(), extra_args.end());
|
|
-#endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
|
|
- return args;
|
|
- }
|
|
- // The name of the file in which the death test is located.
|
|
- const char* const file_;
|
|
- // The line number on which the death test is located.
|
|
- const int line_;
|
|
-};
|
|
-
|
|
-// Utility class for accumulating command-line arguments.
|
|
-class Arguments {
|
|
- public:
|
|
- Arguments() { args_.push_back(nullptr); }
|
|
-
|
|
- ~Arguments() {
|
|
- for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
|
|
- ++i) {
|
|
- free(*i);
|
|
- }
|
|
- }
|
|
- void AddArgument(const char* argument) {
|
|
- args_.insert(args_.end() - 1, posix::StrDup(argument));
|
|
- }
|
|
-
|
|
- template <typename Str>
|
|
- void AddArguments(const ::std::vector<Str>& arguments) {
|
|
- for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
|
|
- i != arguments.end(); ++i) {
|
|
- args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
|
|
- }
|
|
- }
|
|
- char* const* Argv() { return &args_[0]; }
|
|
-
|
|
- private:
|
|
- std::vector<char*> args_;
|
|
-};
|
|
-
|
|
-// A struct that encompasses the arguments to the child process of a
|
|
-// threadsafe-style death test process.
|
|
-struct ExecDeathTestArgs {
|
|
- char* const* argv; // Command-line arguments for the child's call to exec
|
|
- int close_fd; // File descriptor to close; the read end of a pipe
|
|
-};
|
|
-
|
|
-#if GTEST_OS_QNX
|
|
-extern "C" char** environ;
|
|
-#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.
|
|
-static int ExecDeathTestChildMain(void* child_arg) {
|
|
- ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
|
|
-
|
|
- // We need to execute the test program in the same environment where
|
|
- // it was originally invoked. Therefore we change to the original
|
|
- // working directory first.
|
|
- const char* const original_dir =
|
|
- UnitTest::GetInstance()->original_working_dir();
|
|
- // We can safely call chdir() as it's a direct system call.
|
|
- if (chdir(original_dir) != 0) {
|
|
- DeathTestAbort(std::string("chdir(\"") + original_dir +
|
|
- "\") failed: " + GetLastErrnoDescription());
|
|
- return EXIT_FAILURE;
|
|
- }
|
|
-
|
|
- // 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 execv() doesn't search the PATH, the user must
|
|
- // invoke the test program via a valid path that contains at least
|
|
- // one path separator.
|
|
- 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
|
|
-
|
|
-#if GTEST_HAS_CLONE
|
|
-// Two utility routines that together determine the direction the stack
|
|
-// grows.
|
|
-// This could be accomplished more elegantly by a single recursive
|
|
-// function, but we want to guard against the unlikely possibility of
|
|
-// a smart compiler optimizing the recursion away.
|
|
-//
|
|
-// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
|
|
-// StackLowerThanAddress into StackGrowsDown, which then doesn't give
|
|
-// 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 = 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 = 0;
|
|
- bool result;
|
|
- StackLowerThanAddress(&dummy, &result);
|
|
- return result;
|
|
-}
|
|
-#endif // GTEST_HAS_CLONE
|
|
-
|
|
-// Spawns a child process with the same executable as the current process in
|
|
-// a thread-safe manner and instructs it to run the death test. The
|
|
-// implementation uses fork(2) + exec. On systems where clone(2) is
|
|
-// available, it is used instead, being slightly more thread-safe. On QNX,
|
|
-// fork supports only single-threaded environments, so this function uses
|
|
-// spawn(2) there instead. The function dies with an error message if
|
|
-// anything goes wrong.
|
|
-static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
|
- ExecDeathTestArgs args = {argv, close_fd};
|
|
- pid_t child_pid = -1;
|
|
-
|
|
-#if GTEST_OS_QNX
|
|
- // Obtains the current directory and sets it to be closed in the child
|
|
- // process.
|
|
- const int cwd_fd = open(".", O_RDONLY);
|
|
- GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));
|
|
- // We need to execute the test program in the same environment where
|
|
- // it was originally invoked. Therefore we change to the original
|
|
- // working directory first.
|
|
- const char* const original_dir =
|
|
- UnitTest::GetInstance()->original_working_dir();
|
|
- // We can safely call chdir() as it's a direct system call.
|
|
- if (chdir(original_dir) != 0) {
|
|
- DeathTestAbort(std::string("chdir(\"") + original_dir +
|
|
- "\") failed: " + GetLastErrnoDescription());
|
|
- return EXIT_FAILURE;
|
|
- }
|
|
-
|
|
- int fd_flags;
|
|
- // Set close_fd to be closed after spawn.
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(
|
|
- fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC));
|
|
- struct inheritance inherit = {0};
|
|
- // spawn is a system call.
|
|
- 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));
|
|
-
|
|
-#else // GTEST_OS_QNX
|
|
-#if GTEST_OS_LINUX
|
|
- // When a SIGPROF signal is received while fork() or clone() are executing,
|
|
- // the process may hang. To avoid this, we ignore SIGPROF here and re-enable
|
|
- // it after the call to fork()/clone() is complete.
|
|
- struct sigaction saved_sigprof_action;
|
|
- struct sigaction ignore_sigprof_action;
|
|
- memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));
|
|
- sigemptyset(&ignore_sigprof_action.sa_mask);
|
|
- ignore_sigprof_action.sa_handler = SIG_IGN;
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(
|
|
- sigaction(SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));
|
|
-#endif // GTEST_OS_LINUX
|
|
-
|
|
-#if GTEST_HAS_CLONE
|
|
- const bool use_fork = GTEST_FLAG_GET(death_test_use_fork);
|
|
-
|
|
- if (!use_fork) {
|
|
- static const bool stack_grows_down = StackGrowsDown();
|
|
- 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);
|
|
- GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
|
|
-
|
|
- // Maximum stack alignment in bytes: For a downward-growing stack, this
|
|
- // amount is subtracted from size of the stack space to get an address
|
|
- // that is within the stack space and is aligned on all systems we care
|
|
- // about. As far as I know there is no ABI with stack alignment greater
|
|
- // than 64. We assume stack and stack_size already have alignment of
|
|
- // kMaxStackAlignment.
|
|
- const size_t kMaxStackAlignment = 64;
|
|
- void* const stack_top =
|
|
- static_cast<char*>(stack) +
|
|
- (stack_grows_down ? stack_size - kMaxStackAlignment : 0);
|
|
- GTEST_DEATH_TEST_CHECK_(
|
|
- static_cast<size_t>(stack_size) > kMaxStackAlignment &&
|
|
- reinterpret_cast<uintptr_t>(stack_top) % kMaxStackAlignment == 0);
|
|
-
|
|
- child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
|
|
-
|
|
- GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
|
|
- }
|
|
-#else
|
|
- const bool use_fork = true;
|
|
-#endif // GTEST_HAS_CLONE
|
|
-
|
|
- if (use_fork && (child_pid = fork()) == 0) {
|
|
- ExecDeathTestChildMain(&args);
|
|
- _exit(0);
|
|
- }
|
|
-#endif // GTEST_OS_QNX
|
|
-#if GTEST_OS_LINUX
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(
|
|
- sigaction(SIGPROF, &saved_sigprof_action, nullptr));
|
|
-#endif // GTEST_OS_LINUX
|
|
-
|
|
- GTEST_DEATH_TEST_CHECK_(child_pid != -1);
|
|
- return child_pid;
|
|
-}
|
|
-
|
|
-// The AssumeRole process for a fork-and-exec death test. It re-executes the
|
|
-// main program from the beginning, setting the --gtest_filter
|
|
-// and --gtest_internal_run_death_test flags to cause only the current
|
|
-// death test to be re-run.
|
|
-DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
|
- const UnitTestImpl* const impl = GetUnitTestImpl();
|
|
- const InternalRunDeathTestFlag* const flag =
|
|
- impl->internal_run_death_test_flag();
|
|
- const TestInfo* const info = impl->current_test_info();
|
|
- const int death_test_index = info->result()->death_test_count();
|
|
-
|
|
- if (flag != nullptr) {
|
|
- set_write_fd(flag->write_fd());
|
|
- return EXECUTE_TEST;
|
|
- }
|
|
-
|
|
- int pipe_fd[2];
|
|
- GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
|
|
- // Clear the close-on-exec flag on the write end of the pipe, lest
|
|
- // it be closed when the child process does an exec:
|
|
- GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
|
|
-
|
|
- const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
|
- "filter=" + info->test_suite_name() + "." +
|
|
- info->name();
|
|
- const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
|
|
- "internal_run_death_test=" + file_ + "|" +
|
|
- StreamableToString(line_) + "|" +
|
|
- StreamableToString(death_test_index) + "|" +
|
|
- StreamableToString(pipe_fd[1]);
|
|
- Arguments args;
|
|
- args.AddArguments(GetArgvsForDeathTestChildProcess());
|
|
- args.AddArgument(filter_flag.c_str());
|
|
- args.AddArgument(internal_flag.c_str());
|
|
-
|
|
- DeathTest::set_last_death_test_message("");
|
|
-
|
|
- CaptureStderr();
|
|
- // See the comment in NoExecDeathTest::AssumeRole for why the next line
|
|
- // is necessary.
|
|
- FlushInfoLog();
|
|
-
|
|
- const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);
|
|
- GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
|
- set_child_pid(child_pid);
|
|
- set_read_fd(pipe_fd[0]);
|
|
- set_spawned(true);
|
|
- return OVERSEE_TEST;
|
|
-}
|
|
-
|
|
-#endif // !GTEST_OS_WINDOWS
|
|
-
|
|
-// Creates a concrete DeathTest-derived class that depends on the
|
|
-// --gtest_death_test_style flag, and sets the pointer pointed to
|
|
-// by the "test" argument to its address. If the test should be
|
|
-// skipped, sets that pointer to NULL. Returns true, unless the
|
|
-// flag is set to an invalid value.
|
|
-bool DefaultDeathTestFactory::Create(const char* statement,
|
|
- Matcher<const std::string&> matcher,
|
|
- const char* file, int line,
|
|
- DeathTest** test) {
|
|
- UnitTestImpl* const impl = GetUnitTestImpl();
|
|
- const InternalRunDeathTestFlag* const flag =
|
|
- impl->internal_run_death_test_flag();
|
|
- const int death_test_index =
|
|
- impl->current_test_info()->increment_death_test_count();
|
|
-
|
|
- if (flag != nullptr) {
|
|
- if (death_test_index > flag->index()) {
|
|
- DeathTest::set_last_death_test_message(
|
|
- "Death test count (" + StreamableToString(death_test_index) +
|
|
- ") somehow exceeded expected maximum (" +
|
|
- StreamableToString(flag->index()) + ")");
|
|
- return false;
|
|
- }
|
|
-
|
|
- if (!(flag->file() == file && flag->line() == line &&
|
|
- flag->index() == death_test_index)) {
|
|
- *test = nullptr;
|
|
- return true;
|
|
- }
|
|
- }
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-
|
|
- if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
|
- GTEST_FLAG_GET(death_test_style) == "fast") {
|
|
- *test = new WindowsDeathTest(statement, std::move(matcher), file, line);
|
|
- }
|
|
-
|
|
-#elif GTEST_OS_FUCHSIA
|
|
-
|
|
- if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
|
|
- GTEST_FLAG_GET(death_test_style) == "fast") {
|
|
- *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
|
|
- }
|
|
-
|
|
-#else
|
|
-
|
|
- if (GTEST_FLAG_GET(death_test_style) == "threadsafe") {
|
|
- *test = new ExecDeathTest(statement, std::move(matcher), file, line);
|
|
- } else if (GTEST_FLAG_GET(death_test_style) == "fast") {
|
|
- *test = new NoExecDeathTest(statement, std::move(matcher));
|
|
- }
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
- else { // NOLINT - this is more readable than unbalanced brackets inside #if.
|
|
- DeathTest::set_last_death_test_message("Unknown death test style \"" +
|
|
- GTEST_FLAG_GET(death_test_style) +
|
|
- "\" encountered");
|
|
- return false;
|
|
- }
|
|
-
|
|
- return true;
|
|
-}
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-// Recreates the pipe and event handles from the provided parameters,
|
|
-// signals the event, and returns a file descriptor wrapped around the pipe
|
|
-// handle. This function is called in the child process only.
|
|
-static int GetStatusFileDescriptor(unsigned int parent_process_id,
|
|
- size_t write_handle_as_size_t,
|
|
- size_t event_handle_as_size_t) {
|
|
- AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
|
|
- FALSE, // Non-inheritable.
|
|
- parent_process_id));
|
|
- if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
|
|
- DeathTestAbort("Unable to open parent process " +
|
|
- StreamableToString(parent_process_id));
|
|
- }
|
|
-
|
|
- GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
|
|
-
|
|
- const HANDLE write_handle = reinterpret_cast<HANDLE>(write_handle_as_size_t);
|
|
- HANDLE dup_write_handle;
|
|
-
|
|
- // The newly initialized handle is accessible only in the parent
|
|
- // process. To obtain one accessible within the child, we need to use
|
|
- // DuplicateHandle.
|
|
- if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
|
|
- ::GetCurrentProcess(), &dup_write_handle,
|
|
- 0x0, // Requested privileges ignored since
|
|
- // DUPLICATE_SAME_ACCESS is used.
|
|
- FALSE, // Request non-inheritable handler.
|
|
- DUPLICATE_SAME_ACCESS)) {
|
|
- DeathTestAbort("Unable to duplicate the pipe handle " +
|
|
- StreamableToString(write_handle_as_size_t) +
|
|
- " from the parent process " +
|
|
- StreamableToString(parent_process_id));
|
|
- }
|
|
-
|
|
- const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
|
|
- HANDLE dup_event_handle;
|
|
-
|
|
- if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
|
|
- ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE,
|
|
- DUPLICATE_SAME_ACCESS)) {
|
|
- DeathTestAbort("Unable to duplicate the event handle " +
|
|
- StreamableToString(event_handle_as_size_t) +
|
|
- " from the parent process " +
|
|
- StreamableToString(parent_process_id));
|
|
- }
|
|
-
|
|
- const int write_fd =
|
|
- ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
|
|
- if (write_fd == -1) {
|
|
- DeathTestAbort("Unable to convert pipe handle " +
|
|
- StreamableToString(write_handle_as_size_t) +
|
|
- " to a file descriptor");
|
|
- }
|
|
-
|
|
- // Signals the parent that the write end of the pipe has been acquired
|
|
- // so the parent can release its own write end.
|
|
- ::SetEvent(dup_event_handle);
|
|
-
|
|
- return write_fd;
|
|
-}
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-// Returns a newly created InternalRunDeathTestFlag object with fields
|
|
-// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
|
-// the flag is specified; otherwise returns NULL.
|
|
-InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
|
- if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr;
|
|
-
|
|
- // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
|
|
- // can use it here.
|
|
- int line = -1;
|
|
- int index = -1;
|
|
- ::std::vector< ::std::string> fields;
|
|
- SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);
|
|
- int write_fd = -1;
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-
|
|
- unsigned int parent_process_id = 0;
|
|
- size_t write_handle_as_size_t = 0;
|
|
- size_t event_handle_as_size_t = 0;
|
|
-
|
|
- if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) ||
|
|
- !ParseNaturalNumber(fields[2], &index) ||
|
|
- !ParseNaturalNumber(fields[3], &parent_process_id) ||
|
|
- !ParseNaturalNumber(fields[4], &write_handle_as_size_t) ||
|
|
- !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
|
|
- DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
|
- GTEST_FLAG_GET(internal_run_death_test));
|
|
- }
|
|
- write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t,
|
|
- event_handle_as_size_t);
|
|
-
|
|
-#elif GTEST_OS_FUCHSIA
|
|
-
|
|
- if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) ||
|
|
- !ParseNaturalNumber(fields[2], &index)) {
|
|
- DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
|
- GTEST_FLAG_GET(internal_run_death_test));
|
|
- }
|
|
-
|
|
-#else
|
|
-
|
|
- if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) ||
|
|
- !ParseNaturalNumber(fields[2], &index) ||
|
|
- !ParseNaturalNumber(fields[3], &write_fd)) {
|
|
- DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
|
|
- GTEST_FLAG_GET(internal_run_death_test));
|
|
- }
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
- return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-filepath.cc b/vendor/gtest/src/gtest-filepath.cc
|
|
deleted file mode 100644
|
|
index f6ee90cdb..000000000
|
|
--- a/vendor/gtest/src/gtest-filepath.cc
|
|
+++ /dev/null
|
|
@@ -1,367 +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.
|
|
-
|
|
-#include "gtest/internal/gtest-filepath.h"
|
|
-
|
|
-#include <stdlib.h>
|
|
-
|
|
-#include "gtest/gtest-message.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
-#include <windows.h>
|
|
-#elif GTEST_OS_WINDOWS
|
|
-#include <direct.h>
|
|
-#include <io.h>
|
|
-#else
|
|
-#include <limits.h>
|
|
-
|
|
-#include <climits> // Some Linux distributions define PATH_MAX here.
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-#define GTEST_PATH_MAX_ _MAX_PATH
|
|
-#elif defined(PATH_MAX)
|
|
-#define GTEST_PATH_MAX_ PATH_MAX
|
|
-#elif defined(_XOPEN_PATH_MAX)
|
|
-#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
|
|
-#else
|
|
-#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-// On Windows, '\\' is the standard path separator, but many tools and the
|
|
-// Windows API also accept '/' as an alternate path separator. Unless otherwise
|
|
-// noted, a file path can contain either kind of path separators, or a mixture
|
|
-// of them.
|
|
-const char kPathSeparator = '\\';
|
|
-const char kAlternatePathSeparator = '/';
|
|
-const char kAlternatePathSeparatorString[] = "/";
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
-// Windows CE doesn't have a current directory. You should not use
|
|
-// the current directory in tests on Windows CE, but this at least
|
|
-// provides a reasonable fallback.
|
|
-const char kCurrentDirectoryString[] = "\\";
|
|
-// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
|
|
-const DWORD kInvalidFileAttributes = 0xffffffff;
|
|
-#else
|
|
-const char kCurrentDirectoryString[] = ".\\";
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-#else
|
|
-const char kPathSeparator = '/';
|
|
-const char kCurrentDirectoryString[] = "./";
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-// Returns whether the given character is a valid path separator.
|
|
-static bool IsPathSeparator(char c) {
|
|
-#if GTEST_HAS_ALT_PATH_SEP_
|
|
- return (c == kPathSeparator) || (c == kAlternatePathSeparator);
|
|
-#else
|
|
- return c == kPathSeparator;
|
|
-#endif
|
|
-}
|
|
-
|
|
-// Returns the current working directory, or "" if unsuccessful.
|
|
-FilePath FilePath::GetCurrentDir() {
|
|
-#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
|
|
- char cwd[GTEST_PATH_MAX_ + 1] = {'\0'};
|
|
- return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
|
|
-#else
|
|
- char cwd[GTEST_PATH_MAX_ + 1] = {'\0'};
|
|
- char* result = getcwd(cwd, sizeof(cwd));
|
|
-#if GTEST_OS_NACL
|
|
- // getcwd will likely fail in NaCl due to the sandbox, so return something
|
|
- // reasonable. The user may have provided a shim implementation for getcwd,
|
|
- // however, so fallback only when failure is detected.
|
|
- return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
|
|
-#endif // GTEST_OS_NACL
|
|
- return FilePath(result == nullptr ? "" : cwd);
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-}
|
|
-
|
|
-// Returns a copy of the FilePath with the case-insensitive extension removed.
|
|
-// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
|
-// FilePath("dir/file"). If a case-insensitive extension is not
|
|
-// found, returns a copy of the original FilePath.
|
|
-FilePath FilePath::RemoveExtension(const char* extension) const {
|
|
- const std::string dot_extension = std::string(".") + extension;
|
|
- if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
|
|
- return FilePath(
|
|
- pathname_.substr(0, pathname_.length() - dot_extension.length()));
|
|
- }
|
|
- return *this;
|
|
-}
|
|
-
|
|
-// 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* FilePath::FindLastPathSeparator() const {
|
|
- const char* const last_sep = strrchr(c_str(), kPathSeparator);
|
|
-#if GTEST_HAS_ALT_PATH_SEP_
|
|
- const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
|
|
- // Comparing two pointers of which only one is NULL is undefined.
|
|
- if (last_alt_sep != nullptr &&
|
|
- (last_sep == nullptr || last_alt_sep > last_sep)) {
|
|
- return last_alt_sep;
|
|
- }
|
|
-#endif
|
|
- return last_sep;
|
|
-}
|
|
-
|
|
-// Returns a copy of the FilePath with the directory part removed.
|
|
-// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
|
-// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
|
-// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
|
-// returns an empty FilePath ("").
|
|
-// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
|
-FilePath FilePath::RemoveDirectoryName() const {
|
|
- const char* const last_sep = FindLastPathSeparator();
|
|
- return last_sep ? FilePath(last_sep + 1) : *this;
|
|
-}
|
|
-
|
|
-// RemoveFileName returns the directory path with the filename removed.
|
|
-// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
|
-// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
|
-// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
|
-// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
|
-// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
|
-FilePath FilePath::RemoveFileName() const {
|
|
- const char* const last_sep = FindLastPathSeparator();
|
|
- std::string dir;
|
|
- if (last_sep) {
|
|
- dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));
|
|
- } else {
|
|
- dir = kCurrentDirectoryString;
|
|
- }
|
|
- return FilePath(dir);
|
|
-}
|
|
-
|
|
-// Helper functions for naming files in a directory for xml output.
|
|
-
|
|
-// Given directory = "dir", base_name = "test", number = 0,
|
|
-// extension = "xml", returns "dir/test.xml". If number is greater
|
|
-// than zero (e.g., 12), returns "dir/test_12.xml".
|
|
-// On Windows platform, uses \ as the separator rather than /.
|
|
-FilePath FilePath::MakeFileName(const FilePath& directory,
|
|
- const FilePath& base_name, int number,
|
|
- const char* extension) {
|
|
- std::string file;
|
|
- if (number == 0) {
|
|
- file = base_name.string() + "." + extension;
|
|
- } else {
|
|
- file =
|
|
- base_name.string() + "_" + StreamableToString(number) + "." + extension;
|
|
- }
|
|
- return ConcatPaths(directory, FilePath(file));
|
|
-}
|
|
-
|
|
-// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
|
|
-// On Windows, uses \ as the separator rather than /.
|
|
-FilePath FilePath::ConcatPaths(const FilePath& directory,
|
|
- const FilePath& relative_path) {
|
|
- if (directory.IsEmpty()) return relative_path;
|
|
- const FilePath dir(directory.RemoveTrailingPathSeparator());
|
|
- return FilePath(dir.string() + kPathSeparator + relative_path.string());
|
|
-}
|
|
-
|
|
-// Returns true if pathname describes something findable in the file-system,
|
|
-// either a file, directory, or whatever.
|
|
-bool FilePath::FileOrDirectoryExists() const {
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
- LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
|
|
- const DWORD attributes = GetFileAttributes(unicode);
|
|
- delete[] unicode;
|
|
- return attributes != kInvalidFileAttributes;
|
|
-#else
|
|
- posix::StatStruct file_stat{};
|
|
- return posix::Stat(pathname_.c_str(), &file_stat) == 0;
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-}
|
|
-
|
|
-// Returns true if pathname describes a directory in the file-system
|
|
-// that exists.
|
|
-bool FilePath::DirectoryExists() const {
|
|
- bool result = false;
|
|
-#if GTEST_OS_WINDOWS
|
|
- // Don't strip off trailing separator if path is a root directory on
|
|
- // Windows (like "C:\\").
|
|
- const FilePath& path(IsRootDirectory() ? *this
|
|
- : RemoveTrailingPathSeparator());
|
|
-#else
|
|
- const FilePath& path(*this);
|
|
-#endif
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
- LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
|
|
- const DWORD attributes = GetFileAttributes(unicode);
|
|
- delete[] unicode;
|
|
- if ((attributes != kInvalidFileAttributes) &&
|
|
- (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
- result = true;
|
|
- }
|
|
-#else
|
|
- posix::StatStruct file_stat{};
|
|
- result =
|
|
- posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat);
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
- return result;
|
|
-}
|
|
-
|
|
-// Returns true if pathname describes a root directory. (Windows has one
|
|
-// root directory per disk drive.)
|
|
-bool FilePath::IsRootDirectory() const {
|
|
-#if GTEST_OS_WINDOWS
|
|
- return pathname_.length() == 3 && IsAbsolutePath();
|
|
-#else
|
|
- return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
|
|
-#endif
|
|
-}
|
|
-
|
|
-// Returns true if pathname describes an absolute path.
|
|
-bool FilePath::IsAbsolutePath() const {
|
|
- const char* const name = pathname_.c_str();
|
|
-#if GTEST_OS_WINDOWS
|
|
- return pathname_.length() >= 3 &&
|
|
- ((name[0] >= 'a' && name[0] <= 'z') ||
|
|
- (name[0] >= 'A' && name[0] <= 'Z')) &&
|
|
- name[1] == ':' && IsPathSeparator(name[2]);
|
|
-#else
|
|
- return IsPathSeparator(name[0]);
|
|
-#endif
|
|
-}
|
|
-
|
|
-// Returns a pathname for a file that does not currently exist. The pathname
|
|
-// will be directory/base_name.extension or
|
|
-// directory/base_name_<number>.extension if directory/base_name.extension
|
|
-// already exists. The number will be incremented until a pathname is found
|
|
-// that does not already exist.
|
|
-// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
|
-// There could be a race condition if two or more processes are calling this
|
|
-// function at the same time -- they could both pick the same filename.
|
|
-FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
|
|
- const FilePath& base_name,
|
|
- const char* extension) {
|
|
- FilePath full_pathname;
|
|
- int number = 0;
|
|
- do {
|
|
- full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
|
|
- } while (full_pathname.FileOrDirectoryExists());
|
|
- return full_pathname;
|
|
-}
|
|
-
|
|
-// Returns true if FilePath ends with a path separator, which indicates that
|
|
-// it is intended to represent a directory. Returns false otherwise.
|
|
-// This does NOT check that a directory (or file) actually exists.
|
|
-bool FilePath::IsDirectory() const {
|
|
- return !pathname_.empty() &&
|
|
- IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
|
|
-}
|
|
-
|
|
-// Create directories so that path exists. Returns true if successful or if
|
|
-// the directories already exist; returns false if unable to create directories
|
|
-// for any reason.
|
|
-bool FilePath::CreateDirectoriesRecursively() const {
|
|
- if (!this->IsDirectory()) {
|
|
- return false;
|
|
- }
|
|
-
|
|
- if (pathname_.length() == 0 || this->DirectoryExists()) {
|
|
- return true;
|
|
- }
|
|
-
|
|
- const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
|
|
- return parent.CreateDirectoriesRecursively() && this->CreateFolder();
|
|
-}
|
|
-
|
|
-// Create the directory so that path exists. Returns true if successful or
|
|
-// if the directory already exists; returns false if unable to create the
|
|
-// directory for any reason, including if the parent directory does not
|
|
-// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
|
-bool FilePath::CreateFolder() const {
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
- FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
|
- LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
|
- int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
|
|
- 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
|
|
-
|
|
- if (result == -1) {
|
|
- return this->DirectoryExists(); // An error is OK if the directory exists.
|
|
- }
|
|
- return true; // No error.
|
|
-}
|
|
-
|
|
-// If input name has a trailing separator character, remove it and return the
|
|
-// name, otherwise return the name string unmodified.
|
|
-// On Windows platform, uses \ as the separator, other platforms use /.
|
|
-FilePath FilePath::RemoveTrailingPathSeparator() const {
|
|
- return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))
|
|
- : *this;
|
|
-}
|
|
-
|
|
-// Removes any redundant separators that might be in the pathname.
|
|
-// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
|
-// redundancies that might be in a pathname involving "." or "..".
|
|
-void FilePath::Normalize() {
|
|
- auto out = pathname_.begin();
|
|
-
|
|
- for (const char character : pathname_) {
|
|
- if (!IsPathSeparator(character)) {
|
|
- *(out++) = character;
|
|
- } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
|
|
- *(out++) = kPathSeparator;
|
|
- } else {
|
|
- continue;
|
|
- }
|
|
- }
|
|
-
|
|
- pathname_.erase(out, pathname_.end());
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-internal-inl.h b/vendor/gtest/src/gtest-internal-inl.h
|
|
deleted file mode 100644
|
|
index 0b9e929c6..000000000
|
|
--- a/vendor/gtest/src/gtest-internal-inl.h
|
|
+++ /dev/null
|
|
@@ -1,1212 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// Utility functions and classes used by the Google C++ testing framework.//
|
|
-// This file contains purely Google Test's internal implementation. Please
|
|
-// DO NOT #INCLUDE IT IN A USER PROGRAM.
|
|
-
|
|
-#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
|
|
-#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
|
|
-
|
|
-#ifndef _WIN32_WCE
|
|
-#include <errno.h>
|
|
-#endif // !_WIN32_WCE
|
|
-#include <stddef.h>
|
|
-#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
|
|
-#include <string.h> // For memmove.
|
|
-
|
|
-#include <algorithm>
|
|
-#include <cstdint>
|
|
-#include <memory>
|
|
-#include <string>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
-#include <arpa/inet.h> // NOLINT
|
|
-#include <netdb.h> // NOLINT
|
|
-#endif
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-#include <windows.h> // NOLINT
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-#include "gtest/gtest-spi.h"
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
|
-/* class A needs to have dll-interface to be used by clients of class B */)
|
|
-
|
|
-// Declares the flags.
|
|
-//
|
|
-// We don't want the users to modify this flag in the code, but want
|
|
-// Google Test's own unit tests to be able to access it. Therefore we
|
|
-// declare it here as opposed to in gtest.h.
|
|
-GTEST_DECLARE_bool_(death_test_use_fork);
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-// The value of GetTestTypeId() as seen from within the Google Test
|
|
-// library. This is solely for testing GetTestTypeId().
|
|
-GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
|
|
-
|
|
-// A valid random seed must be in [1, kMaxRandomSeed].
|
|
-const int kMaxRandomSeed = 99999;
|
|
-
|
|
-// 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 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.
|
|
-GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
|
|
-
|
|
-// Converts the given time in milliseconds to a date string in the ISO 8601
|
|
-// format, without the timezone information. N.B.: due to the use the
|
|
-// non-reentrant localtime() function, this function is not thread safe. Do
|
|
-// not use it in any code that can be called from multiple threads.
|
|
-GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
|
|
-
|
|
-// Parses a string for an Int32 flag, in the form of "--flag=value".
|
|
-//
|
|
-// On success, stores the value of the flag in *value, and returns
|
|
-// true. On failure, returns false without changing *value.
|
|
-GTEST_API_ bool ParseFlag(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_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);
|
|
-
|
|
- // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
|
|
- // it's easy to type.
|
|
- const int normalized_seed =
|
|
- static_cast<int>((raw_seed - 1U) %
|
|
- static_cast<unsigned int>(kMaxRandomSeed)) +
|
|
- 1;
|
|
- return normalized_seed;
|
|
-}
|
|
-
|
|
-// Returns the first valid random seed after 'seed'. The behavior is
|
|
-// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is
|
|
-// considered to be 1.
|
|
-inline int GetNextRandomSeed(int seed) {
|
|
- GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
|
|
- << "Invalid random seed " << seed << " - must be in [1, "
|
|
- << kMaxRandomSeed << "].";
|
|
- const int next_seed = seed + 1;
|
|
- return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
|
|
-}
|
|
-
|
|
-// This class saves the values of all Google Test flags in its c'tor, and
|
|
-// restores them in its d'tor.
|
|
-class GTestFlagSaver {
|
|
- public:
|
|
- // The c'tor.
|
|
- GTestFlagSaver() {
|
|
- also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);
|
|
- break_on_failure_ = GTEST_FLAG_GET(break_on_failure);
|
|
- catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);
|
|
- color_ = GTEST_FLAG_GET(color);
|
|
- death_test_style_ = GTEST_FLAG_GET(death_test_style);
|
|
- death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);
|
|
- fail_fast_ = GTEST_FLAG_GET(fail_fast);
|
|
- filter_ = GTEST_FLAG_GET(filter);
|
|
- internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);
|
|
- list_tests_ = GTEST_FLAG_GET(list_tests);
|
|
- output_ = GTEST_FLAG_GET(output);
|
|
- brief_ = GTEST_FLAG_GET(brief);
|
|
- print_time_ = GTEST_FLAG_GET(print_time);
|
|
- print_utf8_ = GTEST_FLAG_GET(print_utf8);
|
|
- random_seed_ = GTEST_FLAG_GET(random_seed);
|
|
- repeat_ = GTEST_FLAG_GET(repeat);
|
|
- recreate_environments_when_repeating_ =
|
|
- GTEST_FLAG_GET(recreate_environments_when_repeating);
|
|
- shuffle_ = GTEST_FLAG_GET(shuffle);
|
|
- stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth);
|
|
- stream_result_to_ = GTEST_FLAG_GET(stream_result_to);
|
|
- throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure);
|
|
- }
|
|
-
|
|
- // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
|
|
- ~GTestFlagSaver() {
|
|
- GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);
|
|
- GTEST_FLAG_SET(break_on_failure, break_on_failure_);
|
|
- GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);
|
|
- GTEST_FLAG_SET(color, color_);
|
|
- GTEST_FLAG_SET(death_test_style, death_test_style_);
|
|
- GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);
|
|
- GTEST_FLAG_SET(filter, filter_);
|
|
- GTEST_FLAG_SET(fail_fast, fail_fast_);
|
|
- GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);
|
|
- GTEST_FLAG_SET(list_tests, list_tests_);
|
|
- GTEST_FLAG_SET(output, output_);
|
|
- GTEST_FLAG_SET(brief, brief_);
|
|
- GTEST_FLAG_SET(print_time, print_time_);
|
|
- GTEST_FLAG_SET(print_utf8, print_utf8_);
|
|
- GTEST_FLAG_SET(random_seed, random_seed_);
|
|
- GTEST_FLAG_SET(repeat, repeat_);
|
|
- GTEST_FLAG_SET(recreate_environments_when_repeating,
|
|
- recreate_environments_when_repeating_);
|
|
- GTEST_FLAG_SET(shuffle, shuffle_);
|
|
- GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_);
|
|
- GTEST_FLAG_SET(stream_result_to, stream_result_to_);
|
|
- GTEST_FLAG_SET(throw_on_failure, throw_on_failure_);
|
|
- }
|
|
-
|
|
- private:
|
|
- // Fields for saving the original values of flags.
|
|
- bool also_run_disabled_tests_;
|
|
- bool break_on_failure_;
|
|
- bool catch_exceptions_;
|
|
- 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_;
|
|
- int32_t random_seed_;
|
|
- int32_t repeat_;
|
|
- bool recreate_environments_when_repeating_;
|
|
- bool shuffle_;
|
|
- int32_t stack_trace_depth_;
|
|
- std::string stream_result_to_;
|
|
- bool throw_on_failure_;
|
|
-} GTEST_ATTRIBUTE_UNUSED_;
|
|
-
|
|
-// Converts a Unicode code point to a narrow string in UTF-8 encoding.
|
|
-// code_point parameter is of type UInt32 because wchar_t may not be
|
|
-// wide enough to contain a code point.
|
|
-// If the code_point is not a valid Unicode code point
|
|
-// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted
|
|
-// to "(Invalid Unicode 0xXXXXXXXX)".
|
|
-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:
|
|
-// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
|
|
-// UTF-32 if sizeof(wchar_t) == 4 (on Linux)
|
|
-// Parameter str points to a null-terminated wide string.
|
|
-// Parameter num_chars may additionally limit the number
|
|
-// of wchar_t characters processed. -1 is used when the entire string
|
|
-// should be processed.
|
|
-// If the string contains code points that are not valid Unicode code points
|
|
-// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
|
|
-// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
|
|
-// and contains invalid UTF-16 surrogate pairs, values in those pairs
|
|
-// will be encoded as individual Unicode characters from Basic Normal Plane.
|
|
-GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);
|
|
-
|
|
-// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
|
|
-// if the variable is present. If a file already exists at this location, this
|
|
-// function will write over it. If the variable is present, but the file cannot
|
|
-// be created, prints an error and exits.
|
|
-void WriteToShardStatusFileIfNeeded();
|
|
-
|
|
-// Checks whether sharding is enabled by examining the relevant
|
|
-// environment variable values. If the variables are present,
|
|
-// but inconsistent (e.g., shard_index >= total_shards), prints
|
|
-// an error and exits. If in_subprocess_for_death_test, sharding is
|
|
-// disabled because it must only be applied to the original test
|
|
-// process. Otherwise, we could filter out death tests we intended to execute.
|
|
-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 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_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 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);
|
|
-
|
|
-// STL container utilities.
|
|
-
|
|
-// Returns the number of elements in the given container that satisfy
|
|
-// the given predicate.
|
|
-template <class Container, typename Predicate>
|
|
-inline int CountIf(const Container& c, Predicate predicate) {
|
|
- // Implemented as an explicit loop since std::count_if() in libCstd on
|
|
- // Solaris has a non-standard signature.
|
|
- int count = 0;
|
|
- for (auto it = c.begin(); it != c.end(); ++it) {
|
|
- if (predicate(*it)) ++count;
|
|
- }
|
|
- return count;
|
|
-}
|
|
-
|
|
-// Applies a function/functor to each element in the container.
|
|
-template <class Container, typename Functor>
|
|
-void ForEach(const Container& c, Functor functor) {
|
|
- std::for_each(c.begin(), c.end(), functor);
|
|
-}
|
|
-
|
|
-// Returns the i-th element of the vector, or default_value if i is not
|
|
-// in range [0, v.size()).
|
|
-template <typename E>
|
|
-inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
|
|
- return (i < 0 || i >= static_cast<int>(v.size())) ? default_value
|
|
- : v[static_cast<size_t>(i)];
|
|
-}
|
|
-
|
|
-// Performs an in-place shuffle of a range of the vector's elements.
|
|
-// 'begin' and 'end' are element indices as an STL-style range;
|
|
-// i.e. [begin, end) are shuffled, where 'end' == size() means to
|
|
-// shuffle to the end of the vector.
|
|
-template <typename E>
|
|
-void ShuffleRange(internal::Random* random, int begin, int end,
|
|
- std::vector<E>* v) {
|
|
- const int size = static_cast<int>(v->size());
|
|
- GTEST_CHECK_(0 <= begin && begin <= size)
|
|
- << "Invalid shuffle range start " << begin << ": must be in range [0, "
|
|
- << size << "].";
|
|
- GTEST_CHECK_(begin <= end && end <= size)
|
|
- << "Invalid shuffle range finish " << end << ": must be in range ["
|
|
- << begin << ", " << size << "].";
|
|
-
|
|
- // Fisher-Yates shuffle, from
|
|
- // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
|
|
- for (int range_width = end - begin; range_width >= 2; range_width--) {
|
|
- const int last_in_range = begin + range_width - 1;
|
|
- const int selected =
|
|
- begin +
|
|
- static_cast<int>(random->Generate(static_cast<uint32_t>(range_width)));
|
|
- std::swap((*v)[static_cast<size_t>(selected)],
|
|
- (*v)[static_cast<size_t>(last_in_range)]);
|
|
- }
|
|
-}
|
|
-
|
|
-// Performs an in-place shuffle of the vector's elements.
|
|
-template <typename E>
|
|
-inline void Shuffle(internal::Random* random, std::vector<E>* v) {
|
|
- ShuffleRange(random, 0, static_cast<int>(v->size()), v);
|
|
-}
|
|
-
|
|
-// A function for deleting an object. Handy for being used as a
|
|
-// functor.
|
|
-template <typename T>
|
|
-static void Delete(T* x) {
|
|
- delete x;
|
|
-}
|
|
-
|
|
-// A predicate that checks the key of a TestProperty against a known key.
|
|
-//
|
|
-// TestPropertyKeyIs is copyable.
|
|
-class TestPropertyKeyIs {
|
|
- public:
|
|
- // Constructor.
|
|
- //
|
|
- // TestPropertyKeyIs has NO default constructor.
|
|
- explicit TestPropertyKeyIs(const std::string& key) : key_(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_;
|
|
- }
|
|
-
|
|
- private:
|
|
- std::string key_;
|
|
-};
|
|
-
|
|
-// Class UnitTestOptions.
|
|
-//
|
|
-// This class contains functions for processing options the user
|
|
-// specifies when running the tests. It has only static members.
|
|
-//
|
|
-// In most cases, the user can specify an option using either an
|
|
-// environment variable or a command line flag. E.g. you can set the
|
|
-// test filter using either GTEST_FILTER or --gtest_filter. If both
|
|
-// the variable and the flag are present, the latter overrides the
|
|
-// former.
|
|
-class GTEST_API_ UnitTestOptions {
|
|
- public:
|
|
- // Functions for processing the gtest_output flag.
|
|
-
|
|
- // Returns the output format, or "" for normal printed output.
|
|
- static std::string GetOutputFormat();
|
|
-
|
|
- // Returns the absolute path of the requested output file, or the
|
|
- // default (test_detail.xml in the original working directory) if
|
|
- // none was explicitly specified.
|
|
- static std::string GetAbsolutePathToOutputFile();
|
|
-
|
|
- // Functions for processing the gtest_filter flag.
|
|
-
|
|
- // 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);
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
- // Function for supporting the gtest_catch_exception flag.
|
|
-
|
|
- // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
|
|
- // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
|
|
- // This function is useful as an __except condition.
|
|
- static int GTestShouldProcessSEH(DWORD exception_code);
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
- // Returns true if "name" matches the ':' separated list of glob-style
|
|
- // filters in "filter".
|
|
- static bool MatchesFilter(const std::string& name, const char* filter);
|
|
-};
|
|
-
|
|
-// Returns the current application's name, removing directory path if that
|
|
-// is present. Used by UnitTestOptions::GetOutputFile.
|
|
-GTEST_API_ FilePath GetCurrentExecutableName();
|
|
-
|
|
-// The role interface for getting the OS stack trace as a string.
|
|
-class OsStackTraceGetterInterface {
|
|
- public:
|
|
- OsStackTraceGetterInterface() {}
|
|
- virtual ~OsStackTraceGetterInterface() {}
|
|
-
|
|
- // Returns the current OS stack trace as an std::string. Parameters:
|
|
- //
|
|
- // max_depth - the maximum number of stack frames to be included
|
|
- // in the trace.
|
|
- // skip_count - the number of top frames to be skipped; doesn't count
|
|
- // against max_depth.
|
|
- virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0;
|
|
-
|
|
- // UponLeavingGTest() should be called immediately before Google Test calls
|
|
- // user code. It saves some information about the current stack that
|
|
- // CurrentStackTrace() will use to find and hide Google Test stack frames.
|
|
- virtual void UponLeavingGTest() = 0;
|
|
-
|
|
- // This string is inserted in place of stack frames that are part of
|
|
- // Google Test's implementation.
|
|
- static const char* const kElidedFramesMarker;
|
|
-
|
|
- private:
|
|
- OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete;
|
|
- OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) =
|
|
- delete;
|
|
-};
|
|
-
|
|
-// A working implementation of the OsStackTraceGetterInterface interface.
|
|
-class OsStackTraceGetter : public OsStackTraceGetterInterface {
|
|
- public:
|
|
- OsStackTraceGetter() {}
|
|
-
|
|
- std::string CurrentStackTrace(int max_depth, int skip_count) override;
|
|
- void UponLeavingGTest() override;
|
|
-
|
|
- private:
|
|
-#if GTEST_HAS_ABSL
|
|
- Mutex mutex_; // Protects all internal state.
|
|
-
|
|
- // We save the stack frame below the frame that calls user code.
|
|
- // We do this because the address of the frame immediately below
|
|
- // the user code changes between the call to UponLeavingGTest()
|
|
- // and any calls to the stack trace code from within the user code.
|
|
- void* caller_frame_ = nullptr;
|
|
-#endif // GTEST_HAS_ABSL
|
|
-
|
|
- OsStackTraceGetter(const OsStackTraceGetter&) = delete;
|
|
- OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete;
|
|
-};
|
|
-
|
|
-// Information about a Google Test trace point.
|
|
-struct TraceInfo {
|
|
- const char* file;
|
|
- int line;
|
|
- std::string message;
|
|
-};
|
|
-
|
|
-// This is the default global test part result reporter used in UnitTestImpl.
|
|
-// This class should only be used by UnitTestImpl.
|
|
-class DefaultGlobalTestPartResultReporter
|
|
- : public TestPartResultReporterInterface {
|
|
- public:
|
|
- explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
|
|
- // Implements the TestPartResultReporterInterface. Reports the test part
|
|
- // result in the current test.
|
|
- void ReportTestPartResult(const TestPartResult& result) override;
|
|
-
|
|
- private:
|
|
- UnitTestImpl* const unit_test_;
|
|
-
|
|
- DefaultGlobalTestPartResultReporter(
|
|
- const DefaultGlobalTestPartResultReporter&) = delete;
|
|
- DefaultGlobalTestPartResultReporter& operator=(
|
|
- const DefaultGlobalTestPartResultReporter&) = delete;
|
|
-};
|
|
-
|
|
-// This is the default per thread test part result reporter used in
|
|
-// UnitTestImpl. This class should only be used by UnitTestImpl.
|
|
-class DefaultPerThreadTestPartResultReporter
|
|
- : public TestPartResultReporterInterface {
|
|
- public:
|
|
- explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
|
|
- // Implements the TestPartResultReporterInterface. The implementation just
|
|
- // delegates to the current global test part result reporter of *unit_test_.
|
|
- void ReportTestPartResult(const TestPartResult& result) override;
|
|
-
|
|
- private:
|
|
- UnitTestImpl* const unit_test_;
|
|
-
|
|
- DefaultPerThreadTestPartResultReporter(
|
|
- const DefaultPerThreadTestPartResultReporter&) = delete;
|
|
- DefaultPerThreadTestPartResultReporter& operator=(
|
|
- const DefaultPerThreadTestPartResultReporter&) = delete;
|
|
-};
|
|
-
|
|
-// The private implementation of the UnitTest class. We don't protect
|
|
-// the methods under a mutex, as this class is not accessible by a
|
|
-// user and the UnitTest class that delegates work to this class does
|
|
-// proper locking.
|
|
-class GTEST_API_ UnitTestImpl {
|
|
- public:
|
|
- explicit UnitTestImpl(UnitTest* parent);
|
|
- virtual ~UnitTestImpl();
|
|
-
|
|
- // There are two different ways to register your own TestPartResultReporter.
|
|
- // You can register your own repoter to listen either only for test results
|
|
- // from the current thread or for results from all threads.
|
|
- // By default, each per-thread test result repoter just passes a new
|
|
- // TestPartResult to the global test result reporter, which registers the
|
|
- // test part result for the currently running test.
|
|
-
|
|
- // Returns the global test part result reporter.
|
|
- TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
|
|
-
|
|
- // Sets the global test part result reporter.
|
|
- void SetGlobalTestPartResultReporter(
|
|
- TestPartResultReporterInterface* reporter);
|
|
-
|
|
- // Returns the test part result reporter for the current thread.
|
|
- TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
|
|
-
|
|
- // Sets the test part result reporter for the current thread.
|
|
- void SetTestPartResultReporterForCurrentThread(
|
|
- TestPartResultReporterInterface* reporter);
|
|
-
|
|
- // Gets the number of successful test suites.
|
|
- int successful_test_suite_count() const;
|
|
-
|
|
- // Gets the number of failed test suites.
|
|
- int failed_test_suite_count() const;
|
|
-
|
|
- // Gets the number of all test suites.
|
|
- int total_test_suite_count() const;
|
|
-
|
|
- // Gets the number of all test suites that contain at least one test
|
|
- // that should run.
|
|
- int test_suite_to_run_count() const;
|
|
-
|
|
- // Gets the number of successful tests.
|
|
- int successful_test_count() const;
|
|
-
|
|
- // Gets the number of skipped tests.
|
|
- int skipped_test_count() const;
|
|
-
|
|
- // Gets the number of failed tests.
|
|
- int failed_test_count() const;
|
|
-
|
|
- // Gets the number of disabled tests that will be reported in the XML report.
|
|
- int reportable_disabled_test_count() const;
|
|
-
|
|
- // Gets the number of disabled tests.
|
|
- int disabled_test_count() const;
|
|
-
|
|
- // Gets the number of tests to be printed in the XML report.
|
|
- int reportable_test_count() const;
|
|
-
|
|
- // Gets the number of all tests.
|
|
- int total_test_count() const;
|
|
-
|
|
- // Gets the number of tests that should run.
|
|
- int test_to_run_count() const;
|
|
-
|
|
- // Gets the time of the test program start, in ms from the start of the
|
|
- // UNIX epoch.
|
|
- TimeInMillis start_timestamp() const { return start_timestamp_; }
|
|
-
|
|
- // Gets the elapsed time, in milliseconds.
|
|
- TimeInMillis elapsed_time() const { return elapsed_time_; }
|
|
-
|
|
- // Returns true if and only if the unit test passed (i.e. all test suites
|
|
- // passed).
|
|
- bool Passed() const { return !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();
|
|
- }
|
|
-
|
|
- // Gets the i-th test suite among all the test suites. i can range from 0 to
|
|
- // total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
|
- const TestSuite* GetTestSuite(int i) const {
|
|
- const int index = GetElementOr(test_suite_indices_, i, -1);
|
|
- return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];
|
|
- }
|
|
-
|
|
- // Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- const TestCase* GetTestCase(int i) const { return GetTestSuite(i); }
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Gets the i-th test suite among all the test suites. i can range from 0 to
|
|
- // total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
|
- TestSuite* GetMutableSuiteCase(int i) {
|
|
- const int index = GetElementOr(test_suite_indices_, i, -1);
|
|
- return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];
|
|
- }
|
|
-
|
|
- // Provides access to the event listener list.
|
|
- TestEventListeners* listeners() { return &listeners_; }
|
|
-
|
|
- // Returns the TestResult for the test that's currently running, or
|
|
- // the TestResult for the ad hoc test if no test is running.
|
|
- TestResult* current_test_result();
|
|
-
|
|
- // Returns the TestResult for the ad hoc test.
|
|
- const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
|
|
-
|
|
- // Sets the OS stack trace getter.
|
|
- //
|
|
- // Does nothing if the input and the current OS stack trace getter
|
|
- // are the same; otherwise, deletes the old getter and makes the
|
|
- // input the current getter.
|
|
- void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);
|
|
-
|
|
- // Returns the current OS stack trace getter if it is not NULL;
|
|
- // otherwise, creates an OsStackTraceGetter, makes it the current
|
|
- // getter, and returns it.
|
|
- OsStackTraceGetterInterface* os_stack_trace_getter();
|
|
-
|
|
- // Returns the current OS stack trace as an std::string.
|
|
- //
|
|
- // The maximum number of stack frames to be included is specified by
|
|
- // the gtest_stack_trace_depth flag. The skip_count parameter
|
|
- // specifies the number of top frames to be skipped, which doesn't
|
|
- // count against the number of frames to be included.
|
|
- //
|
|
- // For example, if Foo() calls Bar(), which in turn calls
|
|
- // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
|
|
- // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
|
- std::string CurrentOsStackTraceExceptTop(int skip_count)
|
|
- GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_;
|
|
-
|
|
- // Finds and returns a TestSuite with the given name. If one doesn't
|
|
- // exist, creates one and returns it.
|
|
- //
|
|
- // 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
|
|
- TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
|
|
- internal::SetUpTestSuiteFunc set_up_tc,
|
|
- internal::TearDownTestSuiteFunc tear_down_tc);
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- TestCase* GetTestCase(const char* test_case_name, const char* type_param,
|
|
- internal::SetUpTestSuiteFunc set_up_tc,
|
|
- internal::TearDownTestSuiteFunc tear_down_tc) {
|
|
- return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
|
|
- }
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- // Adds a TestInfo to the unit test.
|
|
- //
|
|
- // Arguments:
|
|
- //
|
|
- // 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
|
|
- // test_info: the TestInfo object
|
|
- 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
|
|
- // the user may have changed the current directory before calling
|
|
- // RUN_ALL_TESTS(). Therefore we capture the current directory in
|
|
- // AddTestInfo(), which is called to register a TEST or TEST_F
|
|
- // before main() is reached.
|
|
- if (original_working_dir_.IsEmpty()) {
|
|
- original_working_dir_.Set(FilePath::GetCurrentDir());
|
|
- 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)
|
|
- ->AddTestInfo(test_info);
|
|
- }
|
|
-
|
|
- // Returns ParameterizedTestSuiteRegistry object used to keep track of
|
|
- // value-parameterized tests and instantiate and register them.
|
|
- internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() {
|
|
- 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;
|
|
- }
|
|
-
|
|
- // Sets the TestInfo object for the test that's currently running. If
|
|
- // current_test_info is NULL, the assertion results will be stored in
|
|
- // ad_hoc_test_result_.
|
|
- void set_current_test_info(TestInfo* a_current_test_info) {
|
|
- current_test_info_ = a_current_test_info;
|
|
- }
|
|
-
|
|
- // Registers all parameterized tests defined using TEST_P and
|
|
- // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
|
|
- // combination. This method can be called more then once; it has guards
|
|
- // protecting from registering the tests more then once. If
|
|
- // value-parameterized tests are disabled, RegisterParameterizedTests is
|
|
- // present but does nothing.
|
|
- void RegisterParameterizedTests();
|
|
-
|
|
- // Runs all tests in this UnitTest object, prints the result, and
|
|
- // returns true if all tests are successful. If any exception is
|
|
- // thrown during a test, this test is considered to be failed, but
|
|
- // the rest of the tests will still be run.
|
|
- bool RunAllTests();
|
|
-
|
|
- // Clears the results of all tests, except the ad hoc tests.
|
|
- void ClearNonAdHocTestResult() {
|
|
- ForEach(test_suites_, TestSuite::ClearTestSuiteResult);
|
|
- }
|
|
-
|
|
- // Clears the results of ad-hoc test assertions.
|
|
- void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); }
|
|
-
|
|
- // Adds a TestProperty to the current TestResult object when invoked in a
|
|
- // context of a test or a test suite, or to the global property set. If the
|
|
- // result already contains a property with the same key, the value will be
|
|
- // updated.
|
|
- void RecordProperty(const TestProperty& test_property);
|
|
-
|
|
- enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL };
|
|
-
|
|
- // Matches the full name of each test against the user-specified
|
|
- // filter to decide whether the test should run, then records the
|
|
- // result in each TestSuite and TestInfo object.
|
|
- // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
|
|
- // based on sharding variables in the environment.
|
|
- // Returns the number of tests that should run.
|
|
- int FilterTests(ReactionToSharding shard_tests);
|
|
-
|
|
- // Prints the names of the tests matching the user-specified filter flag.
|
|
- void ListTestsMatchingFilter();
|
|
-
|
|
- const TestSuite* current_test_suite() const { return current_test_suite_; }
|
|
- TestInfo* current_test_info() { return current_test_info_; }
|
|
- const TestInfo* current_test_info() const { return current_test_info_; }
|
|
-
|
|
- // Returns the vector of environments that need to be set-up/torn-down
|
|
- // before/after the tests are run.
|
|
- std::vector<Environment*>& environments() { return environments_; }
|
|
-
|
|
- // Getters for the per-thread Google Test trace stack.
|
|
- std::vector<TraceInfo>& gtest_trace_stack() {
|
|
- return *(gtest_trace_stack_.pointer());
|
|
- }
|
|
- const std::vector<TraceInfo>& gtest_trace_stack() const {
|
|
- return gtest_trace_stack_.get();
|
|
- }
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
- void InitDeathTestSubprocessControlInfo() {
|
|
- internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
|
|
- }
|
|
- // Returns a pointer to the parsed --gtest_internal_run_death_test
|
|
- // flag, or NULL if that flag was not specified.
|
|
- // This information is useful only in a death test child process.
|
|
- // Must not be called before a call to InitGoogleTest.
|
|
- const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
|
|
- return internal_run_death_test_flag_.get();
|
|
- }
|
|
-
|
|
- // Returns a pointer to the current death test factory.
|
|
- internal::DeathTestFactory* death_test_factory() {
|
|
- return death_test_factory_.get();
|
|
- }
|
|
-
|
|
- void SuppressTestEventsIfInSubprocess();
|
|
-
|
|
- friend class ReplaceDeathTestFactory;
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
- // Initializes the event listener performing XML output as specified by
|
|
- // UnitTestOptions. Must not be called before InitGoogleTest.
|
|
- void ConfigureXmlOutput();
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
- // Initializes the event listener for streaming test results to a socket.
|
|
- // Must not be called before InitGoogleTest.
|
|
- void ConfigureStreamingOutput();
|
|
-#endif
|
|
-
|
|
- // Performs initialization dependent upon flag values obtained in
|
|
- // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
|
|
- // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
|
|
- // this function is also called from RunAllTests. Since this function can be
|
|
- // called more than once, it has to be idempotent.
|
|
- void PostFlagParsingInit();
|
|
-
|
|
- // Gets the random seed used at the start of the current test iteration.
|
|
- int random_seed() const { return random_seed_; }
|
|
-
|
|
- // Gets the random number generator.
|
|
- internal::Random* random() { return &random_; }
|
|
-
|
|
- // Shuffles all test suites, and the tests within each test suite,
|
|
- // making sure that death tests are still run first.
|
|
- void ShuffleTests();
|
|
-
|
|
- // Restores the test suites and tests to their order before the first shuffle.
|
|
- void UnshuffleTests();
|
|
-
|
|
- // Returns the value of GTEST_FLAG(catch_exceptions) at the moment
|
|
- // UnitTest::Run() starts.
|
|
- bool catch_exceptions() const { return catch_exceptions_; }
|
|
-
|
|
- private:
|
|
- friend class ::testing::UnitTest;
|
|
-
|
|
- // Used by UnitTest::Run() to capture the state of
|
|
- // GTEST_FLAG(catch_exceptions) at the moment it starts.
|
|
- void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
|
|
-
|
|
- // The UnitTest object that owns this implementation object.
|
|
- UnitTest* const parent_;
|
|
-
|
|
- // The working directory when the first TEST() or TEST_F() was
|
|
- // executed.
|
|
- internal::FilePath original_working_dir_;
|
|
-
|
|
- // The default test part result reporters.
|
|
- DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
|
|
- DefaultPerThreadTestPartResultReporter
|
|
- default_per_thread_test_part_result_reporter_;
|
|
-
|
|
- // Points to (but doesn't own) the global test part result reporter.
|
|
- TestPartResultReporterInterface* global_test_part_result_repoter_;
|
|
-
|
|
- // Protects read and write access to global_test_part_result_reporter_.
|
|
- internal::Mutex global_test_part_result_reporter_mutex_;
|
|
-
|
|
- // Points to (but doesn't own) the per-thread test part result reporter.
|
|
- internal::ThreadLocal<TestPartResultReporterInterface*>
|
|
- per_thread_test_part_result_reporter_;
|
|
-
|
|
- // The vector of environments that need to be set-up/torn-down
|
|
- // before/after the tests are run.
|
|
- std::vector<Environment*> environments_;
|
|
-
|
|
- // The vector of TestSuites in their original order. It owns the
|
|
- // elements in the vector.
|
|
- std::vector<TestSuite*> test_suites_;
|
|
-
|
|
- // Provides a level of indirection for the test suite list to allow
|
|
- // easy shuffling and restoring the test suite order. The i-th
|
|
- // element of this vector is the index of the i-th test suite in the
|
|
- // shuffled order.
|
|
- std::vector<int> test_suite_indices_;
|
|
-
|
|
- // 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_;
|
|
-
|
|
- // Index of the last death test suite registered. Initially -1.
|
|
- int last_death_test_suite_;
|
|
-
|
|
- // This points to the TestSuite for the currently running test. It
|
|
- // changes as Google Test goes through one test suite after another.
|
|
- // When no test is running, this is set to NULL and Google Test
|
|
- // stores assertion results in ad_hoc_test_result_. Initially NULL.
|
|
- TestSuite* current_test_suite_;
|
|
-
|
|
- // This points to the TestInfo for the currently running test. It
|
|
- // changes as Google Test goes through one test after another. When
|
|
- // no test is running, this is set to NULL and Google Test stores
|
|
- // assertion results in ad_hoc_test_result_. Initially NULL.
|
|
- TestInfo* current_test_info_;
|
|
-
|
|
- // Normally, a user only writes assertions inside a TEST or TEST_F,
|
|
- // or inside a function called by a TEST or TEST_F. Since Google
|
|
- // Test keeps track of which test is current running, it can
|
|
- // associate such an assertion with the test it belongs to.
|
|
- //
|
|
- // If an assertion is encountered when no TEST or TEST_F is running,
|
|
- // Google Test attributes the assertion result to an imaginary "ad hoc"
|
|
- // test, and records the result in ad_hoc_test_result_.
|
|
- TestResult ad_hoc_test_result_;
|
|
-
|
|
- // The list of event listeners that can be used to track events inside
|
|
- // Google Test.
|
|
- TestEventListeners listeners_;
|
|
-
|
|
- // The OS stack trace getter. Will be deleted when the UnitTest
|
|
- // object is destructed. By default, an OsStackTraceGetter is used,
|
|
- // but the user can set this field to use a custom getter if that is
|
|
- // desired.
|
|
- OsStackTraceGetterInterface* os_stack_trace_getter_;
|
|
-
|
|
- // 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.
|
|
- int random_seed_;
|
|
-
|
|
- // Our random number generator.
|
|
- internal::Random random_;
|
|
-
|
|
- // The time of the test program start, in ms from the start of the
|
|
- // UNIX epoch.
|
|
- TimeInMillis start_timestamp_;
|
|
-
|
|
- // How long the test took to run, in milliseconds.
|
|
- TimeInMillis elapsed_time_;
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
- // The decomposed components of the gtest_internal_run_death_test flag,
|
|
- // parsed when RUN_ALL_TESTS is called.
|
|
- std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
|
|
- std::unique_ptr<internal::DeathTestFactory> death_test_factory_;
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
- // A per-thread stack of traces created by the SCOPED_TRACE() macro.
|
|
- internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
|
|
-
|
|
- // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()
|
|
- // starts.
|
|
- bool catch_exceptions_;
|
|
-
|
|
- UnitTestImpl(const UnitTestImpl&) = delete;
|
|
- UnitTestImpl& operator=(const UnitTestImpl&) = delete;
|
|
-}; // class UnitTestImpl
|
|
-
|
|
-// Convenience function for accessing the global UnitTest
|
|
-// implementation object.
|
|
-inline UnitTestImpl* GetUnitTestImpl() {
|
|
- return UnitTest::GetInstance()->impl();
|
|
-}
|
|
-
|
|
-#if GTEST_USES_SIMPLE_RE
|
|
-
|
|
-// Internal helper functions for implementing the simple regular
|
|
-// expression matcher.
|
|
-GTEST_API_ bool IsInSet(char ch, const char* str);
|
|
-GTEST_API_ bool IsAsciiDigit(char ch);
|
|
-GTEST_API_ bool IsAsciiPunct(char ch);
|
|
-GTEST_API_ bool IsRepeat(char ch);
|
|
-GTEST_API_ bool IsAsciiWhiteSpace(char ch);
|
|
-GTEST_API_ bool IsAsciiWordChar(char ch);
|
|
-GTEST_API_ bool IsValidEscape(char ch);
|
|
-GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
|
|
-GTEST_API_ bool ValidateRegex(const char* regex);
|
|
-GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
|
|
-GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,
|
|
- char repeat, const char* regex,
|
|
- const char* str);
|
|
-GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
|
|
-
|
|
-#endif // GTEST_USES_SIMPLE_RE
|
|
-
|
|
-// Parses the command line for Google Test flags, without initializing
|
|
-// other parts of Google Test.
|
|
-GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
|
|
-GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-
|
|
-// Returns the message describing the last system error, regardless of the
|
|
-// platform.
|
|
-GTEST_API_ std::string GetLastErrnoDescription();
|
|
-
|
|
-// Attempts to parse a string into a positive integer pointed to by the
|
|
-// number parameter. Returns true if that is possible.
|
|
-// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
|
|
-// it here.
|
|
-template <typename Integer>
|
|
-bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
|
|
- // Fail fast if the given string does not begin with a digit;
|
|
- // this bypasses strtoXXX's "optional leading whitespace and plus
|
|
- // or minus sign" semantics, which are undesirable here.
|
|
- if (str.empty() || !IsDigit(str[0])) {
|
|
- return false;
|
|
- }
|
|
- errno = 0;
|
|
-
|
|
- char* end;
|
|
- // BiggestConvertible is the largest integer type that system-provided
|
|
- // string-to-number conversion routines can return.
|
|
- using BiggestConvertible = unsigned long long; // NOLINT
|
|
-
|
|
- const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT
|
|
- const bool parse_success = *end == '\0' && errno == 0;
|
|
-
|
|
- GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
|
|
-
|
|
- const Integer result = static_cast<Integer>(parsed);
|
|
- if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
|
|
- *number = result;
|
|
- return true;
|
|
- }
|
|
- return false;
|
|
-}
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-// TestResult contains some private methods that should be hidden from
|
|
-// Google Test user but are required for testing. This class allow our tests
|
|
-// to access them.
|
|
-//
|
|
-// This class is supplied only for the purpose of testing Google Test's own
|
|
-// constructs. Do not use it in user tests, either directly or indirectly.
|
|
-class TestResultAccessor {
|
|
- public:
|
|
- static void RecordProperty(TestResult* test_result,
|
|
- const std::string& xml_element,
|
|
- const TestProperty& property) {
|
|
- test_result->RecordProperty(xml_element, property);
|
|
- }
|
|
-
|
|
- static void ClearTestPartResults(TestResult* test_result) {
|
|
- test_result->ClearTestPartResults();
|
|
- }
|
|
-
|
|
- static const std::vector<testing::TestPartResult>& test_part_results(
|
|
- const TestResult& test_result) {
|
|
- return test_result.test_part_results();
|
|
- }
|
|
-};
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
-
|
|
-// Streams test results to the given port on the given host machine.
|
|
-class StreamingListener : public EmptyTestEventListener {
|
|
- public:
|
|
- // Abstract base class for writing strings to a socket.
|
|
- class AbstractSocketWriter {
|
|
- public:
|
|
- virtual ~AbstractSocketWriter() {}
|
|
-
|
|
- // Sends a string to the socket.
|
|
- virtual void Send(const std::string& message) = 0;
|
|
-
|
|
- // Closes the socket.
|
|
- virtual void CloseConnection() {}
|
|
-
|
|
- // Sends a string and a newline to the socket.
|
|
- void SendLn(const std::string& message) { Send(message + "\n"); }
|
|
- };
|
|
-
|
|
- // Concrete class for actually writing strings to a socket.
|
|
- class SocketWriter : public AbstractSocketWriter {
|
|
- public:
|
|
- SocketWriter(const std::string& host, const std::string& port)
|
|
- : sockfd_(-1), host_name_(host), port_num_(port) {
|
|
- MakeConnection();
|
|
- }
|
|
-
|
|
- ~SocketWriter() override {
|
|
- if (sockfd_ != -1) CloseConnection();
|
|
- }
|
|
-
|
|
- // Sends a string to the socket.
|
|
- void Send(const std::string& message) override {
|
|
- GTEST_CHECK_(sockfd_ != -1)
|
|
- << "Send() can be called only when there is a connection.";
|
|
-
|
|
- const auto len = static_cast<size_t>(message.length());
|
|
- if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
|
|
- GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to "
|
|
- << host_name_ << ":" << port_num_;
|
|
- }
|
|
- }
|
|
-
|
|
- private:
|
|
- // Creates a client socket and connects to the server.
|
|
- void MakeConnection();
|
|
-
|
|
- // Closes the socket.
|
|
- void CloseConnection() override {
|
|
- GTEST_CHECK_(sockfd_ != -1)
|
|
- << "CloseConnection() can be called only when there is a connection.";
|
|
-
|
|
- close(sockfd_);
|
|
- sockfd_ = -1;
|
|
- }
|
|
-
|
|
- int sockfd_; // socket file descriptor
|
|
- const std::string host_name_;
|
|
- const std::string port_num_;
|
|
-
|
|
- SocketWriter(const SocketWriter&) = delete;
|
|
- SocketWriter& operator=(const SocketWriter&) = delete;
|
|
- }; // class SocketWriter
|
|
-
|
|
- // Escapes '=', '&', '%', and '\n' characters in str as "%xx".
|
|
- static std::string UrlEncode(const char* str);
|
|
-
|
|
- StreamingListener(const std::string& host, const std::string& port)
|
|
- : socket_writer_(new SocketWriter(host, port)) {
|
|
- Start();
|
|
- }
|
|
-
|
|
- explicit StreamingListener(AbstractSocketWriter* socket_writer)
|
|
- : socket_writer_(socket_writer) {
|
|
- Start();
|
|
- }
|
|
-
|
|
- void OnTestProgramStart(const UnitTest& /* unit_test */) override {
|
|
- SendLn("event=TestProgramStart");
|
|
- }
|
|
-
|
|
- void OnTestProgramEnd(const UnitTest& unit_test) override {
|
|
- // Note that Google Test current only report elapsed time for each
|
|
- // test iteration, not for the entire test program.
|
|
- SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed()));
|
|
-
|
|
- // Notify the streaming server to stop.
|
|
- socket_writer_->CloseConnection();
|
|
- }
|
|
-
|
|
- void OnTestIterationStart(const UnitTest& /* unit_test */,
|
|
- int iteration) override {
|
|
- SendLn("event=TestIterationStart&iteration=" +
|
|
- StreamableToString(iteration));
|
|
- }
|
|
-
|
|
- void OnTestIterationEnd(const UnitTest& unit_test,
|
|
- int /* iteration */) override {
|
|
- SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) +
|
|
- "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) +
|
|
- "ms");
|
|
- }
|
|
-
|
|
- // Note that "event=TestCaseStart" is a wire format and has to remain
|
|
- // "case" for compatibility
|
|
- void OnTestSuiteStart(const TestSuite& test_suite) override {
|
|
- SendLn(std::string("event=TestCaseStart&name=") + test_suite.name());
|
|
- }
|
|
-
|
|
- // Note that "event=TestCaseEnd" is a wire format and has to remain
|
|
- // "case" for compatibility
|
|
- void OnTestSuiteEnd(const TestSuite& test_suite) override {
|
|
- SendLn("event=TestCaseEnd&passed=" + FormatBool(test_suite.Passed()) +
|
|
- "&elapsed_time=" + StreamableToString(test_suite.elapsed_time()) +
|
|
- "ms");
|
|
- }
|
|
-
|
|
- void OnTestStart(const TestInfo& test_info) override {
|
|
- SendLn(std::string("event=TestStart&name=") + test_info.name());
|
|
- }
|
|
-
|
|
- void OnTestEnd(const TestInfo& test_info) override {
|
|
- SendLn("event=TestEnd&passed=" +
|
|
- FormatBool((test_info.result())->Passed()) + "&elapsed_time=" +
|
|
- StreamableToString((test_info.result())->elapsed_time()) + "ms");
|
|
- }
|
|
-
|
|
- void OnTestPartResult(const TestPartResult& test_part_result) override {
|
|
- const char* file_name = test_part_result.file_name();
|
|
- if (file_name == nullptr) file_name = "";
|
|
- SendLn("event=TestPartResult&file=" + UrlEncode(file_name) +
|
|
- "&line=" + StreamableToString(test_part_result.line_number()) +
|
|
- "&message=" + UrlEncode(test_part_result.message()));
|
|
- }
|
|
-
|
|
- private:
|
|
- // Sends the given message and a newline to the socket.
|
|
- void SendLn(const std::string& message) { socket_writer_->SendLn(message); }
|
|
-
|
|
- // Called at the start of streaming to notify the receiver what
|
|
- // protocol we are using.
|
|
- void Start() { SendLn("gtest_streaming_protocol_version=1.0"); }
|
|
-
|
|
- std::string FormatBool(bool value) { return value ? "1" : "0"; }
|
|
-
|
|
- const std::unique_ptr<AbstractSocketWriter> socket_writer_;
|
|
-
|
|
- StreamingListener(const StreamingListener&) = delete;
|
|
- StreamingListener& operator=(const StreamingListener&) = delete;
|
|
-}; // class StreamingListener
|
|
-
|
|
-#endif // GTEST_CAN_STREAM_RESULTS_
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
|
-
|
|
-#endif // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
|
|
diff --git a/vendor/gtest/src/gtest-matchers.cc b/vendor/gtest/src/gtest-matchers.cc
|
|
deleted file mode 100644
|
|
index 7e3bcc0cf..000000000
|
|
--- a/vendor/gtest/src/gtest-matchers.cc
|
|
+++ /dev/null
|
|
@@ -1,98 +0,0 @@
|
|
-// Copyright 2007, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-//
|
|
-// This file implements just enough of the matcher interface to allow
|
|
-// EXPECT_DEATH and friends to accept a matcher argument.
|
|
-
|
|
-#include "gtest/gtest-matchers.h"
|
|
-
|
|
-#include <string>
|
|
-
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-// Constructs a matcher that matches a const std::string& whose value is
|
|
-// equal to s.
|
|
-Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }
|
|
-
|
|
-// Constructs a matcher that matches a const std::string& whose value is
|
|
-// equal to s.
|
|
-Matcher<const std::string&>::Matcher(const char* s) {
|
|
- *this = Eq(std::string(s));
|
|
-}
|
|
-
|
|
-// Constructs a matcher that matches a std::string whose value is equal to
|
|
-// s.
|
|
-Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
|
|
-
|
|
-// Constructs a matcher that matches a std::string whose value is equal to
|
|
-// s.
|
|
-Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
|
|
-
|
|
-#if GTEST_INTERNAL_HAS_STRING_VIEW
|
|
-// Constructs a matcher that matches a const StringView& whose value is
|
|
-// equal to s.
|
|
-Matcher<const internal::StringView&>::Matcher(const std::string& s) {
|
|
- *this = Eq(s);
|
|
-}
|
|
-
|
|
-// Constructs a matcher that matches a const StringView& whose value is
|
|
-// equal to s.
|
|
-Matcher<const internal::StringView&>::Matcher(const char* s) {
|
|
- *this = Eq(std::string(s));
|
|
-}
|
|
-
|
|
-// Constructs a matcher that matches a const StringView& whose value is
|
|
-// equal to s.
|
|
-Matcher<const internal::StringView&>::Matcher(internal::StringView s) {
|
|
- *this = Eq(std::string(s));
|
|
-}
|
|
-
|
|
-// Constructs a matcher that matches a StringView whose value is equal to
|
|
-// s.
|
|
-Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); }
|
|
-
|
|
-// Constructs a matcher that matches a StringView whose value is equal to
|
|
-// s.
|
|
-Matcher<internal::StringView>::Matcher(const char* s) {
|
|
- *this = Eq(std::string(s));
|
|
-}
|
|
-
|
|
-// Constructs a matcher that matches a StringView whose value is equal to
|
|
-// s.
|
|
-Matcher<internal::StringView>::Matcher(internal::StringView s) {
|
|
- *this = Eq(std::string(s));
|
|
-}
|
|
-#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
|
-
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-port.cc b/vendor/gtest/src/gtest-port.cc
|
|
deleted file mode 100644
|
|
index d797fe4d5..000000000
|
|
--- a/vendor/gtest/src/gtest-port.cc
|
|
+++ /dev/null
|
|
@@ -1,1394 +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.
|
|
-
|
|
-#include "gtest/internal/gtest-port.h"
|
|
-
|
|
-#include <limits.h>
|
|
-#include <stdio.h>
|
|
-#include <stdlib.h>
|
|
-#include <string.h>
|
|
-
|
|
-#include <cstdint>
|
|
-#include <fstream>
|
|
-#include <memory>
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-#include <io.h>
|
|
-#include <sys/stat.h>
|
|
-#include <windows.h>
|
|
-
|
|
-#include <map> // Used in ThreadLocal.
|
|
-#ifdef _MSC_VER
|
|
-#include <crtdbg.h>
|
|
-#endif // _MSC_VER
|
|
-#else
|
|
-#include <unistd.h>
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-#if GTEST_OS_MAC
|
|
-#include <mach/mach_init.h>
|
|
-#include <mach/task.h>
|
|
-#include <mach/vm_map.h>
|
|
-#endif // GTEST_OS_MAC
|
|
-
|
|
-#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
|
|
- GTEST_OS_NETBSD || GTEST_OS_OPENBSD
|
|
-#include <sys/sysctl.h>
|
|
-#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
|
|
-#include <sys/user.h>
|
|
-#endif
|
|
-#endif
|
|
-
|
|
-#if GTEST_OS_QNX
|
|
-#include <devctl.h>
|
|
-#include <fcntl.h>
|
|
-#include <sys/procfs.h>
|
|
-#endif // GTEST_OS_QNX
|
|
-
|
|
-#if GTEST_OS_AIX
|
|
-#include <procinfo.h>
|
|
-#include <sys/types.h>
|
|
-#endif // GTEST_OS_AIX
|
|
-
|
|
-#if GTEST_OS_FUCHSIA
|
|
-#include <zircon/process.h>
|
|
-#include <zircon/syscalls.h>
|
|
-#endif // GTEST_OS_FUCHSIA
|
|
-
|
|
-#include "gtest/gtest-message.h"
|
|
-#include "gtest/gtest-spi.h"
|
|
-#include "gtest/internal/gtest-internal.h"
|
|
-#include "gtest/internal/gtest-string.h"
|
|
-#include "src/gtest-internal-inl.h"
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-#if GTEST_OS_LINUX || GTEST_OS_GNU_HURD
|
|
-
|
|
-namespace {
|
|
-template <typename T>
|
|
-T ReadProcFileField(const std::string& filename, int field) {
|
|
- std::string dummy;
|
|
- std::ifstream file(filename.c_str());
|
|
- while (field-- > 0) {
|
|
- file >> dummy;
|
|
- }
|
|
- T output = 0;
|
|
- file >> output;
|
|
- return output;
|
|
-}
|
|
-} // namespace
|
|
-
|
|
-// Returns the number of active threads, or 0 when there is an error.
|
|
-size_t GetThreadCount() {
|
|
- const std::string filename =
|
|
- (Message() << "/proc/" << getpid() << "/stat").GetString();
|
|
- return ReadProcFileField<size_t>(filename, 19);
|
|
-}
|
|
-
|
|
-#elif GTEST_OS_MAC
|
|
-
|
|
-size_t GetThreadCount() {
|
|
- const task_t task = mach_task_self();
|
|
- mach_msg_type_number_t thread_count;
|
|
- thread_act_array_t thread_list;
|
|
- const kern_return_t status = task_threads(task, &thread_list, &thread_count);
|
|
- if (status == KERN_SUCCESS) {
|
|
- // task_threads allocates resources in thread_list and we need to free them
|
|
- // to avoid leaks.
|
|
- vm_deallocate(task, reinterpret_cast<vm_address_t>(thread_list),
|
|
- sizeof(thread_t) * thread_count);
|
|
- return static_cast<size_t>(thread_count);
|
|
- } else {
|
|
- return 0;
|
|
- }
|
|
-}
|
|
-
|
|
-#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
|
|
- GTEST_OS_NETBSD
|
|
-
|
|
-#if GTEST_OS_NETBSD
|
|
-#undef KERN_PROC
|
|
-#define KERN_PROC KERN_PROC2
|
|
-#define kinfo_proc kinfo_proc2
|
|
-#endif
|
|
-
|
|
-#if GTEST_OS_DRAGONFLY
|
|
-#define KP_NLWP(kp) (kp.kp_nthreads)
|
|
-#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
|
|
-#define KP_NLWP(kp) (kp.ki_numthreads)
|
|
-#elif GTEST_OS_NETBSD
|
|
-#define KP_NLWP(kp) (kp.p_nlwps)
|
|
-#endif
|
|
-
|
|
-// Returns the number of threads running in the process, or 0 to indicate that
|
|
-// we cannot detect it.
|
|
-size_t GetThreadCount() {
|
|
- int mib[] = {
|
|
- CTL_KERN,
|
|
- KERN_PROC,
|
|
- KERN_PROC_PID,
|
|
- getpid(),
|
|
-#if GTEST_OS_NETBSD
|
|
- sizeof(struct kinfo_proc),
|
|
- 1,
|
|
-#endif
|
|
- };
|
|
- u_int miblen = sizeof(mib) / sizeof(mib[0]);
|
|
- struct kinfo_proc info;
|
|
- size_t size = sizeof(info);
|
|
- if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
|
|
- return 0;
|
|
- }
|
|
- return static_cast<size_t>(KP_NLWP(info));
|
|
-}
|
|
-#elif GTEST_OS_OPENBSD
|
|
-
|
|
-// Returns the number of threads running in the process, or 0 to indicate that
|
|
-// we cannot detect it.
|
|
-size_t GetThreadCount() {
|
|
- int mib[] = {
|
|
- CTL_KERN,
|
|
- KERN_PROC,
|
|
- KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
|
|
- getpid(),
|
|
- sizeof(struct kinfo_proc),
|
|
- 0,
|
|
- };
|
|
- u_int miblen = sizeof(mib) / sizeof(mib[0]);
|
|
-
|
|
- // get number of structs
|
|
- size_t size;
|
|
- if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {
|
|
- return 0;
|
|
- }
|
|
-
|
|
- mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4]));
|
|
-
|
|
- // populate array of structs
|
|
- struct kinfo_proc info[mib[5]];
|
|
- if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
|
|
- return 0;
|
|
- }
|
|
-
|
|
- // exclude empty members
|
|
- size_t nthreads = 0;
|
|
- for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) {
|
|
- if (info[i].p_tid != -1) nthreads++;
|
|
- }
|
|
- return nthreads;
|
|
-}
|
|
-
|
|
-#elif GTEST_OS_QNX
|
|
-
|
|
-// Returns the number of threads running in the process, or 0 to indicate that
|
|
-// we cannot detect it.
|
|
-size_t GetThreadCount() {
|
|
- const int fd = open("/proc/self/as", O_RDONLY);
|
|
- if (fd < 0) {
|
|
- return 0;
|
|
- }
|
|
- procfs_info process_info;
|
|
- const int status =
|
|
- devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr);
|
|
- close(fd);
|
|
- if (status == EOK) {
|
|
- return static_cast<size_t>(process_info.num_threads);
|
|
- } else {
|
|
- return 0;
|
|
- }
|
|
-}
|
|
-
|
|
-#elif GTEST_OS_AIX
|
|
-
|
|
-size_t GetThreadCount() {
|
|
- struct procentry64 entry;
|
|
- pid_t pid = getpid();
|
|
- int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1);
|
|
- if (status == 1) {
|
|
- return entry.pi_thcount;
|
|
- } else {
|
|
- return 0;
|
|
- }
|
|
-}
|
|
-
|
|
-#elif GTEST_OS_FUCHSIA
|
|
-
|
|
-size_t GetThreadCount() {
|
|
- int dummy_buffer;
|
|
- size_t avail;
|
|
- zx_status_t status =
|
|
- zx_object_get_info(zx_process_self(), ZX_INFO_PROCESS_THREADS,
|
|
- &dummy_buffer, 0, nullptr, &avail);
|
|
- if (status == ZX_OK) {
|
|
- return avail;
|
|
- } else {
|
|
- return 0;
|
|
- }
|
|
-}
|
|
-
|
|
-#else
|
|
-
|
|
-size_t GetThreadCount() {
|
|
- // There's no portable way to detect the number of threads, so we just
|
|
- // return 0 to indicate that we cannot detect it.
|
|
- return 0;
|
|
-}
|
|
-
|
|
-#endif // GTEST_OS_LINUX
|
|
-
|
|
-#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
|
-
|
|
-AutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
|
|
-
|
|
-AutoHandle::AutoHandle(Handle handle) : handle_(handle) {}
|
|
-
|
|
-AutoHandle::~AutoHandle() { Reset(); }
|
|
-
|
|
-AutoHandle::Handle AutoHandle::Get() const { return handle_; }
|
|
-
|
|
-void AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); }
|
|
-
|
|
-void AutoHandle::Reset(HANDLE handle) {
|
|
- // Resetting with the same handle we already own is invalid.
|
|
- if (handle_ != handle) {
|
|
- if (IsCloseable()) {
|
|
- ::CloseHandle(handle_);
|
|
- }
|
|
- handle_ = handle;
|
|
- } else {
|
|
- GTEST_CHECK_(!IsCloseable())
|
|
- << "Resetting a valid handle to itself is likely a programmer error "
|
|
- "and thus not allowed.";
|
|
- }
|
|
-}
|
|
-
|
|
-bool AutoHandle::IsCloseable() const {
|
|
- // Different Windows APIs may use either of these values to represent an
|
|
- // invalid handle.
|
|
- return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
|
|
-}
|
|
-
|
|
-Mutex::Mutex()
|
|
- : owner_thread_id_(0),
|
|
- type_(kDynamic),
|
|
- critical_section_init_phase_(0),
|
|
- critical_section_(new CRITICAL_SECTION) {
|
|
- ::InitializeCriticalSection(critical_section_);
|
|
-}
|
|
-
|
|
-Mutex::~Mutex() {
|
|
- // Static mutexes are leaked intentionally. It is not thread-safe to try
|
|
- // to clean them up.
|
|
- if (type_ == kDynamic) {
|
|
- ::DeleteCriticalSection(critical_section_);
|
|
- delete critical_section_;
|
|
- critical_section_ = nullptr;
|
|
- }
|
|
-}
|
|
-
|
|
-void Mutex::Lock() {
|
|
- ThreadSafeLazyInit();
|
|
- ::EnterCriticalSection(critical_section_);
|
|
- owner_thread_id_ = ::GetCurrentThreadId();
|
|
-}
|
|
-
|
|
-void Mutex::Unlock() {
|
|
- ThreadSafeLazyInit();
|
|
- // We don't protect writing to owner_thread_id_ here, as it's the
|
|
- // caller's responsibility to ensure that the current thread holds the
|
|
- // mutex when this is called.
|
|
- owner_thread_id_ = 0;
|
|
- ::LeaveCriticalSection(critical_section_);
|
|
-}
|
|
-
|
|
-// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
|
-// with high probability.
|
|
-void Mutex::AssertHeld() {
|
|
- ThreadSafeLazyInit();
|
|
- GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())
|
|
- << "The current thread is not holding the mutex @" << this;
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-// Use the RAII idiom to flag mem allocs that are intentionally never
|
|
-// deallocated. The motivation is to silence the false positive mem leaks
|
|
-// that are reported by the debug version of MS's CRT which can only detect
|
|
-// if an alloc is missing a matching deallocation.
|
|
-// Example:
|
|
-// MemoryIsNotDeallocated memory_is_not_deallocated;
|
|
-// critical_section_ = new CRITICAL_SECTION;
|
|
-//
|
|
-class MemoryIsNotDeallocated {
|
|
- public:
|
|
- MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
|
|
- old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
|
- // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
|
|
- // doesn't report mem leak if there's no matching deallocation.
|
|
- (void)_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
|
|
- }
|
|
-
|
|
- ~MemoryIsNotDeallocated() {
|
|
- // Restore the original _CRTDBG_ALLOC_MEM_DF flag
|
|
- (void)_CrtSetDbgFlag(old_crtdbg_flag_);
|
|
- }
|
|
-
|
|
- private:
|
|
- int old_crtdbg_flag_;
|
|
-
|
|
- MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete;
|
|
- MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) = delete;
|
|
-};
|
|
-#endif // _MSC_VER
|
|
-
|
|
-} // namespace
|
|
-
|
|
-// Initializes owner_thread_id_ and critical_section_ in static mutexes.
|
|
-void Mutex::ThreadSafeLazyInit() {
|
|
- // Dynamic mutexes are initialized in the constructor.
|
|
- if (type_ == kStatic) {
|
|
- switch (
|
|
- ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
|
|
- case 0:
|
|
- // If critical_section_init_phase_ was 0 before the exchange, we
|
|
- // are the first to test it and need to perform the initialization.
|
|
- owner_thread_id_ = 0;
|
|
- {
|
|
- // Use RAII to flag that following mem alloc is never deallocated.
|
|
-#ifdef _MSC_VER
|
|
- MemoryIsNotDeallocated memory_is_not_deallocated;
|
|
-#endif // _MSC_VER
|
|
- critical_section_ = new CRITICAL_SECTION;
|
|
- }
|
|
- ::InitializeCriticalSection(critical_section_);
|
|
- // Updates the critical_section_init_phase_ to 2 to signal
|
|
- // initialization complete.
|
|
- GTEST_CHECK_(::InterlockedCompareExchange(&critical_section_init_phase_,
|
|
- 2L, 1L) == 1L);
|
|
- break;
|
|
- case 1:
|
|
- // Somebody else is already initializing the mutex; spin until they
|
|
- // are done.
|
|
- while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L,
|
|
- 2L) != 2L) {
|
|
- // Possibly yields the rest of the thread's time slice to other
|
|
- // threads.
|
|
- ::Sleep(0);
|
|
- }
|
|
- break;
|
|
-
|
|
- case 2:
|
|
- break; // The mutex is already initialized and ready for use.
|
|
-
|
|
- default:
|
|
- GTEST_CHECK_(false)
|
|
- << "Unexpected value of critical_section_init_phase_ "
|
|
- << "while initializing a static mutex.";
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-class ThreadWithParamSupport : public ThreadWithParamBase {
|
|
- public:
|
|
- static HANDLE CreateThread(Runnable* runnable,
|
|
- Notification* thread_can_start) {
|
|
- ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
|
|
- DWORD thread_id;
|
|
- HANDLE thread_handle = ::CreateThread(
|
|
- nullptr, // Default security.
|
|
- 0, // Default stack size.
|
|
- &ThreadWithParamSupport::ThreadMain,
|
|
- param, // Parameter to ThreadMainStatic
|
|
- 0x0, // Default creation flags.
|
|
- &thread_id); // Need a valid pointer for the call to work under Win98.
|
|
- GTEST_CHECK_(thread_handle != nullptr)
|
|
- << "CreateThread failed with error " << ::GetLastError() << ".";
|
|
- if (thread_handle == nullptr) {
|
|
- delete param;
|
|
- }
|
|
- return thread_handle;
|
|
- }
|
|
-
|
|
- private:
|
|
- struct ThreadMainParam {
|
|
- ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
|
|
- : runnable_(runnable), thread_can_start_(thread_can_start) {}
|
|
- std::unique_ptr<Runnable> runnable_;
|
|
- // Does not own.
|
|
- Notification* thread_can_start_;
|
|
- };
|
|
-
|
|
- static DWORD WINAPI ThreadMain(void* ptr) {
|
|
- // Transfers ownership.
|
|
- std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
|
|
- if (param->thread_can_start_ != nullptr)
|
|
- param->thread_can_start_->WaitForNotification();
|
|
- param->runnable_->Run();
|
|
- return 0;
|
|
- }
|
|
-
|
|
- // Prohibit instantiation.
|
|
- ThreadWithParamSupport();
|
|
-
|
|
- ThreadWithParamSupport(const ThreadWithParamSupport&) = delete;
|
|
- ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) = delete;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-ThreadWithParamBase::ThreadWithParamBase(Runnable* runnable,
|
|
- Notification* thread_can_start)
|
|
- : thread_(
|
|
- ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) {}
|
|
-
|
|
-ThreadWithParamBase::~ThreadWithParamBase() { Join(); }
|
|
-
|
|
-void ThreadWithParamBase::Join() {
|
|
- GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)
|
|
- << "Failed to join the thread with error " << ::GetLastError() << ".";
|
|
-}
|
|
-
|
|
-// Maps a thread to a set of ThreadIdToThreadLocals that have values
|
|
-// instantiated on that thread and notifies them when the thread exits. A
|
|
-// ThreadLocal instance is expected to persist until all threads it has
|
|
-// values on have terminated.
|
|
-class ThreadLocalRegistryImpl {
|
|
- public:
|
|
- // Registers thread_local_instance as having value on the current thread.
|
|
- // 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 =
|
|
- GetThreadLocalsMapLocked();
|
|
- ThreadIdToThreadLocals::iterator thread_local_pos =
|
|
- thread_to_thread_locals->find(current_thread);
|
|
- if (thread_local_pos == thread_to_thread_locals->end()) {
|
|
- thread_local_pos =
|
|
- thread_to_thread_locals
|
|
- ->insert(std::make_pair(current_thread, ThreadLocalValues()))
|
|
- .first;
|
|
- StartWatcherThreadFor(current_thread);
|
|
- }
|
|
- ThreadLocalValues& thread_local_values = thread_local_pos->second;
|
|
- ThreadLocalValues::iterator value_pos =
|
|
- thread_local_values.find(thread_local_instance);
|
|
- if (value_pos == thread_local_values.end()) {
|
|
- value_pos =
|
|
- thread_local_values
|
|
- .insert(std::make_pair(
|
|
- thread_local_instance,
|
|
- std::shared_ptr<ThreadLocalValueHolderBase>(
|
|
- thread_local_instance->NewValueForCurrentThread())))
|
|
- .first;
|
|
- }
|
|
- return value_pos->second.get();
|
|
- }
|
|
-
|
|
- static void OnThreadLocalDestroyed(
|
|
- const ThreadLocalBase* thread_local_instance) {
|
|
- std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
|
|
- // Clean up the ThreadLocalValues data structure while holding the lock, but
|
|
- // defer the destruction of the ThreadLocalValueHolderBases.
|
|
- {
|
|
- MutexLock lock(&mutex_);
|
|
- ThreadIdToThreadLocals* const thread_to_thread_locals =
|
|
- GetThreadLocalsMapLocked();
|
|
- for (ThreadIdToThreadLocals::iterator it =
|
|
- thread_to_thread_locals->begin();
|
|
- it != thread_to_thread_locals->end(); ++it) {
|
|
- ThreadLocalValues& thread_local_values = it->second;
|
|
- ThreadLocalValues::iterator value_pos =
|
|
- thread_local_values.find(thread_local_instance);
|
|
- if (value_pos != thread_local_values.end()) {
|
|
- value_holders.push_back(value_pos->second);
|
|
- thread_local_values.erase(value_pos);
|
|
- // This 'if' can only be successful at most once, so theoretically we
|
|
- // could break out of the loop here, but we don't bother doing so.
|
|
- }
|
|
- }
|
|
- }
|
|
- // Outside the lock, let the destructor for 'value_holders' deallocate the
|
|
- // ThreadLocalValueHolderBases.
|
|
- }
|
|
-
|
|
- static void OnThreadExit(DWORD thread_id) {
|
|
- GTEST_CHECK_(thread_id != 0) << ::GetLastError();
|
|
- std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
|
|
- // Clean up the ThreadIdToThreadLocals data structure while holding the
|
|
- // lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
|
- {
|
|
- MutexLock lock(&mutex_);
|
|
- ThreadIdToThreadLocals* const thread_to_thread_locals =
|
|
- GetThreadLocalsMapLocked();
|
|
- ThreadIdToThreadLocals::iterator thread_local_pos =
|
|
- thread_to_thread_locals->find(thread_id);
|
|
- if (thread_local_pos != thread_to_thread_locals->end()) {
|
|
- ThreadLocalValues& thread_local_values = thread_local_pos->second;
|
|
- for (ThreadLocalValues::iterator value_pos =
|
|
- thread_local_values.begin();
|
|
- value_pos != thread_local_values.end(); ++value_pos) {
|
|
- value_holders.push_back(value_pos->second);
|
|
- }
|
|
- thread_to_thread_locals->erase(thread_local_pos);
|
|
- }
|
|
- }
|
|
- // Outside the lock, let the destructor for 'value_holders' deallocate the
|
|
- // ThreadLocalValueHolderBases.
|
|
- }
|
|
-
|
|
- private:
|
|
- // In a particular thread, maps a ThreadLocal object to its value.
|
|
- typedef std::map<const ThreadLocalBase*,
|
|
- std::shared_ptr<ThreadLocalValueHolderBase> >
|
|
- ThreadLocalValues;
|
|
- // Stores all ThreadIdToThreadLocals having values in a thread, indexed by
|
|
- // thread's ID.
|
|
- typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
|
|
-
|
|
- // Holds the thread id and thread handle that we pass from
|
|
- // StartWatcherThreadFor to WatcherThreadFunc.
|
|
- typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
|
|
-
|
|
- static void StartWatcherThreadFor(DWORD thread_id) {
|
|
- // The returned handle will be kept in thread_map and closed by
|
|
- // watcher_thread in WatcherThreadFunc.
|
|
- HANDLE thread =
|
|
- ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
|
|
- GTEST_CHECK_(thread != nullptr);
|
|
- // We need to pass a valid thread ID pointer into CreateThread for it
|
|
- // to work correctly under Win98.
|
|
- DWORD watcher_thread_id;
|
|
- HANDLE watcher_thread = ::CreateThread(
|
|
- nullptr, // Default security.
|
|
- 0, // Default stack size
|
|
- &ThreadLocalRegistryImpl::WatcherThreadFunc,
|
|
- reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
|
- CREATE_SUSPENDED, &watcher_thread_id);
|
|
- GTEST_CHECK_(watcher_thread != nullptr)
|
|
- << "CreateThread failed with error " << ::GetLastError() << ".";
|
|
- // Give the watcher thread the same priority as ours to avoid being
|
|
- // blocked by it.
|
|
- ::SetThreadPriority(watcher_thread,
|
|
- ::GetThreadPriority(::GetCurrentThread()));
|
|
- ::ResumeThread(watcher_thread);
|
|
- ::CloseHandle(watcher_thread);
|
|
- }
|
|
-
|
|
- // Monitors exit from a given thread and notifies those
|
|
- // ThreadIdToThreadLocals about thread termination.
|
|
- static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
|
|
- const ThreadIdAndHandle* tah =
|
|
- reinterpret_cast<const ThreadIdAndHandle*>(param);
|
|
- GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
|
|
- OnThreadExit(tah->first);
|
|
- ::CloseHandle(tah->second);
|
|
- delete tah;
|
|
- return 0;
|
|
- }
|
|
-
|
|
- // Returns map of thread local instances.
|
|
- static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
|
|
- mutex_.AssertHeld();
|
|
-#ifdef _MSC_VER
|
|
- MemoryIsNotDeallocated memory_is_not_deallocated;
|
|
-#endif // _MSC_VER
|
|
- static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
|
|
- return map;
|
|
- }
|
|
-
|
|
- // Protects access to GetThreadLocalsMapLocked() and its return value.
|
|
- static Mutex mutex_;
|
|
- // Protects access to GetThreadMapLocked() and its return value.
|
|
- static Mutex thread_map_mutex_;
|
|
-};
|
|
-
|
|
-Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT
|
|
-Mutex ThreadLocalRegistryImpl::thread_map_mutex_(
|
|
- Mutex::kStaticMutex); // NOLINT
|
|
-
|
|
-ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
|
|
- const ThreadLocalBase* thread_local_instance) {
|
|
- return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
|
|
- thread_local_instance);
|
|
-}
|
|
-
|
|
-void ThreadLocalRegistry::OnThreadLocalDestroyed(
|
|
- const ThreadLocalBase* thread_local_instance) {
|
|
- ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
|
|
-}
|
|
-
|
|
-#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
|
-
|
|
-#if GTEST_USES_POSIX_RE
|
|
-
|
|
-// Implements RE. Currently only needed for death tests.
|
|
-
|
|
-RE::~RE() {
|
|
- if (is_valid_) {
|
|
- // regfree'ing an invalid regex might crash because the content
|
|
- // of the regex is undefined. Since the regex's are essentially
|
|
- // the same, one cannot be valid (or invalid) without the other
|
|
- // being so too.
|
|
- regfree(&partial_regex_);
|
|
- regfree(&full_regex_);
|
|
- }
|
|
- free(const_cast<char*>(pattern_));
|
|
-}
|
|
-
|
|
-// 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;
|
|
-
|
|
- regmatch_t match;
|
|
- return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
|
|
-}
|
|
-
|
|
-// 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;
|
|
-
|
|
- regmatch_t match;
|
|
- return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
|
|
-}
|
|
-
|
|
-// Initializes an RE from its string representation.
|
|
-void RE::Init(const char* regex) {
|
|
- pattern_ = posix::StrDup(regex);
|
|
-
|
|
- // Reserves enough bytes to hold the regular expression used for a
|
|
- // full match.
|
|
- const size_t full_regex_len = strlen(regex) + 10;
|
|
- char* const full_pattern = new char[full_regex_len];
|
|
-
|
|
- snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
|
|
- is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
|
|
- // We want to call regcomp(&partial_regex_, ...) even if the
|
|
- // previous expression returns false. Otherwise partial_regex_ may
|
|
- // not be properly initialized can may cause trouble when it's
|
|
- // freed.
|
|
- //
|
|
- // Some implementation of POSIX regex (e.g. on at least some
|
|
- // versions of Cygwin) doesn't accept the empty string as a valid
|
|
- // regex. We change it to an equivalent form "()" to be safe.
|
|
- if (is_valid_) {
|
|
- const char* const partial_regex = (*regex == '\0') ? "()" : regex;
|
|
- is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
|
|
- }
|
|
- EXPECT_TRUE(is_valid_)
|
|
- << "Regular expression \"" << regex
|
|
- << "\" is not a valid POSIX Extended regular expression.";
|
|
-
|
|
- delete[] full_pattern;
|
|
-}
|
|
-
|
|
-#elif GTEST_USES_SIMPLE_RE
|
|
-
|
|
-// 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 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) {
|
|
- return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
|
|
-}
|
|
-bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
|
|
-bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
|
|
-bool IsAsciiWordChar(char ch) {
|
|
- return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
|
|
- ('0' <= ch && ch <= '9') || ch == '_';
|
|
-}
|
|
-
|
|
-// Returns true if and only if "\\c" is a supported escape sequence.
|
|
-bool IsValidEscape(char c) {
|
|
- return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
|
|
-}
|
|
-
|
|
-// 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) {
|
|
- case 'd':
|
|
- return IsAsciiDigit(ch);
|
|
- case 'D':
|
|
- return !IsAsciiDigit(ch);
|
|
- case 'f':
|
|
- return ch == '\f';
|
|
- case 'n':
|
|
- return ch == '\n';
|
|
- case 'r':
|
|
- return ch == '\r';
|
|
- case 's':
|
|
- return IsAsciiWhiteSpace(ch);
|
|
- case 'S':
|
|
- return !IsAsciiWhiteSpace(ch);
|
|
- case 't':
|
|
- return ch == '\t';
|
|
- case 'v':
|
|
- return ch == '\v';
|
|
- case 'w':
|
|
- return IsAsciiWordChar(ch);
|
|
- case 'W':
|
|
- return !IsAsciiWordChar(ch);
|
|
- }
|
|
- return IsAsciiPunct(pattern_char) && pattern_char == ch;
|
|
- }
|
|
-
|
|
- return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
|
|
-}
|
|
-
|
|
-// Helper function used by ValidateRegex() to format error messages.
|
|
-static std::string FormatRegexSyntaxError(const char* regex, int index) {
|
|
- return (Message() << "Syntax error at index " << index
|
|
- << " in simple regular expression \"" << regex << "\": ")
|
|
- .GetString();
|
|
-}
|
|
-
|
|
-// Generates non-fatal failures and returns false if regex is invalid;
|
|
-// otherwise returns true.
|
|
-bool ValidateRegex(const char* regex) {
|
|
- if (regex == nullptr) {
|
|
- ADD_FAILURE() << "NULL is not a valid simple regular expression.";
|
|
- return false;
|
|
- }
|
|
-
|
|
- bool is_valid = true;
|
|
-
|
|
- // 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
|
|
- i++;
|
|
- if (regex[i] == '\0') {
|
|
- ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
|
|
- << "'\\' cannot appear at the end.";
|
|
- return false;
|
|
- }
|
|
-
|
|
- if (!IsValidEscape(regex[i])) {
|
|
- ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
|
|
- << "invalid escape sequence \"\\" << regex[i] << "\".";
|
|
- is_valid = false;
|
|
- }
|
|
- prev_repeatable = true;
|
|
- } else { // Not an escape sequence.
|
|
- const char ch = regex[i];
|
|
-
|
|
- if (ch == '^' && i > 0) {
|
|
- ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
|
|
- << "'^' can only appear at the beginning.";
|
|
- is_valid = false;
|
|
- } else if (ch == '$' && regex[i + 1] != '\0') {
|
|
- ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
|
|
- << "'$' can only appear at the end.";
|
|
- is_valid = false;
|
|
- } else if (IsInSet(ch, "()[]{}|")) {
|
|
- ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
|
|
- << "' is unsupported.";
|
|
- is_valid = false;
|
|
- } else if (IsRepeat(ch) && !prev_repeatable) {
|
|
- ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
|
|
- << "' can only follow a repeatable token.";
|
|
- is_valid = false;
|
|
- }
|
|
-
|
|
- prev_repeatable = !IsInSet(ch, "^$?*+");
|
|
- }
|
|
- }
|
|
-
|
|
- return is_valid;
|
|
-}
|
|
-
|
|
-// Matches a repeated regex atom followed by a valid simple regular
|
|
-// expression. The regex atom is defined as c if escaped is false,
|
|
-// or \c otherwise. repeat is the repetition meta character (?, *,
|
|
-// or +). The behavior is undefined if str contains too many
|
|
-// characters to be indexable by size_t, in which case the test will
|
|
-// probably time out anyway. We are fine with this limitation as
|
|
-// std::string has it too.
|
|
-bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,
|
|
- const char* regex, const char* str) {
|
|
- const size_t min_count = (repeat == '+') ? 1 : 0;
|
|
- const size_t max_count = (repeat == '?') ? 1 : static_cast<size_t>(-1) - 1;
|
|
- // We cannot call numeric_limits::max() as it conflicts with the
|
|
- // max() macro on Windows.
|
|
-
|
|
- for (size_t i = 0; i <= max_count; ++i) {
|
|
- // We know that the atom matches each of the first i characters in str.
|
|
- if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
|
|
- // We have enough matches at the head, and the tail matches too.
|
|
- // Since we only care about *whether* the pattern matches str
|
|
- // (as opposed to *how* it matches), there is no need to find a
|
|
- // greedy match.
|
|
- return true;
|
|
- }
|
|
- if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false;
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
-// 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.
|
|
- return true;
|
|
-
|
|
- // "$" only matches the end of a string. Note that regex being
|
|
- // valid guarantees that there's nothing after "$" in it.
|
|
- if (*regex == '$') return *str == '\0';
|
|
-
|
|
- // Is the first thing in regex an escape sequence?
|
|
- const bool escaped = *regex == '\\';
|
|
- if (escaped) ++regex;
|
|
- if (IsRepeat(regex[1])) {
|
|
- // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
|
|
- // here's an indirect recursion. It terminates as the regex gets
|
|
- // shorter in each recursion.
|
|
- return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2,
|
|
- str);
|
|
- } else {
|
|
- // regex isn't empty, isn't "$", and doesn't start with a
|
|
- // repetition. We match the first atom of regex with the first
|
|
- // character of str and recurse.
|
|
- return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
|
|
- MatchRegexAtHead(regex + 1, str + 1);
|
|
- }
|
|
-}
|
|
-
|
|
-// 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
|
|
-// stack space normally. In rare cases the time complexity can be
|
|
-// exponential with respect to the regex length + the string length,
|
|
-// but usually it's must faster (often close to linear).
|
|
-bool MatchRegexAnywhere(const char* regex, const char* str) {
|
|
- if (regex == nullptr || str == nullptr) return false;
|
|
-
|
|
- if (*regex == '^') return MatchRegexAtHead(regex + 1, str);
|
|
-
|
|
- // A successful match can be anywhere in str.
|
|
- do {
|
|
- if (MatchRegexAtHead(regex, str)) return true;
|
|
- } while (*str++ != '\0');
|
|
- return false;
|
|
-}
|
|
-
|
|
-// Implements the RE class.
|
|
-
|
|
-RE::~RE() {
|
|
- free(const_cast<char*>(pattern_));
|
|
- free(const_cast<char*>(full_pattern_));
|
|
-}
|
|
-
|
|
-// 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 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);
|
|
-}
|
|
-
|
|
-// Initializes an RE from its string representation.
|
|
-void RE::Init(const char* regex) {
|
|
- pattern_ = full_pattern_ = nullptr;
|
|
- if (regex != nullptr) {
|
|
- pattern_ = posix::StrDup(regex);
|
|
- }
|
|
-
|
|
- is_valid_ = ValidateRegex(regex);
|
|
- if (!is_valid_) {
|
|
- // No need to calculate the full pattern when the regex is invalid.
|
|
- return;
|
|
- }
|
|
-
|
|
- const size_t len = strlen(regex);
|
|
- // Reserves enough bytes to hold the regular expression used for a
|
|
- // full match: we need space to prepend a '^', append a '$', and
|
|
- // terminate the string with '\0'.
|
|
- char* buffer = static_cast<char*>(malloc(len + 3));
|
|
- full_pattern_ = buffer;
|
|
-
|
|
- if (*regex != '^')
|
|
- *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'.
|
|
-
|
|
- // We don't use snprintf or strncpy, as they trigger a warning when
|
|
- // compiled with VC++ 8.0.
|
|
- memcpy(buffer, regex, len);
|
|
- buffer += len;
|
|
-
|
|
- if (len == 0 || regex[len - 1] != '$')
|
|
- *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'.
|
|
-
|
|
- *buffer = '\0';
|
|
-}
|
|
-
|
|
-#endif // GTEST_USES_POSIX_RE
|
|
-
|
|
-const char kUnknownFile[] = "unknown file";
|
|
-
|
|
-// Formats a source file path and a line number as they would appear
|
|
-// in an error message from the compiler used to compile this code.
|
|
-GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
|
|
- const std::string file_name(file == nullptr ? kUnknownFile : file);
|
|
-
|
|
- if (line < 0) {
|
|
- return file_name + ":";
|
|
- }
|
|
-#ifdef _MSC_VER
|
|
- return file_name + "(" + StreamableToString(line) + "):";
|
|
-#else
|
|
- return file_name + ":" + StreamableToString(line) + ":";
|
|
-#endif // _MSC_VER
|
|
-}
|
|
-
|
|
-// Formats a file location for compiler-independent XML output.
|
|
-// Although this function is not platform dependent, we put it next to
|
|
-// FormatFileLocation in order to contrast the two functions.
|
|
-// Note that FormatCompilerIndependentFileLocation() does NOT append colon
|
|
-// to the file location it produces, unlike FormatFileLocation().
|
|
-GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,
|
|
- int line) {
|
|
- const std::string file_name(file == nullptr ? kUnknownFile : file);
|
|
-
|
|
- if (line < 0)
|
|
- return file_name;
|
|
- else
|
|
- return file_name + ":" + StreamableToString(line);
|
|
-}
|
|
-
|
|
-GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
|
|
- : severity_(severity) {
|
|
- const char* const marker = severity == GTEST_INFO ? "[ INFO ]"
|
|
- : severity == GTEST_WARNING ? "[WARNING]"
|
|
- : severity == GTEST_ERROR ? "[ ERROR ]"
|
|
- : "[ FATAL ]";
|
|
- GetStream() << ::std::endl
|
|
- << marker << " " << FormatFileLocation(file, line).c_str()
|
|
- << ": ";
|
|
-}
|
|
-
|
|
-// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
|
|
-GTestLog::~GTestLog() {
|
|
- GetStream() << ::std::endl;
|
|
- if (severity_ == GTEST_FATAL) {
|
|
- fflush(stderr);
|
|
- posix::Abort();
|
|
- }
|
|
-}
|
|
-
|
|
-// Disable Microsoft deprecation warnings for POSIX functions called from
|
|
-// this class (creat, dup, dup2, and close)
|
|
-GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
|
|
-
|
|
-#if GTEST_HAS_STREAM_REDIRECTION
|
|
-
|
|
-// Object that captures an output stream (stdout/stderr).
|
|
-class CapturedStream {
|
|
- public:
|
|
- // The ctor redirects the stream to a temporary file.
|
|
- explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
|
|
-#if GTEST_OS_WINDOWS
|
|
- char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT
|
|
- char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT
|
|
-
|
|
- ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
|
|
- const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir",
|
|
- 0, // Generate unique file name.
|
|
- temp_file_path);
|
|
- GTEST_CHECK_(success != 0)
|
|
- << "Unable to create a temporary file in " << temp_dir_path;
|
|
- const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
|
|
- GTEST_CHECK_(captured_fd != -1)
|
|
- << "Unable to open temporary file " << temp_file_path;
|
|
- 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 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
|
|
- // the location of the world-writable SD Card directory. However,
|
|
- // this requires a Context handle, which cannot be retrieved
|
|
- // globally from native code. Doing so also precludes running the
|
|
- // 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 /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
|
|
- 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_ = std::move(name_template);
|
|
-#endif // GTEST_OS_WINDOWS
|
|
- fflush(nullptr);
|
|
- dup2(captured_fd, fd_);
|
|
- close(captured_fd);
|
|
- }
|
|
-
|
|
- ~CapturedStream() { remove(filename_.c_str()); }
|
|
-
|
|
- std::string GetCapturedString() {
|
|
- if (uncaptured_fd_ != -1) {
|
|
- // Restores the original stream.
|
|
- fflush(nullptr);
|
|
- dup2(uncaptured_fd_, fd_);
|
|
- close(uncaptured_fd_);
|
|
- uncaptured_fd_ = -1;
|
|
- }
|
|
-
|
|
- FILE* const file = posix::FOpen(filename_.c_str(), "r");
|
|
- if (file == nullptr) {
|
|
- GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_
|
|
- << " for capturing stream.";
|
|
- }
|
|
- const std::string content = ReadEntireFile(file);
|
|
- posix::FClose(file);
|
|
- return content;
|
|
- }
|
|
-
|
|
- private:
|
|
- const int fd_; // A stream to capture.
|
|
- int uncaptured_fd_;
|
|
- // Name of the temporary file holding the stderr output.
|
|
- ::std::string filename_;
|
|
-
|
|
- CapturedStream(const CapturedStream&) = delete;
|
|
- CapturedStream& operator=(const CapturedStream&) = delete;
|
|
-};
|
|
-
|
|
-GTEST_DISABLE_MSC_DEPRECATED_POP_()
|
|
-
|
|
-static CapturedStream* g_captured_stderr = nullptr;
|
|
-static CapturedStream* g_captured_stdout = nullptr;
|
|
-
|
|
-// Starts capturing an output stream (stdout/stderr).
|
|
-static void CaptureStream(int fd, const char* stream_name,
|
|
- CapturedStream** stream) {
|
|
- if (*stream != nullptr) {
|
|
- GTEST_LOG_(FATAL) << "Only one " << stream_name
|
|
- << " capturer can exist at a time.";
|
|
- }
|
|
- *stream = new CapturedStream(fd);
|
|
-}
|
|
-
|
|
-// Stops capturing the output stream and returns the captured string.
|
|
-static std::string GetCapturedStream(CapturedStream** captured_stream) {
|
|
- const std::string content = (*captured_stream)->GetCapturedString();
|
|
-
|
|
- delete *captured_stream;
|
|
- *captured_stream = nullptr;
|
|
-
|
|
- return content;
|
|
-}
|
|
-
|
|
-#if defined(_MSC_VER) || defined(__BORLANDC__)
|
|
-// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
|
|
-const int kStdOutFileno = 1;
|
|
-const int kStdErrFileno = 2;
|
|
-#else
|
|
-const int kStdOutFileno = STDOUT_FILENO;
|
|
-const int kStdErrFileno = STDERR_FILENO;
|
|
-#endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
|
-
|
|
-// Starts capturing stdout.
|
|
-void CaptureStdout() {
|
|
- CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
|
|
-}
|
|
-
|
|
-// Starts capturing stderr.
|
|
-void CaptureStderr() {
|
|
- CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
|
|
-}
|
|
-
|
|
-// Stops capturing stdout and returns the captured string.
|
|
-std::string GetCapturedStdout() {
|
|
- return GetCapturedStream(&g_captured_stdout);
|
|
-}
|
|
-
|
|
-// Stops capturing stderr and returns the captured string.
|
|
-std::string GetCapturedStderr() {
|
|
- return GetCapturedStream(&g_captured_stderr);
|
|
-}
|
|
-
|
|
-#endif // GTEST_HAS_STREAM_REDIRECTION
|
|
-
|
|
-size_t GetFileSize(FILE* file) {
|
|
- fseek(file, 0, SEEK_END);
|
|
- return static_cast<size_t>(ftell(file));
|
|
-}
|
|
-
|
|
-std::string ReadEntireFile(FILE* file) {
|
|
- const size_t file_size = GetFileSize(file);
|
|
- char* const buffer = new char[file_size];
|
|
-
|
|
- size_t bytes_last_read = 0; // # of bytes read in the last fread()
|
|
- size_t bytes_read = 0; // # of bytes read so far
|
|
-
|
|
- fseek(file, 0, SEEK_SET);
|
|
-
|
|
- // Keeps reading the file until we cannot read further or the
|
|
- // pre-determined file size is reached.
|
|
- do {
|
|
- bytes_last_read =
|
|
- fread(buffer + bytes_read, 1, file_size - bytes_read, file);
|
|
- bytes_read += bytes_last_read;
|
|
- } while (bytes_last_read > 0 && bytes_read < file_size);
|
|
-
|
|
- const std::string content(buffer, bytes_read);
|
|
- delete[] buffer;
|
|
-
|
|
- return content;
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-static const std::vector<std::string>* g_injected_test_argvs =
|
|
- nullptr; // Owned.
|
|
-
|
|
-std::vector<std::string> GetInjectableArgvs() {
|
|
- if (g_injected_test_argvs != nullptr) {
|
|
- return *g_injected_test_argvs;
|
|
- }
|
|
- return GetArgvs();
|
|
-}
|
|
-
|
|
-void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
|
|
- if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
|
|
- g_injected_test_argvs = new_argvs;
|
|
-}
|
|
-
|
|
-void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
|
|
- SetInjectableArgvs(
|
|
- new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
|
|
-}
|
|
-
|
|
-void ClearInjectableArgvs() {
|
|
- delete g_injected_test_argvs;
|
|
- g_injected_test_argvs = nullptr;
|
|
-}
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
-namespace posix {
|
|
-void Abort() {
|
|
- DebugBreak();
|
|
- TerminateProcess(GetCurrentProcess(), 1);
|
|
-}
|
|
-} // namespace posix
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
-// Returns the name of the environment variable corresponding to the
|
|
-// given flag. For example, FlagToEnvVar("foo") will return
|
|
-// "GTEST_FOO" in the open-source version.
|
|
-static std::string FlagToEnvVar(const char* flag) {
|
|
- const std::string full_flag =
|
|
- (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
|
|
-
|
|
- Message env_var;
|
|
- for (size_t i = 0; i != full_flag.length(); i++) {
|
|
- env_var << ToUpper(full_flag.c_str()[i]);
|
|
- }
|
|
-
|
|
- return env_var.GetString();
|
|
-}
|
|
-
|
|
-// 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_t* value) {
|
|
- // Parses the environment variable as a decimal integer.
|
|
- char* end = nullptr;
|
|
- const long long_value = strtol(str, &end, 10); // NOLINT
|
|
-
|
|
- // Has strtol() consumed all characters in the string?
|
|
- if (*end != '\0') {
|
|
- // No - an invalid character was encountered.
|
|
- Message msg;
|
|
- msg << "WARNING: " << src_text
|
|
- << " is expected to be a 32-bit integer, but actually"
|
|
- << " has value \"" << str << "\".\n";
|
|
- printf("%s", msg.GetString().c_str());
|
|
- fflush(stdout);
|
|
- return false;
|
|
- }
|
|
-
|
|
- // 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_t.
|
|
- ) {
|
|
- Message msg;
|
|
- msg << "WARNING: " << src_text
|
|
- << " is expected to be a 32-bit integer, but actually"
|
|
- << " has value " << str << ", which overflows.\n";
|
|
- printf("%s", msg.GetString().c_str());
|
|
- fflush(stdout);
|
|
- return false;
|
|
- }
|
|
-
|
|
- *value = result;
|
|
- return true;
|
|
-}
|
|
-
|
|
-// 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 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);
|
|
-#else
|
|
- const std::string env_var = FlagToEnvVar(flag);
|
|
- const char* const string_value = posix::GetEnv(env_var.c_str());
|
|
- return string_value == nullptr ? default_value
|
|
- : strcmp(string_value, "0") != 0;
|
|
-#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
|
|
-}
|
|
-
|
|
-// 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_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
|
|
- const std::string env_var = FlagToEnvVar(flag);
|
|
- const char* const string_value = posix::GetEnv(env_var.c_str());
|
|
- if (string_value == nullptr) {
|
|
- // The environment variable is not set.
|
|
- return 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",
|
|
- (Message() << default_value).GetString().c_str());
|
|
- fflush(stdout);
|
|
- return default_value;
|
|
- }
|
|
-
|
|
- return result;
|
|
-#endif // defined(GTEST_GET_INT32_FROM_ENV_)
|
|
-}
|
|
-
|
|
-// As a special case for the 'output' flag, if GTEST_OUTPUT is not
|
|
-// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
|
|
-// system. The value of XML_OUTPUT_FILE is a filename without the
|
|
-// "xml:" prefix of GTEST_OUTPUT.
|
|
-// Note that this is meant to be called at the call site so it does
|
|
-// not check that the flag is 'output'
|
|
-// In essence this checks an env variable called XML_OUTPUT_FILE
|
|
-// and if it is set we prepend "xml:" to its value, if it not set we return ""
|
|
-std::string OutputFlagAlsoCheckEnvVar() {
|
|
- std::string default_value_for_output_flag = "";
|
|
- const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
|
|
- if (nullptr != xml_output_file_env) {
|
|
- default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
|
|
- }
|
|
- return default_value_for_output_flag;
|
|
-}
|
|
-
|
|
-// Reads and returns the string environment variable corresponding to
|
|
-// the given flag; if it's not set, returns default_value.
|
|
-const char* StringFromGTestEnv(const char* flag, const char* default_value) {
|
|
-#if defined(GTEST_GET_STRING_FROM_ENV_)
|
|
- return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
|
|
-#else
|
|
- const std::string env_var = FlagToEnvVar(flag);
|
|
- const char* const value = posix::GetEnv(env_var.c_str());
|
|
- return value == nullptr ? default_value : value;
|
|
-#endif // defined(GTEST_GET_STRING_FROM_ENV_)
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-printers.cc b/vendor/gtest/src/gtest-printers.cc
|
|
deleted file mode 100644
|
|
index f3976d230..000000000
|
|
--- a/vendor/gtest/src/gtest-printers.cc
|
|
+++ /dev/null
|
|
@@ -1,553 +0,0 @@
|
|
-// Copyright 2007, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-// Google Test - The Google C++ Testing and Mocking Framework
|
|
-//
|
|
-// This file implements a universal value printer that can print a
|
|
-// value of any type T:
|
|
-//
|
|
-// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
|
-//
|
|
-// It uses the << operator when possible, and prints the bytes in the
|
|
-// object otherwise. A user can override its behavior for a class
|
|
-// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
|
-// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
|
-// 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"
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-namespace {
|
|
-
|
|
-using ::std::ostream;
|
|
-
|
|
-// Prints a segment of bytes in the given object.
|
|
-GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
-GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
-GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
|
-GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
-void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
|
- size_t count, ostream* os) {
|
|
- char text[5] = "";
|
|
- for (size_t i = 0; i != count; i++) {
|
|
- const size_t j = start + i;
|
|
- if (i != 0) {
|
|
- // Organizes the bytes into groups of 2 for easy parsing by
|
|
- // human.
|
|
- if ((j % 2) == 0)
|
|
- *os << ' ';
|
|
- else
|
|
- *os << '-';
|
|
- }
|
|
- GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
|
|
- *os << text;
|
|
- }
|
|
-}
|
|
-
|
|
-// Prints the bytes in the given value to the given ostream.
|
|
-void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
|
|
- ostream* os) {
|
|
- // Tells the user how big the object is.
|
|
- *os << count << "-byte object <";
|
|
-
|
|
- const size_t kThreshold = 132;
|
|
- const size_t kChunkSize = 64;
|
|
- // If the object size is bigger than kThreshold, we'll have to omit
|
|
- // some details by printing only the first and the last kChunkSize
|
|
- // bytes.
|
|
- if (count < kThreshold) {
|
|
- PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
|
|
- } else {
|
|
- PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
|
|
- *os << " ... ";
|
|
- // Rounds up to 2-byte boundary.
|
|
- const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2;
|
|
- PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
|
|
- }
|
|
- *os << ">";
|
|
-}
|
|
-
|
|
-// Helpers for widening a character to char32_t. Since the standard does not
|
|
-// specify if char / wchar_t is signed or unsigned, it is important to first
|
|
-// convert it to the unsigned type of the same width before widening it to
|
|
-// char32_t.
|
|
-template <typename CharType>
|
|
-char32_t ToChar32(CharType in) {
|
|
- return static_cast<char32_t>(
|
|
- static_cast<typename std::make_unsigned<CharType>::type>(in));
|
|
-}
|
|
-
|
|
-} // namespace
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
|
-// given object. The delegation simplifies the implementation, which
|
|
-// uses the << operator and thus is easier done outside of the
|
|
-// ::testing::internal namespace, which contains a << operator that
|
|
-// sometimes conflicts with the one in STL.
|
|
-void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
|
|
- ostream* os) {
|
|
- PrintBytesInObjectToImpl(obj_bytes, count, os);
|
|
-}
|
|
-
|
|
-// 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', ' '),
|
|
-// - as a hexadecimal escape sequence (e.g. '\x7F'), or
|
|
-// - as a special escape sequence (e.g. '\r', '\n').
|
|
-enum CharFormat { kAsIs, kHexEscape, kSpecialEscape };
|
|
-
|
|
-// 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(char32_t c) { return 0x20 <= c && c <= 0x7E; }
|
|
-
|
|
-// 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) {
|
|
- const char32_t u_c = ToChar32(c);
|
|
- switch (u_c) {
|
|
- case L'\0':
|
|
- *os << "\\0";
|
|
- break;
|
|
- case L'\'':
|
|
- *os << "\\'";
|
|
- break;
|
|
- case L'\\':
|
|
- *os << "\\\\";
|
|
- break;
|
|
- case L'\a':
|
|
- *os << "\\a";
|
|
- break;
|
|
- case L'\b':
|
|
- *os << "\\b";
|
|
- break;
|
|
- case L'\f':
|
|
- *os << "\\f";
|
|
- break;
|
|
- case L'\n':
|
|
- *os << "\\n";
|
|
- break;
|
|
- case L'\r':
|
|
- *os << "\\r";
|
|
- break;
|
|
- case L'\t':
|
|
- *os << "\\t";
|
|
- break;
|
|
- case L'\v':
|
|
- *os << "\\v";
|
|
- break;
|
|
- default:
|
|
- 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>(u_c);
|
|
- os->flags(flags);
|
|
- return kHexEscape;
|
|
- }
|
|
- }
|
|
- return kSpecialEscape;
|
|
-}
|
|
-
|
|
-// 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(char32_t c, ostream* os) {
|
|
- switch (c) {
|
|
- case L'\'':
|
|
- *os << "'";
|
|
- return kAsIs;
|
|
- case L'"':
|
|
- *os << "\\\"";
|
|
- return kSpecialEscape;
|
|
- default:
|
|
- 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(ToChar32(c), os);
|
|
-}
|
|
-
|
|
-#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 << GetCharWidthPrefix(c) << "'";
|
|
- const CharFormat format = PrintAsCharLiteralTo(c, os);
|
|
- *os << "'";
|
|
-
|
|
- // To aid user debugging, we also print c's code in decimal, unless
|
|
- // it's 0 (in which case c was printed as '\\0', making the code
|
|
- // obvious).
|
|
- if (c == 0) return;
|
|
- *os << " (" << static_cast<int>(c);
|
|
-
|
|
- // For more convenience, we print c's code again in hexadecimal,
|
|
- // unless c was already printed in the form '\x##' or the code is in
|
|
- // [1, 9].
|
|
- if (format == kHexEscape || (1 <= c && c <= 9)) {
|
|
- // Do nothing.
|
|
- } else {
|
|
- *os << ", 0x" << String::FormatHexInt(static_cast<int>(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(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);
|
|
-}
|
|
-
|
|
-// gcc/clang __{u,}int128_t
|
|
-#if defined(__SIZEOF_INT128__)
|
|
-void PrintTo(__uint128_t v, ::std::ostream* os) {
|
|
- if (v == 0) {
|
|
- *os << "0";
|
|
- return;
|
|
- }
|
|
-
|
|
- // Buffer large enough for ceil(log10(2^128))==39 and the null terminator
|
|
- char buf[40];
|
|
- char* p = buf + sizeof(buf);
|
|
-
|
|
- // Some configurations have a __uint128_t, but no support for built in
|
|
- // division. Do manual long division instead.
|
|
-
|
|
- uint64_t high = static_cast<uint64_t>(v >> 64);
|
|
- uint64_t low = static_cast<uint64_t>(v);
|
|
-
|
|
- *--p = 0;
|
|
- while (high != 0 || low != 0) {
|
|
- uint64_t high_mod = high % 10;
|
|
- high = high / 10;
|
|
- // This is the long division algorithm specialized for a divisor of 10 and
|
|
- // only two elements.
|
|
- // Notable values:
|
|
- // 2^64 / 10 == 1844674407370955161
|
|
- // 2^64 % 10 == 6
|
|
- const uint64_t carry = 6 * high_mod + low % 10;
|
|
- low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
|
|
-
|
|
- char digit = static_cast<char>(carry % 10);
|
|
- *--p = '0' + digit;
|
|
- }
|
|
- *os << p;
|
|
-}
|
|
-void PrintTo(__int128_t v, ::std::ostream* os) {
|
|
- __uint128_t uv = static_cast<__uint128_t>(v);
|
|
- if (v < 0) {
|
|
- *os << "-";
|
|
- uv = -uv;
|
|
- }
|
|
- PrintTo(uv, os);
|
|
-}
|
|
-#endif // __SIZEOF_INT128__
|
|
-
|
|
-// Prints the given array of characters to the ostream. CharType must be either
|
|
-// 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>
|
|
-GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
- GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
|
- GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
|
|
- PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
|
|
- 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) {
|
|
- const CharType cur = begin[index];
|
|
- if (is_previous_hex && IsXDigit(cur)) {
|
|
- // Previous character is of '\x..' form and this character can be
|
|
- // interpreted as another hexadecimal digit in its number. Break string to
|
|
- // disambiguate.
|
|
- *os << "\" " << quote_prefix << "\"";
|
|
- }
|
|
- is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
|
- // Remember if any characters required hex escaping.
|
|
- if (is_previous_hex) {
|
|
- print_format = kHexEscape;
|
|
- }
|
|
- }
|
|
- *os << "\"";
|
|
- return print_format;
|
|
-}
|
|
-
|
|
-// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
|
-// 'begin'. CharType must be either char or wchar_t.
|
|
-template <typename CharType>
|
|
-GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
- GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
|
|
- GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void
|
|
- UniversalPrintCharArray(const CharType* begin, size_t len,
|
|
- ostream* os) {
|
|
- // The code
|
|
- // const char kFoo[] = "foo";
|
|
- // generates an array of 4, not 3, elements, with the last one being '\0'.
|
|
- //
|
|
- // Therefore when printing a char array, we don't print the last element if
|
|
- // it's '\0', such that the output matches the string literal as it's
|
|
- // written in the source code.
|
|
- if (len > 0 && begin[len - 1] == '\0') {
|
|
- PrintCharsAsStringTo(begin, len - 1, os);
|
|
- return;
|
|
- }
|
|
-
|
|
- // If, however, the last element in the array is not '\0', e.g.
|
|
- // const char kFoo[] = { 'f', 'o', 'o' };
|
|
- // we must print the entire array. We also print a message to indicate
|
|
- // that the array is not NUL-terminated.
|
|
- PrintCharsAsStringTo(begin, len, os);
|
|
- *os << " (no terminating NUL)";
|
|
-}
|
|
-
|
|
-// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
|
-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);
|
|
-}
|
|
-
|
|
-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, 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,
|
|
-// possibly accessing more memory than intended and causing invalid
|
|
-// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
|
-// 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) { PrintCStringTo(s, os); }
|
|
-#endif // wchar_t is native
|
|
-
|
|
-namespace {
|
|
-
|
|
-bool ContainsUnprintableControlCodes(const char* str, size_t length) {
|
|
- const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
|
|
-
|
|
- for (size_t i = 0; i < length; i++) {
|
|
- unsigned char ch = *s++;
|
|
- if (std::iscntrl(ch)) {
|
|
- switch (ch) {
|
|
- case '\t':
|
|
- case '\n':
|
|
- case '\r':
|
|
- break;
|
|
- default:
|
|
- return true;
|
|
- }
|
|
- }
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
-bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; }
|
|
-
|
|
-bool IsValidUTF8(const char* str, size_t length) {
|
|
- const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
|
|
-
|
|
- for (size_t i = 0; i < length;) {
|
|
- unsigned char lead = s[i++];
|
|
-
|
|
- if (lead <= 0x7f) {
|
|
- continue; // single-byte character (ASCII) 0..7F
|
|
- }
|
|
- if (lead < 0xc2) {
|
|
- return false; // trail byte or non-shortest form
|
|
- } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
|
|
- ++i; // 2-byte character
|
|
- } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
|
|
- IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&
|
|
- // check for non-shortest form and surrogate
|
|
- (lead != 0xe0 || s[i] >= 0xa0) &&
|
|
- (lead != 0xed || s[i] < 0xa0)) {
|
|
- i += 2; // 3-byte character
|
|
- } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
|
|
- IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&
|
|
- IsUTF8TrailByte(s[i + 2]) &&
|
|
- // check for non-shortest form
|
|
- (lead != 0xf0 || s[i] >= 0x90) &&
|
|
- (lead != 0xf4 || s[i] < 0x90)) {
|
|
- i += 3; // 4-byte character
|
|
- } else {
|
|
- return false;
|
|
- }
|
|
- }
|
|
- return true;
|
|
-}
|
|
-
|
|
-void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
|
|
- if (!ContainsUnprintableControlCodes(str, length) &&
|
|
- IsValidUTF8(str, length)) {
|
|
- *os << "\n As Text: \"" << str << "\"";
|
|
- }
|
|
-}
|
|
-
|
|
-} // anonymous namespace
|
|
-
|
|
-void PrintStringTo(const ::std::string& s, ostream* os) {
|
|
- if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
|
|
- if (GTEST_FLAG_GET(print_utf8)) {
|
|
- ConditionalPrintAsText(s.data(), s.size(), os);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-#ifdef __cpp_char8_t
|
|
-void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
|
|
- PrintCharsAsStringTo(s.data(), s.size(), os);
|
|
-}
|
|
-#endif
|
|
-
|
|
-void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
|
|
- PrintCharsAsStringTo(s.data(), s.size(), os);
|
|
-}
|
|
-
|
|
-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);
|
|
-}
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-test-part.cc b/vendor/gtest/src/gtest-test-part.cc
|
|
deleted file mode 100644
|
|
index eb7c8d1cf..000000000
|
|
--- a/vendor/gtest/src/gtest-test-part.cc
|
|
+++ /dev/null
|
|
@@ -1,105 +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.
|
|
-
|
|
-//
|
|
-// 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 {
|
|
-
|
|
-using internal::GetUnitTestImpl;
|
|
-
|
|
-// Gets the summary of the failure message by omitting the stack trace
|
|
-// in it.
|
|
-std::string TestPartResult::ExtractSummary(const char* message) {
|
|
- const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
|
|
- return stack_trace == nullptr ? message : std::string(message, stack_trace);
|
|
-}
|
|
-
|
|
-// Prints a TestPartResult object.
|
|
-std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
|
|
- return os << internal::FormatFileLocation(result.file_name(),
|
|
- result.line_number())
|
|
- << " "
|
|
- << (result.type() == TestPartResult::kSuccess ? "Success"
|
|
- : result.type() == TestPartResult::kSkip ? "Skipped"
|
|
- : result.type() == TestPartResult::kFatalFailure
|
|
- ? "Fatal failure"
|
|
- : "Non-fatal failure")
|
|
- << ":\n"
|
|
- << result.message() << std::endl;
|
|
-}
|
|
-
|
|
-// Appends a TestPartResult to the array.
|
|
-void TestPartResultArray::Append(const TestPartResult& result) {
|
|
- array_.push_back(result);
|
|
-}
|
|
-
|
|
-// Returns the TestPartResult at the given index (0-based).
|
|
-const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
|
|
- if (index < 0 || index >= size()) {
|
|
- printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
|
|
- internal::posix::Abort();
|
|
- }
|
|
-
|
|
- return array_[static_cast<size_t>(index)];
|
|
-}
|
|
-
|
|
-// Returns the number of TestPartResult objects in the array.
|
|
-int TestPartResultArray::size() const {
|
|
- return static_cast<int>(array_.size());
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-HasNewFatalFailureHelper::HasNewFatalFailureHelper()
|
|
- : has_new_fatal_failure_(false),
|
|
- original_reporter_(
|
|
- GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) {
|
|
- GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
|
|
-}
|
|
-
|
|
-HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
|
|
- GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
|
|
- original_reporter_);
|
|
-}
|
|
-
|
|
-void HasNewFatalFailureHelper::ReportTestPartResult(
|
|
- const TestPartResult& result) {
|
|
- if (result.fatally_failed()) has_new_fatal_failure_ = true;
|
|
- original_reporter_->ReportTestPartResult(result);
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest-typed-test.cc b/vendor/gtest/src/gtest-typed-test.cc
|
|
deleted file mode 100644
|
|
index a2828b83c..000000000
|
|
--- a/vendor/gtest/src/gtest-typed-test.cc
|
|
+++ /dev/null
|
|
@@ -1,104 +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.
|
|
-
|
|
-#include "gtest/gtest-typed-test.h"
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-// 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) {
|
|
- while (IsSpace(*str)) str++;
|
|
- return str;
|
|
-}
|
|
-
|
|
-static std::vector<std::string> SplitIntoTestNames(const char* src) {
|
|
- std::vector<std::string> name_vec;
|
|
- src = SkipSpaces(src);
|
|
- for (; src != nullptr; src = SkipComma(src)) {
|
|
- name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));
|
|
- }
|
|
- return name_vec;
|
|
-}
|
|
-
|
|
-// Verifies that registered_tests match the test names in
|
|
-// registered_tests_; returns registered_tests if successful, or
|
|
-// aborts the program otherwise.
|
|
-const char* TypedTestSuitePState::VerifyRegisteredTestNames(
|
|
- 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;
|
|
-
|
|
- std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
|
|
-
|
|
- Message errors;
|
|
-
|
|
- std::set<std::string> tests;
|
|
- for (std::vector<std::string>::const_iterator name_it = name_vec.begin();
|
|
- name_it != name_vec.end(); ++name_it) {
|
|
- const std::string& name = *name_it;
|
|
- if (tests.count(name) != 0) {
|
|
- errors << "Test " << name << " is listed more than once.\n";
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (registered_tests_.count(name) != 0) {
|
|
- tests.insert(name);
|
|
- } else {
|
|
- errors << "No test named " << name
|
|
- << " can be found in this test suite.\n";
|
|
- }
|
|
- }
|
|
-
|
|
- for (RegisteredTestIter it = registered_tests_.begin();
|
|
- it != registered_tests_.end(); ++it) {
|
|
- if (tests.count(it->first) == 0) {
|
|
- errors << "You forgot to list test " << it->first << ".\n";
|
|
- }
|
|
- }
|
|
-
|
|
- const std::string& errors_str = errors.GetString();
|
|
- if (errors_str != "") {
|
|
- fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
|
|
- errors_str.c_str());
|
|
- fflush(stderr);
|
|
- posix::Abort();
|
|
- }
|
|
-
|
|
- return registered_tests;
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest.cc b/vendor/gtest/src/gtest.cc
|
|
deleted file mode 100644
|
|
index 6f31dd226..000000000
|
|
--- a/vendor/gtest/src/gtest.cc
|
|
+++ /dev/null
|
|
@@ -1,6795 +0,0 @@
|
|
-// Copyright 2005, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-//
|
|
-// The Google C++ Testing and Mocking Framework (Google Test)
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-#include <ctype.h>
|
|
-#include <stdarg.h>
|
|
-#include <stdio.h>
|
|
-#include <stdlib.h>
|
|
-#include <time.h>
|
|
-#include <wchar.h>
|
|
-#include <wctype.h>
|
|
-
|
|
-#include <algorithm>
|
|
-#include <chrono> // NOLINT
|
|
-#include <cmath>
|
|
-#include <cstdint>
|
|
-#include <initializer_list>
|
|
-#include <iomanip>
|
|
-#include <iterator>
|
|
-#include <limits>
|
|
-#include <list>
|
|
-#include <map>
|
|
-#include <ostream> // NOLINT
|
|
-#include <sstream>
|
|
-#include <unordered_set>
|
|
-#include <vector>
|
|
-
|
|
-#include "gtest/gtest-assertion-result.h"
|
|
-#include "gtest/gtest-spi.h"
|
|
-#include "gtest/internal/custom/gtest.h"
|
|
-
|
|
-#if GTEST_OS_LINUX
|
|
-
|
|
-#include <fcntl.h> // NOLINT
|
|
-#include <limits.h> // NOLINT
|
|
-#include <sched.h> // NOLINT
|
|
-// Declares vsnprintf(). This header is not available on Windows.
|
|
-#include <strings.h> // NOLINT
|
|
-#include <sys/mman.h> // NOLINT
|
|
-#include <sys/time.h> // NOLINT
|
|
-#include <unistd.h> // NOLINT
|
|
-
|
|
-#include <string>
|
|
-
|
|
-#elif GTEST_OS_ZOS
|
|
-#include <sys/time.h> // NOLINT
|
|
-
|
|
-// On z/OS we additionally need strings.h for strcasecmp.
|
|
-#include <strings.h> // NOLINT
|
|
-
|
|
-#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE.
|
|
-
|
|
-#include <windows.h> // NOLINT
|
|
-#undef min
|
|
-
|
|
-#elif GTEST_OS_WINDOWS // We are on Windows proper.
|
|
-
|
|
-#include <windows.h> // NOLINT
|
|
-#undef min
|
|
-
|
|
-#ifdef _MSC_VER
|
|
-#include <crtdbg.h> // NOLINT
|
|
-#endif
|
|
-
|
|
-#include <io.h> // NOLINT
|
|
-#include <sys/stat.h> // NOLINT
|
|
-#include <sys/timeb.h> // NOLINT
|
|
-#include <sys/types.h> // NOLINT
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MINGW
|
|
-#include <sys/time.h> // NOLINT
|
|
-#endif // GTEST_OS_WINDOWS_MINGW
|
|
-
|
|
-#else
|
|
-
|
|
-// cpplint thinks that the header is already included, so we want to
|
|
-// silence it.
|
|
-#include <sys/time.h> // NOLINT
|
|
-#include <unistd.h> // NOLINT
|
|
-
|
|
-#endif // GTEST_OS_LINUX
|
|
-
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
-#include <stdexcept>
|
|
-#endif
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
-#include <arpa/inet.h> // NOLINT
|
|
-#include <netdb.h> // NOLINT
|
|
-#include <sys/socket.h> // NOLINT
|
|
-#include <sys/types.h> // NOLINT
|
|
-#endif
|
|
-
|
|
-#include "src/gtest-internal-inl.h"
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-#define vsnprintf _vsnprintf
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-#if GTEST_OS_MAC
|
|
-#ifndef GTEST_OS_IOS
|
|
-#include <crt_externs.h>
|
|
-#endif
|
|
-#endif
|
|
-
|
|
-#if GTEST_HAS_ABSL
|
|
-#include "absl/debugging/failure_signal_handler.h"
|
|
-#include "absl/debugging/stacktrace.h"
|
|
-#include "absl/debugging/symbolize.h"
|
|
-#include "absl/flags/parse.h"
|
|
-#include "absl/flags/usage.h"
|
|
-#include "absl/strings/str_cat.h"
|
|
-#include "absl/strings/str_replace.h"
|
|
-#endif // GTEST_HAS_ABSL
|
|
-
|
|
-namespace testing {
|
|
-
|
|
-using internal::CountIf;
|
|
-using internal::ForEach;
|
|
-using internal::GetElementOr;
|
|
-using internal::Shuffle;
|
|
-
|
|
-// Constants.
|
|
-
|
|
-// A test whose test suite name or test name matches this filter is
|
|
-// disabled and not run.
|
|
-static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
|
|
-
|
|
-// A test suite whose name matches this filter is considered a death
|
|
-// test suite and will be run before test suites whose name doesn't
|
|
-// match this filter.
|
|
-static const char kDeathTestSuiteFilter[] = "*DeathTest:*DeathTest/*";
|
|
-
|
|
-// A test filter that matches everything.
|
|
-static const char kUniversalFilter[] = "*";
|
|
-
|
|
-// The default output format.
|
|
-static const char kDefaultOutputFormat[] = "xml";
|
|
-// The default output file.
|
|
-static const char kDefaultOutputFile[] = "test_detail";
|
|
-
|
|
-// The environment variable name for the test shard index.
|
|
-static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
|
-// The environment variable name for the total number of test shards.
|
|
-static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
|
-// The environment variable name for the test shard status file.
|
|
-static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// The text used in failure messages to indicate the start of the
|
|
-// stack trace.
|
|
-const char kStackTraceMarker[] = "\nStack trace:\n";
|
|
-
|
|
-// g_help_flag is true if and only if the --help flag or an equivalent form
|
|
-// is specified on the command line.
|
|
-bool g_help_flag = false;
|
|
-
|
|
-// Utility function to Open File for Writing
|
|
-static FILE* OpenFileForWriting(const std::string& output_file) {
|
|
- FILE* fileout = nullptr;
|
|
- FilePath output_file_path(output_file);
|
|
- FilePath output_dir(output_file_path.RemoveFileName());
|
|
-
|
|
- if (output_dir.CreateDirectoriesRecursively()) {
|
|
- fileout = posix::FOpen(output_file.c_str(), "w");
|
|
- }
|
|
- if (fileout == nullptr) {
|
|
- GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file << "\"";
|
|
- }
|
|
- return fileout;
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY
|
|
-// environment variable.
|
|
-static const char* GetDefaultFilter() {
|
|
- const char* const testbridge_test_only =
|
|
- internal::posix::GetEnv("TESTBRIDGE_TEST_ONLY");
|
|
- if (testbridge_test_only != nullptr) {
|
|
- return testbridge_test_only;
|
|
- }
|
|
- return kUniversalFilter;
|
|
-}
|
|
-
|
|
-// Bazel passes in the argument to '--test_runner_fail_fast' via the
|
|
-// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable.
|
|
-static bool GetDefaultFailFast() {
|
|
- const char* const testbridge_test_runner_fail_fast =
|
|
- internal::posix::GetEnv("TESTBRIDGE_TEST_RUNNER_FAIL_FAST");
|
|
- if (testbridge_test_runner_fail_fast != nullptr) {
|
|
- return strcmp(testbridge_test_runner_fail_fast, "1") == 0;
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
-} // namespace testing
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- fail_fast,
|
|
- testing::internal::BoolFromGTestEnv("fail_fast",
|
|
- testing::GetDefaultFailFast()),
|
|
- "True if and only if a test failure should stop further test execution.");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- also_run_disabled_tests,
|
|
- testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
|
- "Run disabled tests too, in addition to the tests normally being run.");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- break_on_failure,
|
|
- testing::internal::BoolFromGTestEnv("break_on_failure", false),
|
|
- "True if and only if a failed assertion should be a debugger "
|
|
- "break-point.");
|
|
-
|
|
-GTEST_DEFINE_bool_(catch_exceptions,
|
|
- testing::internal::BoolFromGTestEnv("catch_exceptions",
|
|
- true),
|
|
- "True if and only if " GTEST_NAME_
|
|
- " should catch exceptions and treat them as test failures.");
|
|
-
|
|
-GTEST_DEFINE_string_(
|
|
- color, testing::internal::StringFromGTestEnv("color", "auto"),
|
|
- "Whether to use colors in the output. Valid values: yes, no, "
|
|
- "and auto. 'auto' means to use colors if the output is "
|
|
- "being sent to a terminal and the TERM environment variable "
|
|
- "is set to a terminal type that supports colors.");
|
|
-
|
|
-GTEST_DEFINE_string_(
|
|
- filter,
|
|
- testing::internal::StringFromGTestEnv("filter",
|
|
- testing::GetDefaultFilter()),
|
|
- "A colon-separated list of glob (not regex) patterns "
|
|
- "for filtering the tests to run, optionally followed by a "
|
|
- "'-' and a : separated list of negative patterns (tests to "
|
|
- "exclude). A test is run if it matches one of the positive "
|
|
- "patterns and does not match any of the negative patterns.");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- install_failure_signal_handler,
|
|
- testing::internal::BoolFromGTestEnv("install_failure_signal_handler",
|
|
- false),
|
|
- "If true and supported on the current platform, " GTEST_NAME_
|
|
- " should "
|
|
- "install a signal handler that dumps debugging information when fatal "
|
|
- "signals are raised.");
|
|
-
|
|
-GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them.");
|
|
-
|
|
-// The net priority order after flag processing is thus:
|
|
-// --gtest_output command line flag
|
|
-// GTEST_OUTPUT environment variable
|
|
-// XML_OUTPUT_FILE environment variable
|
|
-// ''
|
|
-GTEST_DEFINE_string_(
|
|
- output,
|
|
- testing::internal::StringFromGTestEnv(
|
|
- "output", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()),
|
|
- "A format (defaults to \"xml\" but can be specified to be \"json\"), "
|
|
- "optionally followed by a colon and an output file name or directory. "
|
|
- "A directory is indicated by a trailing pathname separator. "
|
|
- "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
|
|
- "If a directory is specified, output files will be created "
|
|
- "within that directory, with file-names based on the test "
|
|
- "executable's name and, if necessary, made unique by adding "
|
|
- "digits.");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- brief, testing::internal::BoolFromGTestEnv("brief", false),
|
|
- "True if only test failures should be displayed in text output.");
|
|
-
|
|
-GTEST_DEFINE_bool_(print_time,
|
|
- testing::internal::BoolFromGTestEnv("print_time", true),
|
|
- "True if and only if " GTEST_NAME_
|
|
- " should display elapsed time in text output.");
|
|
-
|
|
-GTEST_DEFINE_bool_(print_utf8,
|
|
- testing::internal::BoolFromGTestEnv("print_utf8", true),
|
|
- "True if and only if " GTEST_NAME_
|
|
- " prints UTF8 characters as text.");
|
|
-
|
|
-GTEST_DEFINE_int32_(
|
|
- random_seed, testing::internal::Int32FromGTestEnv("random_seed", 0),
|
|
- "Random number seed to use when shuffling test orders. Must be in range "
|
|
- "[1, 99999], or 0 to use a seed based on the current time.");
|
|
-
|
|
-GTEST_DEFINE_int32_(
|
|
- repeat, testing::internal::Int32FromGTestEnv("repeat", 1),
|
|
- "How many times to repeat each test. Specify a negative number "
|
|
- "for repeating forever. Useful for shaking out flaky tests.");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- recreate_environments_when_repeating,
|
|
- testing::internal::BoolFromGTestEnv("recreate_environments_when_repeating",
|
|
- false),
|
|
- "Controls whether global test environments are recreated for each repeat "
|
|
- "of the tests. If set to false the global test environments are only set "
|
|
- "up once, for the first iteration, and only torn down once, for the last. "
|
|
- "Useful for shaking out flaky tests with stable, expensive test "
|
|
- "environments. If --gtest_repeat is set to a negative number, meaning "
|
|
- "there is no last run, the environments will always be recreated to avoid "
|
|
- "leaks.");
|
|
-
|
|
-GTEST_DEFINE_bool_(show_internal_stack_frames, false,
|
|
- "True if and only if " GTEST_NAME_
|
|
- " should include internal stack frames when "
|
|
- "printing test failure stack traces.");
|
|
-
|
|
-GTEST_DEFINE_bool_(shuffle,
|
|
- testing::internal::BoolFromGTestEnv("shuffle", false),
|
|
- "True if and only if " GTEST_NAME_
|
|
- " should randomize tests' order on every run.");
|
|
-
|
|
-GTEST_DEFINE_int32_(
|
|
- stack_trace_depth,
|
|
- testing::internal::Int32FromGTestEnv("stack_trace_depth",
|
|
- testing::kMaxStackTraceDepth),
|
|
- "The maximum number of stack frames to print when an "
|
|
- "assertion fails. The valid range is 0 through 100, inclusive.");
|
|
-
|
|
-GTEST_DEFINE_string_(
|
|
- stream_result_to,
|
|
- testing::internal::StringFromGTestEnv("stream_result_to", ""),
|
|
- "This flag specifies the host name and the port number on which to stream "
|
|
- "test results. Example: \"localhost:555\". The flag is effective only on "
|
|
- "Linux.");
|
|
-
|
|
-GTEST_DEFINE_bool_(
|
|
- throw_on_failure,
|
|
- testing::internal::BoolFromGTestEnv("throw_on_failure", false),
|
|
- "When this flag is specified, a failed assertion will throw an exception "
|
|
- "if exceptions are enabled or exit the program with a non-zero code "
|
|
- "otherwise. For use with an external test framework.");
|
|
-
|
|
-#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
-GTEST_DEFINE_string_(
|
|
- flagfile, testing::internal::StringFromGTestEnv("flagfile", ""),
|
|
- "This flag specifies the flagfile to read command-line flags from.");
|
|
-#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
-
|
|
-namespace testing {
|
|
-namespace internal {
|
|
-
|
|
-// Generates a random number from [0, range), using a Linear
|
|
-// Congruential Generator (LCG). Crashes if 'range' is 0 or greater
|
|
-// than kMaxRange.
|
|
-uint32_t Random::Generate(uint32_t range) {
|
|
- // These constants are the same as are used in glibc's rand(3).
|
|
- // Use wider types than necessary to prevent unsigned overflow diagnostics.
|
|
- state_ = static_cast<uint32_t>(1103515245ULL * state_ + 12345U) % kMaxRange;
|
|
-
|
|
- GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0).";
|
|
- GTEST_CHECK_(range <= kMaxRange)
|
|
- << "Generation of a number in [0, " << range << ") was requested, "
|
|
- << "but this can only generate numbers in [0, " << kMaxRange << ").";
|
|
-
|
|
- // Converting via modulus introduces a bit of downward bias, but
|
|
- // it's simple, and a linear congruential generator isn't too good
|
|
- // to begin with.
|
|
- return state_ % range;
|
|
-}
|
|
-
|
|
-// GTestIsInitialized() returns true if and only if the user has initialized
|
|
-// Google Test. Useful for catching the user mistake of not initializing
|
|
-// Google Test before calling RUN_ALL_TESTS().
|
|
-static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
|
|
-
|
|
-// Iterates over a vector of TestSuites, keeping a running sum of the
|
|
-// results of calling a given int-returning method on each.
|
|
-// Returns the sum.
|
|
-static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_list,
|
|
- int (TestSuite::*method)() const) {
|
|
- int sum = 0;
|
|
- for (size_t i = 0; i < case_list.size(); i++) {
|
|
- sum += (case_list[i]->*method)();
|
|
- }
|
|
- return sum;
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test suite passed.
|
|
-static bool TestSuitePassed(const TestSuite* test_suite) {
|
|
- return test_suite->should_run() && test_suite->Passed();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test suite failed.
|
|
-static bool TestSuiteFailed(const TestSuite* test_suite) {
|
|
- return test_suite->should_run() && test_suite->Failed();
|
|
-}
|
|
-
|
|
-// Returns true if and only if test_suite contains at least one test that
|
|
-// should run.
|
|
-static bool ShouldRunTestSuite(const TestSuite* test_suite) {
|
|
- return test_suite->should_run();
|
|
-}
|
|
-
|
|
-// AssertHelper constructor.
|
|
-AssertHelper::AssertHelper(TestPartResult::Type type, const char* file,
|
|
- int line, const char* message)
|
|
- : data_(new AssertHelperData(type, file, line, message)) {}
|
|
-
|
|
-AssertHelper::~AssertHelper() { delete data_; }
|
|
-
|
|
-// Message assignment, for assertion streaming support.
|
|
-void AssertHelper::operator=(const Message& message) const {
|
|
- UnitTest::GetInstance()->AddTestPartResult(
|
|
- data_->type, data_->file, data_->line,
|
|
- AppendUserMessage(data_->message, message),
|
|
- UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)
|
|
- // Skips the stack frame for this function itself.
|
|
- ); // NOLINT
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P
|
|
-// to creates test cases for it, a synthetic test case is
|
|
-// inserted to report ether an error or a log message.
|
|
-//
|
|
-// This configuration bit will likely be removed at some point.
|
|
-constexpr bool kErrorOnUninstantiatedParameterizedTest = true;
|
|
-constexpr bool kErrorOnUninstantiatedTypeParameterizedTest = true;
|
|
-
|
|
-// A test that fails at a given file/line location with a given message.
|
|
-class FailureTest : public Test {
|
|
- public:
|
|
- explicit FailureTest(const CodeLocation& loc, std::string error_message,
|
|
- bool as_error)
|
|
- : loc_(loc),
|
|
- error_message_(std::move(error_message)),
|
|
- as_error_(as_error) {}
|
|
-
|
|
- void TestBody() override {
|
|
- if (as_error_) {
|
|
- AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(),
|
|
- loc_.line, "") = Message() << error_message_;
|
|
- } else {
|
|
- std::cout << error_message_ << std::endl;
|
|
- }
|
|
- }
|
|
-
|
|
- private:
|
|
- const CodeLocation loc_;
|
|
- const std::string error_message_;
|
|
- const bool as_error_;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-std::set<std::string>* GetIgnoredParameterizedTestSuites() {
|
|
- return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites();
|
|
-}
|
|
-
|
|
-// Add a given test_suit to the list of them allow to go un-instantiated.
|
|
-MarkAsIgnored::MarkAsIgnored(const char* test_suite) {
|
|
- GetIgnoredParameterizedTestSuites()->insert(test_suite);
|
|
-}
|
|
-
|
|
-// If this parameterized test suite has no instantiations (and that
|
|
-// has not been marked as okay), emit a test case reporting that.
|
|
-void InsertSyntheticTestCase(const std::string& name, CodeLocation location,
|
|
- bool has_test_p) {
|
|
- const auto& ignored = *GetIgnoredParameterizedTestSuites();
|
|
- if (ignored.find(name) != ignored.end()) return;
|
|
-
|
|
- const char kMissingInstantiation[] = //
|
|
- " 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."
|
|
- "\n\n"
|
|
- "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.)";
|
|
-
|
|
- const char kMissingTestCase[] = //
|
|
- " is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are "
|
|
- "defined via TEST_P . No test cases will run."
|
|
- "\n\n"
|
|
- "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.";
|
|
-
|
|
- std::string message =
|
|
- "Parameterized test suite " + name +
|
|
- (has_test_p ? kMissingInstantiation : kMissingTestCase) +
|
|
- "\n\n"
|
|
- "To suppress this error for this test suite, insert the following line "
|
|
- "(in a non-header) in the namespace it is defined in:"
|
|
- "\n\n"
|
|
- "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" +
|
|
- name + ");";
|
|
-
|
|
- std::string full_name = "UninstantiatedParameterizedTestSuite<" + name + ">";
|
|
- RegisterTest( //
|
|
- "GoogleTestVerification", full_name.c_str(),
|
|
- nullptr, // No type parameter.
|
|
- nullptr, // No value parameter.
|
|
- location.file.c_str(), location.line, [message, location] {
|
|
- return new FailureTest(location, message,
|
|
- kErrorOnUninstantiatedParameterizedTest);
|
|
- });
|
|
-}
|
|
-
|
|
-void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
|
|
- CodeLocation code_location) {
|
|
- GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(
|
|
- test_suite_name, code_location);
|
|
-}
|
|
-
|
|
-void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
|
|
- GetUnitTestImpl()->type_parameterized_test_registry().RegisterInstantiation(
|
|
- case_name);
|
|
-}
|
|
-
|
|
-void TypeParameterizedTestSuiteRegistry::RegisterTestSuite(
|
|
- const char* test_suite_name, CodeLocation code_location) {
|
|
- suites_.emplace(std::string(test_suite_name),
|
|
- TypeParameterizedTestSuiteInfo(code_location));
|
|
-}
|
|
-
|
|
-void TypeParameterizedTestSuiteRegistry::RegisterInstantiation(
|
|
- const char* test_suite_name) {
|
|
- auto it = suites_.find(std::string(test_suite_name));
|
|
- if (it != suites_.end()) {
|
|
- it->second.instantiated = true;
|
|
- } else {
|
|
- GTEST_LOG_(ERROR) << "Unknown type parameterized test suit '"
|
|
- << test_suite_name << "'";
|
|
- }
|
|
-}
|
|
-
|
|
-void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() {
|
|
- const auto& ignored = *GetIgnoredParameterizedTestSuites();
|
|
- for (const auto& testcase : suites_) {
|
|
- if (testcase.second.instantiated) continue;
|
|
- if (ignored.find(testcase.first) != ignored.end()) continue;
|
|
-
|
|
- std::string message =
|
|
- "Type parameterized test suite " + testcase.first +
|
|
- " is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated "
|
|
- "via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run."
|
|
- "\n\n"
|
|
- "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.)"
|
|
- "\n\n"
|
|
- "To suppress this error for this test suite, insert the following line "
|
|
- "(in a non-header) in the namespace it is defined in:"
|
|
- "\n\n"
|
|
- "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" +
|
|
- testcase.first + ");";
|
|
-
|
|
- std::string full_name =
|
|
- "UninstantiatedTypeParameterizedTestSuite<" + testcase.first + ">";
|
|
- RegisterTest( //
|
|
- "GoogleTestVerification", full_name.c_str(),
|
|
- nullptr, // No type parameter.
|
|
- nullptr, // No value parameter.
|
|
- testcase.second.code_location.file.c_str(),
|
|
- testcase.second.code_location.line, [message, testcase] {
|
|
- return new FailureTest(testcase.second.code_location, message,
|
|
- kErrorOnUninstantiatedTypeParameterizedTest);
|
|
- });
|
|
- }
|
|
-}
|
|
-
|
|
-// A copy of all command line arguments. Set by InitGoogleTest().
|
|
-static ::std::vector<std::string> g_argvs;
|
|
-
|
|
-::std::vector<std::string> GetArgvs() {
|
|
-#if defined(GTEST_CUSTOM_GET_ARGVS_)
|
|
- // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or
|
|
- // ::string. This code converts it to the appropriate type.
|
|
- const auto& custom = GTEST_CUSTOM_GET_ARGVS_();
|
|
- return ::std::vector<std::string>(custom.begin(), custom.end());
|
|
-#else // defined(GTEST_CUSTOM_GET_ARGVS_)
|
|
- return g_argvs;
|
|
-#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
|
|
-}
|
|
-
|
|
-// Returns the current application's name, removing directory path if that
|
|
-// is present.
|
|
-FilePath GetCurrentExecutableName() {
|
|
- FilePath result;
|
|
-
|
|
-#if GTEST_OS_WINDOWS || GTEST_OS_OS2
|
|
- result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe"));
|
|
-#else
|
|
- result.Set(FilePath(GetArgvs()[0]));
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
- return result.RemoveDirectoryName();
|
|
-}
|
|
-
|
|
-// Functions for processing the gtest_output flag.
|
|
-
|
|
-// Returns the output format, or "" for normal printed output.
|
|
-std::string UnitTestOptions::GetOutputFormat() {
|
|
- std::string s = GTEST_FLAG_GET(output);
|
|
- const char* const gtest_output_flag = s.c_str();
|
|
- const char* const colon = strchr(gtest_output_flag, ':');
|
|
- return (colon == nullptr)
|
|
- ? std::string(gtest_output_flag)
|
|
- : std::string(gtest_output_flag,
|
|
- static_cast<size_t>(colon - gtest_output_flag));
|
|
-}
|
|
-
|
|
-// Returns the name of the requested output file, or the default if none
|
|
-// was explicitly specified.
|
|
-std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
|
|
- std::string s = GTEST_FLAG_GET(output);
|
|
- const char* const gtest_output_flag = s.c_str();
|
|
-
|
|
- std::string format = GetOutputFormat();
|
|
- if (format.empty()) format = std::string(kDefaultOutputFormat);
|
|
-
|
|
- const char* const colon = strchr(gtest_output_flag, ':');
|
|
- if (colon == nullptr)
|
|
- return internal::FilePath::MakeFileName(
|
|
- internal::FilePath(
|
|
- UnitTest::GetInstance()->original_working_dir()),
|
|
- internal::FilePath(kDefaultOutputFile), 0, format.c_str())
|
|
- .string();
|
|
-
|
|
- internal::FilePath output_name(colon + 1);
|
|
- if (!output_name.IsAbsolutePath())
|
|
- output_name = internal::FilePath::ConcatPaths(
|
|
- internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
|
|
- internal::FilePath(colon + 1));
|
|
-
|
|
- if (!output_name.IsDirectory()) return output_name.string();
|
|
-
|
|
- internal::FilePath result(internal::FilePath::GenerateUniqueFileName(
|
|
- output_name, internal::GetCurrentExecutableName(),
|
|
- GetOutputFormat().c_str()));
|
|
- return result.string();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the wildcard pattern matches the string. Each
|
|
-// pattern consists of regular characters, single-character wildcards (?), and
|
|
-// multi-character wildcards (*).
|
|
-//
|
|
-// This function implements a linear-time string globbing algorithm based on
|
|
-// https://research.swtch.com/glob.
|
|
-static bool PatternMatchesString(const std::string& name_str,
|
|
- const char* pattern, const char* pattern_end) {
|
|
- const char* name = name_str.c_str();
|
|
- const char* const name_begin = name;
|
|
- const char* const name_end = name + name_str.size();
|
|
-
|
|
- const char* pattern_next = pattern;
|
|
- const char* name_next = name;
|
|
-
|
|
- while (pattern < pattern_end || name < name_end) {
|
|
- if (pattern < pattern_end) {
|
|
- switch (*pattern) {
|
|
- default: // Match an ordinary character.
|
|
- if (name < name_end && *name == *pattern) {
|
|
- ++pattern;
|
|
- ++name;
|
|
- continue;
|
|
- }
|
|
- break;
|
|
- case '?': // Match any single character.
|
|
- if (name < name_end) {
|
|
- ++pattern;
|
|
- ++name;
|
|
- continue;
|
|
- }
|
|
- break;
|
|
- case '*':
|
|
- // Match zero or more characters. Start by skipping over the wildcard
|
|
- // and matching zero characters from name. If that fails, restart and
|
|
- // match one more character than the last attempt.
|
|
- pattern_next = pattern;
|
|
- name_next = name + 1;
|
|
- ++pattern;
|
|
- continue;
|
|
- }
|
|
- }
|
|
- // Failed to match a character. Restart if possible.
|
|
- if (name_begin < name_next && name_next <= name_end) {
|
|
- pattern = pattern_next;
|
|
- name = name_next;
|
|
- continue;
|
|
- }
|
|
- return false;
|
|
- }
|
|
- return true;
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-bool IsGlobPattern(const std::string& pattern) {
|
|
- return std::any_of(pattern.begin(), pattern.end(),
|
|
- [](const char c) { return c == '?' || c == '*'; });
|
|
-}
|
|
-
|
|
-class UnitTestFilter {
|
|
- public:
|
|
- UnitTestFilter() = default;
|
|
-
|
|
- // Constructs a filter from a string of patterns separated by `:`.
|
|
- explicit UnitTestFilter(const std::string& filter) {
|
|
- // By design "" filter matches "" string.
|
|
- std::vector<std::string> all_patterns;
|
|
- SplitString(filter, ':', &all_patterns);
|
|
- const auto exact_match_patterns_begin = std::partition(
|
|
- all_patterns.begin(), all_patterns.end(), &IsGlobPattern);
|
|
-
|
|
- glob_patterns_.reserve(static_cast<size_t>(
|
|
- std::distance(all_patterns.begin(), exact_match_patterns_begin)));
|
|
- std::move(all_patterns.begin(), exact_match_patterns_begin,
|
|
- std::inserter(glob_patterns_, glob_patterns_.begin()));
|
|
- std::move(
|
|
- exact_match_patterns_begin, all_patterns.end(),
|
|
- std::inserter(exact_match_patterns_, exact_match_patterns_.begin()));
|
|
- }
|
|
-
|
|
- // Returns true if and only if name matches at least one of the patterns in
|
|
- // the filter.
|
|
- bool MatchesName(const std::string& name) const {
|
|
- return exact_match_patterns_.count(name) > 0 ||
|
|
- std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
|
|
- [&name](const std::string& pattern) {
|
|
- return PatternMatchesString(
|
|
- name, pattern.c_str(),
|
|
- pattern.c_str() + pattern.size());
|
|
- });
|
|
- }
|
|
-
|
|
- private:
|
|
- std::vector<std::string> glob_patterns_;
|
|
- std::unordered_set<std::string> exact_match_patterns_;
|
|
-};
|
|
-
|
|
-class PositiveAndNegativeUnitTestFilter {
|
|
- public:
|
|
- // Constructs a positive and a negative filter from a string. The string
|
|
- // contains a positive filter optionally followed by a '-' character and a
|
|
- // negative filter. In case only a negative filter is provided the positive
|
|
- // filter will be assumed "*".
|
|
- // A filter is a list of patterns separated by ':'.
|
|
- explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) {
|
|
- std::vector<std::string> positive_and_negative_filters;
|
|
-
|
|
- // NOTE: `SplitString` always returns a non-empty container.
|
|
- SplitString(filter, '-', &positive_and_negative_filters);
|
|
- const auto& positive_filter = positive_and_negative_filters.front();
|
|
-
|
|
- if (positive_and_negative_filters.size() > 1) {
|
|
- positive_filter_ = UnitTestFilter(
|
|
- positive_filter.empty() ? kUniversalFilter : positive_filter);
|
|
-
|
|
- // TODO(b/214626361): Fail on multiple '-' characters
|
|
- // For the moment to preserve old behavior we concatenate the rest of the
|
|
- // string parts with `-` as separator to generate the negative filter.
|
|
- auto negative_filter_string = positive_and_negative_filters[1];
|
|
- for (std::size_t i = 2; i < positive_and_negative_filters.size(); i++)
|
|
- negative_filter_string =
|
|
- negative_filter_string + '-' + positive_and_negative_filters[i];
|
|
- negative_filter_ = UnitTestFilter(negative_filter_string);
|
|
- } else {
|
|
- // In case we don't have a negative filter and positive filter is ""
|
|
- // we do not use kUniversalFilter by design as opposed to when we have a
|
|
- // negative filter.
|
|
- positive_filter_ = UnitTestFilter(positive_filter);
|
|
- }
|
|
- }
|
|
-
|
|
- // Returns true if and only if test name (this is generated by appending test
|
|
- // suit name and test name via a '.' character) matches the positive filter
|
|
- // and does not match the negative filter.
|
|
- bool MatchesTest(const std::string& test_suite_name,
|
|
- const std::string& test_name) const {
|
|
- return MatchesName(test_suite_name + "." + test_name);
|
|
- }
|
|
-
|
|
- // Returns true if and only if name matches the positive filter and does not
|
|
- // match the negative filter.
|
|
- bool MatchesName(const std::string& name) const {
|
|
- return positive_filter_.MatchesName(name) &&
|
|
- !negative_filter_.MatchesName(name);
|
|
- }
|
|
-
|
|
- private:
|
|
- UnitTestFilter positive_filter_;
|
|
- UnitTestFilter negative_filter_;
|
|
-};
|
|
-} // namespace
|
|
-
|
|
-bool UnitTestOptions::MatchesFilter(const std::string& name_str,
|
|
- const char* filter) {
|
|
- return UnitTestFilter(filter).MatchesName(name_str);
|
|
-}
|
|
-
|
|
-// Returns true if and only if the user-specified filter matches the test
|
|
-// suite name and the test name.
|
|
-bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,
|
|
- const std::string& test_name) {
|
|
- // Split --gtest_filter at '-', if there is one, to separate into
|
|
- // positive filter and negative filter portions
|
|
- return PositiveAndNegativeUnitTestFilter(GTEST_FLAG_GET(filter))
|
|
- .MatchesTest(test_suite_name, test_name);
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_SEH
|
|
-// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
|
|
-// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
|
|
-// This function is useful as an __except condition.
|
|
-int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
|
|
- // Google Test should handle a SEH exception if:
|
|
- // 1. the user wants it to, AND
|
|
- // 2. this is not a breakpoint exception, AND
|
|
- // 3. this is not a C++ exception (VC++ implements them via SEH,
|
|
- // apparently).
|
|
- //
|
|
- // SEH exception code for C++ exceptions.
|
|
- // (see http://support.microsoft.com/kb/185294 for more information).
|
|
- const DWORD kCxxExceptionCode = 0xe06d7363;
|
|
-
|
|
- bool should_handle = true;
|
|
-
|
|
- if (!GTEST_FLAG_GET(catch_exceptions))
|
|
- should_handle = false;
|
|
- else if (exception_code == EXCEPTION_BREAKPOINT)
|
|
- should_handle = false;
|
|
- else if (exception_code == kCxxExceptionCode)
|
|
- should_handle = false;
|
|
-
|
|
- return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
|
|
-}
|
|
-#endif // GTEST_HAS_SEH
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// The c'tor sets this object as the test part result reporter used by
|
|
-// Google Test. The 'result' parameter specifies where to report the
|
|
-// results. Intercepts only failures from the current thread.
|
|
-ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
|
|
- TestPartResultArray* result)
|
|
- : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) {
|
|
- Init();
|
|
-}
|
|
-
|
|
-// The c'tor sets this object as the test part result reporter used by
|
|
-// Google Test. The 'result' parameter specifies where to report the
|
|
-// results.
|
|
-ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
|
|
- InterceptMode intercept_mode, TestPartResultArray* result)
|
|
- : intercept_mode_(intercept_mode), result_(result) {
|
|
- Init();
|
|
-}
|
|
-
|
|
-void ScopedFakeTestPartResultReporter::Init() {
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
|
|
- old_reporter_ = impl->GetGlobalTestPartResultReporter();
|
|
- impl->SetGlobalTestPartResultReporter(this);
|
|
- } else {
|
|
- old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
|
|
- impl->SetTestPartResultReporterForCurrentThread(this);
|
|
- }
|
|
-}
|
|
-
|
|
-// The d'tor restores the test part result reporter used by Google Test
|
|
-// before.
|
|
-ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
|
|
- impl->SetGlobalTestPartResultReporter(old_reporter_);
|
|
- } else {
|
|
- impl->SetTestPartResultReporterForCurrentThread(old_reporter_);
|
|
- }
|
|
-}
|
|
-
|
|
-// Increments the test part result count and remembers the result.
|
|
-// This method is from the TestPartResultReporterInterface interface.
|
|
-void ScopedFakeTestPartResultReporter::ReportTestPartResult(
|
|
- const TestPartResult& result) {
|
|
- result_->Append(result);
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Returns the type ID of ::testing::Test. We should always call this
|
|
-// instead of GetTypeId< ::testing::Test>() to get the type ID of
|
|
-// testing::Test. This is to work around a suspected linker bug when
|
|
-// using Google Test as a framework on Mac OS X. The bug causes
|
|
-// GetTypeId< ::testing::Test>() to return different values depending
|
|
-// on whether the call is from the Google Test framework itself or
|
|
-// from user test code. GetTestTypeId() is guaranteed to always
|
|
-// return the same value, as it always calls GetTypeId<>() from the
|
|
-// gtest.cc, which is within the Google Test framework.
|
|
-TypeId GetTestTypeId() { return GetTypeId<Test>(); }
|
|
-
|
|
-// The value of GetTestTypeId() as seen from within the Google Test
|
|
-// library. This is solely for testing GetTestTypeId().
|
|
-extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
|
|
-
|
|
-// This predicate-formatter checks that 'results' contains a test part
|
|
-// failure of the given type and that the failure message contains the
|
|
-// given substring.
|
|
-static AssertionResult HasOneFailure(const char* /* results_expr */,
|
|
- const char* /* type_expr */,
|
|
- const char* /* substr_expr */,
|
|
- const TestPartResultArray& results,
|
|
- TestPartResult::Type type,
|
|
- const std::string& substr) {
|
|
- const std::string expected(type == TestPartResult::kFatalFailure
|
|
- ? "1 fatal failure"
|
|
- : "1 non-fatal failure");
|
|
- Message msg;
|
|
- if (results.size() != 1) {
|
|
- msg << "Expected: " << expected << "\n"
|
|
- << " Actual: " << results.size() << " failures";
|
|
- for (int i = 0; i < results.size(); i++) {
|
|
- msg << "\n" << results.GetTestPartResult(i);
|
|
- }
|
|
- return AssertionFailure() << msg;
|
|
- }
|
|
-
|
|
- const TestPartResult& r = results.GetTestPartResult(0);
|
|
- if (r.type() != type) {
|
|
- return AssertionFailure() << "Expected: " << expected << "\n"
|
|
- << " Actual:\n"
|
|
- << r;
|
|
- }
|
|
-
|
|
- if (strstr(r.message(), substr.c_str()) == nullptr) {
|
|
- return AssertionFailure()
|
|
- << "Expected: " << expected << " containing \"" << substr << "\"\n"
|
|
- << " Actual:\n"
|
|
- << r;
|
|
- }
|
|
-
|
|
- return AssertionSuccess();
|
|
-}
|
|
-
|
|
-// The constructor of SingleFailureChecker remembers where to look up
|
|
-// test part results, what type of failure we expect, and what
|
|
-// substring the failure message should contain.
|
|
-SingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results,
|
|
- TestPartResult::Type type,
|
|
- const std::string& substr)
|
|
- : results_(results), type_(type), substr_(substr) {}
|
|
-
|
|
-// The destructor of SingleFailureChecker verifies that the given
|
|
-// TestPartResultArray contains exactly one failure that has the given
|
|
-// type and contains the given substring. If that's not the case, a
|
|
-// non-fatal failure will be generated.
|
|
-SingleFailureChecker::~SingleFailureChecker() {
|
|
- EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);
|
|
-}
|
|
-
|
|
-DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
|
|
- UnitTestImpl* unit_test)
|
|
- : unit_test_(unit_test) {}
|
|
-
|
|
-void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
|
|
- const TestPartResult& result) {
|
|
- unit_test_->current_test_result()->AddTestPartResult(result);
|
|
- unit_test_->listeners()->repeater()->OnTestPartResult(result);
|
|
-}
|
|
-
|
|
-DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
|
|
- UnitTestImpl* unit_test)
|
|
- : unit_test_(unit_test) {}
|
|
-
|
|
-void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
|
|
- const TestPartResult& result) {
|
|
- unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
|
|
-}
|
|
-
|
|
-// Returns the global test part result reporter.
|
|
-TestPartResultReporterInterface*
|
|
-UnitTestImpl::GetGlobalTestPartResultReporter() {
|
|
- internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
|
- return global_test_part_result_repoter_;
|
|
-}
|
|
-
|
|
-// Sets the global test part result reporter.
|
|
-void UnitTestImpl::SetGlobalTestPartResultReporter(
|
|
- TestPartResultReporterInterface* reporter) {
|
|
- internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
|
|
- global_test_part_result_repoter_ = reporter;
|
|
-}
|
|
-
|
|
-// Returns the test part result reporter for the current thread.
|
|
-TestPartResultReporterInterface*
|
|
-UnitTestImpl::GetTestPartResultReporterForCurrentThread() {
|
|
- return per_thread_test_part_result_reporter_.get();
|
|
-}
|
|
-
|
|
-// Sets the test part result reporter for the current thread.
|
|
-void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
|
|
- TestPartResultReporterInterface* reporter) {
|
|
- per_thread_test_part_result_reporter_.set(reporter);
|
|
-}
|
|
-
|
|
-// Gets the number of successful test suites.
|
|
-int UnitTestImpl::successful_test_suite_count() const {
|
|
- return CountIf(test_suites_, TestSuitePassed);
|
|
-}
|
|
-
|
|
-// Gets the number of failed test suites.
|
|
-int UnitTestImpl::failed_test_suite_count() const {
|
|
- return CountIf(test_suites_, TestSuiteFailed);
|
|
-}
|
|
-
|
|
-// Gets the number of all test suites.
|
|
-int UnitTestImpl::total_test_suite_count() const {
|
|
- return static_cast<int>(test_suites_.size());
|
|
-}
|
|
-
|
|
-// Gets the number of all test suites that contain at least one test
|
|
-// that should run.
|
|
-int UnitTestImpl::test_suite_to_run_count() const {
|
|
- return CountIf(test_suites_, ShouldRunTestSuite);
|
|
-}
|
|
-
|
|
-// Gets the number of successful tests.
|
|
-int UnitTestImpl::successful_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of skipped tests.
|
|
-int UnitTestImpl::skipped_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of failed tests.
|
|
-int UnitTestImpl::failed_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of disabled tests that will be reported in the XML report.
|
|
-int UnitTestImpl::reportable_disabled_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_,
|
|
- &TestSuite::reportable_disabled_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of disabled tests.
|
|
-int UnitTestImpl::disabled_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of tests to be printed in the XML report.
|
|
-int UnitTestImpl::reportable_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of all tests.
|
|
-int UnitTestImpl::total_test_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count);
|
|
-}
|
|
-
|
|
-// Gets the number of tests that should run.
|
|
-int UnitTestImpl::test_to_run_count() const {
|
|
- return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count);
|
|
-}
|
|
-
|
|
-// Returns the current OS stack trace as an std::string.
|
|
-//
|
|
-// The maximum number of stack frames to be included is specified by
|
|
-// the gtest_stack_trace_depth flag. The skip_count parameter
|
|
-// specifies the number of top frames to be skipped, which doesn't
|
|
-// count against the number of frames to be included.
|
|
-//
|
|
-// For example, if Foo() calls Bar(), which in turn calls
|
|
-// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
|
|
-// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
|
-std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
|
|
- return os_stack_trace_getter()->CurrentStackTrace(
|
|
- static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1
|
|
- // Skips the user-specified number of frames plus this function
|
|
- // itself.
|
|
- ); // NOLINT
|
|
-}
|
|
-
|
|
-// A helper class for measuring elapsed times.
|
|
-class Timer {
|
|
- public:
|
|
- Timer() : start_(std::chrono::steady_clock::now()) {}
|
|
-
|
|
- // Return time elapsed in milliseconds since the timer was created.
|
|
- TimeInMillis Elapsed() {
|
|
- return std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
- std::chrono::steady_clock::now() - start_)
|
|
- .count();
|
|
- }
|
|
-
|
|
- private:
|
|
- std::chrono::steady_clock::time_point start_;
|
|
-};
|
|
-
|
|
-// Returns a timestamp as milliseconds since the epoch. Note this time may jump
|
|
-// around subject to adjustments by the system, to measure elapsed time use
|
|
-// Timer instead.
|
|
-TimeInMillis GetTimeInMillis() {
|
|
- return std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
- std::chrono::system_clock::now() -
|
|
- std::chrono::system_clock::from_time_t(0))
|
|
- .count();
|
|
-}
|
|
-
|
|
-// Utilities
|
|
-
|
|
-// class String.
|
|
-
|
|
-#if GTEST_OS_WINDOWS_MOBILE
|
|
-// Creates a UTF-16 wide string from the given ANSI string, allocating
|
|
-// memory using new. The caller is responsible for deleting the return
|
|
-// value using delete[]. Returns the wide string, or NULL if the
|
|
-// input is NULL.
|
|
-LPCWSTR String::AnsiToUtf16(const char* ansi) {
|
|
- if (!ansi) return nullptr;
|
|
- const int length = strlen(ansi);
|
|
- const int unicode_length =
|
|
- MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0);
|
|
- WCHAR* unicode = new WCHAR[unicode_length + 1];
|
|
- MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length);
|
|
- unicode[unicode_length] = 0;
|
|
- return unicode;
|
|
-}
|
|
-
|
|
-// Creates an ANSI string from the given wide string, allocating
|
|
-// memory using new. The caller is responsible for deleting the return
|
|
-// value using delete[]. Returns the ANSI string, or NULL if the
|
|
-// input is NULL.
|
|
-const char* String::Utf16ToAnsi(LPCWSTR utf16_str) {
|
|
- if (!utf16_str) return nullptr;
|
|
- const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr,
|
|
- 0, nullptr, nullptr);
|
|
- char* ansi = new char[ansi_length + 1];
|
|
- WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr,
|
|
- nullptr);
|
|
- ansi[ansi_length] = 0;
|
|
- return ansi;
|
|
-}
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
-// 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,
|
|
-// including the empty string.
|
|
-bool String::CStringEquals(const char* lhs, const char* rhs) {
|
|
- if (lhs == nullptr) return rhs == nullptr;
|
|
-
|
|
- if (rhs == nullptr) return false;
|
|
-
|
|
- return strcmp(lhs, rhs) == 0;
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_STD_WSTRING
|
|
-
|
|
-// Converts an array of wide chars to a narrow string using the UTF-8
|
|
-// encoding, and streams the result to the given Message object.
|
|
-static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
|
|
- Message* msg) {
|
|
- for (size_t i = 0; i != length;) { // NOLINT
|
|
- if (wstr[i] != L'\0') {
|
|
- *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
|
|
- while (i != length && wstr[i] != L'\0') i++;
|
|
- } else {
|
|
- *msg << '\0';
|
|
- i++;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-void SplitString(const ::std::string& str, char delimiter,
|
|
- ::std::vector< ::std::string>* dest) {
|
|
- ::std::vector< ::std::string> parsed;
|
|
- ::std::string::size_type pos = 0;
|
|
- while (::testing::internal::AlwaysTrue()) {
|
|
- const ::std::string::size_type colon = str.find(delimiter, pos);
|
|
- if (colon == ::std::string::npos) {
|
|
- parsed.push_back(str.substr(pos));
|
|
- break;
|
|
- } else {
|
|
- parsed.push_back(str.substr(pos, colon - pos));
|
|
- pos = colon + 1;
|
|
- }
|
|
- }
|
|
- dest->swap(parsed);
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Constructs an empty Message.
|
|
-// We allocate the stringstream separately because otherwise each use of
|
|
-// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
|
|
-// stack frame leading to huge stack frames in some cases; gcc does not reuse
|
|
-// the stack space.
|
|
-Message::Message() : ss_(new ::std::stringstream) {
|
|
- // By default, we want there to be enough precision when printing
|
|
- // a double to a Message.
|
|
- *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
|
|
-}
|
|
-
|
|
-// These two overloads allow streaming a wide C string to a Message
|
|
-// using the UTF-8 encoding.
|
|
-Message& Message::operator<<(const wchar_t* wide_c_str) {
|
|
- return *this << internal::String::ShowWideCString(wide_c_str);
|
|
-}
|
|
-Message& Message::operator<<(wchar_t* wide_c_str) {
|
|
- return *this << internal::String::ShowWideCString(wide_c_str);
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_STD_WSTRING
|
|
-// Converts the given wide string to a narrow string using the UTF-8
|
|
-// encoding, and streams the result to this Message object.
|
|
-Message& Message::operator<<(const ::std::wstring& wstr) {
|
|
- internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
|
|
- return *this;
|
|
-}
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-// Gets the text streamed to this object so far as an std::string.
|
|
-// Each '\0' character in the buffer is replaced with "\\0".
|
|
-std::string Message::GetString() const {
|
|
- return internal::StringStreamToString(ss_.get());
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-namespace edit_distance {
|
|
-std::vector<EditType> CalculateOptimalEdits(const std::vector<size_t>& left,
|
|
- const std::vector<size_t>& right) {
|
|
- std::vector<std::vector<double> > costs(
|
|
- left.size() + 1, std::vector<double>(right.size() + 1));
|
|
- std::vector<std::vector<EditType> > best_move(
|
|
- left.size() + 1, std::vector<EditType>(right.size() + 1));
|
|
-
|
|
- // Populate for empty right.
|
|
- for (size_t l_i = 0; l_i < costs.size(); ++l_i) {
|
|
- costs[l_i][0] = static_cast<double>(l_i);
|
|
- best_move[l_i][0] = kRemove;
|
|
- }
|
|
- // Populate for empty left.
|
|
- for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) {
|
|
- costs[0][r_i] = static_cast<double>(r_i);
|
|
- best_move[0][r_i] = kAdd;
|
|
- }
|
|
-
|
|
- for (size_t l_i = 0; l_i < left.size(); ++l_i) {
|
|
- for (size_t r_i = 0; r_i < right.size(); ++r_i) {
|
|
- if (left[l_i] == right[r_i]) {
|
|
- // Found a match. Consume it.
|
|
- costs[l_i + 1][r_i + 1] = costs[l_i][r_i];
|
|
- best_move[l_i + 1][r_i + 1] = kMatch;
|
|
- continue;
|
|
- }
|
|
-
|
|
- const double add = costs[l_i + 1][r_i];
|
|
- const double remove = costs[l_i][r_i + 1];
|
|
- const double replace = costs[l_i][r_i];
|
|
- if (add < remove && add < replace) {
|
|
- costs[l_i + 1][r_i + 1] = add + 1;
|
|
- best_move[l_i + 1][r_i + 1] = kAdd;
|
|
- } else if (remove < add && remove < replace) {
|
|
- costs[l_i + 1][r_i + 1] = remove + 1;
|
|
- best_move[l_i + 1][r_i + 1] = kRemove;
|
|
- } else {
|
|
- // We make replace a little more expensive than add/remove to lower
|
|
- // their priority.
|
|
- costs[l_i + 1][r_i + 1] = replace + 1.00001;
|
|
- best_move[l_i + 1][r_i + 1] = kReplace;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- // Reconstruct the best path. We do it in reverse order.
|
|
- std::vector<EditType> best_path;
|
|
- for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) {
|
|
- EditType move = best_move[l_i][r_i];
|
|
- best_path.push_back(move);
|
|
- l_i -= move != kAdd;
|
|
- r_i -= move != kRemove;
|
|
- }
|
|
- std::reverse(best_path.begin(), best_path.end());
|
|
- return best_path;
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-// Helper class to convert string into ids with deduplication.
|
|
-class InternalStrings {
|
|
- public:
|
|
- size_t GetId(const std::string& str) {
|
|
- IdMap::iterator it = ids_.find(str);
|
|
- if (it != ids_.end()) return it->second;
|
|
- size_t id = ids_.size();
|
|
- return ids_[str] = id;
|
|
- }
|
|
-
|
|
- private:
|
|
- typedef std::map<std::string, size_t> IdMap;
|
|
- IdMap ids_;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-std::vector<EditType> CalculateOptimalEdits(
|
|
- const std::vector<std::string>& left,
|
|
- const std::vector<std::string>& right) {
|
|
- std::vector<size_t> left_ids, right_ids;
|
|
- {
|
|
- InternalStrings intern_table;
|
|
- for (size_t i = 0; i < left.size(); ++i) {
|
|
- left_ids.push_back(intern_table.GetId(left[i]));
|
|
- }
|
|
- for (size_t i = 0; i < right.size(); ++i) {
|
|
- right_ids.push_back(intern_table.GetId(right[i]));
|
|
- }
|
|
- }
|
|
- return CalculateOptimalEdits(left_ids, right_ids);
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-// Helper class that holds the state for one hunk and prints it out to the
|
|
-// stream.
|
|
-// It reorders adds/removes when possible to group all removes before all
|
|
-// adds. It also adds the hunk header before printint into the stream.
|
|
-class Hunk {
|
|
- public:
|
|
- Hunk(size_t left_start, size_t right_start)
|
|
- : left_start_(left_start),
|
|
- right_start_(right_start),
|
|
- adds_(),
|
|
- removes_(),
|
|
- common_() {}
|
|
-
|
|
- void PushLine(char edit, const char* line) {
|
|
- switch (edit) {
|
|
- case ' ':
|
|
- ++common_;
|
|
- FlushEdits();
|
|
- hunk_.push_back(std::make_pair(' ', line));
|
|
- break;
|
|
- case '-':
|
|
- ++removes_;
|
|
- hunk_removes_.push_back(std::make_pair('-', line));
|
|
- break;
|
|
- case '+':
|
|
- ++adds_;
|
|
- hunk_adds_.push_back(std::make_pair('+', line));
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- void PrintTo(std::ostream* os) {
|
|
- PrintHeader(os);
|
|
- FlushEdits();
|
|
- for (std::list<std::pair<char, const char*> >::const_iterator it =
|
|
- hunk_.begin();
|
|
- it != hunk_.end(); ++it) {
|
|
- *os << it->first << it->second << "\n";
|
|
- }
|
|
- }
|
|
-
|
|
- bool has_edits() const { return adds_ || removes_; }
|
|
-
|
|
- private:
|
|
- void FlushEdits() {
|
|
- hunk_.splice(hunk_.end(), hunk_removes_);
|
|
- hunk_.splice(hunk_.end(), hunk_adds_);
|
|
- }
|
|
-
|
|
- // Print a unified diff header for one hunk.
|
|
- // The format is
|
|
- // "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
|
|
- // where the left/right parts are omitted if unnecessary.
|
|
- void PrintHeader(std::ostream* ss) const {
|
|
- *ss << "@@ ";
|
|
- if (removes_) {
|
|
- *ss << "-" << left_start_ << "," << (removes_ + common_);
|
|
- }
|
|
- if (removes_ && adds_) {
|
|
- *ss << " ";
|
|
- }
|
|
- if (adds_) {
|
|
- *ss << "+" << right_start_ << "," << (adds_ + common_);
|
|
- }
|
|
- *ss << " @@\n";
|
|
- }
|
|
-
|
|
- size_t left_start_, right_start_;
|
|
- size_t adds_, removes_, common_;
|
|
- std::list<std::pair<char, const char*> > hunk_, hunk_adds_, hunk_removes_;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-// Create a list of diff hunks in Unified diff format.
|
|
-// Each hunk has a header generated by PrintHeader above plus a body with
|
|
-// lines prefixed with ' ' for no change, '-' for deletion and '+' for
|
|
-// addition.
|
|
-// 'context' represents the desired unchanged prefix/suffix around the diff.
|
|
-// If two hunks are close enough that their contexts overlap, then they are
|
|
-// joined into one hunk.
|
|
-std::string CreateUnifiedDiff(const std::vector<std::string>& left,
|
|
- const std::vector<std::string>& right,
|
|
- size_t context) {
|
|
- const std::vector<EditType> edits = CalculateOptimalEdits(left, right);
|
|
-
|
|
- size_t l_i = 0, r_i = 0, edit_i = 0;
|
|
- std::stringstream ss;
|
|
- while (edit_i < edits.size()) {
|
|
- // Find first edit.
|
|
- while (edit_i < edits.size() && edits[edit_i] == kMatch) {
|
|
- ++l_i;
|
|
- ++r_i;
|
|
- ++edit_i;
|
|
- }
|
|
-
|
|
- // Find the first line to include in the hunk.
|
|
- const size_t prefix_context = std::min(l_i, context);
|
|
- Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1);
|
|
- for (size_t i = prefix_context; i > 0; --i) {
|
|
- hunk.PushLine(' ', left[l_i - i].c_str());
|
|
- }
|
|
-
|
|
- // Iterate the edits until we found enough suffix for the hunk or the input
|
|
- // is over.
|
|
- size_t n_suffix = 0;
|
|
- for (; edit_i < edits.size(); ++edit_i) {
|
|
- if (n_suffix >= context) {
|
|
- // Continue only if the next hunk is very close.
|
|
- auto it = edits.begin() + static_cast<int>(edit_i);
|
|
- while (it != edits.end() && *it == kMatch) ++it;
|
|
- if (it == edits.end() ||
|
|
- static_cast<size_t>(it - edits.begin()) - edit_i >= context) {
|
|
- // There is no next edit or it is too far away.
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- EditType edit = edits[edit_i];
|
|
- // Reset count when a non match is found.
|
|
- n_suffix = edit == kMatch ? n_suffix + 1 : 0;
|
|
-
|
|
- if (edit == kMatch || edit == kRemove || edit == kReplace) {
|
|
- hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str());
|
|
- }
|
|
- if (edit == kAdd || edit == kReplace) {
|
|
- hunk.PushLine('+', right[r_i].c_str());
|
|
- }
|
|
-
|
|
- // Advance indices, depending on edit type.
|
|
- l_i += edit != kAdd;
|
|
- r_i += edit != kRemove;
|
|
- }
|
|
-
|
|
- if (!hunk.has_edits()) {
|
|
- // We are done. We don't want this hunk.
|
|
- break;
|
|
- }
|
|
-
|
|
- hunk.PrintTo(&ss);
|
|
- }
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-} // namespace edit_distance
|
|
-
|
|
-namespace {
|
|
-
|
|
-// The string representation of the values received in EqFailure() are already
|
|
-// escaped. Split them on escaped '\n' boundaries. Leave all other escaped
|
|
-// characters the same.
|
|
-std::vector<std::string> SplitEscapedString(const std::string& str) {
|
|
- std::vector<std::string> lines;
|
|
- size_t start = 0, end = str.size();
|
|
- if (end > 2 && str[0] == '"' && str[end - 1] == '"') {
|
|
- ++start;
|
|
- --end;
|
|
- }
|
|
- bool escaped = false;
|
|
- for (size_t i = start; i + 1 < end; ++i) {
|
|
- if (escaped) {
|
|
- escaped = false;
|
|
- if (str[i] == 'n') {
|
|
- lines.push_back(str.substr(start, i - start - 1));
|
|
- start = i + 1;
|
|
- }
|
|
- } else {
|
|
- escaped = str[i] == '\\';
|
|
- }
|
|
- }
|
|
- lines.push_back(str.substr(start, end - start));
|
|
- return lines;
|
|
-}
|
|
-
|
|
-} // namespace
|
|
-
|
|
-// Constructs and returns the message for an equality assertion
|
|
-// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
|
|
-//
|
|
-// The first four parameters are the expressions used in the assertion
|
|
-// and their values, as strings. For example, for ASSERT_EQ(foo, bar)
|
|
-// where foo is 5 and bar is 6, we have:
|
|
-//
|
|
-// lhs_expression: "foo"
|
|
-// rhs_expression: "bar"
|
|
-// lhs_value: "5"
|
|
-// rhs_value: "6"
|
|
-//
|
|
-// 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.
|
|
-AssertionResult EqFailure(const char* lhs_expression,
|
|
- const char* rhs_expression,
|
|
- const std::string& lhs_value,
|
|
- const std::string& rhs_value, bool ignoring_case) {
|
|
- Message msg;
|
|
- msg << "Expected equality of these values:";
|
|
- msg << "\n " << lhs_expression;
|
|
- if (lhs_value != lhs_expression) {
|
|
- msg << "\n Which is: " << lhs_value;
|
|
- }
|
|
- msg << "\n " << rhs_expression;
|
|
- if (rhs_value != rhs_expression) {
|
|
- msg << "\n Which is: " << rhs_value;
|
|
- }
|
|
-
|
|
- if (ignoring_case) {
|
|
- msg << "\nIgnoring case";
|
|
- }
|
|
-
|
|
- if (!lhs_value.empty() && !rhs_value.empty()) {
|
|
- const std::vector<std::string> lhs_lines = SplitEscapedString(lhs_value);
|
|
- const std::vector<std::string> rhs_lines = SplitEscapedString(rhs_value);
|
|
- if (lhs_lines.size() > 1 || rhs_lines.size() > 1) {
|
|
- msg << "\nWith diff:\n"
|
|
- << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines);
|
|
- }
|
|
- }
|
|
-
|
|
- return AssertionFailure() << msg;
|
|
-}
|
|
-
|
|
-// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
|
|
-std::string GetBoolAssertionFailureMessage(
|
|
- const AssertionResult& assertion_result, const char* expression_text,
|
|
- const char* actual_predicate_value, const char* expected_predicate_value) {
|
|
- const char* actual_message = assertion_result.message();
|
|
- Message msg;
|
|
- msg << "Value of: " << expression_text
|
|
- << "\n Actual: " << actual_predicate_value;
|
|
- if (actual_message[0] != '\0') msg << " (" << actual_message << ")";
|
|
- msg << "\nExpected: " << expected_predicate_value;
|
|
- return msg.GetString();
|
|
-}
|
|
-
|
|
-// Helper function for implementing ASSERT_NEAR.
|
|
-AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2,
|
|
- const char* abs_error_expr, double val1,
|
|
- double val2, double abs_error) {
|
|
- const double diff = fabs(val1 - val2);
|
|
- if (diff <= abs_error) return AssertionSuccess();
|
|
-
|
|
- // Find the value which is closest to zero.
|
|
- const double min_abs = std::min(fabs(val1), fabs(val2));
|
|
- // Find the distance to the next double from that value.
|
|
- const double epsilon =
|
|
- nextafter(min_abs, std::numeric_limits<double>::infinity()) - min_abs;
|
|
- // Detect the case where abs_error is so small that EXPECT_NEAR is
|
|
- // effectively the same as EXPECT_EQUAL, and give an informative error
|
|
- // message so that the situation can be more easily understood without
|
|
- // requiring exotic floating-point knowledge.
|
|
- // Don't do an epsilon check if abs_error is zero because that implies
|
|
- // that an equality check was actually intended.
|
|
- if (!(std::isnan)(val1) && !(std::isnan)(val2) && abs_error > 0 &&
|
|
- abs_error < epsilon) {
|
|
- return AssertionFailure()
|
|
- << "The difference between " << expr1 << " and " << expr2 << " is "
|
|
- << diff << ", where\n"
|
|
- << expr1 << " evaluates to " << val1 << ",\n"
|
|
- << expr2 << " evaluates to " << val2 << ".\nThe abs_error parameter "
|
|
- << abs_error_expr << " evaluates to " << abs_error
|
|
- << " which is smaller than the minimum distance between doubles for "
|
|
- "numbers of this magnitude which is "
|
|
- << epsilon
|
|
- << ", thus making this EXPECT_NEAR check equivalent to "
|
|
- "EXPECT_EQUAL. Consider using EXPECT_DOUBLE_EQ instead.";
|
|
- }
|
|
- return AssertionFailure()
|
|
- << "The difference between " << expr1 << " and " << expr2 << " is "
|
|
- << diff << ", which exceeds " << abs_error_expr << ", where\n"
|
|
- << expr1 << " evaluates to " << val1 << ",\n"
|
|
- << expr2 << " evaluates to " << val2 << ", and\n"
|
|
- << abs_error_expr << " evaluates to " << abs_error << ".";
|
|
-}
|
|
-
|
|
-// Helper template for implementing FloatLE() and DoubleLE().
|
|
-template <typename RawType>
|
|
-AssertionResult FloatingPointLE(const char* expr1, const char* expr2,
|
|
- RawType val1, RawType val2) {
|
|
- // Returns success if val1 is less than val2,
|
|
- if (val1 < val2) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- // or if val1 is almost equal to val2.
|
|
- const FloatingPoint<RawType> lhs(val1), rhs(val2);
|
|
- if (lhs.AlmostEquals(rhs)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- // Note that the above two checks will both fail if either val1 or
|
|
- // val2 is NaN, as the IEEE floating-point standard requires that
|
|
- // any predicate involving a NaN must return false.
|
|
-
|
|
- ::std::stringstream val1_ss;
|
|
- val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
|
- << val1;
|
|
-
|
|
- ::std::stringstream val2_ss;
|
|
- val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
|
|
- << val2;
|
|
-
|
|
- return AssertionFailure()
|
|
- << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n"
|
|
- << " Actual: " << StringStreamToString(&val1_ss) << " vs "
|
|
- << StringStreamToString(&val2_ss);
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Asserts that val1 is less than, or almost equal to, val2. Fails
|
|
-// otherwise. In particular, it fails if either val1 or val2 is NaN.
|
|
-AssertionResult FloatLE(const char* expr1, const char* expr2, float val1,
|
|
- float val2) {
|
|
- return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);
|
|
-}
|
|
-
|
|
-// Asserts that val1 is less than, or almost equal to, val2. Fails
|
|
-// otherwise. In particular, it fails if either val1 or val2 is NaN.
|
|
-AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1,
|
|
- double val2) {
|
|
- return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STREQ.
|
|
-AssertionResult CmpHelperSTREQ(const char* lhs_expression,
|
|
- const char* rhs_expression, const char* lhs,
|
|
- const char* rhs) {
|
|
- if (String::CStringEquals(lhs, rhs)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),
|
|
- PrintToString(rhs), false);
|
|
-}
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
|
|
-AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,
|
|
- const char* rhs_expression, const char* lhs,
|
|
- const char* rhs) {
|
|
- if (String::CaseInsensitiveCStringEquals(lhs, rhs)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),
|
|
- PrintToString(rhs), true);
|
|
-}
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STRNE.
|
|
-AssertionResult CmpHelperSTRNE(const char* s1_expression,
|
|
- const char* s2_expression, const char* s1,
|
|
- const char* s2) {
|
|
- if (!String::CStringEquals(s1, s2)) {
|
|
- return AssertionSuccess();
|
|
- } else {
|
|
- return AssertionFailure()
|
|
- << "Expected: (" << s1_expression << ") != (" << s2_expression
|
|
- << "), actual: \"" << s1 << "\" vs \"" << s2 << "\"";
|
|
- }
|
|
-}
|
|
-
|
|
-// The helper function for {ASSERT|EXPECT}_STRCASENE.
|
|
-AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
|
|
- const char* s2_expression, const char* s1,
|
|
- const char* s2) {
|
|
- if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
|
|
- return AssertionSuccess();
|
|
- } else {
|
|
- return AssertionFailure()
|
|
- << "Expected: (" << s1_expression << ") != (" << s2_expression
|
|
- << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\"";
|
|
- }
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-namespace {
|
|
-
|
|
-// Helper functions for implementing IsSubString() and IsNotSubstring().
|
|
-
|
|
-// This group of overloaded functions return true if and only if needle
|
|
-// is a substring of haystack. NULL is considered a substring of
|
|
-// itself only.
|
|
-
|
|
-bool IsSubstringPred(const char* needle, const char* haystack) {
|
|
- if (needle == nullptr || haystack == nullptr) return needle == haystack;
|
|
-
|
|
- return strstr(haystack, needle) != nullptr;
|
|
-}
|
|
-
|
|
-bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
|
|
- if (needle == nullptr || haystack == nullptr) return needle == haystack;
|
|
-
|
|
- return wcsstr(haystack, needle) != nullptr;
|
|
-}
|
|
-
|
|
-// StringType here can be either ::std::string or ::std::wstring.
|
|
-template <typename StringType>
|
|
-bool IsSubstringPred(const StringType& needle, const StringType& haystack) {
|
|
- return haystack.find(needle) != StringType::npos;
|
|
-}
|
|
-
|
|
-// This function implements either IsSubstring() or IsNotSubstring(),
|
|
-// depending on the value of the expected_to_be_substring parameter.
|
|
-// StringType here can be const char*, const wchar_t*, ::std::string,
|
|
-// or ::std::wstring.
|
|
-template <typename StringType>
|
|
-AssertionResult IsSubstringImpl(bool expected_to_be_substring,
|
|
- const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const StringType& needle,
|
|
- const StringType& haystack) {
|
|
- if (IsSubstringPred(needle, haystack) == expected_to_be_substring)
|
|
- return AssertionSuccess();
|
|
-
|
|
- const bool is_wide_string = sizeof(needle[0]) > 1;
|
|
- const char* const begin_string_quote = is_wide_string ? "L\"" : "\"";
|
|
- return AssertionFailure()
|
|
- << "Value of: " << needle_expr << "\n"
|
|
- << " Actual: " << begin_string_quote << needle << "\"\n"
|
|
- << "Expected: " << (expected_to_be_substring ? "" : "not ")
|
|
- << "a substring of " << haystack_expr << "\n"
|
|
- << "Which is: " << begin_string_quote << haystack << "\"";
|
|
-}
|
|
-
|
|
-} // namespace
|
|
-
|
|
-// IsSubstring() and IsNotSubstring() check whether needle is a
|
|
-// substring of haystack (NULL is considered a substring of itself
|
|
-// only), and return an appropriate error message when they fail.
|
|
-
|
|
-AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
|
|
- const char* needle, const char* haystack) {
|
|
- return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
|
|
- const wchar_t* needle, const wchar_t* haystack) {
|
|
- return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr, const char* needle,
|
|
- const char* haystack) {
|
|
- return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr, const wchar_t* needle,
|
|
- const wchar_t* haystack) {
|
|
- return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
|
|
- const ::std::string& needle,
|
|
- const ::std::string& haystack) {
|
|
- return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const ::std::string& needle,
|
|
- const ::std::string& haystack) {
|
|
- return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_STD_WSTRING
|
|
-AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
|
|
- const ::std::wstring& needle,
|
|
- const ::std::wstring& haystack) {
|
|
- return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-
|
|
-AssertionResult IsNotSubstring(const char* needle_expr,
|
|
- const char* haystack_expr,
|
|
- const ::std::wstring& needle,
|
|
- const ::std::wstring& haystack) {
|
|
- return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
|
|
-}
|
|
-#endif // GTEST_HAS_STD_WSTRING
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
-
|
|
-namespace {
|
|
-
|
|
-// Helper function for IsHRESULT{SuccessFailure} predicates
|
|
-AssertionResult HRESULTFailureHelper(const char* expr, const char* expected,
|
|
- long hr) { // NOLINT
|
|
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE
|
|
-
|
|
- // Windows CE doesn't support FormatMessage.
|
|
- const char error_text[] = "";
|
|
-
|
|
-#else
|
|
-
|
|
- // Looks up the human-readable system message for the HRESULT code
|
|
- // and since we're not passing any params to FormatMessage, we don't
|
|
- // want inserts expanded.
|
|
- const DWORD kFlags =
|
|
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
- const DWORD kBufSize = 4096;
|
|
- // Gets the system's human readable message string for this HRESULT.
|
|
- char error_text[kBufSize] = {'\0'};
|
|
- DWORD message_length = ::FormatMessageA(kFlags,
|
|
- 0, // no source, we're asking system
|
|
- static_cast<DWORD>(hr), // the error
|
|
- 0, // no line width restrictions
|
|
- error_text, // output buffer
|
|
- kBufSize, // buf size
|
|
- nullptr); // no arguments for inserts
|
|
- // Trims tailing white space (FormatMessage leaves a trailing CR-LF)
|
|
- for (; message_length && IsSpace(error_text[message_length - 1]);
|
|
- --message_length) {
|
|
- error_text[message_length - 1] = '\0';
|
|
- }
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
- const std::string error_hex("0x" + String::FormatHexInt(hr));
|
|
- return ::testing::AssertionFailure()
|
|
- << "Expected: " << expr << " " << expected << ".\n"
|
|
- << " Actual: " << error_hex << " " << error_text << "\n";
|
|
-}
|
|
-
|
|
-} // namespace
|
|
-
|
|
-AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT
|
|
- if (SUCCEEDED(hr)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
- return HRESULTFailureHelper(expr, "succeeds", hr);
|
|
-}
|
|
-
|
|
-AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT
|
|
- if (FAILED(hr)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
- return HRESULTFailureHelper(expr, "fails", hr);
|
|
-}
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
-// Utility functions for encoding Unicode text (wide strings) in
|
|
-// UTF-8.
|
|
-
|
|
-// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8
|
|
-// like this:
|
|
-//
|
|
-// Code-point length Encoding
|
|
-// 0 - 7 bits 0xxxxxxx
|
|
-// 8 - 11 bits 110xxxxx 10xxxxxx
|
|
-// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx
|
|
-// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
-
|
|
-// The maximum code-point a one-byte UTF-8 sequence can represent.
|
|
-constexpr uint32_t kMaxCodePoint1 = (static_cast<uint32_t>(1) << 7) - 1;
|
|
-
|
|
-// The maximum code-point a two-byte UTF-8 sequence can represent.
|
|
-constexpr uint32_t kMaxCodePoint2 = (static_cast<uint32_t>(1) << (5 + 6)) - 1;
|
|
-
|
|
-// The maximum code-point a three-byte UTF-8 sequence can represent.
|
|
-constexpr uint32_t kMaxCodePoint3 =
|
|
- (static_cast<uint32_t>(1) << (4 + 2 * 6)) - 1;
|
|
-
|
|
-// The maximum code-point a four-byte UTF-8 sequence can represent.
|
|
-constexpr uint32_t kMaxCodePoint4 =
|
|
- (static_cast<uint32_t>(1) << (3 + 3 * 6)) - 1;
|
|
-
|
|
-// Chops off the n lowest bits from a bit pattern. Returns the n
|
|
-// lowest bits. As a side effect, the original bit pattern will be
|
|
-// shifted to the right by n bits.
|
|
-inline uint32_t ChopLowBits(uint32_t* bits, int n) {
|
|
- const uint32_t low_bits = *bits & ((static_cast<uint32_t>(1) << n) - 1);
|
|
- *bits >>= n;
|
|
- return low_bits;
|
|
-}
|
|
-
|
|
-// Converts a Unicode code point to a narrow string in UTF-8 encoding.
|
|
-// code_point parameter is of type uint32_t because wchar_t may not be
|
|
-// wide enough to contain a code point.
|
|
-// If the code_point is not a valid Unicode code point
|
|
-// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted
|
|
-// to "(Invalid Unicode 0xXXXXXXXX)".
|
|
-std::string CodePointToUtf8(uint32_t code_point) {
|
|
- if (code_point > kMaxCodePoint4) {
|
|
- return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")";
|
|
- }
|
|
-
|
|
- char str[5]; // Big enough for the largest valid code point.
|
|
- if (code_point <= kMaxCodePoint1) {
|
|
- str[1] = '\0';
|
|
- str[0] = static_cast<char>(code_point); // 0xxxxxxx
|
|
- } else if (code_point <= kMaxCodePoint2) {
|
|
- str[2] = '\0';
|
|
- str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
|
|
- str[0] = static_cast<char>(0xC0 | code_point); // 110xxxxx
|
|
- } else if (code_point <= kMaxCodePoint3) {
|
|
- str[3] = '\0';
|
|
- str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
|
|
- str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
|
|
- str[0] = static_cast<char>(0xE0 | code_point); // 1110xxxx
|
|
- } else { // code_point <= kMaxCodePoint4
|
|
- str[4] = '\0';
|
|
- str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
|
|
- str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
|
|
- str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx
|
|
- str[0] = static_cast<char>(0xF0 | code_point); // 11110xxx
|
|
- }
|
|
- return str;
|
|
-}
|
|
-
|
|
-// The following two functions only make sense if the system
|
|
-// uses UTF-16 for wide string encoding. All supported systems
|
|
-// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16.
|
|
-
|
|
-// Determines if the arguments constitute UTF-16 surrogate pair
|
|
-// and thus should be combined into a single Unicode code point
|
|
-// using CreateCodePointFromUtf16SurrogatePair.
|
|
-inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
|
|
- return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 &&
|
|
- (second & 0xFC00) == 0xDC00;
|
|
-}
|
|
-
|
|
-// Creates a Unicode code point from UTF16 surrogate pair.
|
|
-inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,
|
|
- wchar_t second) {
|
|
- const auto first_u = static_cast<uint32_t>(first);
|
|
- const auto second_u = static_cast<uint32_t>(second);
|
|
- const uint32_t mask = (1 << 10) - 1;
|
|
- return (sizeof(wchar_t) == 2)
|
|
- ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000
|
|
- :
|
|
- // This function should not be called when the condition is
|
|
- // false, but we provide a sensible default in case it is.
|
|
- first_u;
|
|
-}
|
|
-
|
|
-// Converts a wide string to a narrow string in UTF-8 encoding.
|
|
-// The wide string is assumed to have the following encoding:
|
|
-// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
|
|
-// UTF-32 if sizeof(wchar_t) == 4 (on Linux)
|
|
-// Parameter str points to a null-terminated wide string.
|
|
-// Parameter num_chars may additionally limit the number
|
|
-// of wchar_t characters processed. -1 is used when the entire string
|
|
-// should be processed.
|
|
-// If the string contains code points that are not valid Unicode code points
|
|
-// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
|
|
-// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
|
|
-// and contains invalid UTF-16 surrogate pairs, values in those pairs
|
|
-// will be encoded as individual Unicode characters from Basic Normal Plane.
|
|
-std::string WideStringToUtf8(const wchar_t* str, int num_chars) {
|
|
- if (num_chars == -1) num_chars = static_cast<int>(wcslen(str));
|
|
-
|
|
- ::std::stringstream stream;
|
|
- for (int i = 0; i < num_chars; ++i) {
|
|
- uint32_t unicode_code_point;
|
|
-
|
|
- if (str[i] == L'\0') {
|
|
- break;
|
|
- } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
|
|
- unicode_code_point =
|
|
- CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]);
|
|
- i++;
|
|
- } else {
|
|
- unicode_code_point = static_cast<uint32_t>(str[i]);
|
|
- }
|
|
-
|
|
- stream << CodePointToUtf8(unicode_code_point);
|
|
- }
|
|
- return StringStreamToString(&stream);
|
|
-}
|
|
-
|
|
-// Converts a wide C string to an std::string using the UTF-8 encoding.
|
|
-// NULL will be converted to "(null)".
|
|
-std::string String::ShowWideCString(const wchar_t* wide_c_str) {
|
|
- if (wide_c_str == nullptr) return "(null)";
|
|
-
|
|
- return internal::WideStringToUtf8(wide_c_str, -1);
|
|
-}
|
|
-
|
|
-// 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.
|
|
-bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) {
|
|
- if (lhs == nullptr) return rhs == nullptr;
|
|
-
|
|
- if (rhs == nullptr) return false;
|
|
-
|
|
- return wcscmp(lhs, rhs) == 0;
|
|
-}
|
|
-
|
|
-// Helper function for *_STREQ on wide strings.
|
|
-AssertionResult CmpHelperSTREQ(const char* lhs_expression,
|
|
- const char* rhs_expression, const wchar_t* lhs,
|
|
- const wchar_t* rhs) {
|
|
- if (String::WideCStringEquals(lhs, rhs)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),
|
|
- PrintToString(rhs), false);
|
|
-}
|
|
-
|
|
-// Helper function for *_STRNE on wide strings.
|
|
-AssertionResult CmpHelperSTRNE(const char* s1_expression,
|
|
- const char* s2_expression, const wchar_t* s1,
|
|
- const wchar_t* s2) {
|
|
- if (!String::WideCStringEquals(s1, s2)) {
|
|
- return AssertionSuccess();
|
|
- }
|
|
-
|
|
- return AssertionFailure()
|
|
- << "Expected: (" << s1_expression << ") != (" << s2_expression
|
|
- << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2);
|
|
-}
|
|
-
|
|
-// 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,
|
|
-// including the empty string.
|
|
-bool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {
|
|
- if (lhs == nullptr) return rhs == nullptr;
|
|
- if (rhs == nullptr) return false;
|
|
- return posix::StrCaseCmp(lhs, rhs) == 0;
|
|
-}
|
|
-
|
|
-// 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,
|
|
-// including the empty string.
|
|
-// NB: The implementations on different platforms slightly differ.
|
|
-// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
|
-// environment variable. On GNU platform this method uses wcscasecmp
|
|
-// which compares according to LC_CTYPE category of the current locale.
|
|
-// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
|
-// current locale.
|
|
-bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
|
- const wchar_t* rhs) {
|
|
- if (lhs == nullptr) return rhs == nullptr;
|
|
-
|
|
- if (rhs == nullptr) return false;
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
- return _wcsicmp(lhs, rhs) == 0;
|
|
-#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID
|
|
- return wcscasecmp(lhs, rhs) == 0;
|
|
-#else
|
|
- // Android, Mac OS X and Cygwin don't define wcscasecmp.
|
|
- // Other unknown OSes may not define it either.
|
|
- wint_t left, right;
|
|
- do {
|
|
- left = towlower(static_cast<wint_t>(*lhs++));
|
|
- right = towlower(static_cast<wint_t>(*rhs++));
|
|
- } while (left && left == right);
|
|
- return left == right;
|
|
-#endif // OS selector
|
|
-}
|
|
-
|
|
-// Returns true if and only if str ends with the given suffix, ignoring case.
|
|
-// Any string is considered to end with an empty suffix.
|
|
-bool String::EndsWithCaseInsensitive(const std::string& str,
|
|
- const std::string& suffix) {
|
|
- const size_t str_len = str.length();
|
|
- const size_t suffix_len = suffix.length();
|
|
- return (str_len >= suffix_len) &&
|
|
- CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len,
|
|
- suffix.c_str());
|
|
-}
|
|
-
|
|
-// Formats an int value as "%02d".
|
|
-std::string String::FormatIntWidth2(int value) {
|
|
- return FormatIntWidthN(value, 2);
|
|
-}
|
|
-
|
|
-// Formats an int value to given width with leading zeros.
|
|
-std::string String::FormatIntWidthN(int value, int width) {
|
|
- std::stringstream ss;
|
|
- ss << std::setfill('0') << std::setw(width) << value;
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-// Formats an int value as "%X".
|
|
-std::string String::FormatHexUInt32(uint32_t value) {
|
|
- std::stringstream ss;
|
|
- ss << std::hex << std::uppercase << value;
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-// Formats an int value as "%X".
|
|
-std::string String::FormatHexInt(int value) {
|
|
- return FormatHexUInt32(static_cast<uint32_t>(value));
|
|
-}
|
|
-
|
|
-// Formats a byte as "%02X".
|
|
-std::string String::FormatByte(unsigned char value) {
|
|
- std::stringstream ss;
|
|
- ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase
|
|
- << static_cast<unsigned int>(value);
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-// Converts the buffer in a stringstream to an std::string, converting NUL
|
|
-// bytes to "\\0" along the way.
|
|
-std::string StringStreamToString(::std::stringstream* ss) {
|
|
- const ::std::string& str = ss->str();
|
|
- const char* const start = str.c_str();
|
|
- const char* const end = start + str.length();
|
|
-
|
|
- std::string result;
|
|
- result.reserve(static_cast<size_t>(2 * (end - start)));
|
|
- for (const char* ch = start; ch != end; ++ch) {
|
|
- if (*ch == '\0') {
|
|
- result += "\\0"; // Replaces NUL with "\\0";
|
|
- } else {
|
|
- result += *ch;
|
|
- }
|
|
- }
|
|
-
|
|
- return result;
|
|
-}
|
|
-
|
|
-// Appends the user-supplied message to the Google-Test-generated message.
|
|
-std::string AppendUserMessage(const std::string& gtest_msg,
|
|
- const Message& user_msg) {
|
|
- // Appends the user message if it's non-empty.
|
|
- const std::string user_msg_string = user_msg.GetString();
|
|
- if (user_msg_string.empty()) {
|
|
- return gtest_msg;
|
|
- }
|
|
- if (gtest_msg.empty()) {
|
|
- return user_msg_string;
|
|
- }
|
|
- return gtest_msg + "\n" + user_msg_string;
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// class TestResult
|
|
-
|
|
-// Creates an empty TestResult.
|
|
-TestResult::TestResult()
|
|
- : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {}
|
|
-
|
|
-// D'tor.
|
|
-TestResult::~TestResult() {}
|
|
-
|
|
-// 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& TestResult::GetTestPartResult(int i) const {
|
|
- if (i < 0 || i >= total_part_count()) internal::posix::Abort();
|
|
- return test_part_results_.at(static_cast<size_t>(i));
|
|
-}
|
|
-
|
|
-// Returns the i-th test property. i can range from 0 to
|
|
-// test_property_count() - 1. If i is not in that range, aborts the
|
|
-// program.
|
|
-const TestProperty& TestResult::GetTestProperty(int i) const {
|
|
- if (i < 0 || i >= test_property_count()) internal::posix::Abort();
|
|
- return test_properties_.at(static_cast<size_t>(i));
|
|
-}
|
|
-
|
|
-// Clears the test part results.
|
|
-void TestResult::ClearTestPartResults() { test_part_results_.clear(); }
|
|
-
|
|
-// Adds a test part result to the list.
|
|
-void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
|
|
- test_part_results_.push_back(test_part_result);
|
|
-}
|
|
-
|
|
-// Adds a test property to the list. If a property with the same key as the
|
|
-// supplied property is already represented, the value of this test_property
|
|
-// replaces the old value for that key.
|
|
-void TestResult::RecordProperty(const std::string& xml_element,
|
|
- const TestProperty& test_property) {
|
|
- if (!ValidateTestProperty(xml_element, test_property)) {
|
|
- return;
|
|
- }
|
|
- internal::MutexLock lock(&test_properties_mutex_);
|
|
- const std::vector<TestProperty>::iterator property_with_matching_key =
|
|
- std::find_if(test_properties_.begin(), test_properties_.end(),
|
|
- internal::TestPropertyKeyIs(test_property.key()));
|
|
- if (property_with_matching_key == test_properties_.end()) {
|
|
- test_properties_.push_back(test_property);
|
|
- return;
|
|
- }
|
|
- property_with_matching_key->SetValue(test_property.value());
|
|
-}
|
|
-
|
|
-// The list of reserved attributes used in the <testsuites> element of XML
|
|
-// output.
|
|
-static const char* const kReservedTestSuitesAttributes[] = {
|
|
- "disabled", "errors", "failures", "name",
|
|
- "random_seed", "tests", "time", "timestamp"};
|
|
-
|
|
-// The list of reserved attributes used in the <testsuite> element of XML
|
|
-// output.
|
|
-static const char* const kReservedTestSuiteAttributes[] = {
|
|
- "disabled", "errors", "failures", "name",
|
|
- "tests", "time", "timestamp", "skipped"};
|
|
-
|
|
-// The list of reserved attributes used in the <testcase> element of XML output.
|
|
-static const char* const kReservedTestCaseAttributes[] = {
|
|
- "classname", "name", "status", "time",
|
|
- "type_param", "value_param", "file", "line"};
|
|
-
|
|
-// Use a slightly different set for allowed output to ensure existing tests can
|
|
-// still RecordProperty("result") or "RecordProperty(timestamp")
|
|
-static const char* const kReservedOutputTestCaseAttributes[] = {
|
|
- "classname", "name", "status", "time", "type_param",
|
|
- "value_param", "file", "line", "result", "timestamp"};
|
|
-
|
|
-template <size_t kSize>
|
|
-std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
|
|
- return std::vector<std::string>(array, array + kSize);
|
|
-}
|
|
-
|
|
-static std::vector<std::string> GetReservedAttributesForElement(
|
|
- const std::string& xml_element) {
|
|
- if (xml_element == "testsuites") {
|
|
- return ArrayAsVector(kReservedTestSuitesAttributes);
|
|
- } else if (xml_element == "testsuite") {
|
|
- return ArrayAsVector(kReservedTestSuiteAttributes);
|
|
- } else if (xml_element == "testcase") {
|
|
- return ArrayAsVector(kReservedTestCaseAttributes);
|
|
- } else {
|
|
- GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element;
|
|
- }
|
|
- // This code is unreachable but some compilers may not realizes that.
|
|
- return std::vector<std::string>();
|
|
-}
|
|
-
|
|
-// TODO(jdesprez): Merge the two getReserved attributes once skip is improved
|
|
-static std::vector<std::string> GetReservedOutputAttributesForElement(
|
|
- const std::string& xml_element) {
|
|
- if (xml_element == "testsuites") {
|
|
- return ArrayAsVector(kReservedTestSuitesAttributes);
|
|
- } else if (xml_element == "testsuite") {
|
|
- return ArrayAsVector(kReservedTestSuiteAttributes);
|
|
- } else if (xml_element == "testcase") {
|
|
- return ArrayAsVector(kReservedOutputTestCaseAttributes);
|
|
- } else {
|
|
- GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element;
|
|
- }
|
|
- // This code is unreachable but some compilers may not realizes that.
|
|
- return std::vector<std::string>();
|
|
-}
|
|
-
|
|
-static std::string FormatWordList(const std::vector<std::string>& words) {
|
|
- Message word_list;
|
|
- for (size_t i = 0; i < words.size(); ++i) {
|
|
- if (i > 0 && words.size() > 2) {
|
|
- word_list << ", ";
|
|
- }
|
|
- if (i == words.size() - 1) {
|
|
- word_list << "and ";
|
|
- }
|
|
- word_list << "'" << words[i] << "'";
|
|
- }
|
|
- return word_list.GetString();
|
|
-}
|
|
-
|
|
-static bool ValidateTestPropertyName(
|
|
- const std::string& property_name,
|
|
- const std::vector<std::string>& reserved_names) {
|
|
- if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=
|
|
- reserved_names.end()) {
|
|
- ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name
|
|
- << " (" << FormatWordList(reserved_names)
|
|
- << " are reserved by " << GTEST_NAME_ << ")";
|
|
- return false;
|
|
- }
|
|
- return true;
|
|
-}
|
|
-
|
|
-// Adds a failure if the key is a reserved attribute of the element named
|
|
-// xml_element. Returns true if the property is valid.
|
|
-bool TestResult::ValidateTestProperty(const std::string& xml_element,
|
|
- const TestProperty& test_property) {
|
|
- return ValidateTestPropertyName(test_property.key(),
|
|
- GetReservedAttributesForElement(xml_element));
|
|
-}
|
|
-
|
|
-// Clears the object.
|
|
-void TestResult::Clear() {
|
|
- test_part_results_.clear();
|
|
- test_properties_.clear();
|
|
- death_test_count_ = 0;
|
|
- elapsed_time_ = 0;
|
|
-}
|
|
-
|
|
-// Returns true off the test part was skipped.
|
|
-static bool TestPartSkipped(const TestPartResult& result) {
|
|
- return result.skipped();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test was skipped.
|
|
-bool TestResult::Skipped() const {
|
|
- return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0;
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test failed.
|
|
-bool TestResult::Failed() const {
|
|
- for (int i = 0; i < total_part_count(); ++i) {
|
|
- if (GetTestPartResult(i).failed()) return true;
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test part fatally failed.
|
|
-static bool TestPartFatallyFailed(const TestPartResult& result) {
|
|
- return result.fatally_failed();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test fatally failed.
|
|
-bool TestResult::HasFatalFailure() const {
|
|
- return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test part non-fatally failed.
|
|
-static bool TestPartNonfatallyFailed(const TestPartResult& result) {
|
|
- return result.nonfatally_failed();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the test has a non-fatal failure.
|
|
-bool TestResult::HasNonfatalFailure() const {
|
|
- return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
|
|
-}
|
|
-
|
|
-// Gets the number of all test parts. This is the sum of the number
|
|
-// of successful test parts and the number of failed test parts.
|
|
-int TestResult::total_part_count() const {
|
|
- return static_cast<int>(test_part_results_.size());
|
|
-}
|
|
-
|
|
-// Returns the number of the test properties.
|
|
-int TestResult::test_property_count() const {
|
|
- return static_cast<int>(test_properties_.size());
|
|
-}
|
|
-
|
|
-// class Test
|
|
-
|
|
-// Creates a Test object.
|
|
-
|
|
-// The c'tor saves the states of all flags.
|
|
-Test::Test() : gtest_flag_saver_(new GTEST_FLAG_SAVER_) {}
|
|
-
|
|
-// The d'tor restores the states of all flags. The actual work is
|
|
-// done by the d'tor of the gtest_flag_saver_ field, and thus not
|
|
-// visible here.
|
|
-Test::~Test() {}
|
|
-
|
|
-// Sets up the test fixture.
|
|
-//
|
|
-// A sub-class may override this.
|
|
-void Test::SetUp() {}
|
|
-
|
|
-// Tears down the test fixture.
|
|
-//
|
|
-// A sub-class may override this.
|
|
-void Test::TearDown() {}
|
|
-
|
|
-// Allows user supplied key value pairs to be recorded for later output.
|
|
-void Test::RecordProperty(const std::string& key, const std::string& value) {
|
|
- UnitTest::GetInstance()->RecordProperty(key, value);
|
|
-}
|
|
-
|
|
-// Allows user supplied key value pairs to be recorded for later output.
|
|
-void Test::RecordProperty(const std::string& key, int value) {
|
|
- Message value_message;
|
|
- value_message << value;
|
|
- RecordProperty(key, value_message.GetString().c_str());
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
|
|
- const std::string& message) {
|
|
- // This function is a friend of UnitTest and as such has access to
|
|
- // AddTestPartResult.
|
|
- UnitTest::GetInstance()->AddTestPartResult(
|
|
- result_type,
|
|
- nullptr, // No info about the source file where the exception occurred.
|
|
- -1, // We have no info on which line caused the exception.
|
|
- message,
|
|
- ""); // No stack trace, either.
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Google Test requires all tests in the same test suite to use the same test
|
|
-// fixture class. This function checks if the current test has the
|
|
-// same fixture class as the first test in the current test suite. If
|
|
-// yes, it returns true; otherwise it generates a Google Test failure and
|
|
-// returns false.
|
|
-bool Test::HasSameFixtureClass() {
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- const TestSuite* const test_suite = impl->current_test_suite();
|
|
-
|
|
- // Info about the first test in the current test suite.
|
|
- const TestInfo* const first_test_info = test_suite->test_info_list()[0];
|
|
- const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;
|
|
- const char* const first_test_name = first_test_info->name();
|
|
-
|
|
- // Info about the current test.
|
|
- const TestInfo* const this_test_info = impl->current_test_info();
|
|
- const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;
|
|
- const char* const this_test_name = this_test_info->name();
|
|
-
|
|
- if (this_fixture_id != first_fixture_id) {
|
|
- // Is the first test defined using TEST?
|
|
- const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();
|
|
- // Is this test defined using TEST?
|
|
- const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
|
|
-
|
|
- if (first_is_TEST || this_is_TEST) {
|
|
- // Both TEST and TEST_F appear in same test suite, which is incorrect.
|
|
- // Tell the user how to fix this.
|
|
-
|
|
- // Gets the name of the TEST and the name of the TEST_F. Note
|
|
- // that first_is_TEST and this_is_TEST cannot both be true, as
|
|
- // the fixture IDs are different for the two tests.
|
|
- const char* const TEST_name =
|
|
- first_is_TEST ? first_test_name : this_test_name;
|
|
- const char* const TEST_F_name =
|
|
- first_is_TEST ? this_test_name : first_test_name;
|
|
-
|
|
- ADD_FAILURE()
|
|
- << "All tests in the same test suite must use the same test fixture\n"
|
|
- << "class, so mixing TEST_F and TEST in the same test suite is\n"
|
|
- << "illegal. In test suite " << this_test_info->test_suite_name()
|
|
- << ",\n"
|
|
- << "test " << TEST_F_name << " is defined using TEST_F but\n"
|
|
- << "test " << TEST_name << " is defined using TEST. You probably\n"
|
|
- << "want to change the TEST to TEST_F or move it to another test\n"
|
|
- << "case.";
|
|
- } else {
|
|
- // Two fixture classes with the same name appear in two different
|
|
- // namespaces, which is not allowed. Tell the user how to fix this.
|
|
- ADD_FAILURE()
|
|
- << "All tests in the same test suite must use the same test fixture\n"
|
|
- << "class. However, in test suite "
|
|
- << this_test_info->test_suite_name() << ",\n"
|
|
- << "you defined test " << first_test_name << " and test "
|
|
- << this_test_name << "\n"
|
|
- << "using two different test fixture classes. This can happen if\n"
|
|
- << "the two classes are from different namespaces or translation\n"
|
|
- << "units and have the same name. You should probably rename one\n"
|
|
- << "of the classes to put the tests into different test suites.";
|
|
- }
|
|
- return false;
|
|
- }
|
|
-
|
|
- return true;
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_SEH
|
|
-
|
|
-// Adds an "exception thrown" fatal failure to the current test. This
|
|
-// function returns its result via an output parameter pointer because VC++
|
|
-// prohibits creation of objects with destructors on stack in functions
|
|
-// using __try (see error C2712).
|
|
-static std::string* FormatSehExceptionMessage(DWORD exception_code,
|
|
- const char* location) {
|
|
- Message message;
|
|
- message << "SEH exception with code 0x" << std::setbase(16) << exception_code
|
|
- << std::setbase(10) << " thrown in " << location << ".";
|
|
-
|
|
- return new std::string(message.GetString());
|
|
-}
|
|
-
|
|
-#endif // GTEST_HAS_SEH
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-// Adds an "exception thrown" fatal failure to the current test.
|
|
-static std::string FormatCxxExceptionMessage(const char* description,
|
|
- const char* location) {
|
|
- Message message;
|
|
- if (description != nullptr) {
|
|
- message << "C++ exception with description \"" << description << "\"";
|
|
- } else {
|
|
- message << "Unknown C++ exception";
|
|
- }
|
|
- message << " thrown in " << location << ".";
|
|
-
|
|
- return message.GetString();
|
|
-}
|
|
-
|
|
-static std::string PrintTestPartResultToString(
|
|
- const TestPartResult& test_part_result);
|
|
-
|
|
-GoogleTestFailureException::GoogleTestFailureException(
|
|
- const TestPartResult& failure)
|
|
- : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
|
|
-
|
|
-#endif // GTEST_HAS_EXCEPTIONS
|
|
-
|
|
-// We put these helper functions in the internal namespace as IBM's xlC
|
|
-// compiler rejects the code if they were declared static.
|
|
-
|
|
-// Runs the given method and handles SEH exceptions it throws, when
|
|
-// SEH is supported; returns the 0-value for type Result in case of an
|
|
-// SEH exception. (Microsoft compilers cannot handle SEH and C++
|
|
-// exceptions in the same function. Therefore, we provide a separate
|
|
-// wrapper function for handling SEH exceptions.)
|
|
-template <class T, typename Result>
|
|
-Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
|
|
- const char* location) {
|
|
-#if GTEST_HAS_SEH
|
|
- __try {
|
|
- return (object->*method)();
|
|
- } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT
|
|
- GetExceptionCode())) {
|
|
- // We create the exception message on the heap because VC++ prohibits
|
|
- // creation of objects with destructors on stack in functions using __try
|
|
- // (see error C2712).
|
|
- std::string* exception_message =
|
|
- FormatSehExceptionMessage(GetExceptionCode(), location);
|
|
- internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
|
|
- *exception_message);
|
|
- delete exception_message;
|
|
- return static_cast<Result>(0);
|
|
- }
|
|
-#else
|
|
- (void)location;
|
|
- return (object->*method)();
|
|
-#endif // GTEST_HAS_SEH
|
|
-}
|
|
-
|
|
-// Runs the given method and catches and reports C++ and/or SEH-style
|
|
-// exceptions, if they are supported; returns the 0-value for type
|
|
-// Result in case of an SEH exception.
|
|
-template <class T, typename Result>
|
|
-Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),
|
|
- const char* location) {
|
|
- // NOTE: The user code can affect the way in which Google Test handles
|
|
- // exceptions by setting GTEST_FLAG(catch_exceptions), but only before
|
|
- // RUN_ALL_TESTS() starts. It is technically possible to check the flag
|
|
- // after the exception is caught and either report or re-throw the
|
|
- // exception based on the flag's value:
|
|
- //
|
|
- // try {
|
|
- // // Perform the test method.
|
|
- // } catch (...) {
|
|
- // if (GTEST_FLAG_GET(catch_exceptions))
|
|
- // // Report the exception as failure.
|
|
- // else
|
|
- // throw; // Re-throws the original exception.
|
|
- // }
|
|
- //
|
|
- // However, the purpose of this flag is to allow the program to drop into
|
|
- // the debugger when the exception is thrown. On most platforms, once the
|
|
- // control enters the catch block, the exception origin information is
|
|
- // lost and the debugger will stop the program at the point of the
|
|
- // re-throw in this function -- instead of at the point of the original
|
|
- // throw statement in the code under test. For this reason, we perform
|
|
- // the check early, sacrificing the ability to affect Google Test's
|
|
- // exception handling in the method where the exception is thrown.
|
|
- if (internal::GetUnitTestImpl()->catch_exceptions()) {
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
- try {
|
|
- return HandleSehExceptionsInMethodIfSupported(object, method, location);
|
|
- } catch (const AssertionException&) { // NOLINT
|
|
- // This failure was reported already.
|
|
- } catch (const internal::GoogleTestFailureException&) { // NOLINT
|
|
- // This exception type can only be thrown by a failed Google
|
|
- // Test assertion with the intention of letting another testing
|
|
- // framework catch it. Therefore we just re-throw it.
|
|
- throw;
|
|
- } catch (const std::exception& e) { // NOLINT
|
|
- internal::ReportFailureInUnknownLocation(
|
|
- TestPartResult::kFatalFailure,
|
|
- FormatCxxExceptionMessage(e.what(), location));
|
|
- } catch (...) { // NOLINT
|
|
- internal::ReportFailureInUnknownLocation(
|
|
- TestPartResult::kFatalFailure,
|
|
- FormatCxxExceptionMessage(nullptr, location));
|
|
- }
|
|
- return static_cast<Result>(0);
|
|
-#else
|
|
- return HandleSehExceptionsInMethodIfSupported(object, method, location);
|
|
-#endif // GTEST_HAS_EXCEPTIONS
|
|
- } else {
|
|
- return (object->*method)();
|
|
- }
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Runs the test and updates the test result.
|
|
-void Test::Run() {
|
|
- if (!HasSameFixtureClass()) return;
|
|
-
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
- internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
|
|
- // We will run the test only if SetUp() was successful and didn't call
|
|
- // GTEST_SKIP().
|
|
- if (!HasFatalFailure() && !IsSkipped()) {
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
- internal::HandleExceptionsInMethodIfSupported(this, &Test::TestBody,
|
|
- "the test body");
|
|
- }
|
|
-
|
|
- // However, we want to clean up as much as possible. Hence we will
|
|
- // always call TearDown(), even if SetUp() or the test body has
|
|
- // failed.
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
- internal::HandleExceptionsInMethodIfSupported(this, &Test::TearDown,
|
|
- "TearDown()");
|
|
-}
|
|
-
|
|
-// Returns true if and only if the current test has a fatal failure.
|
|
-bool Test::HasFatalFailure() {
|
|
- return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the current test has a non-fatal failure.
|
|
-bool Test::HasNonfatalFailure() {
|
|
- return internal::GetUnitTestImpl()
|
|
- ->current_test_result()
|
|
- ->HasNonfatalFailure();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the current test was skipped.
|
|
-bool Test::IsSkipped() {
|
|
- return internal::GetUnitTestImpl()->current_test_result()->Skipped();
|
|
-}
|
|
-
|
|
-// class TestInfo
|
|
-
|
|
-// Constructs a TestInfo object. It assumes ownership of the test factory
|
|
-// object.
|
|
-TestInfo::TestInfo(const std::string& a_test_suite_name,
|
|
- const std::string& a_name, const char* a_type_param,
|
|
- const char* a_value_param,
|
|
- internal::CodeLocation a_code_location,
|
|
- internal::TypeId fixture_class_id,
|
|
- internal::TestFactoryBase* factory)
|
|
- : test_suite_name_(a_test_suite_name),
|
|
- name_(a_name),
|
|
- type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
|
|
- value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
|
|
- location_(a_code_location),
|
|
- fixture_class_id_(fixture_class_id),
|
|
- should_run_(false),
|
|
- is_disabled_(false),
|
|
- matches_filter_(false),
|
|
- is_in_another_shard_(false),
|
|
- factory_(factory),
|
|
- result_() {}
|
|
-
|
|
-// Destructs a TestInfo object.
|
|
-TestInfo::~TestInfo() { delete factory_; }
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// Creates a new TestInfo object and registers it with Google Test;
|
|
-// returns the created object.
|
|
-//
|
|
-// Arguments:
|
|
-//
|
|
-// 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
|
|
-// this is not a typed or a type-parameterized test.
|
|
-// value_param: text representation of the test's value parameter,
|
|
-// or NULL if this is not a value-parameterized test.
|
|
-// code_location: code location where the test is defined
|
|
-// fixture_class_id: ID of the test fixture class
|
|
-// 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
|
|
-// factory: pointer to the factory that creates a test object.
|
|
-// The newly created TestInfo instance will assume
|
|
-// ownership of the factory object.
|
|
-TestInfo* MakeAndRegisterTestInfo(
|
|
- const char* test_suite_name, const char* name, const char* type_param,
|
|
- const char* value_param, CodeLocation code_location,
|
|
- TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
|
- TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
|
|
- TestInfo* const test_info =
|
|
- new TestInfo(test_suite_name, name, type_param, value_param,
|
|
- code_location, fixture_class_id, factory);
|
|
- GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
|
|
- return test_info;
|
|
-}
|
|
-
|
|
-void ReportInvalidTestSuiteType(const char* test_suite_name,
|
|
- CodeLocation code_location) {
|
|
- Message errors;
|
|
- errors
|
|
- << "Attempted redefinition of test suite " << test_suite_name << ".\n"
|
|
- << "All tests in the same test suite must use the same test fixture\n"
|
|
- << "class. However, in test suite " << test_suite_name << ", you tried\n"
|
|
- << "to define a test using a fixture class different from the one\n"
|
|
- << "used earlier. This can happen if the two fixture classes are\n"
|
|
- << "from different namespaces and have the same name. You should\n"
|
|
- << "probably rename one of the classes to put the tests into different\n"
|
|
- << "test suites.";
|
|
-
|
|
- GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
|
|
- code_location.line)
|
|
- << " " << errors.GetString();
|
|
-}
|
|
-} // namespace internal
|
|
-
|
|
-namespace {
|
|
-
|
|
-// A predicate that checks the test name of a TestInfo against a known
|
|
-// value.
|
|
-//
|
|
-// This is used for implementation of the TestSuite class only. We put
|
|
-// it in the anonymous namespace to prevent polluting the outer
|
|
-// namespace.
|
|
-//
|
|
-// TestNameIs is copyable.
|
|
-class TestNameIs {
|
|
- public:
|
|
- // Constructor.
|
|
- //
|
|
- // TestNameIs has NO default constructor.
|
|
- explicit TestNameIs(const char* name) : name_(name) {}
|
|
-
|
|
- // Returns true if and only if the test name of test_info matches name_.
|
|
- bool operator()(const TestInfo* test_info) const {
|
|
- return test_info && test_info->name() == name_;
|
|
- }
|
|
-
|
|
- private:
|
|
- std::string name_;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-// This method expands all parameterized tests registered with macros TEST_P
|
|
-// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.
|
|
-// This will be done just once during the program runtime.
|
|
-void UnitTestImpl::RegisterParameterizedTests() {
|
|
- if (!parameterized_tests_registered_) {
|
|
- parameterized_test_registry_.RegisterTests();
|
|
- type_parameterized_test_registry_.CheckForInstantiations();
|
|
- parameterized_tests_registered_ = true;
|
|
- }
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Creates the test object, runs it, records its result, and then
|
|
-// deletes it.
|
|
-void TestInfo::Run() {
|
|
- TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
|
- if (!should_run_) {
|
|
- if (is_disabled_ && matches_filter_) repeater->OnTestDisabled(*this);
|
|
- return;
|
|
- }
|
|
-
|
|
- // Tells UnitTest where to store test result.
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- impl->set_current_test_info(this);
|
|
-
|
|
- // Notifies the unit test event listeners that a test is about to start.
|
|
- repeater->OnTestStart(*this);
|
|
- result_.set_start_timestamp(internal::GetTimeInMillis());
|
|
- internal::Timer timer;
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
-
|
|
- // Creates the test object.
|
|
- Test* const test = internal::HandleExceptionsInMethodIfSupported(
|
|
- factory_, &internal::TestFactoryBase::CreateTest,
|
|
- "the test fixture's constructor");
|
|
-
|
|
- // Runs the test if the constructor didn't generate a fatal failure or invoke
|
|
- // GTEST_SKIP().
|
|
- // Note that the object will not be null
|
|
- if (!Test::HasFatalFailure() && !Test::IsSkipped()) {
|
|
- // This doesn't throw as all user code that can throw are wrapped into
|
|
- // exception handling code.
|
|
- test->Run();
|
|
- }
|
|
-
|
|
- if (test != nullptr) {
|
|
- // Deletes the test object.
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
- internal::HandleExceptionsInMethodIfSupported(
|
|
- test, &Test::DeleteSelf_, "the test fixture's destructor");
|
|
- }
|
|
-
|
|
- result_.set_elapsed_time(timer.Elapsed());
|
|
-
|
|
- // Notifies the unit test event listener that a test has just finished.
|
|
- repeater->OnTestEnd(*this);
|
|
-
|
|
- // Tells UnitTest to stop associating assertion results to this
|
|
- // test.
|
|
- impl->set_current_test_info(nullptr);
|
|
-}
|
|
-
|
|
-// Skip and records a skipped test result for this object.
|
|
-void TestInfo::Skip() {
|
|
- if (!should_run_) return;
|
|
-
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- impl->set_current_test_info(this);
|
|
-
|
|
- TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
|
-
|
|
- // Notifies the unit test event listeners that a test is about to start.
|
|
- repeater->OnTestStart(*this);
|
|
-
|
|
- const TestPartResult test_part_result =
|
|
- TestPartResult(TestPartResult::kSkip, this->file(), this->line(), "");
|
|
- impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(
|
|
- test_part_result);
|
|
-
|
|
- // Notifies the unit test event listener that a test has just finished.
|
|
- repeater->OnTestEnd(*this);
|
|
- impl->set_current_test_info(nullptr);
|
|
-}
|
|
-
|
|
-// class TestSuite
|
|
-
|
|
-// Gets the number of successful tests in this test suite.
|
|
-int TestSuite::successful_test_count() const {
|
|
- return CountIf(test_info_list_, TestPassed);
|
|
-}
|
|
-
|
|
-// Gets the number of successful tests in this test suite.
|
|
-int TestSuite::skipped_test_count() const {
|
|
- return CountIf(test_info_list_, TestSkipped);
|
|
-}
|
|
-
|
|
-// Gets the number of failed tests in this test suite.
|
|
-int TestSuite::failed_test_count() const {
|
|
- return CountIf(test_info_list_, TestFailed);
|
|
-}
|
|
-
|
|
-// Gets the number of disabled tests that will be reported in the XML report.
|
|
-int TestSuite::reportable_disabled_test_count() const {
|
|
- return CountIf(test_info_list_, TestReportableDisabled);
|
|
-}
|
|
-
|
|
-// Gets the number of disabled tests in this test suite.
|
|
-int TestSuite::disabled_test_count() const {
|
|
- return CountIf(test_info_list_, TestDisabled);
|
|
-}
|
|
-
|
|
-// Gets the number of tests to be printed in the XML report.
|
|
-int TestSuite::reportable_test_count() const {
|
|
- return CountIf(test_info_list_, TestReportable);
|
|
-}
|
|
-
|
|
-// Get the number of tests in this test suite that should run.
|
|
-int TestSuite::test_to_run_count() const {
|
|
- return CountIf(test_info_list_, ShouldRunTest);
|
|
-}
|
|
-
|
|
-// Gets the number of all tests.
|
|
-int TestSuite::total_test_count() const {
|
|
- return static_cast<int>(test_info_list_.size());
|
|
-}
|
|
-
|
|
-// Creates a TestSuite with the given name.
|
|
-//
|
|
-// Arguments:
|
|
-//
|
|
-// a_name: name of the test suite
|
|
-// a_type_param: the name of the test suite's type parameter, or NULL if
|
|
-// this is not a typed or a type-parameterized test suite.
|
|
-// 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::TestSuite(const char* a_name, const char* a_type_param,
|
|
- internal::SetUpTestSuiteFunc set_up_tc,
|
|
- internal::TearDownTestSuiteFunc tear_down_tc)
|
|
- : name_(a_name),
|
|
- type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
|
|
- set_up_tc_(set_up_tc),
|
|
- tear_down_tc_(tear_down_tc),
|
|
- should_run_(false),
|
|
- start_timestamp_(0),
|
|
- elapsed_time_(0) {}
|
|
-
|
|
-// Destructor of TestSuite.
|
|
-TestSuite::~TestSuite() {
|
|
- // Deletes every Test in the collection.
|
|
- ForEach(test_info_list_, internal::Delete<TestInfo>);
|
|
-}
|
|
-
|
|
-// 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* TestSuite::GetTestInfo(int i) const {
|
|
- const int index = GetElementOr(test_indices_, i, -1);
|
|
- return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];
|
|
-}
|
|
-
|
|
-// 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.
|
|
-TestInfo* TestSuite::GetMutableTestInfo(int i) {
|
|
- const int index = GetElementOr(test_indices_, i, -1);
|
|
- return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];
|
|
-}
|
|
-
|
|
-// Adds a test to this test suite. Will delete the test upon
|
|
-// destruction of the TestSuite object.
|
|
-void TestSuite::AddTestInfo(TestInfo* test_info) {
|
|
- test_info_list_.push_back(test_info);
|
|
- test_indices_.push_back(static_cast<int>(test_indices_.size()));
|
|
-}
|
|
-
|
|
-// Runs every test in this TestSuite.
|
|
-void TestSuite::Run() {
|
|
- if (!should_run_) return;
|
|
-
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- impl->set_current_test_suite(this);
|
|
-
|
|
- TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
|
-
|
|
- // Call both legacy and the new API
|
|
- repeater->OnTestSuiteStart(*this);
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- repeater->OnTestCaseStart(*this);
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
- internal::HandleExceptionsInMethodIfSupported(
|
|
- this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
|
|
-
|
|
- const bool skip_all = ad_hoc_test_result().Failed();
|
|
-
|
|
- start_timestamp_ = internal::GetTimeInMillis();
|
|
- internal::Timer timer;
|
|
- for (int i = 0; i < total_test_count(); i++) {
|
|
- if (skip_all) {
|
|
- GetMutableTestInfo(i)->Skip();
|
|
- } else {
|
|
- GetMutableTestInfo(i)->Run();
|
|
- }
|
|
- if (GTEST_FLAG_GET(fail_fast) &&
|
|
- GetMutableTestInfo(i)->result()->Failed()) {
|
|
- for (int j = i + 1; j < total_test_count(); j++) {
|
|
- GetMutableTestInfo(j)->Skip();
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- elapsed_time_ = timer.Elapsed();
|
|
-
|
|
- impl->os_stack_trace_getter()->UponLeavingGTest();
|
|
- internal::HandleExceptionsInMethodIfSupported(
|
|
- this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()");
|
|
-
|
|
- // Call both legacy and the new API
|
|
- repeater->OnTestSuiteEnd(*this);
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- repeater->OnTestCaseEnd(*this);
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- impl->set_current_test_suite(nullptr);
|
|
-}
|
|
-
|
|
-// Skips all tests under this TestSuite.
|
|
-void TestSuite::Skip() {
|
|
- if (!should_run_) return;
|
|
-
|
|
- internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
|
|
- impl->set_current_test_suite(this);
|
|
-
|
|
- TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
|
|
-
|
|
- // Call both legacy and the new API
|
|
- repeater->OnTestSuiteStart(*this);
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- repeater->OnTestCaseStart(*this);
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- for (int i = 0; i < total_test_count(); i++) {
|
|
- GetMutableTestInfo(i)->Skip();
|
|
- }
|
|
-
|
|
- // Call both legacy and the new API
|
|
- repeater->OnTestSuiteEnd(*this);
|
|
- // Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- repeater->OnTestCaseEnd(*this);
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- impl->set_current_test_suite(nullptr);
|
|
-}
|
|
-
|
|
-// Clears the results of all tests in this test suite.
|
|
-void TestSuite::ClearResult() {
|
|
- ad_hoc_test_result_.Clear();
|
|
- ForEach(test_info_list_, TestInfo::ClearTestResult);
|
|
-}
|
|
-
|
|
-// Shuffles the tests in this test suite.
|
|
-void TestSuite::ShuffleTests(internal::Random* random) {
|
|
- Shuffle(random, &test_indices_);
|
|
-}
|
|
-
|
|
-// Restores the test order to before the first shuffle.
|
|
-void TestSuite::UnshuffleTests() {
|
|
- for (size_t i = 0; i < test_indices_.size(); i++) {
|
|
- test_indices_[i] = static_cast<int>(i);
|
|
- }
|
|
-}
|
|
-
|
|
-// Formats a countable noun. Depending on its quantity, either the
|
|
-// singular form or the plural form is used. e.g.
|
|
-//
|
|
-// FormatCountableNoun(1, "formula", "formuli") returns "1 formula".
|
|
-// FormatCountableNoun(5, "book", "books") returns "5 books".
|
|
-static std::string FormatCountableNoun(int count, const char* singular_form,
|
|
- const char* plural_form) {
|
|
- return internal::StreamableToString(count) + " " +
|
|
- (count == 1 ? singular_form : plural_form);
|
|
-}
|
|
-
|
|
-// Formats the count of tests.
|
|
-static std::string FormatTestCount(int test_count) {
|
|
- return FormatCountableNoun(test_count, "test", "tests");
|
|
-}
|
|
-
|
|
-// Formats the count of test suites.
|
|
-static std::string FormatTestSuiteCount(int test_suite_count) {
|
|
- return FormatCountableNoun(test_suite_count, "test suite", "test suites");
|
|
-}
|
|
-
|
|
-// Converts a TestPartResult::Type enum to human-friendly string
|
|
-// representation. Both kNonFatalFailure and kFatalFailure are translated
|
|
-// to "Failure", as the user usually doesn't care about the difference
|
|
-// between the two when viewing the test result.
|
|
-static const char* TestPartResultTypeToString(TestPartResult::Type type) {
|
|
- switch (type) {
|
|
- case TestPartResult::kSkip:
|
|
- return "Skipped\n";
|
|
- case TestPartResult::kSuccess:
|
|
- return "Success";
|
|
-
|
|
- case TestPartResult::kNonFatalFailure:
|
|
- case TestPartResult::kFatalFailure:
|
|
-#ifdef _MSC_VER
|
|
- return "error: ";
|
|
-#else
|
|
- return "Failure\n";
|
|
-#endif
|
|
- default:
|
|
- return "Unknown result type";
|
|
- }
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-namespace {
|
|
-enum class GTestColor { kDefault, kRed, kGreen, kYellow };
|
|
-} // namespace
|
|
-
|
|
-// Prints a TestPartResult to an std::string.
|
|
-static std::string PrintTestPartResultToString(
|
|
- const TestPartResult& test_part_result) {
|
|
- return (Message() << internal::FormatFileLocation(
|
|
- test_part_result.file_name(),
|
|
- test_part_result.line_number())
|
|
- << " "
|
|
- << TestPartResultTypeToString(test_part_result.type())
|
|
- << test_part_result.message())
|
|
- .GetString();
|
|
-}
|
|
-
|
|
-// Prints a TestPartResult.
|
|
-static void PrintTestPartResult(const TestPartResult& test_part_result) {
|
|
- const std::string& result = PrintTestPartResultToString(test_part_result);
|
|
- printf("%s\n", result.c_str());
|
|
- fflush(stdout);
|
|
- // If the test program runs in Visual Studio or a debugger, the
|
|
- // following statements add the test part result message to the Output
|
|
- // window such that the user can double-click on it to jump to the
|
|
- // corresponding source code location; otherwise they do nothing.
|
|
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
|
|
- // We don't call OutputDebugString*() on Windows Mobile, as printing
|
|
- // to stdout is done by OutputDebugString() there already - we don't
|
|
- // want the same message printed twice.
|
|
- ::OutputDebugStringA(result.c_str());
|
|
- ::OutputDebugStringA("\n");
|
|
-#endif
|
|
-}
|
|
-
|
|
-// class PrettyUnitTestResultPrinter
|
|
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
|
|
- !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
|
|
-
|
|
-// Returns the character attribute for the given color.
|
|
-static WORD GetColorAttribute(GTestColor color) {
|
|
- switch (color) {
|
|
- case GTestColor::kRed:
|
|
- return FOREGROUND_RED;
|
|
- case GTestColor::kGreen:
|
|
- return FOREGROUND_GREEN;
|
|
- case GTestColor::kYellow:
|
|
- return FOREGROUND_RED | FOREGROUND_GREEN;
|
|
- default:
|
|
- return 0;
|
|
- }
|
|
-}
|
|
-
|
|
-static int GetBitOffset(WORD color_mask) {
|
|
- if (color_mask == 0) return 0;
|
|
-
|
|
- int bitOffset = 0;
|
|
- while ((color_mask & 1) == 0) {
|
|
- color_mask >>= 1;
|
|
- ++bitOffset;
|
|
- }
|
|
- return bitOffset;
|
|
-}
|
|
-
|
|
-static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
|
|
- // Let's reuse the BG
|
|
- static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
|
|
- BACKGROUND_RED | BACKGROUND_INTENSITY;
|
|
- static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
|
|
- FOREGROUND_RED | FOREGROUND_INTENSITY;
|
|
- const WORD existing_bg = old_color_attrs & background_mask;
|
|
-
|
|
- WORD new_color =
|
|
- GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
|
|
- static const int bg_bitOffset = GetBitOffset(background_mask);
|
|
- static const int fg_bitOffset = GetBitOffset(foreground_mask);
|
|
-
|
|
- if (((new_color & background_mask) >> bg_bitOffset) ==
|
|
- ((new_color & foreground_mask) >> fg_bitOffset)) {
|
|
- new_color ^= FOREGROUND_INTENSITY; // invert intensity
|
|
- }
|
|
- return new_color;
|
|
-}
|
|
-
|
|
-#else
|
|
-
|
|
-// Returns the ANSI color code for the given color. GTestColor::kDefault is
|
|
-// an invalid input.
|
|
-static const char* GetAnsiColorCode(GTestColor color) {
|
|
- switch (color) {
|
|
- case GTestColor::kRed:
|
|
- return "1";
|
|
- case GTestColor::kGreen:
|
|
- return "2";
|
|
- case GTestColor::kYellow:
|
|
- return "3";
|
|
- default:
|
|
- return nullptr;
|
|
- }
|
|
-}
|
|
-
|
|
-#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
-// Returns true if and only if Google Test should use colors in the output.
|
|
-bool ShouldUseColor(bool stdout_is_tty) {
|
|
- std::string c = GTEST_FLAG_GET(color);
|
|
- const char* const gtest_color = c.c_str();
|
|
-
|
|
- if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
|
|
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
|
|
- // On Windows the TERM variable is usually not set, but the
|
|
- // console there does support colors.
|
|
- return stdout_is_tty;
|
|
-#else
|
|
- // On non-Windows platforms, we rely on the TERM variable.
|
|
- const char* const term = posix::GetEnv("TERM");
|
|
- const bool term_supports_color =
|
|
- String::CStringEquals(term, "xterm") ||
|
|
- String::CStringEquals(term, "xterm-color") ||
|
|
- String::CStringEquals(term, "xterm-256color") ||
|
|
- String::CStringEquals(term, "screen") ||
|
|
- String::CStringEquals(term, "screen-256color") ||
|
|
- String::CStringEquals(term, "tmux") ||
|
|
- String::CStringEquals(term, "tmux-256color") ||
|
|
- String::CStringEquals(term, "rxvt-unicode") ||
|
|
- String::CStringEquals(term, "rxvt-unicode-256color") ||
|
|
- String::CStringEquals(term, "linux") ||
|
|
- String::CStringEquals(term, "cygwin");
|
|
- return stdout_is_tty && term_supports_color;
|
|
-#endif // GTEST_OS_WINDOWS
|
|
- }
|
|
-
|
|
- return String::CaseInsensitiveCStringEquals(gtest_color, "yes") ||
|
|
- String::CaseInsensitiveCStringEquals(gtest_color, "true") ||
|
|
- String::CaseInsensitiveCStringEquals(gtest_color, "t") ||
|
|
- String::CStringEquals(gtest_color, "1");
|
|
- // We take "yes", "true", "t", and "1" as meaning "yes". If the
|
|
- // value is neither one of these nor "auto", we treat it as "no" to
|
|
- // be conservative.
|
|
-}
|
|
-
|
|
-// Helpers for printing colored strings to stdout. Note that on Windows, we
|
|
-// cannot simply emit special characters and have the terminal change colors.
|
|
-// This routine must actually emit the characters rather than return a string
|
|
-// that would be colored when printed, as can be done on Linux.
|
|
-
|
|
-GTEST_ATTRIBUTE_PRINTF_(2, 3)
|
|
-static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
|
- va_list args;
|
|
- va_start(args, fmt);
|
|
-
|
|
- static const bool in_color_mode =
|
|
- ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
|
|
- const bool use_color = in_color_mode && (color != GTestColor::kDefault);
|
|
-
|
|
- if (!use_color) {
|
|
- vprintf(fmt, args);
|
|
- va_end(args);
|
|
- return;
|
|
- }
|
|
-
|
|
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
|
|
- !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
|
|
- const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
-
|
|
- // Gets the current text color.
|
|
- CONSOLE_SCREEN_BUFFER_INFO buffer_info;
|
|
- GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
|
|
- const WORD old_color_attrs = buffer_info.wAttributes;
|
|
- const WORD new_color = GetNewColor(color, old_color_attrs);
|
|
-
|
|
- // We need to flush the stream buffers into the console before each
|
|
- // SetConsoleTextAttribute call lest it affect the text that is already
|
|
- // printed but has not yet reached the console.
|
|
- fflush(stdout);
|
|
- SetConsoleTextAttribute(stdout_handle, new_color);
|
|
-
|
|
- vprintf(fmt, args);
|
|
-
|
|
- fflush(stdout);
|
|
- // Restores the text color.
|
|
- SetConsoleTextAttribute(stdout_handle, old_color_attrs);
|
|
-#else
|
|
- printf("\033[0;3%sm", GetAnsiColorCode(color));
|
|
- vprintf(fmt, args);
|
|
- printf("\033[m"); // Resets the terminal to default.
|
|
-#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
|
|
- va_end(args);
|
|
-}
|
|
-
|
|
-// Text printed in Google Test's text output and --gtest_list_tests
|
|
-// output to label the type parameter and value parameter for a test.
|
|
-static const char kTypeParamLabel[] = "TypeParam";
|
|
-static const char kValueParamLabel[] = "GetParam()";
|
|
-
|
|
-static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
|
|
- const char* const type_param = test_info.type_param();
|
|
- const char* const value_param = test_info.value_param();
|
|
-
|
|
- if (type_param != nullptr || value_param != nullptr) {
|
|
- printf(", where ");
|
|
- if (type_param != nullptr) {
|
|
- printf("%s = %s", kTypeParamLabel, type_param);
|
|
- if (value_param != nullptr) printf(" and ");
|
|
- }
|
|
- if (value_param != nullptr) {
|
|
- printf("%s = %s", kValueParamLabel, value_param);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-// This class implements the TestEventListener interface.
|
|
-//
|
|
-// Class PrettyUnitTestResultPrinter is copyable.
|
|
-class PrettyUnitTestResultPrinter : public TestEventListener {
|
|
- public:
|
|
- PrettyUnitTestResultPrinter() {}
|
|
- static void PrintTestName(const char* test_suite, const char* test) {
|
|
- printf("%s.%s", test_suite, test);
|
|
- }
|
|
-
|
|
- // The following methods override what's in the TestEventListener class.
|
|
- void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;
|
|
- void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;
|
|
- void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseStart(const TestCase& test_case) override;
|
|
-#else
|
|
- void OnTestSuiteStart(const TestSuite& test_suite) override;
|
|
-#endif // OnTestCaseStart
|
|
-
|
|
- void OnTestStart(const TestInfo& test_info) override;
|
|
- void OnTestDisabled(const TestInfo& test_info) override;
|
|
-
|
|
- void OnTestPartResult(const TestPartResult& result) override;
|
|
- void OnTestEnd(const TestInfo& test_info) override;
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseEnd(const TestCase& test_case) override;
|
|
-#else
|
|
- void OnTestSuiteEnd(const TestSuite& test_suite) override;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;
|
|
- void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
|
|
- void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
|
|
-
|
|
- private:
|
|
- static void PrintFailedTests(const UnitTest& unit_test);
|
|
- static void PrintFailedTestSuites(const UnitTest& unit_test);
|
|
- static void PrintSkippedTests(const UnitTest& unit_test);
|
|
-};
|
|
-
|
|
-// Fired before each iteration of tests starts.
|
|
-void PrettyUnitTestResultPrinter::OnTestIterationStart(
|
|
- const UnitTest& unit_test, int iteration) {
|
|
- if (GTEST_FLAG_GET(repeat) != 1)
|
|
- printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
|
|
-
|
|
- std::string f = GTEST_FLAG_GET(filter);
|
|
- const char* const filter = f.c_str();
|
|
-
|
|
- // Prints the filter if it's not *. This reminds the user that some
|
|
- // tests may be skipped.
|
|
- if (!String::CStringEquals(filter, kUniversalFilter)) {
|
|
- ColoredPrintf(GTestColor::kYellow, "Note: %s filter = %s\n", GTEST_NAME_,
|
|
- filter);
|
|
- }
|
|
-
|
|
- if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
|
|
- const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
|
|
- ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n",
|
|
- static_cast<int>(shard_index) + 1,
|
|
- internal::posix::GetEnv(kTestTotalShards));
|
|
- }
|
|
-
|
|
- if (GTEST_FLAG_GET(shuffle)) {
|
|
- ColoredPrintf(GTestColor::kYellow,
|
|
- "Note: Randomizing tests' orders with a seed of %d .\n",
|
|
- unit_test.random_seed());
|
|
- }
|
|
-
|
|
- ColoredPrintf(GTestColor::kGreen, "[==========] ");
|
|
- printf("Running %s from %s.\n",
|
|
- FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
|
- FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
|
|
- const UnitTest& /*unit_test*/) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[----------] ");
|
|
- printf("Global test environment set-up.\n");
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
|
|
- const std::string counts =
|
|
- FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
|
- ColoredPrintf(GTestColor::kGreen, "[----------] ");
|
|
- printf("%s from %s", counts.c_str(), test_case.name());
|
|
- if (test_case.type_param() == nullptr) {
|
|
- printf("\n");
|
|
- } else {
|
|
- printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param());
|
|
- }
|
|
- fflush(stdout);
|
|
-}
|
|
-#else
|
|
-void PrettyUnitTestResultPrinter::OnTestSuiteStart(
|
|
- const TestSuite& test_suite) {
|
|
- const std::string counts =
|
|
- FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
|
|
- ColoredPrintf(GTestColor::kGreen, "[----------] ");
|
|
- printf("%s from %s", counts.c_str(), test_suite.name());
|
|
- if (test_suite.type_param() == nullptr) {
|
|
- printf("\n");
|
|
- } else {
|
|
- printf(", where %s = %s\n", kTypeParamLabel, test_suite.type_param());
|
|
- }
|
|
- fflush(stdout);
|
|
-}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[ RUN ] ");
|
|
- PrintTestName(test_info.test_suite_name(), test_info.name());
|
|
- printf("\n");
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-void PrettyUnitTestResultPrinter::OnTestDisabled(const TestInfo& test_info) {
|
|
- ColoredPrintf(GTestColor::kYellow, "[ DISABLED ] ");
|
|
- PrintTestName(test_info.test_suite_name(), test_info.name());
|
|
- printf("\n");
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-// Called after an assertion failure.
|
|
-void PrettyUnitTestResultPrinter::OnTestPartResult(
|
|
- const TestPartResult& result) {
|
|
- switch (result.type()) {
|
|
- // If the test part succeeded, we don't need to do anything.
|
|
- case TestPartResult::kSuccess:
|
|
- return;
|
|
- default:
|
|
- // Print failure message from the assertion
|
|
- // (e.g. expected this and got that).
|
|
- PrintTestPartResult(result);
|
|
- fflush(stdout);
|
|
- }
|
|
-}
|
|
-
|
|
-void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|
- if (test_info.result()->Passed()) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[ OK ] ");
|
|
- } else if (test_info.result()->Skipped()) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] ");
|
|
- } else {
|
|
- ColoredPrintf(GTestColor::kRed, "[ FAILED ] ");
|
|
- }
|
|
- PrintTestName(test_info.test_suite_name(), test_info.name());
|
|
- if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info);
|
|
-
|
|
- if (GTEST_FLAG_GET(print_time)) {
|
|
- printf(" (%s ms)\n",
|
|
- internal::StreamableToString(test_info.result()->elapsed_time())
|
|
- .c_str());
|
|
- } else {
|
|
- printf("\n");
|
|
- }
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
|
- if (!GTEST_FLAG_GET(print_time)) return;
|
|
-
|
|
- const std::string counts =
|
|
- FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
|
- ColoredPrintf(GTestColor::kGreen, "[----------] ");
|
|
- printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(),
|
|
- internal::StreamableToString(test_case.elapsed_time()).c_str());
|
|
- fflush(stdout);
|
|
-}
|
|
-#else
|
|
-void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
|
|
- if (!GTEST_FLAG_GET(print_time)) return;
|
|
-
|
|
- const std::string counts =
|
|
- FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
|
|
- ColoredPrintf(GTestColor::kGreen, "[----------] ");
|
|
- printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(),
|
|
- internal::StreamableToString(test_suite.elapsed_time()).c_str());
|
|
- fflush(stdout);
|
|
-}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
|
|
- const UnitTest& /*unit_test*/) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[----------] ");
|
|
- printf("Global test environment tear-down\n");
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-// Internal helper for printing the list of failed tests.
|
|
-void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
|
|
- const int failed_test_count = unit_test.failed_test_count();
|
|
- ColoredPrintf(GTestColor::kRed, "[ FAILED ] ");
|
|
- printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
|
|
-
|
|
- for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
|
|
- const TestSuite& test_suite = *unit_test.GetTestSuite(i);
|
|
- if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) {
|
|
- continue;
|
|
- }
|
|
- for (int j = 0; j < test_suite.total_test_count(); ++j) {
|
|
- const TestInfo& test_info = *test_suite.GetTestInfo(j);
|
|
- if (!test_info.should_run() || !test_info.result()->Failed()) {
|
|
- continue;
|
|
- }
|
|
- ColoredPrintf(GTestColor::kRed, "[ FAILED ] ");
|
|
- printf("%s.%s", test_suite.name(), test_info.name());
|
|
- PrintFullTestCommentIfPresent(test_info);
|
|
- printf("\n");
|
|
- }
|
|
- }
|
|
- printf("\n%2d FAILED %s\n", failed_test_count,
|
|
- failed_test_count == 1 ? "TEST" : "TESTS");
|
|
-}
|
|
-
|
|
-// Internal helper for printing the list of test suite failures not covered by
|
|
-// PrintFailedTests.
|
|
-void PrettyUnitTestResultPrinter::PrintFailedTestSuites(
|
|
- const UnitTest& unit_test) {
|
|
- int suite_failure_count = 0;
|
|
- for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
|
|
- const TestSuite& test_suite = *unit_test.GetTestSuite(i);
|
|
- if (!test_suite.should_run()) {
|
|
- continue;
|
|
- }
|
|
- if (test_suite.ad_hoc_test_result().Failed()) {
|
|
- ColoredPrintf(GTestColor::kRed, "[ FAILED ] ");
|
|
- printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name());
|
|
- ++suite_failure_count;
|
|
- }
|
|
- }
|
|
- if (suite_failure_count > 0) {
|
|
- printf("\n%2d FAILED TEST %s\n", suite_failure_count,
|
|
- suite_failure_count == 1 ? "SUITE" : "SUITES");
|
|
- }
|
|
-}
|
|
-
|
|
-// Internal helper for printing the list of skipped tests.
|
|
-void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {
|
|
- const int skipped_test_count = unit_test.skipped_test_count();
|
|
- if (skipped_test_count == 0) {
|
|
- return;
|
|
- }
|
|
-
|
|
- for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
|
|
- const TestSuite& test_suite = *unit_test.GetTestSuite(i);
|
|
- if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) {
|
|
- continue;
|
|
- }
|
|
- for (int j = 0; j < test_suite.total_test_count(); ++j) {
|
|
- const TestInfo& test_info = *test_suite.GetTestInfo(j);
|
|
- if (!test_info.should_run() || !test_info.result()->Skipped()) {
|
|
- continue;
|
|
- }
|
|
- ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] ");
|
|
- printf("%s.%s", test_suite.name(), test_info.name());
|
|
- printf("\n");
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|
- int /*iteration*/) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[==========] ");
|
|
- printf("%s from %s ran.",
|
|
- FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
|
- FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
|
- if (GTEST_FLAG_GET(print_time)) {
|
|
- printf(" (%s ms total)",
|
|
- internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
|
- }
|
|
- printf("\n");
|
|
- ColoredPrintf(GTestColor::kGreen, "[ PASSED ] ");
|
|
- printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
|
|
-
|
|
- const int skipped_test_count = unit_test.skipped_test_count();
|
|
- if (skipped_test_count > 0) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] ");
|
|
- printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str());
|
|
- PrintSkippedTests(unit_test);
|
|
- }
|
|
-
|
|
- if (!unit_test.Passed()) {
|
|
- PrintFailedTests(unit_test);
|
|
- PrintFailedTestSuites(unit_test);
|
|
- }
|
|
-
|
|
- int num_disabled = unit_test.reportable_disabled_test_count();
|
|
- if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {
|
|
- if (unit_test.Passed()) {
|
|
- printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
|
- }
|
|
- ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n",
|
|
- num_disabled, num_disabled == 1 ? "TEST" : "TESTS");
|
|
- }
|
|
- // Ensure that Google Test output is printed before, e.g., heapchecker output.
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-// End PrettyUnitTestResultPrinter
|
|
-
|
|
-// This class implements the TestEventListener interface.
|
|
-//
|
|
-// Class BriefUnitTestResultPrinter is copyable.
|
|
-class BriefUnitTestResultPrinter : public TestEventListener {
|
|
- public:
|
|
- BriefUnitTestResultPrinter() {}
|
|
- static void PrintTestName(const char* test_suite, const char* test) {
|
|
- printf("%s.%s", test_suite, test);
|
|
- }
|
|
-
|
|
- // The following methods override what's in the TestEventListener class.
|
|
- void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
|
- int /*iteration*/) override {}
|
|
- void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseStart(const TestCase& /*test_case*/) override {}
|
|
-#else
|
|
- void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
|
|
-#endif // OnTestCaseStart
|
|
-
|
|
- void OnTestStart(const TestInfo& /*test_info*/) override {}
|
|
- void OnTestDisabled(const TestInfo& /*test_info*/) override {}
|
|
-
|
|
- void OnTestPartResult(const TestPartResult& result) override;
|
|
- void OnTestEnd(const TestInfo& test_info) override;
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
|
|
-#else
|
|
- void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
- void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}
|
|
- void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
|
|
- void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
|
|
- void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
|
|
-};
|
|
-
|
|
-// Called after an assertion failure.
|
|
-void BriefUnitTestResultPrinter::OnTestPartResult(
|
|
- const TestPartResult& result) {
|
|
- switch (result.type()) {
|
|
- // If the test part succeeded, we don't need to do anything.
|
|
- case TestPartResult::kSuccess:
|
|
- return;
|
|
- default:
|
|
- // Print failure message from the assertion
|
|
- // (e.g. expected this and got that).
|
|
- PrintTestPartResult(result);
|
|
- fflush(stdout);
|
|
- }
|
|
-}
|
|
-
|
|
-void BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|
- if (test_info.result()->Failed()) {
|
|
- ColoredPrintf(GTestColor::kRed, "[ FAILED ] ");
|
|
- PrintTestName(test_info.test_suite_name(), test_info.name());
|
|
- PrintFullTestCommentIfPresent(test_info);
|
|
-
|
|
- if (GTEST_FLAG_GET(print_time)) {
|
|
- printf(" (%s ms)\n",
|
|
- internal::StreamableToString(test_info.result()->elapsed_time())
|
|
- .c_str());
|
|
- } else {
|
|
- printf("\n");
|
|
- }
|
|
- fflush(stdout);
|
|
- }
|
|
-}
|
|
-
|
|
-void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|
- int /*iteration*/) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[==========] ");
|
|
- printf("%s from %s ran.",
|
|
- FormatTestCount(unit_test.test_to_run_count()).c_str(),
|
|
- FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
|
|
- if (GTEST_FLAG_GET(print_time)) {
|
|
- printf(" (%s ms total)",
|
|
- internal::StreamableToString(unit_test.elapsed_time()).c_str());
|
|
- }
|
|
- printf("\n");
|
|
- ColoredPrintf(GTestColor::kGreen, "[ PASSED ] ");
|
|
- printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
|
|
-
|
|
- const int skipped_test_count = unit_test.skipped_test_count();
|
|
- if (skipped_test_count > 0) {
|
|
- ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] ");
|
|
- printf("%s.\n", FormatTestCount(skipped_test_count).c_str());
|
|
- }
|
|
-
|
|
- int num_disabled = unit_test.reportable_disabled_test_count();
|
|
- if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {
|
|
- if (unit_test.Passed()) {
|
|
- printf("\n"); // Add a spacer if no FAILURE banner is displayed.
|
|
- }
|
|
- ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n",
|
|
- num_disabled, num_disabled == 1 ? "TEST" : "TESTS");
|
|
- }
|
|
- // Ensure that Google Test output is printed before, e.g., heapchecker output.
|
|
- fflush(stdout);
|
|
-}
|
|
-
|
|
-// End BriefUnitTestResultPrinter
|
|
-
|
|
-// class TestEventRepeater
|
|
-//
|
|
-// This class forwards events to other event listeners.
|
|
-class TestEventRepeater : public TestEventListener {
|
|
- public:
|
|
- TestEventRepeater() : forwarding_enabled_(true) {}
|
|
- ~TestEventRepeater() override;
|
|
- void Append(TestEventListener* listener);
|
|
- TestEventListener* Release(TestEventListener* listener);
|
|
-
|
|
- // Controls whether events will be forwarded to listeners_. Set to false
|
|
- // in death test child processes.
|
|
- bool forwarding_enabled() const { return forwarding_enabled_; }
|
|
- void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
|
|
-
|
|
- void OnTestProgramStart(const UnitTest& unit_test) override;
|
|
- void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;
|
|
- void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;
|
|
- void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) override;
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseStart(const TestSuite& parameter) override;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestSuiteStart(const TestSuite& parameter) override;
|
|
- void OnTestStart(const TestInfo& test_info) override;
|
|
- void OnTestDisabled(const TestInfo& test_info) override;
|
|
- void OnTestPartResult(const TestPartResult& result) override;
|
|
- void OnTestEnd(const TestInfo& test_info) override;
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestCaseEnd(const TestCase& parameter) override;
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
- void OnTestSuiteEnd(const TestSuite& parameter) override;
|
|
- void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;
|
|
- void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) override;
|
|
- void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
|
|
- void OnTestProgramEnd(const UnitTest& unit_test) override;
|
|
-
|
|
- private:
|
|
- // Controls whether events will be forwarded to listeners_. Set to false
|
|
- // in death test child processes.
|
|
- bool forwarding_enabled_;
|
|
- // The list of listeners that receive events.
|
|
- std::vector<TestEventListener*> listeners_;
|
|
-
|
|
- TestEventRepeater(const TestEventRepeater&) = delete;
|
|
- TestEventRepeater& operator=(const TestEventRepeater&) = delete;
|
|
-};
|
|
-
|
|
-TestEventRepeater::~TestEventRepeater() {
|
|
- ForEach(listeners_, Delete<TestEventListener>);
|
|
-}
|
|
-
|
|
-void TestEventRepeater::Append(TestEventListener* listener) {
|
|
- listeners_.push_back(listener);
|
|
-}
|
|
-
|
|
-TestEventListener* TestEventRepeater::Release(TestEventListener* listener) {
|
|
- for (size_t i = 0; i < listeners_.size(); ++i) {
|
|
- if (listeners_[i] == listener) {
|
|
- listeners_.erase(listeners_.begin() + static_cast<int>(i));
|
|
- return listener;
|
|
- }
|
|
- }
|
|
-
|
|
- return nullptr;
|
|
-}
|
|
-
|
|
-// Since most methods are very similar, use macros to reduce boilerplate.
|
|
-// This defines a member that forwards the call to all listeners.
|
|
-#define GTEST_REPEATER_METHOD_(Name, Type) \
|
|
- void TestEventRepeater::Name(const Type& parameter) { \
|
|
- if (forwarding_enabled_) { \
|
|
- for (size_t i = 0; i < listeners_.size(); i++) { \
|
|
- listeners_[i]->Name(parameter); \
|
|
- } \
|
|
- } \
|
|
- }
|
|
-// This defines a member that forwards the call to all listeners in reverse
|
|
-// order.
|
|
-#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
|
|
- void TestEventRepeater::Name(const Type& parameter) { \
|
|
- if (forwarding_enabled_) { \
|
|
- for (size_t i = listeners_.size(); i != 0; i--) { \
|
|
- listeners_[i - 1]->Name(parameter); \
|
|
- } \
|
|
- } \
|
|
- }
|
|
-
|
|
-GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
|
|
-GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)
|
|
-GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
|
|
-GTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo)
|
|
-GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
|
|
-GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
|
|
-GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
|
|
-GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
|
|
-GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite)
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-GTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite)
|
|
-GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
|
|
-
|
|
-#undef GTEST_REPEATER_METHOD_
|
|
-#undef GTEST_REVERSE_REPEATER_METHOD_
|
|
-
|
|
-void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
|
|
- int iteration) {
|
|
- if (forwarding_enabled_) {
|
|
- for (size_t i = 0; i < listeners_.size(); i++) {
|
|
- listeners_[i]->OnTestIterationStart(unit_test, iteration);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
|
|
- int iteration) {
|
|
- if (forwarding_enabled_) {
|
|
- for (size_t i = listeners_.size(); i > 0; i--) {
|
|
- listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-// End TestEventRepeater
|
|
-
|
|
-// This class generates an XML output file.
|
|
-class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
|
- public:
|
|
- explicit XmlUnitTestResultPrinter(const char* output_file);
|
|
-
|
|
- void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
|
|
- void ListTestsMatchingFilter(const std::vector<TestSuite*>& test_suites);
|
|
-
|
|
- // Prints an XML summary of all unit tests.
|
|
- static void PrintXmlTestsList(std::ostream* stream,
|
|
- const std::vector<TestSuite*>& test_suites);
|
|
-
|
|
- private:
|
|
- // Is c a whitespace character that is normalized to a space character
|
|
- // when it appears in an XML attribute value?
|
|
- static bool IsNormalizableWhitespace(unsigned char c) {
|
|
- return c == '\t' || c == '\n' || c == '\r';
|
|
- }
|
|
-
|
|
- // May c appear in a well-formed XML document?
|
|
- // https://www.w3.org/TR/REC-xml/#charsets
|
|
- static bool IsValidXmlCharacter(unsigned char c) {
|
|
- return IsNormalizableWhitespace(c) || c >= 0x20;
|
|
- }
|
|
-
|
|
- // Returns an XML-escaped copy of the input string str. If
|
|
- // is_attribute is true, the text is meant to appear as an attribute
|
|
- // value, and normalizable whitespace is preserved by replacing it
|
|
- // with character references.
|
|
- static std::string EscapeXml(const std::string& str, bool is_attribute);
|
|
-
|
|
- // Returns the given string with all characters invalid in XML removed.
|
|
- static std::string RemoveInvalidXmlCharacters(const std::string& str);
|
|
-
|
|
- // Convenience wrapper around EscapeXml when str is an attribute value.
|
|
- static std::string EscapeXmlAttribute(const std::string& str) {
|
|
- return EscapeXml(str, true);
|
|
- }
|
|
-
|
|
- // Convenience wrapper around EscapeXml when str is not an attribute value.
|
|
- static std::string EscapeXmlText(const char* str) {
|
|
- return EscapeXml(str, false);
|
|
- }
|
|
-
|
|
- // Verifies that the given attribute belongs to the given element and
|
|
- // streams the attribute as XML.
|
|
- static void OutputXmlAttribute(std::ostream* stream,
|
|
- const std::string& element_name,
|
|
- const std::string& name,
|
|
- const std::string& value);
|
|
-
|
|
- // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
|
- static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
|
|
-
|
|
- // Streams a test suite XML stanza containing the given test result.
|
|
- //
|
|
- // Requires: result.Failed()
|
|
- static void OutputXmlTestSuiteForTestResult(::std::ostream* stream,
|
|
- const TestResult& result);
|
|
-
|
|
- // Streams an XML representation of a TestResult object.
|
|
- static void OutputXmlTestResult(::std::ostream* stream,
|
|
- const TestResult& result);
|
|
-
|
|
- // Streams an XML representation of a TestInfo object.
|
|
- static void OutputXmlTestInfo(::std::ostream* stream,
|
|
- const char* test_suite_name,
|
|
- const TestInfo& test_info);
|
|
-
|
|
- // Prints an XML representation of a TestSuite object
|
|
- static void PrintXmlTestSuite(::std::ostream* stream,
|
|
- const TestSuite& test_suite);
|
|
-
|
|
- // Prints an XML summary of unit_test to output stream out.
|
|
- static void PrintXmlUnitTest(::std::ostream* stream,
|
|
- const UnitTest& unit_test);
|
|
-
|
|
- // Produces a string representing the test properties in a result as space
|
|
- // delimited XML attributes based on the property key="value" pairs.
|
|
- // When the std::string is not empty, it includes a space at the beginning,
|
|
- // to delimit this attribute from prior attributes.
|
|
- static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
|
|
-
|
|
- // Streams an XML representation of the test properties of a TestResult
|
|
- // object.
|
|
- static void OutputXmlTestProperties(std::ostream* stream,
|
|
- const TestResult& result);
|
|
-
|
|
- // The output file.
|
|
- const std::string output_file_;
|
|
-
|
|
- XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;
|
|
- XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter&) = delete;
|
|
-};
|
|
-
|
|
-// Creates a new XmlUnitTestResultPrinter.
|
|
-XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
|
|
- : output_file_(output_file) {
|
|
- if (output_file_.empty()) {
|
|
- GTEST_LOG_(FATAL) << "XML output file may not be null";
|
|
- }
|
|
-}
|
|
-
|
|
-// Called after the unit test ends.
|
|
-void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|
- int /*iteration*/) {
|
|
- FILE* xmlout = OpenFileForWriting(output_file_);
|
|
- std::stringstream stream;
|
|
- PrintXmlUnitTest(&stream, unit_test);
|
|
- fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
|
|
- fclose(xmlout);
|
|
-}
|
|
-
|
|
-void XmlUnitTestResultPrinter::ListTestsMatchingFilter(
|
|
- const std::vector<TestSuite*>& test_suites) {
|
|
- FILE* xmlout = OpenFileForWriting(output_file_);
|
|
- std::stringstream stream;
|
|
- PrintXmlTestsList(&stream, test_suites);
|
|
- fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
|
|
- fclose(xmlout);
|
|
-}
|
|
-
|
|
-// Returns an XML-escaped copy of the input string str. If is_attribute
|
|
-// is true, the text is meant to appear as an attribute value, and
|
|
-// normalizable whitespace is preserved by replacing it with character
|
|
-// references.
|
|
-//
|
|
-// Invalid XML characters in str, if any, are stripped from the output.
|
|
-// It is expected that most, if not all, of the text processed by this
|
|
-// module will consist of ordinary English text.
|
|
-// If this module is ever modified to produce version 1.1 XML output,
|
|
-// most invalid characters can be retained using character references.
|
|
-std::string XmlUnitTestResultPrinter::EscapeXml(const std::string& str,
|
|
- bool is_attribute) {
|
|
- Message m;
|
|
-
|
|
- for (size_t i = 0; i < str.size(); ++i) {
|
|
- const char ch = str[i];
|
|
- switch (ch) {
|
|
- case '<':
|
|
- m << "<";
|
|
- break;
|
|
- case '>':
|
|
- m << ">";
|
|
- break;
|
|
- case '&':
|
|
- m << "&";
|
|
- break;
|
|
- case '\'':
|
|
- if (is_attribute)
|
|
- m << "'";
|
|
- else
|
|
- m << '\'';
|
|
- break;
|
|
- case '"':
|
|
- if (is_attribute)
|
|
- m << """;
|
|
- else
|
|
- m << '"';
|
|
- break;
|
|
- default:
|
|
- if (IsValidXmlCharacter(static_cast<unsigned char>(ch))) {
|
|
- if (is_attribute &&
|
|
- IsNormalizableWhitespace(static_cast<unsigned char>(ch)))
|
|
- m << "&#x" << String::FormatByte(static_cast<unsigned char>(ch))
|
|
- << ";";
|
|
- else
|
|
- m << ch;
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- return m.GetString();
|
|
-}
|
|
-
|
|
-// Returns the given string with all characters invalid in XML removed.
|
|
-// Currently invalid characters are dropped from the string. An
|
|
-// alternative is to replace them with certain characters such as . or ?.
|
|
-std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
|
|
- const std::string& str) {
|
|
- std::string output;
|
|
- output.reserve(str.size());
|
|
- for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
|
|
- if (IsValidXmlCharacter(static_cast<unsigned char>(*it)))
|
|
- output.push_back(*it);
|
|
-
|
|
- return output;
|
|
-}
|
|
-
|
|
-// The following routines generate an XML representation of a UnitTest
|
|
-// object.
|
|
-//
|
|
-// This is how Google Test concepts map to the DTD:
|
|
-//
|
|
-// <testsuites name="AllTests"> <-- corresponds to a UnitTest object
|
|
-// <testsuite name="testcase-name"> <-- corresponds to a TestSuite object
|
|
-// <testcase name="test-name"> <-- corresponds to a TestInfo object
|
|
-// <failure message="...">...</failure>
|
|
-// <failure message="...">...</failure>
|
|
-// <failure message="...">...</failure>
|
|
-// <-- individual assertion failures
|
|
-// </testcase>
|
|
-// </testsuite>
|
|
-// </testsuites>
|
|
-
|
|
-// Formats the given time in milliseconds as seconds.
|
|
-std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
|
|
- ::std::stringstream ss;
|
|
- ss << (static_cast<double>(ms) * 1e-3);
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-static bool PortableLocaltime(time_t seconds, struct tm* out) {
|
|
-#if defined(_MSC_VER)
|
|
- return localtime_s(out, &seconds) == 0;
|
|
-#elif defined(__MINGW32__) || defined(__MINGW64__)
|
|
- // MINGW <time.h> provides neither localtime_r nor localtime_s, but uses
|
|
- // Windows' localtime(), which has a thread-local tm buffer.
|
|
- struct tm* tm_ptr = localtime(&seconds); // NOLINT
|
|
- if (tm_ptr == nullptr) return false;
|
|
- *out = *tm_ptr;
|
|
- return true;
|
|
-#elif defined(__STDC_LIB_EXT1__)
|
|
- // Uses localtime_s when available as localtime_r is only available from
|
|
- // C23 standard.
|
|
- return localtime_s(&seconds, out) != nullptr;
|
|
-#else
|
|
- return localtime_r(&seconds, out) != nullptr;
|
|
-#endif
|
|
-}
|
|
-
|
|
-// Converts the given epoch time in milliseconds to a date string in the ISO
|
|
-// 8601 format, without the timezone information.
|
|
-std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
|
|
- struct tm time_struct;
|
|
- if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))
|
|
- return "";
|
|
- // YYYY-MM-DDThh:mm:ss.sss
|
|
- return StreamableToString(time_struct.tm_year + 1900) + "-" +
|
|
- String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
|
|
- String::FormatIntWidth2(time_struct.tm_mday) + "T" +
|
|
- String::FormatIntWidth2(time_struct.tm_hour) + ":" +
|
|
- String::FormatIntWidth2(time_struct.tm_min) + ":" +
|
|
- String::FormatIntWidth2(time_struct.tm_sec) + "." +
|
|
- String::FormatIntWidthN(static_cast<int>(ms % 1000), 3);
|
|
-}
|
|
-
|
|
-// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
|
-void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
|
|
- const char* data) {
|
|
- const char* segment = data;
|
|
- *stream << "<![CDATA[";
|
|
- for (;;) {
|
|
- const char* const next_segment = strstr(segment, "]]>");
|
|
- if (next_segment != nullptr) {
|
|
- stream->write(segment,
|
|
- static_cast<std::streamsize>(next_segment - segment));
|
|
- *stream << "]]>]]><![CDATA[";
|
|
- segment = next_segment + strlen("]]>");
|
|
- } else {
|
|
- *stream << segment;
|
|
- break;
|
|
- }
|
|
- }
|
|
- *stream << "]]>";
|
|
-}
|
|
-
|
|
-void XmlUnitTestResultPrinter::OutputXmlAttribute(
|
|
- std::ostream* stream, const std::string& element_name,
|
|
- const std::string& name, const std::string& value) {
|
|
- const std::vector<std::string>& allowed_names =
|
|
- GetReservedOutputAttributesForElement(element_name);
|
|
-
|
|
- GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
|
|
- allowed_names.end())
|
|
- << "Attribute " << name << " is not allowed for element <" << element_name
|
|
- << ">.";
|
|
-
|
|
- *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\"";
|
|
-}
|
|
-
|
|
-// Streams a test suite XML stanza containing the given test result.
|
|
-void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult(
|
|
- ::std::ostream* stream, const TestResult& result) {
|
|
- // Output the boilerplate for a minimal test suite with one test.
|
|
- *stream << " <testsuite";
|
|
- OutputXmlAttribute(stream, "testsuite", "name", "NonTestSuiteFailure");
|
|
- OutputXmlAttribute(stream, "testsuite", "tests", "1");
|
|
- OutputXmlAttribute(stream, "testsuite", "failures", "1");
|
|
- OutputXmlAttribute(stream, "testsuite", "disabled", "0");
|
|
- OutputXmlAttribute(stream, "testsuite", "skipped", "0");
|
|
- OutputXmlAttribute(stream, "testsuite", "errors", "0");
|
|
- OutputXmlAttribute(stream, "testsuite", "time",
|
|
- FormatTimeInMillisAsSeconds(result.elapsed_time()));
|
|
- OutputXmlAttribute(
|
|
- stream, "testsuite", "timestamp",
|
|
- FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
|
|
- *stream << ">";
|
|
-
|
|
- // Output the boilerplate for a minimal test case with a single test.
|
|
- *stream << " <testcase";
|
|
- OutputXmlAttribute(stream, "testcase", "name", "");
|
|
- OutputXmlAttribute(stream, "testcase", "status", "run");
|
|
- OutputXmlAttribute(stream, "testcase", "result", "completed");
|
|
- OutputXmlAttribute(stream, "testcase", "classname", "");
|
|
- OutputXmlAttribute(stream, "testcase", "time",
|
|
- FormatTimeInMillisAsSeconds(result.elapsed_time()));
|
|
- OutputXmlAttribute(
|
|
- stream, "testcase", "timestamp",
|
|
- FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
|
|
-
|
|
- // Output the actual test result.
|
|
- OutputXmlTestResult(stream, result);
|
|
-
|
|
- // Complete the test suite.
|
|
- *stream << " </testsuite>\n";
|
|
-}
|
|
-
|
|
-// Prints an XML representation of a TestInfo object.
|
|
-void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
|
|
- const char* test_suite_name,
|
|
- const TestInfo& test_info) {
|
|
- const TestResult& result = *test_info.result();
|
|
- const std::string kTestsuite = "testcase";
|
|
-
|
|
- if (test_info.is_in_another_shard()) {
|
|
- return;
|
|
- }
|
|
-
|
|
- *stream << " <testcase";
|
|
- OutputXmlAttribute(stream, kTestsuite, "name", test_info.name());
|
|
-
|
|
- if (test_info.value_param() != nullptr) {
|
|
- OutputXmlAttribute(stream, kTestsuite, "value_param",
|
|
- test_info.value_param());
|
|
- }
|
|
- if (test_info.type_param() != nullptr) {
|
|
- OutputXmlAttribute(stream, kTestsuite, "type_param",
|
|
- test_info.type_param());
|
|
- }
|
|
-
|
|
- OutputXmlAttribute(stream, kTestsuite, "file", test_info.file());
|
|
- OutputXmlAttribute(stream, kTestsuite, "line",
|
|
- StreamableToString(test_info.line()));
|
|
- if (GTEST_FLAG_GET(list_tests)) {
|
|
- *stream << " />\n";
|
|
- return;
|
|
- }
|
|
-
|
|
- OutputXmlAttribute(stream, kTestsuite, "status",
|
|
- test_info.should_run() ? "run" : "notrun");
|
|
- OutputXmlAttribute(stream, kTestsuite, "result",
|
|
- test_info.should_run()
|
|
- ? (result.Skipped() ? "skipped" : "completed")
|
|
- : "suppressed");
|
|
- OutputXmlAttribute(stream, kTestsuite, "time",
|
|
- FormatTimeInMillisAsSeconds(result.elapsed_time()));
|
|
- OutputXmlAttribute(
|
|
- stream, kTestsuite, "timestamp",
|
|
- FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
|
|
- OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name);
|
|
-
|
|
- OutputXmlTestResult(stream, result);
|
|
-}
|
|
-
|
|
-void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,
|
|
- const TestResult& result) {
|
|
- int failures = 0;
|
|
- int skips = 0;
|
|
- for (int i = 0; i < result.total_part_count(); ++i) {
|
|
- const TestPartResult& part = result.GetTestPartResult(i);
|
|
- if (part.failed()) {
|
|
- if (++failures == 1 && skips == 0) {
|
|
- *stream << ">\n";
|
|
- }
|
|
- const std::string location =
|
|
- internal::FormatCompilerIndependentFileLocation(part.file_name(),
|
|
- part.line_number());
|
|
- const std::string summary = location + "\n" + part.summary();
|
|
- *stream << " <failure message=\"" << EscapeXmlAttribute(summary)
|
|
- << "\" type=\"\">";
|
|
- const std::string detail = location + "\n" + part.message();
|
|
- OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
|
|
- *stream << "</failure>\n";
|
|
- } else if (part.skipped()) {
|
|
- if (++skips == 1 && failures == 0) {
|
|
- *stream << ">\n";
|
|
- }
|
|
- const std::string location =
|
|
- internal::FormatCompilerIndependentFileLocation(part.file_name(),
|
|
- part.line_number());
|
|
- const std::string summary = location + "\n" + part.summary();
|
|
- *stream << " <skipped message=\""
|
|
- << EscapeXmlAttribute(summary.c_str()) << "\">";
|
|
- const std::string detail = location + "\n" + part.message();
|
|
- OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
|
|
- *stream << "</skipped>\n";
|
|
- }
|
|
- }
|
|
-
|
|
- if (failures == 0 && skips == 0 && result.test_property_count() == 0) {
|
|
- *stream << " />\n";
|
|
- } else {
|
|
- if (failures == 0 && skips == 0) {
|
|
- *stream << ">\n";
|
|
- }
|
|
- OutputXmlTestProperties(stream, result);
|
|
- *stream << " </testcase>\n";
|
|
- }
|
|
-}
|
|
-
|
|
-// Prints an XML representation of a TestSuite object
|
|
-void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
|
|
- const TestSuite& test_suite) {
|
|
- const std::string kTestsuite = "testsuite";
|
|
- *stream << " <" << kTestsuite;
|
|
- OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name());
|
|
- OutputXmlAttribute(stream, kTestsuite, "tests",
|
|
- StreamableToString(test_suite.reportable_test_count()));
|
|
- if (!GTEST_FLAG_GET(list_tests)) {
|
|
- OutputXmlAttribute(stream, kTestsuite, "failures",
|
|
- StreamableToString(test_suite.failed_test_count()));
|
|
- OutputXmlAttribute(
|
|
- stream, kTestsuite, "disabled",
|
|
- StreamableToString(test_suite.reportable_disabled_test_count()));
|
|
- OutputXmlAttribute(stream, kTestsuite, "skipped",
|
|
- StreamableToString(test_suite.skipped_test_count()));
|
|
-
|
|
- OutputXmlAttribute(stream, kTestsuite, "errors", "0");
|
|
-
|
|
- OutputXmlAttribute(stream, kTestsuite, "time",
|
|
- FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));
|
|
- OutputXmlAttribute(
|
|
- stream, kTestsuite, "timestamp",
|
|
- FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));
|
|
- *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());
|
|
- }
|
|
- *stream << ">\n";
|
|
- for (int i = 0; i < test_suite.total_test_count(); ++i) {
|
|
- if (test_suite.GetTestInfo(i)->is_reportable())
|
|
- OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
|
|
- }
|
|
- *stream << " </" << kTestsuite << ">\n";
|
|
-}
|
|
-
|
|
-// Prints an XML summary of unit_test to output stream out.
|
|
-void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
|
|
- const UnitTest& unit_test) {
|
|
- const std::string kTestsuites = "testsuites";
|
|
-
|
|
- *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
|
- *stream << "<" << kTestsuites;
|
|
-
|
|
- OutputXmlAttribute(stream, kTestsuites, "tests",
|
|
- StreamableToString(unit_test.reportable_test_count()));
|
|
- OutputXmlAttribute(stream, kTestsuites, "failures",
|
|
- StreamableToString(unit_test.failed_test_count()));
|
|
- OutputXmlAttribute(
|
|
- stream, kTestsuites, "disabled",
|
|
- StreamableToString(unit_test.reportable_disabled_test_count()));
|
|
- OutputXmlAttribute(stream, kTestsuites, "errors", "0");
|
|
- OutputXmlAttribute(stream, kTestsuites, "time",
|
|
- FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
|
|
- OutputXmlAttribute(
|
|
- stream, kTestsuites, "timestamp",
|
|
- FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
|
|
-
|
|
- if (GTEST_FLAG_GET(shuffle)) {
|
|
- OutputXmlAttribute(stream, kTestsuites, "random_seed",
|
|
- StreamableToString(unit_test.random_seed()));
|
|
- }
|
|
- *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
|
|
-
|
|
- OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
|
|
- *stream << ">\n";
|
|
-
|
|
- for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
|
|
- if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)
|
|
- PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));
|
|
- }
|
|
-
|
|
- // If there was a test failure outside of one of the test suites (like in a
|
|
- // test environment) include that in the output.
|
|
- if (unit_test.ad_hoc_test_result().Failed()) {
|
|
- OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
|
|
- }
|
|
-
|
|
- *stream << "</" << kTestsuites << ">\n";
|
|
-}
|
|
-
|
|
-void XmlUnitTestResultPrinter::PrintXmlTestsList(
|
|
- std::ostream* stream, const std::vector<TestSuite*>& test_suites) {
|
|
- const std::string kTestsuites = "testsuites";
|
|
-
|
|
- *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
|
- *stream << "<" << kTestsuites;
|
|
-
|
|
- int total_tests = 0;
|
|
- for (auto test_suite : test_suites) {
|
|
- total_tests += test_suite->total_test_count();
|
|
- }
|
|
- OutputXmlAttribute(stream, kTestsuites, "tests",
|
|
- StreamableToString(total_tests));
|
|
- OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
|
|
- *stream << ">\n";
|
|
-
|
|
- for (auto test_suite : test_suites) {
|
|
- PrintXmlTestSuite(stream, *test_suite);
|
|
- }
|
|
- *stream << "</" << kTestsuites << ">\n";
|
|
-}
|
|
-
|
|
-// Produces a string representing the test properties in a result as space
|
|
-// delimited XML attributes based on the property key="value" pairs.
|
|
-std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
|
|
- const TestResult& result) {
|
|
- Message attributes;
|
|
- for (int i = 0; i < result.test_property_count(); ++i) {
|
|
- const TestProperty& property = result.GetTestProperty(i);
|
|
- attributes << " " << property.key() << "="
|
|
- << "\"" << EscapeXmlAttribute(property.value()) << "\"";
|
|
- }
|
|
- return attributes.GetString();
|
|
-}
|
|
-
|
|
-void XmlUnitTestResultPrinter::OutputXmlTestProperties(
|
|
- std::ostream* stream, const TestResult& result) {
|
|
- const std::string kProperties = "properties";
|
|
- const std::string kProperty = "property";
|
|
-
|
|
- if (result.test_property_count() <= 0) {
|
|
- return;
|
|
- }
|
|
-
|
|
- *stream << " <" << kProperties << ">\n";
|
|
- for (int i = 0; i < result.test_property_count(); ++i) {
|
|
- const TestProperty& property = result.GetTestProperty(i);
|
|
- *stream << " <" << kProperty;
|
|
- *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
|
|
- *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
|
|
- *stream << "/>\n";
|
|
- }
|
|
- *stream << " </" << kProperties << ">\n";
|
|
-}
|
|
-
|
|
-// End XmlUnitTestResultPrinter
|
|
-
|
|
-// This class generates an JSON output file.
|
|
-class JsonUnitTestResultPrinter : public EmptyTestEventListener {
|
|
- public:
|
|
- explicit JsonUnitTestResultPrinter(const char* output_file);
|
|
-
|
|
- void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
|
|
-
|
|
- // Prints an JSON summary of all unit tests.
|
|
- static void PrintJsonTestList(::std::ostream* stream,
|
|
- const std::vector<TestSuite*>& test_suites);
|
|
-
|
|
- private:
|
|
- // Returns an JSON-escaped copy of the input string str.
|
|
- static std::string EscapeJson(const std::string& str);
|
|
-
|
|
- //// Verifies that the given attribute belongs to the given element and
|
|
- //// streams the attribute as JSON.
|
|
- static void OutputJsonKey(std::ostream* stream,
|
|
- const std::string& element_name,
|
|
- const std::string& name, const std::string& value,
|
|
- const std::string& indent, bool comma = true);
|
|
- static void OutputJsonKey(std::ostream* stream,
|
|
- const std::string& element_name,
|
|
- const std::string& name, int value,
|
|
- const std::string& indent, bool comma = true);
|
|
-
|
|
- // Streams a test suite JSON stanza containing the given test result.
|
|
- //
|
|
- // Requires: result.Failed()
|
|
- static void OutputJsonTestSuiteForTestResult(::std::ostream* stream,
|
|
- const TestResult& result);
|
|
-
|
|
- // Streams a JSON representation of a TestResult object.
|
|
- static void OutputJsonTestResult(::std::ostream* stream,
|
|
- const TestResult& result);
|
|
-
|
|
- // Streams a JSON representation of a TestInfo object.
|
|
- static void OutputJsonTestInfo(::std::ostream* stream,
|
|
- const char* test_suite_name,
|
|
- const TestInfo& test_info);
|
|
-
|
|
- // Prints a JSON representation of a TestSuite object
|
|
- static void PrintJsonTestSuite(::std::ostream* stream,
|
|
- const TestSuite& test_suite);
|
|
-
|
|
- // Prints a JSON summary of unit_test to output stream out.
|
|
- static void PrintJsonUnitTest(::std::ostream* stream,
|
|
- const UnitTest& unit_test);
|
|
-
|
|
- // Produces a string representing the test properties in a result as
|
|
- // a JSON dictionary.
|
|
- static std::string TestPropertiesAsJson(const TestResult& result,
|
|
- const std::string& indent);
|
|
-
|
|
- // The output file.
|
|
- const std::string output_file_;
|
|
-
|
|
- JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;
|
|
- JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrinter&) =
|
|
- delete;
|
|
-};
|
|
-
|
|
-// Creates a new JsonUnitTestResultPrinter.
|
|
-JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
|
|
- : output_file_(output_file) {
|
|
- if (output_file_.empty()) {
|
|
- GTEST_LOG_(FATAL) << "JSON output file may not be null";
|
|
- }
|
|
-}
|
|
-
|
|
-void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
|
|
- int /*iteration*/) {
|
|
- FILE* jsonout = OpenFileForWriting(output_file_);
|
|
- std::stringstream stream;
|
|
- PrintJsonUnitTest(&stream, unit_test);
|
|
- fprintf(jsonout, "%s", StringStreamToString(&stream).c_str());
|
|
- fclose(jsonout);
|
|
-}
|
|
-
|
|
-// Returns an JSON-escaped copy of the input string str.
|
|
-std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
|
|
- Message m;
|
|
-
|
|
- for (size_t i = 0; i < str.size(); ++i) {
|
|
- const char ch = str[i];
|
|
- switch (ch) {
|
|
- case '\\':
|
|
- case '"':
|
|
- case '/':
|
|
- m << '\\' << ch;
|
|
- break;
|
|
- case '\b':
|
|
- m << "\\b";
|
|
- break;
|
|
- case '\t':
|
|
- m << "\\t";
|
|
- break;
|
|
- case '\n':
|
|
- m << "\\n";
|
|
- break;
|
|
- case '\f':
|
|
- m << "\\f";
|
|
- break;
|
|
- case '\r':
|
|
- m << "\\r";
|
|
- break;
|
|
- default:
|
|
- if (ch < ' ') {
|
|
- m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
|
|
- } else {
|
|
- m << ch;
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- return m.GetString();
|
|
-}
|
|
-
|
|
-// The following routines generate an JSON representation of a UnitTest
|
|
-// object.
|
|
-
|
|
-// Formats the given time in milliseconds as seconds.
|
|
-static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
|
|
- ::std::stringstream ss;
|
|
- ss << (static_cast<double>(ms) * 1e-3) << "s";
|
|
- return ss.str();
|
|
-}
|
|
-
|
|
-// Converts the given epoch time in milliseconds to a date string in the
|
|
-// RFC3339 format, without the timezone information.
|
|
-static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
|
|
- struct tm time_struct;
|
|
- if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))
|
|
- return "";
|
|
- // YYYY-MM-DDThh:mm:ss
|
|
- return StreamableToString(time_struct.tm_year + 1900) + "-" +
|
|
- String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
|
|
- String::FormatIntWidth2(time_struct.tm_mday) + "T" +
|
|
- String::FormatIntWidth2(time_struct.tm_hour) + ":" +
|
|
- String::FormatIntWidth2(time_struct.tm_min) + ":" +
|
|
- String::FormatIntWidth2(time_struct.tm_sec) + "Z";
|
|
-}
|
|
-
|
|
-static inline std::string Indent(size_t width) {
|
|
- return std::string(width, ' ');
|
|
-}
|
|
-
|
|
-void JsonUnitTestResultPrinter::OutputJsonKey(std::ostream* stream,
|
|
- const std::string& element_name,
|
|
- const std::string& name,
|
|
- const std::string& value,
|
|
- const std::string& indent,
|
|
- bool comma) {
|
|
- const std::vector<std::string>& allowed_names =
|
|
- GetReservedOutputAttributesForElement(element_name);
|
|
-
|
|
- GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
|
|
- allowed_names.end())
|
|
- << "Key \"" << name << "\" is not allowed for value \"" << element_name
|
|
- << "\".";
|
|
-
|
|
- *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\"";
|
|
- if (comma) *stream << ",\n";
|
|
-}
|
|
-
|
|
-void JsonUnitTestResultPrinter::OutputJsonKey(
|
|
- std::ostream* stream, const std::string& element_name,
|
|
- const std::string& name, int value, const std::string& indent, bool comma) {
|
|
- const std::vector<std::string>& allowed_names =
|
|
- GetReservedOutputAttributesForElement(element_name);
|
|
-
|
|
- GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
|
|
- allowed_names.end())
|
|
- << "Key \"" << name << "\" is not allowed for value \"" << element_name
|
|
- << "\".";
|
|
-
|
|
- *stream << indent << "\"" << name << "\": " << StreamableToString(value);
|
|
- if (comma) *stream << ",\n";
|
|
-}
|
|
-
|
|
-// Streams a test suite JSON stanza containing the given test result.
|
|
-void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(
|
|
- ::std::ostream* stream, const TestResult& result) {
|
|
- // Output the boilerplate for a new test suite.
|
|
- *stream << Indent(4) << "{\n";
|
|
- OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6));
|
|
- OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6));
|
|
- if (!GTEST_FLAG_GET(list_tests)) {
|
|
- OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6));
|
|
- OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6));
|
|
- OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6));
|
|
- OutputJsonKey(stream, "testsuite", "errors", 0, Indent(6));
|
|
- OutputJsonKey(stream, "testsuite", "time",
|
|
- FormatTimeInMillisAsDuration(result.elapsed_time()),
|
|
- Indent(6));
|
|
- OutputJsonKey(stream, "testsuite", "timestamp",
|
|
- FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
|
|
- Indent(6));
|
|
- }
|
|
- *stream << Indent(6) << "\"testsuite\": [\n";
|
|
-
|
|
- // Output the boilerplate for a new test case.
|
|
- *stream << Indent(8) << "{\n";
|
|
- OutputJsonKey(stream, "testcase", "name", "", Indent(10));
|
|
- OutputJsonKey(stream, "testcase", "status", "RUN", Indent(10));
|
|
- OutputJsonKey(stream, "testcase", "result", "COMPLETED", Indent(10));
|
|
- OutputJsonKey(stream, "testcase", "timestamp",
|
|
- FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
|
|
- Indent(10));
|
|
- OutputJsonKey(stream, "testcase", "time",
|
|
- FormatTimeInMillisAsDuration(result.elapsed_time()),
|
|
- Indent(10));
|
|
- OutputJsonKey(stream, "testcase", "classname", "", Indent(10), false);
|
|
- *stream << TestPropertiesAsJson(result, Indent(10));
|
|
-
|
|
- // Output the actual test result.
|
|
- OutputJsonTestResult(stream, result);
|
|
-
|
|
- // Finish the test suite.
|
|
- *stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}";
|
|
-}
|
|
-
|
|
-// Prints a JSON representation of a TestInfo object.
|
|
-void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
|
|
- const char* test_suite_name,
|
|
- const TestInfo& test_info) {
|
|
- const TestResult& result = *test_info.result();
|
|
- const std::string kTestsuite = "testcase";
|
|
- const std::string kIndent = Indent(10);
|
|
-
|
|
- *stream << Indent(8) << "{\n";
|
|
- OutputJsonKey(stream, kTestsuite, "name", test_info.name(), kIndent);
|
|
-
|
|
- if (test_info.value_param() != nullptr) {
|
|
- OutputJsonKey(stream, kTestsuite, "value_param", test_info.value_param(),
|
|
- kIndent);
|
|
- }
|
|
- if (test_info.type_param() != nullptr) {
|
|
- OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(),
|
|
- kIndent);
|
|
- }
|
|
-
|
|
- OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false);
|
|
- if (GTEST_FLAG_GET(list_tests)) {
|
|
- *stream << "\n" << Indent(8) << "}";
|
|
- return;
|
|
- } else {
|
|
- *stream << ",\n";
|
|
- }
|
|
-
|
|
- OutputJsonKey(stream, kTestsuite, "status",
|
|
- test_info.should_run() ? "RUN" : "NOTRUN", kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "result",
|
|
- test_info.should_run()
|
|
- ? (result.Skipped() ? "SKIPPED" : "COMPLETED")
|
|
- : "SUPPRESSED",
|
|
- kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "timestamp",
|
|
- FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
|
|
- kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "time",
|
|
- FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent,
|
|
- false);
|
|
- *stream << TestPropertiesAsJson(result, kIndent);
|
|
-
|
|
- OutputJsonTestResult(stream, result);
|
|
-}
|
|
-
|
|
-void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream,
|
|
- const TestResult& result) {
|
|
- const std::string kIndent = Indent(10);
|
|
-
|
|
- int failures = 0;
|
|
- for (int i = 0; i < result.total_part_count(); ++i) {
|
|
- const TestPartResult& part = result.GetTestPartResult(i);
|
|
- if (part.failed()) {
|
|
- *stream << ",\n";
|
|
- if (++failures == 1) {
|
|
- *stream << kIndent << "\""
|
|
- << "failures"
|
|
- << "\": [\n";
|
|
- }
|
|
- const std::string location =
|
|
- internal::FormatCompilerIndependentFileLocation(part.file_name(),
|
|
- part.line_number());
|
|
- const std::string message = EscapeJson(location + "\n" + part.message());
|
|
- *stream << kIndent << " {\n"
|
|
- << kIndent << " \"failure\": \"" << message << "\",\n"
|
|
- << kIndent << " \"type\": \"\"\n"
|
|
- << kIndent << " }";
|
|
- }
|
|
- }
|
|
-
|
|
- if (failures > 0) *stream << "\n" << kIndent << "]";
|
|
- *stream << "\n" << Indent(8) << "}";
|
|
-}
|
|
-
|
|
-// Prints an JSON representation of a TestSuite object
|
|
-void JsonUnitTestResultPrinter::PrintJsonTestSuite(
|
|
- std::ostream* stream, const TestSuite& test_suite) {
|
|
- const std::string kTestsuite = "testsuite";
|
|
- const std::string kIndent = Indent(6);
|
|
-
|
|
- *stream << Indent(4) << "{\n";
|
|
- OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(),
|
|
- kIndent);
|
|
- if (!GTEST_FLAG_GET(list_tests)) {
|
|
- OutputJsonKey(stream, kTestsuite, "failures",
|
|
- test_suite.failed_test_count(), kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "disabled",
|
|
- test_suite.reportable_disabled_test_count(), kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
|
|
- OutputJsonKey(
|
|
- stream, kTestsuite, "timestamp",
|
|
- FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()),
|
|
- kIndent);
|
|
- OutputJsonKey(stream, kTestsuite, "time",
|
|
- FormatTimeInMillisAsDuration(test_suite.elapsed_time()),
|
|
- kIndent, false);
|
|
- *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent)
|
|
- << ",\n";
|
|
- }
|
|
-
|
|
- *stream << kIndent << "\"" << kTestsuite << "\": [\n";
|
|
-
|
|
- bool comma = false;
|
|
- for (int i = 0; i < test_suite.total_test_count(); ++i) {
|
|
- if (test_suite.GetTestInfo(i)->is_reportable()) {
|
|
- if (comma) {
|
|
- *stream << ",\n";
|
|
- } else {
|
|
- comma = true;
|
|
- }
|
|
- OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
|
|
- }
|
|
- }
|
|
- *stream << "\n" << kIndent << "]\n" << Indent(4) << "}";
|
|
-}
|
|
-
|
|
-// Prints a JSON summary of unit_test to output stream out.
|
|
-void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
|
|
- const UnitTest& unit_test) {
|
|
- const std::string kTestsuites = "testsuites";
|
|
- const std::string kIndent = Indent(2);
|
|
- *stream << "{\n";
|
|
-
|
|
- OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(),
|
|
- kIndent);
|
|
- OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(),
|
|
- kIndent);
|
|
- OutputJsonKey(stream, kTestsuites, "disabled",
|
|
- unit_test.reportable_disabled_test_count(), kIndent);
|
|
- OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
|
|
- if (GTEST_FLAG_GET(shuffle)) {
|
|
- OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
|
|
- kIndent);
|
|
- }
|
|
- OutputJsonKey(stream, kTestsuites, "timestamp",
|
|
- FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),
|
|
- kIndent);
|
|
- OutputJsonKey(stream, kTestsuites, "time",
|
|
- FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,
|
|
- false);
|
|
-
|
|
- *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)
|
|
- << ",\n";
|
|
-
|
|
- OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
|
|
- *stream << kIndent << "\"" << kTestsuites << "\": [\n";
|
|
-
|
|
- bool comma = false;
|
|
- for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
|
|
- if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) {
|
|
- if (comma) {
|
|
- *stream << ",\n";
|
|
- } else {
|
|
- comma = true;
|
|
- }
|
|
- PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i));
|
|
- }
|
|
- }
|
|
-
|
|
- // If there was a test failure outside of one of the test suites (like in a
|
|
- // test environment) include that in the output.
|
|
- if (unit_test.ad_hoc_test_result().Failed()) {
|
|
- OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
|
|
- }
|
|
-
|
|
- *stream << "\n"
|
|
- << kIndent << "]\n"
|
|
- << "}\n";
|
|
-}
|
|
-
|
|
-void JsonUnitTestResultPrinter::PrintJsonTestList(
|
|
- std::ostream* stream, const std::vector<TestSuite*>& test_suites) {
|
|
- const std::string kTestsuites = "testsuites";
|
|
- const std::string kIndent = Indent(2);
|
|
- *stream << "{\n";
|
|
- int total_tests = 0;
|
|
- for (auto test_suite : test_suites) {
|
|
- total_tests += test_suite->total_test_count();
|
|
- }
|
|
- OutputJsonKey(stream, kTestsuites, "tests", total_tests, kIndent);
|
|
-
|
|
- OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
|
|
- *stream << kIndent << "\"" << kTestsuites << "\": [\n";
|
|
-
|
|
- for (size_t i = 0; i < test_suites.size(); ++i) {
|
|
- if (i != 0) {
|
|
- *stream << ",\n";
|
|
- }
|
|
- PrintJsonTestSuite(stream, *test_suites[i]);
|
|
- }
|
|
-
|
|
- *stream << "\n"
|
|
- << kIndent << "]\n"
|
|
- << "}\n";
|
|
-}
|
|
-// Produces a string representing the test properties in a result as
|
|
-// a JSON dictionary.
|
|
-std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
|
|
- const TestResult& result, const std::string& indent) {
|
|
- Message attributes;
|
|
- for (int i = 0; i < result.test_property_count(); ++i) {
|
|
- const TestProperty& property = result.GetTestProperty(i);
|
|
- attributes << ",\n"
|
|
- << indent << "\"" << property.key() << "\": "
|
|
- << "\"" << EscapeJson(property.value()) << "\"";
|
|
- }
|
|
- return attributes.GetString();
|
|
-}
|
|
-
|
|
-// End JsonUnitTestResultPrinter
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
-
|
|
-// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
|
|
-// replaces them by "%xx" where xx is their hexadecimal value. For
|
|
-// example, replaces "=" with "%3D". This algorithm is O(strlen(str))
|
|
-// in both time and space -- important as the input str may contain an
|
|
-// arbitrarily long test failure message and stack trace.
|
|
-std::string StreamingListener::UrlEncode(const char* str) {
|
|
- std::string result;
|
|
- result.reserve(strlen(str) + 1);
|
|
- for (char ch = *str; ch != '\0'; ch = *++str) {
|
|
- switch (ch) {
|
|
- case '%':
|
|
- case '=':
|
|
- case '&':
|
|
- case '\n':
|
|
- result.append("%" + String::FormatByte(static_cast<unsigned char>(ch)));
|
|
- break;
|
|
- default:
|
|
- result.push_back(ch);
|
|
- break;
|
|
- }
|
|
- }
|
|
- return result;
|
|
-}
|
|
-
|
|
-void StreamingListener::SocketWriter::MakeConnection() {
|
|
- GTEST_CHECK_(sockfd_ == -1)
|
|
- << "MakeConnection() can't be called when there is already a connection.";
|
|
-
|
|
- addrinfo hints;
|
|
- memset(&hints, 0, sizeof(hints));
|
|
- hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses.
|
|
- hints.ai_socktype = SOCK_STREAM;
|
|
- addrinfo* servinfo = nullptr;
|
|
-
|
|
- // Use the getaddrinfo() to get a linked list of IP addresses for
|
|
- // the given host name.
|
|
- const int error_num =
|
|
- getaddrinfo(host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);
|
|
- if (error_num != 0) {
|
|
- GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: "
|
|
- << gai_strerror(error_num);
|
|
- }
|
|
-
|
|
- // Loop through all the results and connect to the first we can.
|
|
- for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr;
|
|
- cur_addr = cur_addr->ai_next) {
|
|
- sockfd_ = socket(cur_addr->ai_family, cur_addr->ai_socktype,
|
|
- cur_addr->ai_protocol);
|
|
- if (sockfd_ != -1) {
|
|
- // Connect the client socket to the server socket.
|
|
- if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {
|
|
- close(sockfd_);
|
|
- sockfd_ = -1;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- freeaddrinfo(servinfo); // all done with this structure
|
|
-
|
|
- if (sockfd_ == -1) {
|
|
- GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to "
|
|
- << host_name_ << ":" << port_num_;
|
|
- }
|
|
-}
|
|
-
|
|
-// End of class Streaming Listener
|
|
-#endif // GTEST_CAN_STREAM_RESULTS__
|
|
-
|
|
-// class OsStackTraceGetter
|
|
-
|
|
-const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
|
|
- "... " GTEST_NAME_ " internal frames ...";
|
|
-
|
|
-std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
|
|
- GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
-#if GTEST_HAS_ABSL
|
|
- std::string result;
|
|
-
|
|
- if (max_depth <= 0) {
|
|
- return result;
|
|
- }
|
|
-
|
|
- max_depth = std::min(max_depth, kMaxStackTraceDepth);
|
|
-
|
|
- std::vector<void*> raw_stack(max_depth);
|
|
- // Skips the frames requested by the caller, plus this function.
|
|
- const int raw_stack_size =
|
|
- absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1);
|
|
-
|
|
- void* caller_frame = nullptr;
|
|
- {
|
|
- MutexLock lock(&mutex_);
|
|
- caller_frame = caller_frame_;
|
|
- }
|
|
-
|
|
- for (int i = 0; i < raw_stack_size; ++i) {
|
|
- if (raw_stack[i] == caller_frame &&
|
|
- !GTEST_FLAG_GET(show_internal_stack_frames)) {
|
|
- // Add a marker to the trace and stop adding frames.
|
|
- absl::StrAppend(&result, kElidedFramesMarker, "\n");
|
|
- break;
|
|
- }
|
|
-
|
|
- char tmp[1024];
|
|
- const char* symbol = "(unknown)";
|
|
- if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) {
|
|
- symbol = tmp;
|
|
- }
|
|
-
|
|
- char line[1024];
|
|
- snprintf(line, sizeof(line), " %p: %s\n", raw_stack[i], symbol);
|
|
- result += line;
|
|
- }
|
|
-
|
|
- return result;
|
|
-
|
|
-#else // !GTEST_HAS_ABSL
|
|
- static_cast<void>(max_depth);
|
|
- static_cast<void>(skip_count);
|
|
- return "";
|
|
-#endif // GTEST_HAS_ABSL
|
|
-}
|
|
-
|
|
-void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
-#if GTEST_HAS_ABSL
|
|
- void* caller_frame = nullptr;
|
|
- if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) {
|
|
- caller_frame = nullptr;
|
|
- }
|
|
-
|
|
- MutexLock lock(&mutex_);
|
|
- caller_frame_ = caller_frame;
|
|
-#endif // GTEST_HAS_ABSL
|
|
-}
|
|
-
|
|
-// A helper class that creates the premature-exit file in its
|
|
-// constructor and deletes the file in its destructor.
|
|
-class ScopedPrematureExitFile {
|
|
- public:
|
|
- explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
|
|
- : premature_exit_filepath_(
|
|
- premature_exit_filepath ? premature_exit_filepath : "") {
|
|
- // If a path to the premature-exit file is specified...
|
|
- if (!premature_exit_filepath_.empty()) {
|
|
- // create the file with a single "0" character in it. I/O
|
|
- // errors are ignored as there's nothing better we can do and we
|
|
- // don't want to fail the test because of this.
|
|
- FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w");
|
|
- fwrite("0", 1, 1, pfile);
|
|
- fclose(pfile);
|
|
- }
|
|
- }
|
|
-
|
|
- ~ScopedPrematureExitFile() {
|
|
-#if !defined GTEST_OS_ESP8266
|
|
- if (!premature_exit_filepath_.empty()) {
|
|
- int retval = remove(premature_exit_filepath_.c_str());
|
|
- if (retval) {
|
|
- GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
|
|
- << premature_exit_filepath_ << "\" with error "
|
|
- << retval;
|
|
- }
|
|
- }
|
|
-#endif
|
|
- }
|
|
-
|
|
- private:
|
|
- const std::string premature_exit_filepath_;
|
|
-
|
|
- ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;
|
|
- ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;
|
|
-};
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// class TestEventListeners
|
|
-
|
|
-TestEventListeners::TestEventListeners()
|
|
- : repeater_(new internal::TestEventRepeater()),
|
|
- default_result_printer_(nullptr),
|
|
- default_xml_generator_(nullptr) {}
|
|
-
|
|
-TestEventListeners::~TestEventListeners() { delete repeater_; }
|
|
-
|
|
-// Returns the standard listener responsible for the default console
|
|
-// output. Can be removed from the listeners list to shut down default
|
|
-// console output. Note that removing this object from the listener list
|
|
-// with Release transfers its ownership to the user.
|
|
-void TestEventListeners::Append(TestEventListener* listener) {
|
|
- repeater_->Append(listener);
|
|
-}
|
|
-
|
|
-// Removes the given event listener from the list and returns it. It then
|
|
-// becomes the caller's responsibility to delete the listener. Returns
|
|
-// NULL if the listener is not found in the list.
|
|
-TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
|
|
- if (listener == default_result_printer_)
|
|
- default_result_printer_ = nullptr;
|
|
- else if (listener == default_xml_generator_)
|
|
- default_xml_generator_ = nullptr;
|
|
- return repeater_->Release(listener);
|
|
-}
|
|
-
|
|
-// Returns repeater that broadcasts the TestEventListener events to all
|
|
-// subscribers.
|
|
-TestEventListener* TestEventListeners::repeater() { return repeater_; }
|
|
-
|
|
-// Sets the default_result_printer attribute to the provided listener.
|
|
-// The listener is also added to the listener list and previous
|
|
-// default_result_printer is removed from it and deleted. The listener can
|
|
-// also be NULL in which case it will not be added to the list. Does
|
|
-// nothing if the previous and the current listener objects are the same.
|
|
-void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
|
|
- if (default_result_printer_ != listener) {
|
|
- // It is an error to pass this method a listener that is already in the
|
|
- // list.
|
|
- delete Release(default_result_printer_);
|
|
- default_result_printer_ = listener;
|
|
- if (listener != nullptr) Append(listener);
|
|
- }
|
|
-}
|
|
-
|
|
-// Sets the default_xml_generator attribute to the provided listener. The
|
|
-// listener is also added to the listener list and previous
|
|
-// default_xml_generator is removed from it and deleted. The listener can
|
|
-// also be NULL in which case it will not be added to the list. Does
|
|
-// nothing if the previous and the current listener objects are the same.
|
|
-void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
|
|
- if (default_xml_generator_ != listener) {
|
|
- // It is an error to pass this method a listener that is already in the
|
|
- // list.
|
|
- delete Release(default_xml_generator_);
|
|
- default_xml_generator_ = listener;
|
|
- if (listener != nullptr) Append(listener);
|
|
- }
|
|
-}
|
|
-
|
|
-// Controls whether events will be forwarded by the repeater to the
|
|
-// listeners in the list.
|
|
-bool TestEventListeners::EventForwardingEnabled() const {
|
|
- return repeater_->forwarding_enabled();
|
|
-}
|
|
-
|
|
-void TestEventListeners::SuppressEventForwarding() {
|
|
- repeater_->set_forwarding_enabled(false);
|
|
-}
|
|
-
|
|
-// class UnitTest
|
|
-
|
|
-// Gets the singleton UnitTest object. The first time this method is
|
|
-// called, a UnitTest object is constructed and returned. Consecutive
|
|
-// calls will return the same object.
|
|
-//
|
|
-// We don't protect this under mutex_ as a user is not supposed to
|
|
-// call this before main() starts, from which point on the return
|
|
-// value will never change.
|
|
-UnitTest* UnitTest::GetInstance() {
|
|
- // CodeGear C++Builder insists on a public destructor for the
|
|
- // default implementation. Use this implementation to keep good OO
|
|
- // design with private destructor.
|
|
-
|
|
-#if defined(__BORLANDC__)
|
|
- static UnitTest* const instance = new UnitTest;
|
|
- return instance;
|
|
-#else
|
|
- static UnitTest instance;
|
|
- return &instance;
|
|
-#endif // defined(__BORLANDC__)
|
|
-}
|
|
-
|
|
-// Gets the number of successful test suites.
|
|
-int UnitTest::successful_test_suite_count() const {
|
|
- return impl()->successful_test_suite_count();
|
|
-}
|
|
-
|
|
-// Gets the number of failed test suites.
|
|
-int UnitTest::failed_test_suite_count() const {
|
|
- return impl()->failed_test_suite_count();
|
|
-}
|
|
-
|
|
-// Gets the number of all test suites.
|
|
-int UnitTest::total_test_suite_count() const {
|
|
- return impl()->total_test_suite_count();
|
|
-}
|
|
-
|
|
-// Gets the number of all test suites that contain at least one test
|
|
-// that should run.
|
|
-int UnitTest::test_suite_to_run_count() const {
|
|
- return impl()->test_suite_to_run_count();
|
|
-}
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-int UnitTest::successful_test_case_count() const {
|
|
- return impl()->successful_test_suite_count();
|
|
-}
|
|
-int UnitTest::failed_test_case_count() const {
|
|
- return impl()->failed_test_suite_count();
|
|
-}
|
|
-int UnitTest::total_test_case_count() const {
|
|
- return impl()->total_test_suite_count();
|
|
-}
|
|
-int UnitTest::test_case_to_run_count() const {
|
|
- return impl()->test_suite_to_run_count();
|
|
-}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-// Gets the number of successful tests.
|
|
-int UnitTest::successful_test_count() const {
|
|
- return impl()->successful_test_count();
|
|
-}
|
|
-
|
|
-// Gets the number of skipped tests.
|
|
-int UnitTest::skipped_test_count() const {
|
|
- return impl()->skipped_test_count();
|
|
-}
|
|
-
|
|
-// Gets the number of failed tests.
|
|
-int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
|
|
-
|
|
-// Gets the number of disabled tests that will be reported in the XML report.
|
|
-int UnitTest::reportable_disabled_test_count() const {
|
|
- return impl()->reportable_disabled_test_count();
|
|
-}
|
|
-
|
|
-// Gets the number of disabled tests.
|
|
-int UnitTest::disabled_test_count() const {
|
|
- return impl()->disabled_test_count();
|
|
-}
|
|
-
|
|
-// Gets the number of tests to be printed in the XML report.
|
|
-int UnitTest::reportable_test_count() const {
|
|
- return impl()->reportable_test_count();
|
|
-}
|
|
-
|
|
-// Gets the number of all tests.
|
|
-int UnitTest::total_test_count() const { return impl()->total_test_count(); }
|
|
-
|
|
-// Gets the number of tests that should run.
|
|
-int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
|
|
-
|
|
-// Gets the time of the test program start, in ms from the start of the
|
|
-// UNIX epoch.
|
|
-internal::TimeInMillis UnitTest::start_timestamp() const {
|
|
- return impl()->start_timestamp();
|
|
-}
|
|
-
|
|
-// Gets the elapsed time, in milliseconds.
|
|
-internal::TimeInMillis UnitTest::elapsed_time() const {
|
|
- return impl()->elapsed_time();
|
|
-}
|
|
-
|
|
-// Returns true if and only if the unit test passed (i.e. all test suites
|
|
-// passed).
|
|
-bool UnitTest::Passed() const { return impl()->Passed(); }
|
|
-
|
|
-// Returns true if and only if the unit test failed (i.e. some test suite
|
|
-// failed or something outside of all tests failed).
|
|
-bool UnitTest::Failed() const { return impl()->Failed(); }
|
|
-
|
|
-// Gets the i-th test suite among all the test suites. i can range from 0 to
|
|
-// total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
|
-const TestSuite* UnitTest::GetTestSuite(int i) const {
|
|
- return impl()->GetTestSuite(i);
|
|
-}
|
|
-
|
|
-// Legacy API is deprecated but still available
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-const TestCase* UnitTest::GetTestCase(int i) const {
|
|
- return impl()->GetTestCase(i);
|
|
-}
|
|
-#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-
|
|
-// Returns the TestResult containing information on test failures and
|
|
-// properties logged outside of individual test suites.
|
|
-const TestResult& UnitTest::ad_hoc_test_result() const {
|
|
- return *impl()->ad_hoc_test_result();
|
|
-}
|
|
-
|
|
-// Gets the i-th test suite among all the test suites. i can range from 0 to
|
|
-// total_test_suite_count() - 1. If i is not in that range, returns NULL.
|
|
-TestSuite* UnitTest::GetMutableTestSuite(int i) {
|
|
- return impl()->GetMutableSuiteCase(i);
|
|
-}
|
|
-
|
|
-// Returns the list of event listeners that can be used to track events
|
|
-// inside Google Test.
|
|
-TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); }
|
|
-
|
|
-// Registers and returns a global test environment. When a test
|
|
-// program is run, all global test environments will be set-up in the
|
|
-// order they were registered. After all tests in the program have
|
|
-// finished, all global test environments will be torn-down in the
|
|
-// *reverse* order they were registered.
|
|
-//
|
|
-// The UnitTest object takes ownership of the given environment.
|
|
-//
|
|
-// We don't protect this under mutex_, as we only support calling it
|
|
-// from the main thread.
|
|
-Environment* UnitTest::AddEnvironment(Environment* env) {
|
|
- if (env == nullptr) {
|
|
- return nullptr;
|
|
- }
|
|
-
|
|
- impl_->environments().push_back(env);
|
|
- return env;
|
|
-}
|
|
-
|
|
-// Adds a TestPartResult to the current TestResult object. All Google Test
|
|
-// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
|
|
-// this to report their results. The user code should use the
|
|
-// assertion macros instead of calling this directly.
|
|
-void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
|
|
- const char* file_name, int line_number,
|
|
- const std::string& message,
|
|
- const std::string& os_stack_trace)
|
|
- GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- Message msg;
|
|
- msg << message;
|
|
-
|
|
- internal::MutexLock lock(&mutex_);
|
|
- if (impl_->gtest_trace_stack().size() > 0) {
|
|
- msg << "\n" << GTEST_NAME_ << " trace:";
|
|
-
|
|
- for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) {
|
|
- const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
|
|
- msg << "\n"
|
|
- << internal::FormatFileLocation(trace.file, trace.line) << " "
|
|
- << trace.message;
|
|
- }
|
|
- }
|
|
-
|
|
- if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) {
|
|
- msg << internal::kStackTraceMarker << os_stack_trace;
|
|
- }
|
|
-
|
|
- const TestPartResult result = TestPartResult(
|
|
- result_type, file_name, line_number, msg.GetString().c_str());
|
|
- impl_->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(
|
|
- result);
|
|
-
|
|
- if (result_type != TestPartResult::kSuccess &&
|
|
- result_type != TestPartResult::kSkip) {
|
|
- // gtest_break_on_failure takes precedence over
|
|
- // gtest_throw_on_failure. This allows a user to set the latter
|
|
- // in the code (perhaps in order to use Google Test assertions
|
|
- // with another testing framework) and specify the former on the
|
|
- // command line for debugging.
|
|
- if (GTEST_FLAG_GET(break_on_failure)) {
|
|
-#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
|
- // Using DebugBreak on Windows allows gtest to still break into a debugger
|
|
- // when a failure happens and both the --gtest_break_on_failure and
|
|
- // the --gtest_catch_exceptions flags are specified.
|
|
- DebugBreak();
|
|
-#elif (!defined(__native_client__)) && \
|
|
- ((defined(__clang__) || defined(__GNUC__)) && \
|
|
- (defined(__x86_64__) || defined(__i386__)))
|
|
- // with clang/gcc we can achieve the same effect on x86 by invoking int3
|
|
- asm("int3");
|
|
-#else
|
|
- // Dereference nullptr through a volatile pointer to prevent the compiler
|
|
- // from removing. We use this rather than abort() or __builtin_trap() for
|
|
- // portability: some debuggers don't correctly trap abort().
|
|
- *static_cast<volatile int*>(nullptr) = 1;
|
|
-#endif // GTEST_OS_WINDOWS
|
|
- } else if (GTEST_FLAG_GET(throw_on_failure)) {
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
- throw internal::GoogleTestFailureException(result);
|
|
-#else
|
|
- // We cannot call abort() as it generates a pop-up in debug mode
|
|
- // that cannot be suppressed in VC 7.1 or below.
|
|
- exit(1);
|
|
-#endif
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-// Adds a TestProperty to the current TestResult object when invoked from
|
|
-// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked
|
|
-// from SetUpTestSuite or TearDownTestSuite, or to the global property set
|
|
-// when invoked elsewhere. If the result already contains a property with
|
|
-// the same key, the value will be updated.
|
|
-void UnitTest::RecordProperty(const std::string& key,
|
|
- const std::string& value) {
|
|
- impl_->RecordProperty(TestProperty(key, value));
|
|
-}
|
|
-
|
|
-// Runs all tests in this UnitTest object and prints the result.
|
|
-// Returns 0 if successful, or 1 otherwise.
|
|
-//
|
|
-// We don't protect this under mutex_, as we only support calling it
|
|
-// from the main thread.
|
|
-int UnitTest::Run() {
|
|
- const bool in_death_test_child_process =
|
|
- GTEST_FLAG_GET(internal_run_death_test).length() > 0;
|
|
-
|
|
- // Google Test implements this protocol for catching that a test
|
|
- // program exits before returning control to Google Test:
|
|
- //
|
|
- // 1. Upon start, Google Test creates a file whose absolute path
|
|
- // is specified by the environment variable
|
|
- // TEST_PREMATURE_EXIT_FILE.
|
|
- // 2. When Google Test has finished its work, it deletes the file.
|
|
- //
|
|
- // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before
|
|
- // running a Google-Test-based test program and check the existence
|
|
- // of the file at the end of the test execution to see if it has
|
|
- // exited prematurely.
|
|
-
|
|
- // If we are in the child process of a death test, don't
|
|
- // create/delete the premature exit file, as doing so is unnecessary
|
|
- // and will confuse the parent process. Otherwise, create/delete
|
|
- // the file upon entering/leaving this function. If the program
|
|
- // somehow exits before this function has a chance to return, the
|
|
- // premature-exit file will be left undeleted, causing a test runner
|
|
- // that understands the premature-exit-file protocol to report the
|
|
- // test as having failed.
|
|
- const internal::ScopedPrematureExitFile premature_exit_file(
|
|
- in_death_test_child_process
|
|
- ? nullptr
|
|
- : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
|
|
-
|
|
- // Captures the value of GTEST_FLAG(catch_exceptions). This value will be
|
|
- // used for the duration of the program.
|
|
- impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions));
|
|
-
|
|
-#if GTEST_OS_WINDOWS
|
|
- // Either the user wants Google Test to catch exceptions thrown by the
|
|
- // tests or this is executing in the context of death test child
|
|
- // process. In either case the user does not want to see pop-up dialogs
|
|
- // about crashes - they are expected.
|
|
- if (impl()->catch_exceptions() || in_death_test_child_process) {
|
|
-#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
|
- // SetErrorMode doesn't exist on CE.
|
|
- SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
|
|
- SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
|
-#endif // !GTEST_OS_WINDOWS_MOBILE
|
|
-
|
|
-#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
|
|
- // Death test children can be terminated with _abort(). On Windows,
|
|
- // _abort() can show a dialog with a warning message. This forces the
|
|
- // abort message to go to stderr instead.
|
|
- _set_error_mode(_OUT_TO_STDERR);
|
|
-#endif
|
|
-
|
|
-#if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE
|
|
- // In the debug version, Visual Studio pops up a separate dialog
|
|
- // offering a choice to debug the aborted program. We need to suppress
|
|
- // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
|
|
- // executed. Google Test will notify the user of any unexpected
|
|
- // failure via stderr.
|
|
- if (!GTEST_FLAG_GET(break_on_failure))
|
|
- _set_abort_behavior(
|
|
- 0x0, // Clear the following flags:
|
|
- _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
|
|
-
|
|
- // In debug mode, the Windows CRT can crash with an assertion over invalid
|
|
- // input (e.g. passing an invalid file descriptor). The default handling
|
|
- // for these assertions is to pop up a dialog and wait for user input.
|
|
- // Instead ask the CRT to dump such assertions to stderr non-interactively.
|
|
- if (!IsDebuggerPresent()) {
|
|
- (void)_CrtSetReportMode(_CRT_ASSERT,
|
|
- _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
|
|
- (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
|
- }
|
|
-#endif
|
|
- }
|
|
-#endif // GTEST_OS_WINDOWS
|
|
-
|
|
- return internal::HandleExceptionsInMethodIfSupported(
|
|
- impl(), &internal::UnitTestImpl::RunAllTests,
|
|
- "auxiliary test code (environments or event listeners)")
|
|
- ? 0
|
|
- : 1;
|
|
-}
|
|
-
|
|
-// Returns the working directory when the first TEST() or TEST_F() was
|
|
-// executed.
|
|
-const char* UnitTest::original_working_dir() const {
|
|
- return impl_->original_working_dir_.c_str();
|
|
-}
|
|
-
|
|
-// Returns the TestSuite object for the test that's currently running,
|
|
-// or NULL if no test is running.
|
|
-const TestSuite* UnitTest::current_test_suite() const
|
|
- GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- internal::MutexLock lock(&mutex_);
|
|
- return impl_->current_test_suite();
|
|
-}
|
|
-
|
|
-// Legacy API is still available but deprecated
|
|
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
|
-const TestCase* UnitTest::current_test_case() const
|
|
- GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- internal::MutexLock lock(&mutex_);
|
|
- return impl_->current_test_suite();
|
|
-}
|
|
-#endif
|
|
-
|
|
-// Returns the TestInfo object for the test that's currently running,
|
|
-// or NULL if no test is running.
|
|
-const TestInfo* UnitTest::current_test_info() const
|
|
- GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- internal::MutexLock lock(&mutex_);
|
|
- return impl_->current_test_info();
|
|
-}
|
|
-
|
|
-// Returns the random seed used at the start of the current test run.
|
|
-int UnitTest::random_seed() const { return impl_->random_seed(); }
|
|
-
|
|
-// Returns ParameterizedTestSuiteRegistry object used to keep track of
|
|
-// value-parameterized tests and instantiate and register them.
|
|
-internal::ParameterizedTestSuiteRegistry&
|
|
-UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- return impl_->parameterized_test_registry();
|
|
-}
|
|
-
|
|
-// Creates an empty UnitTest.
|
|
-UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); }
|
|
-
|
|
-// Destructor of UnitTest.
|
|
-UnitTest::~UnitTest() { delete impl_; }
|
|
-
|
|
-// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
|
|
-// Google Test trace stack.
|
|
-void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
|
|
- GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- internal::MutexLock lock(&mutex_);
|
|
- impl_->gtest_trace_stack().push_back(trace);
|
|
-}
|
|
-
|
|
-// Pops a trace from the per-thread Google Test trace stack.
|
|
-void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
|
|
- internal::MutexLock lock(&mutex_);
|
|
- impl_->gtest_trace_stack().pop_back();
|
|
-}
|
|
-
|
|
-namespace internal {
|
|
-
|
|
-UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
|
- : parent_(parent),
|
|
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)
|
|
- default_global_test_part_result_reporter_(this),
|
|
- default_per_thread_test_part_result_reporter_(this),
|
|
- GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_(
|
|
- &default_global_test_part_result_reporter_),
|
|
- per_thread_test_part_result_reporter_(
|
|
- &default_per_thread_test_part_result_reporter_),
|
|
- parameterized_test_registry_(),
|
|
- parameterized_tests_registered_(false),
|
|
- last_death_test_suite_(-1),
|
|
- current_test_suite_(nullptr),
|
|
- current_test_info_(nullptr),
|
|
- ad_hoc_test_result_(),
|
|
- os_stack_trace_getter_(nullptr),
|
|
- post_flag_parse_init_performed_(false),
|
|
- random_seed_(0), // Will be overridden by the flag before first use.
|
|
- random_(0), // Will be reseeded before first use.
|
|
- start_timestamp_(0),
|
|
- elapsed_time_(0),
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
- death_test_factory_(new DefaultDeathTestFactory),
|
|
-#endif
|
|
- // Will be overridden by the flag before first use.
|
|
- catch_exceptions_(false) {
|
|
- listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
|
|
-}
|
|
-
|
|
-UnitTestImpl::~UnitTestImpl() {
|
|
- // Deletes every TestSuite.
|
|
- ForEach(test_suites_, internal::Delete<TestSuite>);
|
|
-
|
|
- // Deletes every Environment.
|
|
- ForEach(environments_, internal::Delete<Environment>);
|
|
-
|
|
- delete os_stack_trace_getter_;
|
|
-}
|
|
-
|
|
-// Adds a TestProperty to the current TestResult object when invoked in a
|
|
-// context of a test, to current test suite's ad_hoc_test_result when invoke
|
|
-// from SetUpTestSuite/TearDownTestSuite, or to the global property set
|
|
-// otherwise. If the result already contains a property with the same key,
|
|
-// the value will be updated.
|
|
-void UnitTestImpl::RecordProperty(const TestProperty& test_property) {
|
|
- std::string xml_element;
|
|
- TestResult* test_result; // TestResult appropriate for property recording.
|
|
-
|
|
- if (current_test_info_ != nullptr) {
|
|
- xml_element = "testcase";
|
|
- test_result = &(current_test_info_->result_);
|
|
- } else if (current_test_suite_ != nullptr) {
|
|
- xml_element = "testsuite";
|
|
- test_result = &(current_test_suite_->ad_hoc_test_result_);
|
|
- } else {
|
|
- xml_element = "testsuites";
|
|
- test_result = &ad_hoc_test_result_;
|
|
- }
|
|
- test_result->RecordProperty(xml_element, test_property);
|
|
-}
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
-// Disables event forwarding if the control is currently in a death test
|
|
-// subprocess. Must not be called before InitGoogleTest.
|
|
-void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
|
|
- if (internal_run_death_test_flag_.get() != nullptr)
|
|
- listeners()->SuppressEventForwarding();
|
|
-}
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
-// Initializes event listeners performing XML output as specified by
|
|
-// UnitTestOptions. Must not be called before InitGoogleTest.
|
|
-void UnitTestImpl::ConfigureXmlOutput() {
|
|
- const std::string& output_format = UnitTestOptions::GetOutputFormat();
|
|
- if (output_format == "xml") {
|
|
- listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
|
|
- UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
|
- } else if (output_format == "json") {
|
|
- listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
|
|
- UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
|
|
- } else if (output_format != "") {
|
|
- GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
|
|
- << output_format << "\" ignored.";
|
|
- }
|
|
-}
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
-// Initializes event listeners for streaming test results in string form.
|
|
-// Must not be called before InitGoogleTest.
|
|
-void UnitTestImpl::ConfigureStreamingOutput() {
|
|
- const std::string& target = GTEST_FLAG_GET(stream_result_to);
|
|
- if (!target.empty()) {
|
|
- const size_t pos = target.find(':');
|
|
- if (pos != std::string::npos) {
|
|
- listeners()->Append(
|
|
- new StreamingListener(target.substr(0, pos), target.substr(pos + 1)));
|
|
- } else {
|
|
- GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
|
|
- << "\" ignored.";
|
|
- }
|
|
- }
|
|
-}
|
|
-#endif // GTEST_CAN_STREAM_RESULTS_
|
|
-
|
|
-// Performs initialization dependent upon flag values obtained in
|
|
-// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
|
|
-// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
|
|
-// this function is also called from RunAllTests. Since this function can be
|
|
-// called more than once, it has to be idempotent.
|
|
-void UnitTestImpl::PostFlagParsingInit() {
|
|
- // Ensures that this function does not execute more than once.
|
|
- if (!post_flag_parse_init_performed_) {
|
|
- post_flag_parse_init_performed_ = true;
|
|
-
|
|
-#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)
|
|
- // Register to send notifications about key process state changes.
|
|
- listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_());
|
|
-#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
- InitDeathTestSubprocessControlInfo();
|
|
- SuppressTestEventsIfInSubprocess();
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
- // Registers parameterized tests. This makes parameterized tests
|
|
- // available to the UnitTest reflection API without running
|
|
- // RUN_ALL_TESTS.
|
|
- RegisterParameterizedTests();
|
|
-
|
|
- // Configures listeners for XML output. This makes it possible for users
|
|
- // to shut down the default XML output before invoking RUN_ALL_TESTS.
|
|
- ConfigureXmlOutput();
|
|
-
|
|
- if (GTEST_FLAG_GET(brief)) {
|
|
- listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter);
|
|
- }
|
|
-
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
- // Configures listeners for streaming test results to the specified server.
|
|
- ConfigureStreamingOutput();
|
|
-#endif // GTEST_CAN_STREAM_RESULTS_
|
|
-
|
|
-#if GTEST_HAS_ABSL
|
|
- if (GTEST_FLAG_GET(install_failure_signal_handler)) {
|
|
- absl::FailureSignalHandlerOptions options;
|
|
- absl::InstallFailureSignalHandler(options);
|
|
- }
|
|
-#endif // GTEST_HAS_ABSL
|
|
- }
|
|
-}
|
|
-
|
|
-// A predicate that checks the name of a TestSuite against a known
|
|
-// value.
|
|
-//
|
|
-// This is used for implementation of the UnitTest class only. We put
|
|
-// it in the anonymous namespace to prevent polluting the outer
|
|
-// namespace.
|
|
-//
|
|
-// TestSuiteNameIs is copyable.
|
|
-class TestSuiteNameIs {
|
|
- public:
|
|
- // Constructor.
|
|
- explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
|
|
-
|
|
- // Returns true if and only if the name of test_suite matches name_.
|
|
- bool operator()(const TestSuite* test_suite) const {
|
|
- return test_suite != nullptr &&
|
|
- strcmp(test_suite->name(), name_.c_str()) == 0;
|
|
- }
|
|
-
|
|
- private:
|
|
- std::string name_;
|
|
-};
|
|
-
|
|
-// Finds and returns a TestSuite with the given name. If one doesn't
|
|
-// exist, creates one and returns it. It's the CALLER'S
|
|
-// RESPONSIBILITY to ensure that this function is only called WHEN THE
|
|
-// TESTS ARE NOT SHUFFLED.
|
|
-//
|
|
-// Arguments:
|
|
-//
|
|
-// test_suite_name: name of the test suite
|
|
-// type_param: the name of the test suite's type parameter, or NULL if
|
|
-// this is not a typed or a type-parameterized test suite.
|
|
-// 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* UnitTestImpl::GetTestSuite(
|
|
- const char* test_suite_name, const char* type_param,
|
|
- internal::SetUpTestSuiteFunc set_up_tc,
|
|
- internal::TearDownTestSuiteFunc tear_down_tc) {
|
|
- // Can we find a TestSuite with the given name?
|
|
- const auto test_suite =
|
|
- std::find_if(test_suites_.rbegin(), test_suites_.rend(),
|
|
- TestSuiteNameIs(test_suite_name));
|
|
-
|
|
- if (test_suite != test_suites_.rend()) return *test_suite;
|
|
-
|
|
- // No. Let's create one.
|
|
- auto* const new_test_suite =
|
|
- new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
|
|
-
|
|
- const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);
|
|
- // Is this a death test suite?
|
|
- if (death_test_suite_filter.MatchesName(test_suite_name)) {
|
|
- // Yes. Inserts the test suite after the last death test suite
|
|
- // defined so far. This only works when the test suites haven't
|
|
- // been shuffled. Otherwise we may end up running a death test
|
|
- // after a non-death test.
|
|
- ++last_death_test_suite_;
|
|
- test_suites_.insert(test_suites_.begin() + last_death_test_suite_,
|
|
- new_test_suite);
|
|
- } else {
|
|
- // No. Appends to the end of the list.
|
|
- test_suites_.push_back(new_test_suite);
|
|
- }
|
|
-
|
|
- test_suite_indices_.push_back(static_cast<int>(test_suite_indices_.size()));
|
|
- return new_test_suite;
|
|
-}
|
|
-
|
|
-// Helpers for setting up / tearing down the given environment. They
|
|
-// are for use in the ForEach() function.
|
|
-static void SetUpEnvironment(Environment* env) { env->SetUp(); }
|
|
-static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
|
-
|
|
-// Runs all tests in this UnitTest object, prints the result, and
|
|
-// returns true if all tests are successful. If any exception is
|
|
-// thrown during a test, the test is considered to be failed, but the
|
|
-// rest of the tests will still be run.
|
|
-//
|
|
-// When parameterized tests are enabled, it expands and registers
|
|
-// parameterized tests first in RegisterParameterizedTests().
|
|
-// All other functions called from RunAllTests() may safely assume that
|
|
-// parameterized tests are ready to be counted and run.
|
|
-bool UnitTestImpl::RunAllTests() {
|
|
- // True if and only if Google Test is initialized before RUN_ALL_TESTS() is
|
|
- // called.
|
|
- const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
|
|
-
|
|
- // Do not run any test if the --help flag was specified.
|
|
- if (g_help_flag) return true;
|
|
-
|
|
- // Repeats the call to the post-flag parsing initialization in case the
|
|
- // user didn't call InitGoogleTest.
|
|
- PostFlagParsingInit();
|
|
-
|
|
- // Even if sharding is not on, test runners may want to use the
|
|
- // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
|
- // protocol.
|
|
- internal::WriteToShardStatusFileIfNeeded();
|
|
-
|
|
- // True if and only if we are in a subprocess for running a thread-safe-style
|
|
- // death test.
|
|
- bool in_subprocess_for_death_test = false;
|
|
-
|
|
-#if GTEST_HAS_DEATH_TEST
|
|
- in_subprocess_for_death_test =
|
|
- (internal_run_death_test_flag_.get() != nullptr);
|
|
-#if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
|
|
- if (in_subprocess_for_death_test) {
|
|
- GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();
|
|
- }
|
|
-#endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
|
|
-#endif // GTEST_HAS_DEATH_TEST
|
|
-
|
|
- const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
|
|
- in_subprocess_for_death_test);
|
|
-
|
|
- // Compares the full test names with the filter to decide which
|
|
- // tests to run.
|
|
- const bool has_tests_to_run =
|
|
- FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL
|
|
- : IGNORE_SHARDING_PROTOCOL) > 0;
|
|
-
|
|
- // Lists the tests and exits if the --gtest_list_tests flag was specified.
|
|
- if (GTEST_FLAG_GET(list_tests)) {
|
|
- // This must be called *after* FilterTests() has been called.
|
|
- ListTestsMatchingFilter();
|
|
- return true;
|
|
- }
|
|
-
|
|
- random_seed_ = GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed));
|
|
-
|
|
- // True if and only if at least one test has failed.
|
|
- bool failed = false;
|
|
-
|
|
- TestEventListener* repeater = listeners()->repeater();
|
|
-
|
|
- start_timestamp_ = GetTimeInMillis();
|
|
- repeater->OnTestProgramStart(*parent_);
|
|
-
|
|
- // How many times to repeat the tests? We don't want to repeat them
|
|
- // when we are inside the subprocess of a death test.
|
|
- const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat);
|
|
-
|
|
- // Repeats forever if the repeat count is negative.
|
|
- const bool gtest_repeat_forever = repeat < 0;
|
|
-
|
|
- // Should test environments be set up and torn down for each repeat, or only
|
|
- // set up on the first and torn down on the last iteration? If there is no
|
|
- // "last" iteration because the tests will repeat forever, always recreate the
|
|
- // environments to avoid leaks in case one of the environments is using
|
|
- // resources that are external to this process. Without this check there would
|
|
- // be no way to clean up those external resources automatically.
|
|
- const bool recreate_environments_when_repeating =
|
|
- GTEST_FLAG_GET(recreate_environments_when_repeating) ||
|
|
- gtest_repeat_forever;
|
|
-
|
|
- for (int i = 0; gtest_repeat_forever || i != repeat; i++) {
|
|
- // We want to preserve failures generated by ad-hoc test
|
|
- // assertions executed before RUN_ALL_TESTS().
|
|
- ClearNonAdHocTestResult();
|
|
-
|
|
- Timer timer;
|
|
-
|
|
- // Shuffles test suites and tests if requested.
|
|
- if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) {
|
|
- random()->Reseed(static_cast<uint32_t>(random_seed_));
|
|
- // This should be done before calling OnTestIterationStart(),
|
|
- // such that a test event listener can see the actual test order
|
|
- // in the event.
|
|
- ShuffleTests();
|
|
- }
|
|
-
|
|
- // Tells the unit test event listeners that the tests are about to start.
|
|
- repeater->OnTestIterationStart(*parent_, i);
|
|
-
|
|
- // Runs each test suite if there is at least one test to run.
|
|
- if (has_tests_to_run) {
|
|
- // Sets up all environments beforehand. If test environments aren't
|
|
- // recreated for each iteration, only do so on the first iteration.
|
|
- if (i == 0 || recreate_environments_when_repeating) {
|
|
- repeater->OnEnvironmentsSetUpStart(*parent_);
|
|
- ForEach(environments_, SetUpEnvironment);
|
|
- repeater->OnEnvironmentsSetUpEnd(*parent_);
|
|
- }
|
|
-
|
|
- // Runs the tests only if there was no fatal failure or skip triggered
|
|
- // during global set-up.
|
|
- if (Test::IsSkipped()) {
|
|
- // Emit diagnostics when global set-up calls skip, as it will not be
|
|
- // emitted by default.
|
|
- TestResult& test_result =
|
|
- *internal::GetUnitTestImpl()->current_test_result();
|
|
- for (int j = 0; j < test_result.total_part_count(); ++j) {
|
|
- const TestPartResult& test_part_result =
|
|
- test_result.GetTestPartResult(j);
|
|
- if (test_part_result.type() == TestPartResult::kSkip) {
|
|
- const std::string& result = test_part_result.message();
|
|
- printf("%s\n", result.c_str());
|
|
- }
|
|
- }
|
|
- fflush(stdout);
|
|
- } else if (!Test::HasFatalFailure()) {
|
|
- for (int test_index = 0; test_index < total_test_suite_count();
|
|
- test_index++) {
|
|
- GetMutableSuiteCase(test_index)->Run();
|
|
- if (GTEST_FLAG_GET(fail_fast) &&
|
|
- GetMutableSuiteCase(test_index)->Failed()) {
|
|
- for (int j = test_index + 1; j < total_test_suite_count(); j++) {
|
|
- GetMutableSuiteCase(j)->Skip();
|
|
- }
|
|
- break;
|
|
- }
|
|
- }
|
|
- } else if (Test::HasFatalFailure()) {
|
|
- // If there was a fatal failure during the global setup then we know we
|
|
- // aren't going to run any tests. Explicitly mark all of the tests as
|
|
- // skipped to make this obvious in the output.
|
|
- for (int test_index = 0; test_index < total_test_suite_count();
|
|
- test_index++) {
|
|
- GetMutableSuiteCase(test_index)->Skip();
|
|
- }
|
|
- }
|
|
-
|
|
- // Tears down all environments in reverse order afterwards. If test
|
|
- // environments aren't recreated for each iteration, only do so on the
|
|
- // last iteration.
|
|
- if (i == repeat - 1 || recreate_environments_when_repeating) {
|
|
- repeater->OnEnvironmentsTearDownStart(*parent_);
|
|
- std::for_each(environments_.rbegin(), environments_.rend(),
|
|
- TearDownEnvironment);
|
|
- repeater->OnEnvironmentsTearDownEnd(*parent_);
|
|
- }
|
|
- }
|
|
-
|
|
- elapsed_time_ = timer.Elapsed();
|
|
-
|
|
- // Tells the unit test event listener that the tests have just finished.
|
|
- repeater->OnTestIterationEnd(*parent_, i);
|
|
-
|
|
- // Gets the result and clears it.
|
|
- if (!Passed()) {
|
|
- failed = true;
|
|
- }
|
|
-
|
|
- // Restores the original test order after the iteration. This
|
|
- // allows the user to quickly repro a failure that happens in the
|
|
- // N-th iteration without repeating the first (N - 1) iterations.
|
|
- // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
|
|
- // case the user somehow changes the value of the flag somewhere
|
|
- // (it's always safe to unshuffle the tests).
|
|
- UnshuffleTests();
|
|
-
|
|
- if (GTEST_FLAG_GET(shuffle)) {
|
|
- // Picks a new random seed for each iteration.
|
|
- random_seed_ = GetNextRandomSeed(random_seed_);
|
|
- }
|
|
- }
|
|
-
|
|
- repeater->OnTestProgramEnd(*parent_);
|
|
-
|
|
- if (!gtest_is_initialized_before_run_all_tests) {
|
|
- ColoredPrintf(
|
|
- GTestColor::kRed,
|
|
- "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
|
|
- "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
|
|
- "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
|
|
- " will start to enforce the valid usage. "
|
|
- "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT
|
|
-#if GTEST_FOR_GOOGLE_
|
|
- ColoredPrintf(GTestColor::kRed,
|
|
- "For more details, see http://wiki/Main/ValidGUnitMain.\n");
|
|
-#endif // GTEST_FOR_GOOGLE_
|
|
- }
|
|
-
|
|
- return !failed;
|
|
-}
|
|
-
|
|
-// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
|
|
-// if the variable is present. If a file already exists at this location, this
|
|
-// function will write over it. If the variable is present, but the file cannot
|
|
-// be created, prints an error and exits.
|
|
-void WriteToShardStatusFileIfNeeded() {
|
|
- const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
|
|
- if (test_shard_file != nullptr) {
|
|
- FILE* const file = posix::FOpen(test_shard_file, "w");
|
|
- if (file == nullptr) {
|
|
- ColoredPrintf(GTestColor::kRed,
|
|
- "Could not write to the test shard status file \"%s\" "
|
|
- "specified by the %s environment variable.\n",
|
|
- test_shard_file, kTestShardStatusFile);
|
|
- fflush(stdout);
|
|
- exit(EXIT_FAILURE);
|
|
- }
|
|
- fclose(file);
|
|
- }
|
|
-}
|
|
-
|
|
-// Checks whether sharding is enabled by examining the relevant
|
|
-// environment variable values. If the variables are present,
|
|
-// but inconsistent (i.e., shard_index >= total_shards), prints
|
|
-// an error and exits. If in_subprocess_for_death_test, sharding is
|
|
-// disabled because it must only be applied to the original test
|
|
-// process. Otherwise, we could filter out death tests we intended to execute.
|
|
-bool ShouldShard(const char* total_shards_env, const char* shard_index_env,
|
|
- bool in_subprocess_for_death_test) {
|
|
- if (in_subprocess_for_death_test) {
|
|
- return false;
|
|
- }
|
|
-
|
|
- const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1);
|
|
- const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1);
|
|
-
|
|
- if (total_shards == -1 && shard_index == -1) {
|
|
- return false;
|
|
- } else if (total_shards == -1 && shard_index != -1) {
|
|
- const Message msg = Message() << "Invalid environment variables: you have "
|
|
- << kTestShardIndex << " = " << shard_index
|
|
- << ", but have left " << kTestTotalShards
|
|
- << " unset.\n";
|
|
- ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
|
|
- fflush(stdout);
|
|
- exit(EXIT_FAILURE);
|
|
- } else if (total_shards != -1 && shard_index == -1) {
|
|
- const Message msg = Message()
|
|
- << "Invalid environment variables: you have "
|
|
- << kTestTotalShards << " = " << total_shards
|
|
- << ", but have left " << kTestShardIndex << " unset.\n";
|
|
- ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
|
|
- fflush(stdout);
|
|
- exit(EXIT_FAILURE);
|
|
- } else if (shard_index < 0 || shard_index >= total_shards) {
|
|
- const Message msg =
|
|
- Message() << "Invalid environment variables: we require 0 <= "
|
|
- << kTestShardIndex << " < " << kTestTotalShards
|
|
- << ", but you have " << kTestShardIndex << "=" << shard_index
|
|
- << ", " << kTestTotalShards << "=" << total_shards << ".\n";
|
|
- ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str());
|
|
- fflush(stdout);
|
|
- exit(EXIT_FAILURE);
|
|
- }
|
|
-
|
|
- return total_shards > 1;
|
|
-}
|
|
-
|
|
-// 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 aborts.
|
|
-int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {
|
|
- const char* str_val = posix::GetEnv(var);
|
|
- if (str_val == nullptr) {
|
|
- return default_val;
|
|
- }
|
|
-
|
|
- int32_t result;
|
|
- if (!ParseInt32(Message() << "The value of environment variable " << var,
|
|
- str_val, &result)) {
|
|
- exit(EXIT_FAILURE);
|
|
- }
|
|
- return result;
|
|
-}
|
|
-
|
|
-// Given the total number of shards, the shard index, and the test id,
|
|
-// 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.
|
|
-bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
|
|
- return (test_id % total_shards) == shard_index;
|
|
-}
|
|
-
|
|
-// Compares the name of each test with the user-specified filter to
|
|
-// decide whether the test should be run, then records the result in
|
|
-// each TestSuite and TestInfo object.
|
|
-// If shard_tests == true, further filters tests based on sharding
|
|
-// variables in the environment - see
|
|
-// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md
|
|
-// . Returns the number of tests that should run.
|
|
-int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|
- const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL
|
|
- ? Int32FromEnvOrDie(kTestTotalShards, -1)
|
|
- : -1;
|
|
- const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL
|
|
- ? Int32FromEnvOrDie(kTestShardIndex, -1)
|
|
- : -1;
|
|
-
|
|
- const PositiveAndNegativeUnitTestFilter gtest_flag_filter(
|
|
- GTEST_FLAG_GET(filter));
|
|
- const UnitTestFilter disable_test_filter(kDisableTestFilter);
|
|
- // num_runnable_tests are the number of tests that will
|
|
- // run across all shards (i.e., match filter and are not disabled).
|
|
- // num_selected_tests are the number of tests to be run on
|
|
- // this shard.
|
|
- int num_runnable_tests = 0;
|
|
- int num_selected_tests = 0;
|
|
- for (auto* test_suite : test_suites_) {
|
|
- const std::string& test_suite_name = test_suite->name();
|
|
- test_suite->set_should_run(false);
|
|
-
|
|
- for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
|
|
- TestInfo* const test_info = test_suite->test_info_list()[j];
|
|
- const std::string test_name(test_info->name());
|
|
- // A test is disabled if test suite name or test name matches
|
|
- // kDisableTestFilter.
|
|
- const bool is_disabled =
|
|
- disable_test_filter.MatchesName(test_suite_name) ||
|
|
- disable_test_filter.MatchesName(test_name);
|
|
- test_info->is_disabled_ = is_disabled;
|
|
-
|
|
- const bool matches_filter =
|
|
- gtest_flag_filter.MatchesTest(test_suite_name, test_name);
|
|
- test_info->matches_filter_ = matches_filter;
|
|
-
|
|
- const bool is_runnable =
|
|
- (GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) &&
|
|
- matches_filter;
|
|
-
|
|
- const bool is_in_another_shard =
|
|
- shard_tests != IGNORE_SHARDING_PROTOCOL &&
|
|
- !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests);
|
|
- test_info->is_in_another_shard_ = is_in_another_shard;
|
|
- const bool is_selected = is_runnable && !is_in_another_shard;
|
|
-
|
|
- num_runnable_tests += is_runnable;
|
|
- num_selected_tests += is_selected;
|
|
-
|
|
- test_info->should_run_ = is_selected;
|
|
- test_suite->set_should_run(test_suite->should_run() || is_selected);
|
|
- }
|
|
- }
|
|
- return num_selected_tests;
|
|
-}
|
|
-
|
|
-// Prints the given C-string on a single line by replacing all '\n'
|
|
-// characters with string "\\n". If the output takes more than
|
|
-// max_length characters, only prints the first max_length characters
|
|
-// and "...".
|
|
-static void PrintOnOneLine(const char* str, int max_length) {
|
|
- if (str != nullptr) {
|
|
- for (int i = 0; *str != '\0'; ++str) {
|
|
- if (i >= max_length) {
|
|
- printf("...");
|
|
- break;
|
|
- }
|
|
- if (*str == '\n') {
|
|
- printf("\\n");
|
|
- i += 2;
|
|
- } else {
|
|
- printf("%c", *str);
|
|
- ++i;
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-// Prints the names of the tests matching the user-specified filter flag.
|
|
-void UnitTestImpl::ListTestsMatchingFilter() {
|
|
- // Print at most this many characters for each type/value parameter.
|
|
- const int kMaxParamLength = 250;
|
|
-
|
|
- for (auto* test_suite : test_suites_) {
|
|
- bool printed_test_suite_name = false;
|
|
-
|
|
- for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
|
|
- const TestInfo* const test_info = test_suite->test_info_list()[j];
|
|
- if (test_info->matches_filter_) {
|
|
- if (!printed_test_suite_name) {
|
|
- printed_test_suite_name = true;
|
|
- printf("%s.", test_suite->name());
|
|
- if (test_suite->type_param() != nullptr) {
|
|
- printf(" # %s = ", kTypeParamLabel);
|
|
- // We print the type parameter on a single line to make
|
|
- // the output easy to parse by a program.
|
|
- PrintOnOneLine(test_suite->type_param(), kMaxParamLength);
|
|
- }
|
|
- printf("\n");
|
|
- }
|
|
- printf(" %s", test_info->name());
|
|
- if (test_info->value_param() != nullptr) {
|
|
- printf(" # %s = ", kValueParamLabel);
|
|
- // We print the value parameter on a single line to make the
|
|
- // output easy to parse by a program.
|
|
- PrintOnOneLine(test_info->value_param(), kMaxParamLength);
|
|
- }
|
|
- printf("\n");
|
|
- }
|
|
- }
|
|
- }
|
|
- fflush(stdout);
|
|
- const std::string& output_format = UnitTestOptions::GetOutputFormat();
|
|
- if (output_format == "xml" || output_format == "json") {
|
|
- FILE* fileout = OpenFileForWriting(
|
|
- UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
|
|
- std::stringstream stream;
|
|
- if (output_format == "xml") {
|
|
- XmlUnitTestResultPrinter(
|
|
- UnitTestOptions::GetAbsolutePathToOutputFile().c_str())
|
|
- .PrintXmlTestsList(&stream, test_suites_);
|
|
- } else if (output_format == "json") {
|
|
- JsonUnitTestResultPrinter(
|
|
- UnitTestOptions::GetAbsolutePathToOutputFile().c_str())
|
|
- .PrintJsonTestList(&stream, test_suites_);
|
|
- }
|
|
- fprintf(fileout, "%s", StringStreamToString(&stream).c_str());
|
|
- fclose(fileout);
|
|
- }
|
|
-}
|
|
-
|
|
-// Sets the OS stack trace getter.
|
|
-//
|
|
-// Does nothing if the input and the current OS stack trace getter are
|
|
-// the same; otherwise, deletes the old getter and makes the input the
|
|
-// current getter.
|
|
-void UnitTestImpl::set_os_stack_trace_getter(
|
|
- OsStackTraceGetterInterface* getter) {
|
|
- if (os_stack_trace_getter_ != getter) {
|
|
- delete os_stack_trace_getter_;
|
|
- os_stack_trace_getter_ = getter;
|
|
- }
|
|
-}
|
|
-
|
|
-// Returns the current OS stack trace getter if it is not NULL;
|
|
-// otherwise, creates an OsStackTraceGetter, makes it the current
|
|
-// getter, and returns it.
|
|
-OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
|
|
- if (os_stack_trace_getter_ == nullptr) {
|
|
-#ifdef GTEST_OS_STACK_TRACE_GETTER_
|
|
- os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_;
|
|
-#else
|
|
- os_stack_trace_getter_ = new OsStackTraceGetter;
|
|
-#endif // GTEST_OS_STACK_TRACE_GETTER_
|
|
- }
|
|
-
|
|
- return os_stack_trace_getter_;
|
|
-}
|
|
-
|
|
-// Returns the most specific TestResult currently running.
|
|
-TestResult* UnitTestImpl::current_test_result() {
|
|
- if (current_test_info_ != nullptr) {
|
|
- return ¤t_test_info_->result_;
|
|
- }
|
|
- if (current_test_suite_ != nullptr) {
|
|
- return ¤t_test_suite_->ad_hoc_test_result_;
|
|
- }
|
|
- return &ad_hoc_test_result_;
|
|
-}
|
|
-
|
|
-// Shuffles all test suites, and the tests within each test suite,
|
|
-// making sure that death tests are still run first.
|
|
-void UnitTestImpl::ShuffleTests() {
|
|
- // Shuffles the death test suites.
|
|
- ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_);
|
|
-
|
|
- // Shuffles the non-death test suites.
|
|
- ShuffleRange(random(), last_death_test_suite_ + 1,
|
|
- static_cast<int>(test_suites_.size()), &test_suite_indices_);
|
|
-
|
|
- // Shuffles the tests inside each test suite.
|
|
- for (auto& test_suite : test_suites_) {
|
|
- test_suite->ShuffleTests(random());
|
|
- }
|
|
-}
|
|
-
|
|
-// Restores the test suites and tests to their order before the first shuffle.
|
|
-void UnitTestImpl::UnshuffleTests() {
|
|
- for (size_t i = 0; i < test_suites_.size(); i++) {
|
|
- // Unshuffles the tests in each test suite.
|
|
- test_suites_[i]->UnshuffleTests();
|
|
- // Resets the index of each test suite.
|
|
- test_suite_indices_[i] = static_cast<int>(i);
|
|
- }
|
|
-}
|
|
-
|
|
-// Returns the current OS stack trace as an std::string.
|
|
-//
|
|
-// The maximum number of stack frames to be included is specified by
|
|
-// the gtest_stack_trace_depth flag. The skip_count parameter
|
|
-// specifies the number of top frames to be skipped, which doesn't
|
|
-// count against the number of frames to be included.
|
|
-//
|
|
-// For example, if Foo() calls Bar(), which in turn calls
|
|
-// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
|
|
-// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
|
-GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string
|
|
-GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) {
|
|
- // We pass skip_count + 1 to skip this wrapper function in addition
|
|
- // to what the user really wants to skip.
|
|
- return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
|
|
-}
|
|
-
|
|
-// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to
|
|
-// suppress unreachable code warnings.
|
|
-namespace {
|
|
-class ClassUniqueToAlwaysTrue {};
|
|
-} // namespace
|
|
-
|
|
-bool IsTrue(bool condition) { return condition; }
|
|
-
|
|
-bool AlwaysTrue() {
|
|
-#if GTEST_HAS_EXCEPTIONS
|
|
- // This condition is always false so AlwaysTrue() never actually throws,
|
|
- // but it makes the compiler think that it may throw.
|
|
- if (IsTrue(false)) throw ClassUniqueToAlwaysTrue();
|
|
-#endif // GTEST_HAS_EXCEPTIONS
|
|
- return true;
|
|
-}
|
|
-
|
|
-// If *pstr starts with the given prefix, modifies *pstr to be right
|
|
-// past the prefix and returns true; otherwise leaves *pstr unchanged
|
|
-// and returns false. None of pstr, *pstr, and prefix can be NULL.
|
|
-bool SkipPrefix(const char* prefix, const char** pstr) {
|
|
- const size_t prefix_len = strlen(prefix);
|
|
- if (strncmp(*pstr, prefix, prefix_len) == 0) {
|
|
- *pstr += prefix_len;
|
|
- return true;
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
-// Parses a string as a command line flag. The string should have
|
|
-// the format "--flag=value". When def_optional is true, the "=value"
|
|
-// part can be omitted.
|
|
-//
|
|
-// Returns the value of the flag, or NULL if the parsing failed.
|
|
-static const char* ParseFlagValue(const char* str, const char* flag_name,
|
|
- bool def_optional) {
|
|
- // str and flag must not be NULL.
|
|
- if (str == nullptr || flag_name == nullptr) return nullptr;
|
|
-
|
|
- // The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
|
|
- const std::string flag_str =
|
|
- std::string("--") + GTEST_FLAG_PREFIX_ + flag_name;
|
|
- const size_t flag_len = flag_str.length();
|
|
- if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
|
|
-
|
|
- // Skips the flag name.
|
|
- const char* flag_end = str + flag_len;
|
|
-
|
|
- // When def_optional is true, it's OK to not have a "=value" part.
|
|
- if (def_optional && (flag_end[0] == '\0')) {
|
|
- return flag_end;
|
|
- }
|
|
-
|
|
- // If def_optional is true and there are more characters after the
|
|
- // flag name, or if def_optional is false, there must be a '=' after
|
|
- // the flag name.
|
|
- if (flag_end[0] != '=') return nullptr;
|
|
-
|
|
- // Returns the string after "=".
|
|
- return flag_end + 1;
|
|
-}
|
|
-
|
|
-// Parses a string for a bool flag, in the form of either
|
|
-// "--flag=value" or "--flag".
|
|
-//
|
|
-// In the former case, the value is taken as true as long as it does
|
|
-// not start with '0', 'f', or 'F'.
|
|
-//
|
|
-// In the latter case, the value is taken as true.
|
|
-//
|
|
-// On success, stores the value of the flag in *value, and returns
|
|
-// true. On failure, returns false without changing *value.
|
|
-static bool ParseFlag(const char* str, const char* flag_name, bool* value) {
|
|
- // Gets the value of the flag as a string.
|
|
- const char* const value_str = ParseFlagValue(str, flag_name, true);
|
|
-
|
|
- // Aborts if the parsing failed.
|
|
- if (value_str == nullptr) return false;
|
|
-
|
|
- // Converts the string value to a bool.
|
|
- *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
|
|
- return true;
|
|
-}
|
|
-
|
|
-// Parses a string for an int32_t flag, in the form of "--flag=value".
|
|
-//
|
|
-// On success, stores the value of the flag in *value, and returns
|
|
-// true. On failure, returns false without changing *value.
|
|
-bool ParseFlag(const char* str, const char* flag_name, int32_t* value) {
|
|
- // Gets the value of the flag as a string.
|
|
- const char* const value_str = ParseFlagValue(str, flag_name, false);
|
|
-
|
|
- // Aborts if the parsing failed.
|
|
- if (value_str == nullptr) return false;
|
|
-
|
|
- // Sets *value to the value of the flag.
|
|
- return ParseInt32(Message() << "The value of flag --" << flag_name, value_str,
|
|
- value);
|
|
-}
|
|
-
|
|
-// Parses a string for a string flag, in the form of "--flag=value".
|
|
-//
|
|
-// On success, stores the value of the flag in *value, and returns
|
|
-// true. On failure, returns false without changing *value.
|
|
-template <typename String>
|
|
-static bool ParseFlag(const char* str, const char* flag_name, String* value) {
|
|
- // Gets the value of the flag as a string.
|
|
- const char* const value_str = ParseFlagValue(str, flag_name, false);
|
|
-
|
|
- // Aborts if the parsing failed.
|
|
- if (value_str == nullptr) return false;
|
|
-
|
|
- // Sets *value to the value of the flag.
|
|
- *value = value_str;
|
|
- return true;
|
|
-}
|
|
-
|
|
-// Determines whether a string has a prefix that Google Test uses for its
|
|
-// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
|
|
-// If Google Test detects that a command line flag has its prefix but is not
|
|
-// recognized, it will print its help message. Flags starting with
|
|
-// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
|
|
-// internal flags and do not trigger the help message.
|
|
-static bool HasGoogleTestFlagPrefix(const char* str) {
|
|
- return (SkipPrefix("--", &str) || SkipPrefix("-", &str) ||
|
|
- SkipPrefix("/", &str)) &&
|
|
- !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
|
|
- (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
|
|
- SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
|
|
-}
|
|
-
|
|
-// Prints a string containing code-encoded text. The following escape
|
|
-// sequences can be used in the string to control the text color:
|
|
-//
|
|
-// @@ prints a single '@' character.
|
|
-// @R changes the color to red.
|
|
-// @G changes the color to green.
|
|
-// @Y changes the color to yellow.
|
|
-// @D changes to the default terminal text color.
|
|
-//
|
|
-static void PrintColorEncoded(const char* str) {
|
|
- GTestColor color = GTestColor::kDefault; // The current color.
|
|
-
|
|
- // Conceptually, we split the string into segments divided by escape
|
|
- // sequences. Then we print one segment at a time. At the end of
|
|
- // each iteration, the str pointer advances to the beginning of the
|
|
- // next segment.
|
|
- for (;;) {
|
|
- const char* p = strchr(str, '@');
|
|
- if (p == nullptr) {
|
|
- ColoredPrintf(color, "%s", str);
|
|
- return;
|
|
- }
|
|
-
|
|
- ColoredPrintf(color, "%s", std::string(str, p).c_str());
|
|
-
|
|
- const char ch = p[1];
|
|
- str = p + 2;
|
|
- if (ch == '@') {
|
|
- ColoredPrintf(color, "@");
|
|
- } else if (ch == 'D') {
|
|
- color = GTestColor::kDefault;
|
|
- } else if (ch == 'R') {
|
|
- color = GTestColor::kRed;
|
|
- } else if (ch == 'G') {
|
|
- color = GTestColor::kGreen;
|
|
- } else if (ch == 'Y') {
|
|
- color = GTestColor::kYellow;
|
|
- } else {
|
|
- --str;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-static const char kColorEncodedHelpMessage[] =
|
|
- "This program contains tests written using " GTEST_NAME_
|
|
- ". You can use the\n"
|
|
- "following command line flags to control its behavior:\n"
|
|
- "\n"
|
|
- "Test Selection:\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "list_tests@D\n"
|
|
- " List the names of all tests instead of running them. The name of\n"
|
|
- " TEST(Foo, Bar) is \"Foo.Bar\".\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "filter=@YPOSITIVE_PATTERNS"
|
|
- "[@G-@YNEGATIVE_PATTERNS]@D\n"
|
|
- " Run only the tests whose name matches one of the positive patterns "
|
|
- "but\n"
|
|
- " none of the negative patterns. '?' matches any single character; "
|
|
- "'*'\n"
|
|
- " matches any substring; ':' separates two patterns.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "also_run_disabled_tests@D\n"
|
|
- " Run all disabled tests too.\n"
|
|
- "\n"
|
|
- "Test Execution:\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "repeat=@Y[COUNT]@D\n"
|
|
- " Run the tests repeatedly; use a negative count to repeat forever.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "shuffle@D\n"
|
|
- " Randomize tests' orders on every iteration.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "random_seed=@Y[NUMBER]@D\n"
|
|
- " Random number seed to use for shuffling test orders (between 1 and\n"
|
|
- " 99999, or 0 to use a seed based on the current time).\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "recreate_environments_when_repeating@D\n"
|
|
- " Sets up and tears down the global test environment on each repeat\n"
|
|
- " of the test.\n"
|
|
- "\n"
|
|
- "Test Output:\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
|
|
- " Enable/disable colored output. The default is @Gauto@D.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "brief=1@D\n"
|
|
- " Only print test failures.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "print_time=0@D\n"
|
|
- " Don't print the elapsed time of each test.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_
|
|
- "@Y|@G:@YFILE_PATH]@D\n"
|
|
- " Generate a JSON or XML report in the given directory or with the "
|
|
- "given\n"
|
|
- " file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n"
|
|
-#if GTEST_CAN_STREAM_RESULTS_
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "stream_result_to=@YHOST@G:@YPORT@D\n"
|
|
- " Stream test results to the given server.\n"
|
|
-#endif // GTEST_CAN_STREAM_RESULTS_
|
|
- "\n"
|
|
- "Assertion Behavior:\n"
|
|
-#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
|
|
- " Set the default death test style.\n"
|
|
-#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "break_on_failure@D\n"
|
|
- " Turn assertion failures into debugger break-points.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "throw_on_failure@D\n"
|
|
- " Turn assertion failures into C++ exceptions for use by an external\n"
|
|
- " test framework.\n"
|
|
- " @G--" GTEST_FLAG_PREFIX_
|
|
- "catch_exceptions=0@D\n"
|
|
- " Do not report exceptions as test failures. Instead, allow them\n"
|
|
- " to crash the program or throw a pop-up (on Windows).\n"
|
|
- "\n"
|
|
- "Except for @G--" GTEST_FLAG_PREFIX_
|
|
- "list_tests@D, you can alternatively set "
|
|
- "the corresponding\n"
|
|
- "environment variable of a flag (all letters in upper-case). For example, "
|
|
- "to\n"
|
|
- "disable colored text output, you can either specify "
|
|
- "@G--" GTEST_FLAG_PREFIX_
|
|
- "color=no@D or set\n"
|
|
- "the @G" GTEST_FLAG_PREFIX_UPPER_
|
|
- "COLOR@D environment variable to @Gno@D.\n"
|
|
- "\n"
|
|
- "For more information, please read the " GTEST_NAME_
|
|
- " documentation at\n"
|
|
- "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_
|
|
- "\n"
|
|
- "(not one in your own code or tests), please report it to\n"
|
|
- "@G<" GTEST_DEV_EMAIL_ ">@D.\n";
|
|
-
|
|
-static bool ParseGoogleTestFlag(const char* const arg) {
|
|
-#define GTEST_INTERNAL_PARSE_FLAG(flag_name) \
|
|
- do { \
|
|
- auto value = GTEST_FLAG_GET(flag_name); \
|
|
- if (ParseFlag(arg, #flag_name, &value)) { \
|
|
- GTEST_FLAG_SET(flag_name, value); \
|
|
- return true; \
|
|
- } \
|
|
- } while (false)
|
|
-
|
|
- GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests);
|
|
- GTEST_INTERNAL_PARSE_FLAG(break_on_failure);
|
|
- GTEST_INTERNAL_PARSE_FLAG(catch_exceptions);
|
|
- GTEST_INTERNAL_PARSE_FLAG(color);
|
|
- GTEST_INTERNAL_PARSE_FLAG(death_test_style);
|
|
- GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
|
- GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
|
- GTEST_INTERNAL_PARSE_FLAG(filter);
|
|
- GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
|
- GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
|
- GTEST_INTERNAL_PARSE_FLAG(output);
|
|
- GTEST_INTERNAL_PARSE_FLAG(brief);
|
|
- GTEST_INTERNAL_PARSE_FLAG(print_time);
|
|
- GTEST_INTERNAL_PARSE_FLAG(print_utf8);
|
|
- GTEST_INTERNAL_PARSE_FLAG(random_seed);
|
|
- GTEST_INTERNAL_PARSE_FLAG(repeat);
|
|
- GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);
|
|
- GTEST_INTERNAL_PARSE_FLAG(shuffle);
|
|
- GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);
|
|
- GTEST_INTERNAL_PARSE_FLAG(stream_result_to);
|
|
- GTEST_INTERNAL_PARSE_FLAG(throw_on_failure);
|
|
- return false;
|
|
-}
|
|
-
|
|
-#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
-static void LoadFlagsFromFile(const std::string& path) {
|
|
- FILE* flagfile = posix::FOpen(path.c_str(), "r");
|
|
- if (!flagfile) {
|
|
- GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG_GET(flagfile)
|
|
- << "\"";
|
|
- }
|
|
- std::string contents(ReadEntireFile(flagfile));
|
|
- posix::FClose(flagfile);
|
|
- std::vector<std::string> lines;
|
|
- SplitString(contents, '\n', &lines);
|
|
- for (size_t i = 0; i < lines.size(); ++i) {
|
|
- if (lines[i].empty()) continue;
|
|
- if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true;
|
|
- }
|
|
-}
|
|
-#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
-
|
|
-// Parses the command line for Google Test flags, without initializing
|
|
-// other parts of Google Test. The type parameter CharType can be
|
|
-// instantiated to either char or wchar_t.
|
|
-template <typename CharType>
|
|
-void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
|
- std::string flagfile_value;
|
|
- for (int i = 1; i < *argc; i++) {
|
|
- const std::string arg_string = StreamableToString(argv[i]);
|
|
- const char* const arg = arg_string.c_str();
|
|
-
|
|
- using internal::ParseFlag;
|
|
-
|
|
- bool remove_flag = false;
|
|
- if (ParseGoogleTestFlag(arg)) {
|
|
- remove_flag = true;
|
|
-#if GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
- } else if (ParseFlag(arg, "flagfile", &flagfile_value)) {
|
|
- GTEST_FLAG_SET(flagfile, flagfile_value);
|
|
- LoadFlagsFromFile(flagfile_value);
|
|
- remove_flag = true;
|
|
-#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
|
|
- } else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) {
|
|
- // Both help flag and unrecognized Google Test flags (excluding
|
|
- // internal ones) trigger help display.
|
|
- g_help_flag = true;
|
|
- }
|
|
-
|
|
- if (remove_flag) {
|
|
- // Shift the remainder of the argv list left by one. Note
|
|
- // that argv has (*argc + 1) elements, the last one always being
|
|
- // NULL. The following loop moves the trailing NULL element as
|
|
- // well.
|
|
- for (int j = i; j != *argc; j++) {
|
|
- argv[j] = argv[j + 1];
|
|
- }
|
|
-
|
|
- // Decrements the argument count.
|
|
- (*argc)--;
|
|
-
|
|
- // We also need to decrement the iterator as we just removed
|
|
- // an element.
|
|
- i--;
|
|
- }
|
|
- }
|
|
-
|
|
- if (g_help_flag) {
|
|
- // We print the help here instead of in RUN_ALL_TESTS(), as the
|
|
- // latter may not be called at all if the user is using Google
|
|
- // Test with another testing framework.
|
|
- PrintColorEncoded(kColorEncodedHelpMessage);
|
|
- }
|
|
-}
|
|
-
|
|
-// Parses the command line for Google Test flags, without initializing
|
|
-// other parts of Google Test.
|
|
-void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
|
|
-#if GTEST_HAS_ABSL
|
|
- if (*argc > 0) {
|
|
- // absl::ParseCommandLine() requires *argc > 0.
|
|
- auto positional_args = absl::flags_internal::ParseCommandLineImpl(
|
|
- *argc, argv, absl::flags_internal::ArgvListAction::kRemoveParsedArgs,
|
|
- absl::flags_internal::UsageFlagsAction::kHandleUsage,
|
|
- absl::flags_internal::OnUndefinedFlag::kReportUndefined);
|
|
- // Any command-line positional arguments not part of any command-line flag
|
|
- // (or arguments to a flag) are copied back out to argv, with the program
|
|
- // invocation name at position 0, and argc is resized. This includes
|
|
- // positional arguments after the flag-terminating delimiter '--'.
|
|
- // See https://abseil.io/docs/cpp/guides/flags.
|
|
- std::copy(positional_args.begin(), positional_args.end(), argv);
|
|
- if (static_cast<int>(positional_args.size()) < *argc) {
|
|
- argv[positional_args.size()] = nullptr;
|
|
- *argc = static_cast<int>(positional_args.size());
|
|
- }
|
|
- }
|
|
-#else
|
|
- ParseGoogleTestFlagsOnlyImpl(argc, argv);
|
|
-#endif
|
|
-
|
|
- // Fix the value of *_NSGetArgc() on macOS, but if and only if
|
|
- // *_NSGetArgv() == argv
|
|
- // Only applicable to char** version of argv
|
|
-#if GTEST_OS_MAC
|
|
-#ifndef GTEST_OS_IOS
|
|
- if (*_NSGetArgv() == argv) {
|
|
- *_NSGetArgc() = *argc;
|
|
- }
|
|
-#endif
|
|
-#endif
|
|
-}
|
|
-void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
|
|
- ParseGoogleTestFlagsOnlyImpl(argc, argv);
|
|
-}
|
|
-
|
|
-// The internal implementation of InitGoogleTest().
|
|
-//
|
|
-// The type parameter CharType can be instantiated to either char or
|
|
-// wchar_t.
|
|
-template <typename CharType>
|
|
-void InitGoogleTestImpl(int* argc, CharType** argv) {
|
|
- // We don't want to run the initialization code twice.
|
|
- if (GTestIsInitialized()) return;
|
|
-
|
|
- if (*argc <= 0) return;
|
|
-
|
|
- g_argvs.clear();
|
|
- for (int i = 0; i != *argc; i++) {
|
|
- g_argvs.push_back(StreamableToString(argv[i]));
|
|
- }
|
|
-
|
|
-#if GTEST_HAS_ABSL
|
|
- absl::InitializeSymbolizer(g_argvs[0].c_str());
|
|
-
|
|
- // When using the Abseil Flags library, set the program usage message to the
|
|
- // help message, but remove the color-encoding from the message first.
|
|
- absl::SetProgramUsageMessage(absl::StrReplaceAll(
|
|
- kColorEncodedHelpMessage,
|
|
- {{"@D", ""}, {"@R", ""}, {"@G", ""}, {"@Y", ""}, {"@@", "@"}}));
|
|
-#endif // GTEST_HAS_ABSL
|
|
-
|
|
- ParseGoogleTestFlagsOnly(argc, argv);
|
|
- GetUnitTestImpl()->PostFlagParsingInit();
|
|
-}
|
|
-
|
|
-} // namespace internal
|
|
-
|
|
-// Initializes Google Test. This must be called before calling
|
|
-// RUN_ALL_TESTS(). In particular, it parses a command line for the
|
|
-// flags that Google Test recognizes. Whenever a Google Test flag is
|
|
-// seen, it is removed from argv, and *argc is decremented.
|
|
-//
|
|
-// No value is returned. Instead, the Google Test flag variables are
|
|
-// updated.
|
|
-//
|
|
-// Calling the function for the second time has no user-visible effect.
|
|
-void InitGoogleTest(int* argc, char** argv) {
|
|
-#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
- GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);
|
|
-#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
- internal::InitGoogleTestImpl(argc, argv);
|
|
-#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
-}
|
|
-
|
|
-// This overloaded version can be used in Windows programs compiled in
|
|
-// UNICODE mode.
|
|
-void InitGoogleTest(int* argc, wchar_t** argv) {
|
|
-#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
- GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);
|
|
-#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
- internal::InitGoogleTestImpl(argc, argv);
|
|
-#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
-}
|
|
-
|
|
-// This overloaded version can be used on Arduino/embedded platforms where
|
|
-// there is no argc/argv.
|
|
-void InitGoogleTest() {
|
|
- // Since Arduino doesn't have a command line, fake out the argc/argv arguments
|
|
- int argc = 1;
|
|
- const auto arg0 = "dummy";
|
|
- char* argv0 = const_cast<char*>(arg0);
|
|
- char** argv = &argv0;
|
|
-
|
|
-#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
- GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv);
|
|
-#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
- internal::InitGoogleTestImpl(&argc, argv);
|
|
-#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
|
-}
|
|
-
|
|
-#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
|
-// Return value of first environment variable that is set and contains
|
|
-// a non-empty string. If there are none, return the "fallback" string.
|
|
-// Since we like the temporary directory to have a directory separator suffix,
|
|
-// add it if not provided in the environment variable value.
|
|
-static std::string GetTempDirFromEnv(
|
|
- std::initializer_list<const char*> environment_variables,
|
|
- const char* fallback, char separator) {
|
|
- for (const char* variable_name : environment_variables) {
|
|
- const char* value = internal::posix::GetEnv(variable_name);
|
|
- if (value != nullptr && value[0] != '\0') {
|
|
- if (value[strlen(value) - 1] != separator) {
|
|
- return std::string(value).append(1, separator);
|
|
- }
|
|
- return value;
|
|
- }
|
|
- }
|
|
- return fallback;
|
|
-}
|
|
-#endif
|
|
-
|
|
-std::string TempDir() {
|
|
-#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
|
|
- return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
|
|
-#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE
|
|
- return GetTempDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\');
|
|
-#elif GTEST_OS_LINUX_ANDROID
|
|
- return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/');
|
|
-#else
|
|
- return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/');
|
|
-#endif
|
|
-}
|
|
-
|
|
-// Class ScopedTrace
|
|
-
|
|
-// Pushes the given source file location and message onto a per-thread
|
|
-// trace stack maintained by Google Test.
|
|
-void ScopedTrace::PushTrace(const char* file, int line, std::string message) {
|
|
- internal::TraceInfo trace;
|
|
- trace.file = file;
|
|
- trace.line = line;
|
|
- trace.message.swap(message);
|
|
-
|
|
- UnitTest::GetInstance()->PushGTestTrace(trace);
|
|
-}
|
|
-
|
|
-// Pops the info pushed by the c'tor.
|
|
-ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
|
|
- UnitTest::GetInstance()->PopGTestTrace();
|
|
-}
|
|
-
|
|
-} // namespace testing
|
|
diff --git a/vendor/gtest/src/gtest_main.cc b/vendor/gtest/src/gtest_main.cc
|
|
deleted file mode 100644
|
|
index 44976375c..000000000
|
|
--- a/vendor/gtest/src/gtest_main.cc
|
|
+++ /dev/null
|
|
@@ -1,53 +0,0 @@
|
|
-// Copyright 2006, Google Inc.
|
|
-// All rights reserved.
|
|
-//
|
|
-// Redistribution and use in source and binary forms, with or without
|
|
-// modification, are permitted provided that the following conditions are
|
|
-// met:
|
|
-//
|
|
-// * Redistributions of source code must retain the above copyright
|
|
-// notice, this list of conditions and the following disclaimer.
|
|
-// * Redistributions in binary form must reproduce the above
|
|
-// copyright notice, this list of conditions and the following disclaimer
|
|
-// in the documentation and/or other materials provided with the
|
|
-// distribution.
|
|
-// * Neither the name of Google Inc. nor the names of its
|
|
-// contributors may be used to endorse or promote products derived from
|
|
-// this software without specific prior written permission.
|
|
-//
|
|
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-
|
|
-#include <cstdio>
|
|
-
|
|
-#include "gtest/gtest.h"
|
|
-
|
|
-#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
|
|
-#if GTEST_OS_ESP8266
|
|
-extern "C" {
|
|
-#endif
|
|
-void setup() { testing::InitGoogleTest(); }
|
|
-
|
|
-void loop() { RUN_ALL_TESTS(); }
|
|
-
|
|
-#if GTEST_OS_ESP8266
|
|
-}
|
|
-#endif
|
|
-
|
|
-#else
|
|
-
|
|
-GTEST_API_ int main(int argc, char **argv) {
|
|
- printf("Running main() from %s\n", __FILE__);
|
|
- testing::InitGoogleTest(&argc, argv);
|
|
- return RUN_ALL_TESTS();
|
|
-}
|
|
-#endif
|