Googletest: Update to 1.12.1

pull/4731/head
Kim Kulling 2022-09-18 09:58:12 +02:00
parent b3c7bdbdd6
commit 09fe87b6d4
61 changed files with 2869 additions and 7025 deletions

View File

@ -46,14 +46,9 @@ endif()
# Project version: # Project version:
if (CMAKE_VERSION VERSION_LESS 3.0) cmake_minimum_required(VERSION 3.5)
project(gtest CXX C) cmake_policy(SET CMP0048 NEW)
set(PROJECT_VERSION ${GOOGLETEST_VERSION}) project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
else()
cmake_policy(SET CMP0048 NEW)
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
endif()
cmake_minimum_required(VERSION 2.8.12)
if (POLICY CMP0063) # Visibility if (POLICY CMP0063) # Visibility
cmake_policy(SET CMP0063 NEW) cmake_policy(SET CMP0063 NEW)
@ -136,13 +131,17 @@ set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})
# to the targets for when we are part of a parent build (ie being pulled # to the targets for when we are part of a parent build (ie being pulled
# in via add_subdirectory() rather than being a standalone build). # in via add_subdirectory() rather than being a standalone build).
if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
string(REPLACE ";" "$<SEMICOLON>" dirs "${gtest_build_include_dirs}")
target_include_directories(gtest SYSTEM INTERFACE target_include_directories(gtest SYSTEM INTERFACE
"$<BUILD_INTERFACE:${gtest_build_include_dirs}>" "$<BUILD_INTERFACE:${dirs}>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>") "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
target_include_directories(gtest_main SYSTEM INTERFACE target_include_directories(gtest_main SYSTEM INTERFACE
"$<BUILD_INTERFACE:${gtest_build_include_dirs}>" "$<BUILD_INTERFACE:${dirs}>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>") "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
endif() endif()
if(CMAKE_SYSTEM_NAME MATCHES "QNX")
target_link_libraries(gtest PUBLIC regex)
endif()
target_link_libraries(gtest_main PUBLIC gtest) target_link_libraries(gtest_main PUBLIC gtest)
######################################################################## ########################################################################

View File

@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with with
``` ```
git clone https://github.com/google/googletest.git -b release-1.10.0 git clone https://github.com/google/googletest.git -b release-1.11.0
cd googletest # Main directory of the cloned repository. cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output. mkdir build # Create a directory to hold the build output.
cd build cd build
@ -94,7 +94,7 @@ include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
googletest googletest
# Specify the commit you depend on and update it regularly. # Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip URL https://github.com/google/googletest/archive/e2239ee6043f73722e7aa812a459f54a28552929.zip
) )
# For Windows: Prevent overriding the parent project's compiler/linker settings # For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
@ -203,7 +203,9 @@ add
-DGTEST_DONT_DEFINE_FOO=1 -DGTEST_DONT_DEFINE_FOO=1
to the compiler flags to tell GoogleTest to change the macro's name from `FOO` to the compiler flags to tell GoogleTest to change the macro's name from `FOO`
to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`, or `TEST`. For 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 example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write
GTEST_TEST(SomeTest, DoesThis) { ... } GTEST_TEST(SomeTest, DoesThis) { ... }

View File

@ -84,13 +84,13 @@ macro(config_compiler_and_linker)
# Ensure MSVC treats source files as UTF-8 encoded. # Ensure MSVC treats source files as UTF-8 encoded.
set(cxx_base_flags "${cxx_base_flags} -utf-8") set(cxx_base_flags "${cxx_base_flags} -utf-8")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion") set(cxx_base_flags "-Wall -Wshadow -Wconversion")
set(cxx_exception_flags "-fexceptions") set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions") 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_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") set(cxx_no_rtti_flags "-fno-rtti")
elseif (CMAKE_COMPILER_IS_GNUCXX) elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow -Werror") set(cxx_base_flags "-Wall -Wshadow")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else") set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
endif() endif()
@ -154,10 +154,6 @@ function(cxx_library_with_type name type cxx_flags)
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES
COMPILE_FLAGS "${cxx_flags}") COMPILE_FLAGS "${cxx_flags}")
# Generate debug library name with a postfix.
set_target_properties(${name}
PROPERTIES
DEBUG_POSTFIX "d")
# Set the output directory for build artifacts # Set the output directory for build artifacts
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES
@ -304,6 +300,8 @@ function(py_test name)
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN}) --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN})
endif() endif()
# Make the Python import path consistent between Bazel and CMake.
set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR})
endif(PYTHONINTERP_FOUND) endif(PYTHONINTERP_FOUND)
endfunction() endfunction()

View File

@ -27,21 +27,21 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file defines the public API for death tests. It is // This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this // #included by gtest.h so a user doesn't need to include this
// directly. // directly.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h" #include "gtest/internal/gtest-death-test-internal.h"
namespace testing {
// This flag controls the style of death tests. Valid values are "threadsafe", // 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 // meaning that the death test child process will re-execute the test binary
// from the start, running only a single death test, or "fast", // from the start, running only a single death test, or "fast",
@ -49,6 +49,8 @@ namespace testing {
// after forking. // after forking.
GTEST_DECLARE_string_(death_test_style); GTEST_DECLARE_string_(death_test_style);
namespace testing {
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
namespace internal { namespace internal {
@ -103,7 +105,6 @@ GTEST_API_ bool InDeathTestChild();
// //
// On the regular expressions used in death tests: // On the regular expressions used in death tests:
// //
// GOOGLETEST_CM0005 DO NOT DELETE
// On POSIX-compliant systems (*nix), we use the <regex.h> library, // On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax. // which uses the POSIX extended regex syntax.
// //
@ -169,23 +170,23 @@ GTEST_API_ bool InDeathTestChild();
// Asserts that a given `statement` causes the program to exit, with an // Asserts that a given `statement` causes the program to exit, with an
// integer exit status that satisfies `predicate`, and emitting error output // integer exit status that satisfies `predicate`, and emitting error output
// that matches `matcher`. // that matches `matcher`.
# define ASSERT_EXIT(statement, predicate, matcher) \ #define ASSERT_EXIT(statement, predicate, matcher) \
GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_) GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_)
// Like `ASSERT_EXIT`, but continues on to successive tests in the // Like `ASSERT_EXIT`, but continues on to successive tests in the
// test suite, if any: // test suite, if any:
# define EXPECT_EXIT(statement, predicate, matcher) \ #define EXPECT_EXIT(statement, predicate, matcher) \
GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_) GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_)
// Asserts that a given `statement` causes the program to exit, either by // Asserts that a given `statement` causes the program to exit, either by
// explicitly exiting with a nonzero exit code or being killed by a // explicitly exiting with a nonzero exit code or being killed by a
// signal, and emitting error output that matches `matcher`. // signal, and emitting error output that matches `matcher`.
# define ASSERT_DEATH(statement, matcher) \ #define ASSERT_DEATH(statement, matcher) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Like `ASSERT_DEATH`, but continues on to successive tests in the // Like `ASSERT_DEATH`, but continues on to successive tests in the
// test suite, if any: // test suite, if any:
# define EXPECT_DEATH(statement, matcher) \ #define EXPECT_DEATH(statement, matcher) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
@ -197,22 +198,23 @@ class GTEST_API_ ExitedWithCode {
ExitedWithCode(const ExitedWithCode&) = default; ExitedWithCode(const ExitedWithCode&) = default;
void operator=(const ExitedWithCode& other) = delete; void operator=(const ExitedWithCode& other) = delete;
bool operator()(int exit_status) const; bool operator()(int exit_status) const;
private: private:
const int exit_code_; const int exit_code_;
}; };
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA #if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Tests that an exit code describes an exit due to termination by a // Tests that an exit code describes an exit due to termination by a
// given signal. // given signal.
// GOOGLETEST_CM0006 DO NOT DELETE
class GTEST_API_ KilledBySignal { class GTEST_API_ KilledBySignal {
public: public:
explicit KilledBySignal(int signum); explicit KilledBySignal(int signum);
bool operator()(int exit_status) const; bool operator()(int exit_status) const;
private: private:
const int signum_; const int signum_;
}; };
# endif // !GTEST_OS_WINDOWS #endif // !GTEST_OS_WINDOWS
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
// The death testing framework causes this to have interesting semantics, // The death testing framework causes this to have interesting semantics,
@ -257,23 +259,21 @@ class GTEST_API_ KilledBySignal {
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
// }, "death"); // }, "death");
// //
# ifdef NDEBUG #ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \ #define EXPECT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex) GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \ #define ASSERT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex) GTEST_EXECUTE_STATEMENT_(statement, regex)
# else #else
# define EXPECT_DEBUG_DEATH(statement, regex) \ #define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
EXPECT_DEATH(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \ #define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex)
ASSERT_DEATH(statement, regex)
# endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as // This macro is used for implementing macros such as
@ -311,11 +311,10 @@ class GTEST_API_ KilledBySignal {
// statement unconditionally returns or throws. The Message constructor at // statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the // the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \ #define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \ GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \ << "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \ } else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \ ::testing::internal::RE::PartialMatch(".*", (regex)); \
@ -330,14 +329,14 @@ class GTEST_API_ KilledBySignal {
// useful when you are combining death test assertions with normal test // useful when you are combining death test assertions with normal test
// assertions in one test. // assertions in one test.
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ #define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ #define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
ASSERT_DEATH(statement, regex) ASSERT_DEATH(statement, regex)
#else #else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ #define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, ) GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ #define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return) GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
#endif #endif

View File

@ -32,6 +32,10 @@
// This file implements just enough of the matcher interface to allow // This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument. // 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_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
@ -98,11 +102,11 @@ class MatchResultListener {
private: private:
::std::ostream* const stream_; ::std::ostream* const stream_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); MatchResultListener(const MatchResultListener&) = delete;
MatchResultListener& operator=(const MatchResultListener&) = delete;
}; };
inline MatchResultListener::~MatchResultListener() { inline MatchResultListener::~MatchResultListener() {}
}
// An instance of a subclass of this knows how to describe itself as a // An instance of a subclass of this knows how to describe itself as a
// matcher. // matcher.
@ -176,27 +180,39 @@ namespace internal {
struct AnyEq { struct AnyEq {
template <typename A, typename B> template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a == b; } bool operator()(const A& a, const B& b) const {
return a == b;
}
}; };
struct AnyNe { struct AnyNe {
template <typename A, typename B> template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a != b; } bool operator()(const A& a, const B& b) const {
return a != b;
}
}; };
struct AnyLt { struct AnyLt {
template <typename A, typename B> template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a < b; } bool operator()(const A& a, const B& b) const {
return a < b;
}
}; };
struct AnyGt { struct AnyGt {
template <typename A, typename B> template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a > b; } bool operator()(const A& a, const B& b) const {
return a > b;
}
}; };
struct AnyLe { struct AnyLe {
template <typename A, typename B> template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a <= b; } bool operator()(const A& a, const B& b) const {
return a <= b;
}
}; };
struct AnyGe { struct AnyGe {
template <typename A, typename B> template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a >= b; } bool operator()(const A& a, const B& b) const {
return a >= b;
}
}; };
// A match result listener that ignores the explanation. // A match result listener that ignores the explanation.
@ -205,7 +221,8 @@ class DummyMatchResultListener : public MatchResultListener {
DummyMatchResultListener() : MatchResultListener(nullptr) {} DummyMatchResultListener() : MatchResultListener(nullptr) {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); DummyMatchResultListener(const DummyMatchResultListener&) = delete;
DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;
}; };
// A match result listener that forwards the explanation to a given // A match result listener that forwards the explanation to a given
@ -217,7 +234,9 @@ class StreamMatchResultListener : public MatchResultListener {
: MatchResultListener(os) {} : MatchResultListener(os) {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); StreamMatchResultListener(const StreamMatchResultListener&) = delete;
StreamMatchResultListener& operator=(const StreamMatchResultListener&) =
delete;
}; };
struct SharedPayloadBase { struct SharedPayloadBase {
@ -284,17 +303,18 @@ class MatcherBase : private MatcherDescriberInterface {
} }
protected: protected:
MatcherBase() : vtable_(nullptr) {} MatcherBase() : vtable_(nullptr), buffer_() {}
// Constructs a matcher from its implementation. // Constructs a matcher from its implementation.
template <typename U> template <typename U>
explicit MatcherBase(const MatcherInterface<U>* impl) { explicit MatcherBase(const MatcherInterface<U>* impl)
: vtable_(nullptr), buffer_() {
Init(impl); Init(impl);
} }
template <typename M, typename = typename std::remove_reference< template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher> M>::type::is_gtest_matcher>
MatcherBase(M&& m) { // NOLINT MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT
Init(std::forward<M>(m)); Init(std::forward<M>(m));
} }
@ -420,8 +440,8 @@ class MatcherBase : private MatcherDescriberInterface {
static const M& Get(const MatcherBase& m) { static const M& Get(const MatcherBase& m) {
// When inlined along with Init, need to be explicit to avoid violating // When inlined along with Init, need to be explicit to avoid violating
// strict aliasing rules. // strict aliasing rules.
const M *ptr = static_cast<const M*>( const M* ptr =
static_cast<const void*>(&m.buffer_)); static_cast<const M*>(static_cast<const void*>(&m.buffer_));
return *ptr; return *ptr;
} }
static void Init(MatcherBase& m, M impl) { static void Init(MatcherBase& m, M impl) {
@ -741,7 +761,7 @@ template <typename Rhs>
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> { class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
public: public:
explicit EqMatcher(const Rhs& rhs) explicit EqMatcher(const Rhs& rhs)
: ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { } : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) {}
static const char* Desc() { return "is equal to"; } static const char* Desc() { return "is equal to"; }
static const char* NegatedDesc() { return "isn't equal to"; } static const char* NegatedDesc() { return "isn't equal to"; }
}; };
@ -749,7 +769,7 @@ template <typename Rhs>
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> { class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
public: public:
explicit NeMatcher(const Rhs& rhs) explicit NeMatcher(const Rhs& rhs)
: ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { } : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) {}
static const char* Desc() { return "isn't equal to"; } static const char* Desc() { return "isn't equal to"; }
static const char* NegatedDesc() { return "is equal to"; } static const char* NegatedDesc() { return "is equal to"; }
}; };
@ -757,7 +777,7 @@ template <typename Rhs>
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> { class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
public: public:
explicit LtMatcher(const Rhs& rhs) explicit LtMatcher(const Rhs& rhs)
: ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { } : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) {}
static const char* Desc() { return "is <"; } static const char* Desc() { return "is <"; }
static const char* NegatedDesc() { return "isn't <"; } static const char* NegatedDesc() { return "isn't <"; }
}; };
@ -765,7 +785,7 @@ template <typename Rhs>
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> { class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
public: public:
explicit GtMatcher(const Rhs& rhs) explicit GtMatcher(const Rhs& rhs)
: ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { } : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) {}
static const char* Desc() { return "is >"; } static const char* Desc() { return "is >"; }
static const char* NegatedDesc() { return "isn't >"; } static const char* NegatedDesc() { return "isn't >"; }
}; };
@ -773,7 +793,7 @@ template <typename Rhs>
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> { class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
public: public:
explicit LeMatcher(const Rhs& rhs) explicit LeMatcher(const Rhs& rhs)
: ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { } : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) {}
static const char* Desc() { return "is <="; } static const char* Desc() { return "is <="; }
static const char* NegatedDesc() { return "isn't <="; } static const char* NegatedDesc() { return "isn't <="; }
}; };
@ -781,7 +801,7 @@ template <typename Rhs>
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> { class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
public: public:
explicit GeMatcher(const Rhs& rhs) explicit GeMatcher(const Rhs& rhs)
: ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { } : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) {}
static const char* Desc() { return "is >="; } static const char* Desc() { return "is >="; }
static const char* NegatedDesc() { return "isn't >="; } static const char* NegatedDesc() { return "isn't >="; }
}; };
@ -872,12 +892,16 @@ PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
// Note: if the parameter of Eq() were declared as const T&, Eq("foo") // Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// wouldn't compile. // wouldn't compile.
template <typename T> template <typename T>
inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); } inline internal::EqMatcher<T> Eq(T x) {
return internal::EqMatcher<T>(x);
}
// Constructs a Matcher<T> from a 'value' of type T. The constructed // Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'. // matcher matches any value that's equal to 'value'.
template <typename T> template <typename T>
Matcher<T>::Matcher(T value) { *this = Eq(value); } Matcher<T>::Matcher(T value) {
*this = Eq(value);
}
// Creates a monomorphic matcher that matches anything with type Lhs // Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...) // and equal to rhs. A user may need to use this instead of Eq(...)
@ -892,7 +916,9 @@ Matcher<T>::Matcher(T value) { *this = Eq(value); }
// can always write Matcher<T>(Lt(5)) to be explicit about the type, // can always write Matcher<T>(Lt(5)) to be explicit about the type,
// for example. // for example.
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); } inline Matcher<Lhs> TypedEq(const Rhs& rhs) {
return Eq(rhs);
}
// Creates a polymorphic matcher that matches anything >= x. // Creates a polymorphic matcher that matches anything >= x.
template <typename Rhs> template <typename Rhs>

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file defines the Message class. // This header file defines the Message class.
@ -42,7 +41,9 @@
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program! // program!
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
@ -110,7 +111,7 @@ class GTEST_API_ Message {
// Streams a non-pointer value to this object. // Streams a non-pointer value to this object.
template <typename T> template <typename T>
inline Message& operator <<(const T& val) { inline Message& operator<<(const T& val) {
// Some libraries overload << for STL containers. These // Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std. // overloads are defined in the global namespace instead of ::std.
// //
@ -125,7 +126,7 @@ class GTEST_API_ Message {
// from the global namespace. With this using declaration, // from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those // overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function. // visible via Koenig lookup are both exposed in this function.
using ::operator <<; using ::operator<<;
*ss_ << val; *ss_ << val;
return *this; return *this;
} }
@ -144,7 +145,7 @@ class GTEST_API_ Message {
// ensure consistent result across compilers, we always treat NULL // ensure consistent result across compilers, we always treat NULL
// as "(null)". // as "(null)".
template <typename T> template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT inline Message& operator<<(T* const& pointer) { // NOLINT
if (pointer == nullptr) { if (pointer == nullptr) {
*ss_ << "(null)"; *ss_ << "(null)";
} else { } else {
@ -159,25 +160,23 @@ class GTEST_API_ Message {
// templatized version above. Without this definition, streaming // templatized version above. Without this definition, streaming
// endl or other basic IO manipulators to Message will confuse the // endl or other basic IO manipulators to Message will confuse the
// compiler. // compiler.
Message& operator <<(BasicNarrowIoManip val) { Message& operator<<(BasicNarrowIoManip val) {
*ss_ << val; *ss_ << val;
return *this; return *this;
} }
// Instead of 1/0, we want to see true/false for bool values. // Instead of 1/0, we want to see true/false for bool values.
Message& operator <<(bool b) { Message& operator<<(bool b) { return *this << (b ? "true" : "false"); }
return *this << (b ? "true" : "false");
}
// These two overloads allow streaming a wide C string to a Message // These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding. // using the UTF-8 encoding.
Message& operator <<(const wchar_t* wide_c_str); Message& operator<<(const wchar_t* wide_c_str);
Message& operator <<(wchar_t* wide_c_str); Message& operator<<(wchar_t* wide_c_str);
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8 // Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object. // encoding, and streams the result to this Message object.
Message& operator <<(const ::std::wstring& wstr); Message& operator<<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
// Gets the text streamed to this object so far as an std::string. // Gets the text streamed to this object so far as an std::string.
@ -196,7 +195,7 @@ class GTEST_API_ Message {
}; };
// Streams a Message to an ostream. // Streams a Message to an ostream.
inline std::ostream& operator <<(std::ostream& os, const Message& sb) { inline std::ostream& operator<<(std::ostream& os, const Message& sb) {
return os << sb.GetString(); return os << sb.GetString();
} }

View File

@ -26,11 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Macros and functions for implementing parameterized tests // Macros and functions for implementing parameterized tests
// in Google C++ Testing and Mocking Framework (Google Test) // in Google C++ Testing and Mocking Framework (Google Test)
//
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
@ -353,9 +356,7 @@ internal::ValueArray<T...> Values(T... v) {
// } // }
// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool()); // INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
// //
inline internal::ParamGenerator<bool> Bool() { inline internal::ParamGenerator<bool> Bool() { return Values(false, true); }
return Values(false, true);
}
// Combine() allows the user to combine two or more sequences to produce // Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements. // values of a Cartesian product of those sequences' elements.
@ -428,8 +429,11 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
return 0; \ return 0; \
} \ } \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_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, \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::gtest_registering_dummy_ = \ test_name)::gtest_registering_dummy_ = \
@ -487,7 +491,6 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
&gtest_##prefix##test_suite_name##_EvalGenerateName_, \ &gtest_##prefix##test_suite_name##_EvalGenerateName_, \
__FILE__, __LINE__) __FILE__, __LINE__)
// Allow Marking a Parameterized test class as not needing to be instantiated. // Allow Marking a Parameterized test class as not needing to be instantiated.
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ #define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
namespace gtest_do_not_use_outside_namespace_scope {} \ namespace gtest_do_not_use_outside_namespace_scope {} \

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Test - The Google C++ Testing and Mocking Framework // Google Test - The Google C++ Testing and Mocking Framework
// //
// This file implements a universal value printer that can print a // This file implements a universal value printer that can print a
@ -95,7 +94,9 @@
// being defined as many user-defined container types don't have // being defined as many user-defined container types don't have
// value_type. // value_type.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
@ -257,12 +258,10 @@ struct ConvertibleToStringViewPrinter {
#endif #endif
}; };
// Prints the given number of bytes in the given object to the given // Prints the given number of bytes in the given object to the given
// ostream. // ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count, size_t count, ::std::ostream* os);
::std::ostream* os);
struct RawBytesPrinter { struct RawBytesPrinter {
// SFINAE on `sizeof` to make sure we have a complete type. // SFINAE on `sizeof` to make sure we have a complete type.
template <typename T, size_t = sizeof(T)> template <typename T, size_t = sizeof(T)>
@ -360,7 +359,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const 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_(wchar_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
#ifdef __cpp_char8_t #ifdef __cpp_lib_char8_t
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
#endif #endif
@ -410,8 +409,8 @@ GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
template <typename T1, typename T2> template <typename T1, typename T2>
std::string FormatForComparisonFailureMessage( std::string FormatForComparisonFailureMessage(const T1& value,
const T1& value, const T2& /* other_operand */) { const T2& /* other_operand */) {
return FormatForComparison<T1, T2>::Format(value); return FormatForComparison<T1, T2>::Format(value);
} }
@ -479,6 +478,12 @@ inline void PrintTo(char8_t c, ::std::ostream* os) {
} }
#endif #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. // Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) { inline void PrintTo(char* s, ::std::ostream* os) {
@ -545,7 +550,7 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
} }
// Overloads for ::std::string. // Overloads for ::std::string.
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* os) { inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os); PrintStringTo(s, os);
} }
@ -572,7 +577,7 @@ inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
// Overloads for ::std::wstring. // Overloads for ::std::wstring.
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
PrintWideStringTo(s, os); PrintWideStringTo(s, os);
} }
@ -587,6 +592,12 @@ inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } 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> template <typename T>
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) { void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
UniversalPrinter<T&>::Print(ref.get(), os); UniversalPrinter<T&>::Print(ref.get(), os);
@ -744,6 +755,14 @@ class UniversalPrinter<Optional<T>> {
} }
}; };
template <>
class UniversalPrinter<decltype(Nullopt())> {
public:
static void Print(decltype(Nullopt()), ::std::ostream* os) {
*os << "(nullopt)";
}
};
#endif // GTEST_INTERNAL_HAS_OPTIONAL #endif // GTEST_INTERNAL_HAS_OPTIONAL
#if GTEST_INTERNAL_HAS_VARIANT #if GTEST_INTERNAL_HAS_VARIANT
@ -802,8 +821,8 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
} }
} }
// This overload prints a (const) char array compactly. // This overload prints a (const) char array compactly.
GTEST_API_ void UniversalPrintArray( GTEST_API_ void UniversalPrintArray(const char* begin, size_t len,
const char* begin, size_t len, ::std::ostream* os); ::std::ostream* os);
#ifdef __cpp_char8_t #ifdef __cpp_char8_t
// This overload prints a (const) char8_t array compactly. // This overload prints a (const) char8_t array compactly.
@ -820,8 +839,8 @@ GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
::std::ostream* os); ::std::ostream* os);
// This overload prints a (const) wchar_t array compactly. // This overload prints a (const) wchar_t array compactly.
GTEST_API_ void UniversalPrintArray( GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
const wchar_t* begin, size_t len, ::std::ostream* os); ::std::ostream* os);
// Implements printing an array type T[N]. // Implements printing an array type T[N].
template <typename T, size_t N> template <typename T, size_t N>
@ -980,10 +999,10 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
UniversalPrinter<T1>::Print(value, os); UniversalPrinter<T1>::Print(value, os);
} }
typedef ::std::vector< ::std::string> Strings; typedef ::std::vector<::std::string> Strings;
// Tersely prints the first N fields of a tuple to a string vector, // Tersely prints the first N fields of a tuple to a string vector,
// one element for each field. // one element for each field.
template <typename Tuple> template <typename Tuple>
void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>, void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
Strings*) {} Strings*) {}

View File

@ -27,12 +27,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Utilities for testing Google Test itself and code that uses Google Test // Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test). // (e.g. frameworks built on top of Google Test).
// GOOGLETEST_CM0004 DO NOT DELETE
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
@ -88,7 +85,10 @@ class GTEST_API_ ScopedFakeTestPartResultReporter
TestPartResultReporterInterface* old_reporter_; TestPartResultReporterInterface* old_reporter_;
TestPartResultArray* const result_; TestPartResultArray* const result_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =
delete;
ScopedFakeTestPartResultReporter& operator=(
const ScopedFakeTestPartResultReporter&) = delete;
}; };
namespace internal { namespace internal {
@ -104,12 +104,14 @@ class GTEST_API_ SingleFailureChecker {
SingleFailureChecker(const TestPartResultArray* results, SingleFailureChecker(const TestPartResultArray* results,
TestPartResult::Type type, const std::string& substr); TestPartResult::Type type, const std::string& substr);
~SingleFailureChecker(); ~SingleFailureChecker();
private: private:
const TestPartResultArray* const results_; const TestPartResultArray* const results_;
const TestPartResult::Type type_; const TestPartResult::Type type_;
const std::string substr_; const std::string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); SingleFailureChecker(const SingleFailureChecker&) = delete;
SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;
}; };
} // namespace internal } // namespace internal
@ -119,7 +121,8 @@ class GTEST_API_ SingleFailureChecker {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// A set of macros for testing Google Test assertions or code that's expected // A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given // to generate Google Test fatal failures (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' // statement will cause exactly one fatal Google Test failure with 'substr'
// being part of the failure message. // being part of the failure message.
// //
@ -143,42 +146,44 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// gtest_unittest.cc will fail to compile if we do that. // gtest_unittest.cc will fail to compile if we do that.
#define EXPECT_FATAL_FAILURE(statement, substr) \ #define EXPECT_FATAL_FAILURE(statement, substr) \
do { \ do { \
class GTestExpectFatalFailureHelper {\ class GTestExpectFatalFailureHelper { \
public:\ public: \
static void Execute() { statement; }\ static void Execute() { statement; } \
};\ }; \
::testing::TestPartResultArray gtest_failures;\ ::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker(\ ::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
{\ { \
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter:: \ ::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\ INTERCEPT_ONLY_CURRENT_THREAD, \
GTestExpectFatalFailureHelper::Execute();\ &gtest_failures); \
}\ GTestExpectFatalFailureHelper::Execute(); \
} \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \ do { \
class GTestExpectFatalFailureHelper {\ class GTestExpectFatalFailureHelper { \
public:\ public: \
static void Execute() { statement; }\ static void Execute() { statement; } \
};\ }; \
::testing::TestPartResultArray gtest_failures;\ ::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker(\ ::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
{\ { \
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter:: \ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
INTERCEPT_ALL_THREADS, &gtest_failures);\ &gtest_failures); \
GTestExpectFatalFailureHelper::Execute();\ GTestExpectFatalFailureHelper::Execute(); \
}\ } \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
// A macro for testing Google Test assertions or code that's expected to // A macro for testing Google Test assertions or code that's expected to
// generate Google Test non-fatal failures. It asserts that the given // generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,
// statement will cause exactly one non-fatal Google Test failure with 'substr' // but not from an ASSERT_EQ). It asserts that the given statement will cause
// being part of the failure message. // 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 // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
// affects and considers failures generated in the current thread and // affects and considers failures generated in the current thread and
@ -208,31 +213,36 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
// to avoid an MSVC warning on unreachable code. // to avoid an MSVC warning on unreachable code.
#define EXPECT_NONFATAL_FAILURE(statement, substr) \ #define EXPECT_NONFATAL_FAILURE(statement, substr) \
do {\ do { \
::testing::TestPartResultArray gtest_failures;\ ::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker(\ ::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \ &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\ (substr)); \
{\ { \
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter:: \ ::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\ INTERCEPT_ONLY_CURRENT_THREAD, \
if (::testing::internal::AlwaysTrue()) { statement; }\ &gtest_failures); \
}\ if (::testing::internal::AlwaysTrue()) { \
statement; \
} \
} \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do {\ do { \
::testing::TestPartResultArray gtest_failures;\ ::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker(\ ::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \ &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\ (substr)); \
{\ { \
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures);\ &gtest_failures); \
if (::testing::internal::AlwaysTrue()) { statement; }\ if (::testing::internal::AlwaysTrue()) { \
}\ statement; \
} \
} \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_

View File

@ -26,14 +26,17 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd> #include <iosfwd>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
@ -142,7 +145,8 @@ class GTEST_API_ TestPartResultArray {
private: private:
std::vector<TestPartResult> array_; std::vector<TestPartResult> array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); TestPartResultArray(const TestPartResultArray&) = delete;
TestPartResultArray& operator=(const TestPartResultArray&) = delete;
}; };
// This interface knows how to report a test part result. // This interface knows how to report a test part result.
@ -168,11 +172,13 @@ class GTEST_API_ HasNewFatalFailureHelper
~HasNewFatalFailureHelper() override; ~HasNewFatalFailureHelper() override;
void ReportTestPartResult(const TestPartResult& result) override; void ReportTestPartResult(const TestPartResult& result) override;
bool has_new_fatal_failure() const { return has_new_fatal_failure_; } bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private: private:
bool has_new_fatal_failure_; bool has_new_fatal_failure_;
TestPartResultReporterInterface* original_reporter_; TestPartResultReporterInterface* original_reporter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete;
HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete;
}; };
} // namespace internal } // namespace internal

View File

@ -27,7 +27,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file defines the public API for Google Test. It should be // This header file defines the public API for Google Test. It should be
@ -47,8 +46,6 @@
// registration from Barthelemy Dagenais' (barthelemy@prologique.com) // registration from Barthelemy Dagenais' (barthelemy@prologique.com)
// easyUnit framework. // easyUnit framework.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
@ -59,31 +56,22 @@
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/gtest-assertion-result.h"
#include "gtest/internal/gtest-string.h"
#include "gtest/gtest-death-test.h" #include "gtest/gtest-death-test.h"
#include "gtest/gtest-matchers.h" #include "gtest/gtest-matchers.h"
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
#include "gtest/gtest-param-test.h" #include "gtest/gtest-param-test.h"
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include "gtest/gtest_prod.h"
#include "gtest/gtest-test-part.h" #include "gtest/gtest-test-part.h"
#include "gtest/gtest-typed-test.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 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
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
// Declares the flags. // Declares the flags.
// This flag temporary enables the disabled tests. // This flag temporary enables the disabled tests.
@ -138,6 +126,12 @@ GTEST_DECLARE_int32_(random_seed);
// is 1. If the value is -1 the tests are repeating forever. // is 1. If the value is -1 the tests are repeating forever.
GTEST_DECLARE_int32_(repeat); 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 // This flag controls whether Google Test includes Google Test internal
// stack frames in failure stack traces. // stack frames in failure stack traces.
GTEST_DECLARE_bool_(show_internal_stack_frames); GTEST_DECLARE_bool_(show_internal_stack_frames);
@ -163,6 +157,16 @@ GTEST_DECLARE_string_(stream_result_to);
GTEST_DECLARE_string_(flagfile); GTEST_DECLARE_string_(flagfile);
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ #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. // The upper limit for valid stack trace depths.
const int kMaxStackTraceDepth = 100; const int kMaxStackTraceDepth = 100;
@ -201,193 +205,6 @@ using TestCase = TestSuite;
class TestInfo; class TestInfo;
class UnitTest; class UnitTest;
// 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
// Includes the auto-generated header that implements a family of generic
// predicate assertion macros. This include comes late because it relies on
// APIs declared above.
#include "gtest/gtest_pred_impl.h"
namespace testing {
// The abstract class that all tests inherit from. // The abstract class that all tests inherit from.
// //
// In Google Test, a unit test program contains one or many TestSuites, and // In Google Test, a unit test program contains one or many TestSuites, and
@ -522,7 +339,8 @@ class GTEST_API_ Test {
virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; } virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
// We disallow copying Tests. // We disallow copying Tests.
GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); Test(const Test&) = delete;
Test& operator=(const Test&) = delete;
}; };
typedef internal::TimeInMillis TimeInMillis; typedef internal::TimeInMillis TimeInMillis;
@ -536,24 +354,17 @@ class TestProperty {
// C'tor. TestProperty does NOT have a default constructor. // C'tor. TestProperty does NOT have a default constructor.
// Always use this constructor (with parameters) to create a // Always use this constructor (with parameters) to create a
// TestProperty object. // TestProperty object.
TestProperty(const std::string& a_key, const std::string& a_value) : TestProperty(const std::string& a_key, const std::string& a_value)
key_(a_key), value_(a_value) { : key_(a_key), value_(a_value) {}
}
// Gets the user supplied key. // Gets the user supplied key.
const char* key() const { const char* key() const { return key_.c_str(); }
return key_.c_str();
}
// Gets the user supplied value. // Gets the user supplied value.
const char* value() const { const char* value() const { return value_.c_str(); }
return value_.c_str();
}
// Sets a new value, overriding the one supplied in the constructor. // Sets a new value, overriding the one supplied in the constructor.
void SetValue(const std::string& new_value) { void SetValue(const std::string& new_value) { value_ = new_value; }
value_ = new_value;
}
private: private:
// The key supplied by the user. // The key supplied by the user.
@ -687,7 +498,8 @@ class GTEST_API_ TestResult {
TimeInMillis elapsed_time_; TimeInMillis elapsed_time_;
// We disallow copying TestResult. // We disallow copying TestResult.
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); TestResult(const TestResult&) = delete;
TestResult& operator=(const TestResult&) = delete;
}; // class TestResult }; // class TestResult
// A TestInfo object stores the following information about a test: // A TestInfo object stores the following information about a test:
@ -833,7 +645,8 @@ class GTEST_API_ TestInfo {
// test for the second time. // test for the second time.
TestResult result_; TestResult result_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); TestInfo(const TestInfo&) = delete;
TestInfo& operator=(const TestInfo&) = delete;
}; };
// A test suite, which consists of a vector of TestInfos. // A test suite, which consists of a vector of TestInfos.
@ -941,7 +754,7 @@ class GTEST_API_ TestSuite {
// Adds a TestInfo to this test suite. Will delete the TestInfo upon // Adds a TestInfo to this test suite. Will delete the TestInfo upon
// destruction of the TestSuite object. // destruction of the TestSuite object.
void AddTestInfo(TestInfo * test_info); void AddTestInfo(TestInfo* test_info);
// Clears the results of all tests in this test suite. // Clears the results of all tests in this test suite.
void ClearResult(); void ClearResult();
@ -1042,7 +855,8 @@ class GTEST_API_ TestSuite {
TestResult ad_hoc_test_result_; TestResult ad_hoc_test_result_;
// We disallow copying TestSuites. // We disallow copying TestSuites.
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestSuite); TestSuite(const TestSuite&) = delete;
TestSuite& operator=(const TestSuite&) = delete;
}; };
// An Environment object is capable of setting up and tearing down an // An Environment object is capable of setting up and tearing down an
@ -1069,6 +883,7 @@ class Environment {
// Override this to define how to tear down the environment. // Override this to define how to tear down the environment.
virtual void TearDown() {} virtual void TearDown() {}
private: private:
// If you see an error about overriding the following function or // If you see an error about overriding the following function or
// about it being private, you have mis-spelled SetUp() as Setup(). // about it being private, you have mis-spelled SetUp() as Setup().
@ -1120,6 +935,9 @@ class TestEventListener {
// Fired before the test starts. // Fired before the test starts.
virtual void OnTestStart(const TestInfo& test_info) = 0; 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. // Fired after a failed assertion or a SUCCEED() invocation.
// If you want to throw an exception from this function to skip to the next // 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. // TEST, it must be AssertionException defined above, or inherited from it.
@ -1143,8 +961,7 @@ class TestEventListener {
virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
// Fired after each iteration of tests finishes. // Fired after each iteration of tests finishes.
virtual void OnTestIterationEnd(const UnitTest& unit_test, virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0;
int iteration) = 0;
// Fired after all test activities have ended. // Fired after all test activities have ended.
virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
@ -1169,6 +986,7 @@ class EmptyTestEventListener : public TestEventListener {
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void OnTestStart(const TestInfo& /*test_info*/) override {} void OnTestStart(const TestInfo& /*test_info*/) override {}
void OnTestDisabled(const TestInfo& /*test_info*/) override {}
void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {} void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
void OnTestEnd(const TestInfo& /*test_info*/) override {} void OnTestEnd(const TestInfo& /*test_info*/) override {}
void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {} void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
@ -1258,7 +1076,8 @@ class GTEST_API_ TestEventListeners {
TestEventListener* default_xml_generator_; TestEventListener* default_xml_generator_;
// We disallow copying TestEventListeners. // We disallow copying TestEventListeners.
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); TestEventListeners(const TestEventListeners&) = delete;
TestEventListeners& operator=(const TestEventListeners&) = delete;
}; };
// A UnitTest consists of a vector of TestSuites. // A UnitTest consists of a vector of TestSuites.
@ -1301,8 +1120,7 @@ class GTEST_API_ UnitTest {
// Returns the TestInfo object for the test that's currently running, // Returns the TestInfo object for the test that's currently running,
// or NULL if no test is running. // or NULL if no test is running.
const TestInfo* current_test_info() const const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_);
GTEST_LOCK_EXCLUDED_(mutex_);
// Returns the random seed used at the start of the current test run. // Returns the random seed used at the start of the current test run.
int random_seed() const; int random_seed() const;
@ -1408,8 +1226,7 @@ class GTEST_API_ UnitTest {
// eventually call this to report their results. The user code // eventually call this to report their results. The user code
// should use the assertion macros instead of calling this directly. // should use the assertion macros instead of calling this directly.
void AddTestPartResult(TestPartResult::Type result_type, void AddTestPartResult(TestPartResult::Type result_type,
const char* file_name, const char* file_name, int line_number,
int line_number,
const std::string& message, const std::string& message,
const std::string& os_stack_trace) const std::string& os_stack_trace)
GTEST_LOCK_EXCLUDED_(mutex_); GTEST_LOCK_EXCLUDED_(mutex_);
@ -1440,8 +1257,7 @@ class GTEST_API_ UnitTest {
friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites(); friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites();
friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend internal::UnitTestImpl* internal::GetUnitTestImpl();
friend void internal::ReportFailureInUnknownLocation( friend void internal::ReportFailureInUnknownLocation(
TestPartResult::Type result_type, TestPartResult::Type result_type, const std::string& message);
const std::string& message);
// Creates an empty UnitTest. // Creates an empty UnitTest.
UnitTest(); UnitTest();
@ -1455,8 +1271,7 @@ class GTEST_API_ UnitTest {
GTEST_LOCK_EXCLUDED_(mutex_); GTEST_LOCK_EXCLUDED_(mutex_);
// Pops a trace from the per-thread Google Test trace stack. // Pops a trace from the per-thread Google Test trace stack.
void PopGTestTrace() void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_);
GTEST_LOCK_EXCLUDED_(mutex_);
// Protects mutable state in *impl_. This is mutable as some const // Protects mutable state in *impl_. This is mutable as some const
// methods need to lock it too. // methods need to lock it too.
@ -1469,7 +1284,8 @@ class GTEST_API_ UnitTest {
internal::UnitTestImpl* impl_; internal::UnitTestImpl* impl_;
// We disallow copying UnitTest. // We disallow copying UnitTest.
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); UnitTest(const UnitTest&) = delete;
UnitTest& operator=(const UnitTest&) = delete;
}; };
// A convenient wrapper for adding an environment for the test // A convenient wrapper for adding an environment for the test
@ -1520,13 +1336,11 @@ namespace internal {
// when calling EXPECT_* in a tight loop. // when calling EXPECT_* in a tight loop.
template <typename T1, typename T2> template <typename T1, typename T2>
AssertionResult CmpHelperEQFailure(const char* lhs_expression, AssertionResult CmpHelperEQFailure(const char* lhs_expression,
const char* rhs_expression, const char* rhs_expression, const T1& lhs,
const T1& lhs, const T2& rhs) { const T2& rhs) {
return EqFailure(lhs_expression, return EqFailure(lhs_expression, rhs_expression,
rhs_expression,
FormatForComparisonFailureMessage(lhs, rhs), FormatForComparisonFailureMessage(lhs, rhs),
FormatForComparisonFailureMessage(rhs, lhs), FormatForComparisonFailureMessage(rhs, lhs), false);
false);
} }
// This block of code defines operator==/!= // This block of code defines operator==/!=
@ -1539,8 +1353,7 @@ inline bool operator!=(faketype, faketype) { return false; }
// The helper function for {ASSERT|EXPECT}_EQ. // The helper function for {ASSERT|EXPECT}_EQ.
template <typename T1, typename T2> template <typename T1, typename T2>
AssertionResult CmpHelperEQ(const char* lhs_expression, AssertionResult CmpHelperEQ(const char* lhs_expression,
const char* rhs_expression, const char* rhs_expression, const T1& lhs,
const T1& lhs,
const T2& rhs) { const T2& rhs) {
if (lhs == rhs) { if (lhs == rhs) {
return AssertionSuccess(); return AssertionSuccess();
@ -1571,8 +1384,7 @@ class EqHelper {
// Even though its body looks the same as the above version, we // Even though its body looks the same as the above version, we
// cannot merge the two, as it will make anonymous enums unhappy. // cannot merge the two, as it will make anonymous enums unhappy.
static AssertionResult Compare(const char* lhs_expression, static AssertionResult Compare(const char* lhs_expression,
const char* rhs_expression, const char* rhs_expression, BiggestInt lhs,
BiggestInt lhs,
BiggestInt rhs) { BiggestInt rhs) {
return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
} }
@ -1607,16 +1419,16 @@ AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ #define GTEST_IMPL_CMP_HELPER_(op_name, op) \
template <typename T1, typename T2>\ template <typename T1, typename T2> \
AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
const T1& val1, const T2& val2) {\ const T1& val1, const T2& val2) { \
if (val1 op val2) {\ if (val1 op val2) { \
return AssertionSuccess();\ return AssertionSuccess(); \
} else {\ } else { \
return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\ return CmpHelperOpFailure(expr1, expr2, val1, val2, #op); \
}\ } \
} }
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
@ -1638,49 +1450,42 @@ GTEST_IMPL_CMP_HELPER_(GT, >)
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const char* s1, const char* s1, const char* s2);
const char* s2);
// The helper function for {ASSERT|EXPECT}_STRCASEEQ. // The helper function for {ASSERT|EXPECT}_STRCASEEQ.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression, GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const char* s1, const char* s1, const char* s2);
const char* s2);
// The helper function for {ASSERT|EXPECT}_STRNE. // The helper function for {ASSERT|EXPECT}_STRNE.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const char* s1, const char* s1, const char* s2);
const char* s2);
// The helper function for {ASSERT|EXPECT}_STRCASENE. // The helper function for {ASSERT|EXPECT}_STRCASENE.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const char* s1, const char* s1, const char* s2);
const char* s2);
// Helper function for *_STREQ on wide strings. // Helper function for *_STREQ on wide strings.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const wchar_t* s1, const wchar_t* s1, const wchar_t* s2);
const wchar_t* s2);
// Helper function for *_STRNE on wide strings. // Helper function for *_STRNE on wide strings.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const wchar_t* s1, const wchar_t* s1, const wchar_t* s2);
const wchar_t* s2);
} // namespace internal } // namespace internal
@ -1692,32 +1497,40 @@ GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
// //
// The {needle,haystack}_expr arguments are the stringified // The {needle,haystack}_expr arguments are the stringified
// expressions that generated the two real arguments. // expressions that generated the two real arguments.
GTEST_API_ AssertionResult IsSubstring( GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* needle_expr, const char* haystack_expr, const char* haystack_expr,
const char* needle, const char* haystack); const char* needle,
GTEST_API_ AssertionResult IsSubstring( const char* haystack);
const char* needle_expr, const char* haystack_expr, GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const wchar_t* needle, const wchar_t* haystack); const char* haystack_expr,
GTEST_API_ AssertionResult IsNotSubstring( const wchar_t* needle,
const char* needle_expr, const char* haystack_expr, const wchar_t* haystack);
const char* needle, const char* haystack); GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
GTEST_API_ AssertionResult IsNotSubstring( const char* haystack_expr,
const char* needle_expr, const char* haystack_expr, const char* needle,
const wchar_t* needle, const wchar_t* haystack); const char* haystack);
GTEST_API_ AssertionResult IsSubstring( GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
const char* needle_expr, const char* haystack_expr, const char* haystack_expr,
const ::std::string& needle, const ::std::string& haystack); const wchar_t* needle,
GTEST_API_ AssertionResult IsNotSubstring( const wchar_t* haystack);
const char* needle_expr, const char* haystack_expr, GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const ::std::string& needle, const ::std::string& haystack); 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 #if GTEST_HAS_STD_WSTRING
GTEST_API_ AssertionResult IsSubstring( GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* needle_expr, const char* haystack_expr, const char* haystack_expr,
const ::std::wstring& needle, const ::std::wstring& haystack); const ::std::wstring& needle,
GTEST_API_ AssertionResult IsNotSubstring( const ::std::wstring& haystack);
const char* needle_expr, const char* haystack_expr, GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
const ::std::wstring& needle, const ::std::wstring& haystack); const char* haystack_expr,
const ::std::wstring& needle,
const ::std::wstring& haystack);
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
namespace internal { namespace internal {
@ -1732,8 +1545,7 @@ namespace internal {
template <typename RawType> template <typename RawType>
AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression, AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
const char* rhs_expression, const char* rhs_expression,
RawType lhs_value, RawType lhs_value, RawType rhs_value) {
RawType rhs_value) {
const FloatingPoint<RawType> lhs(lhs_value), rhs(rhs_value); const FloatingPoint<RawType> lhs(lhs_value), rhs(rhs_value);
if (lhs.AlmostEquals(rhs)) { if (lhs.AlmostEquals(rhs)) {
@ -1748,10 +1560,8 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
<< rhs_value; << rhs_value;
return EqFailure(lhs_expression, return EqFailure(lhs_expression, rhs_expression,
rhs_expression, StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
StringStreamToString(&lhs_ss),
StringStreamToString(&rhs_ss),
false); false);
} }
@ -1761,8 +1571,7 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
const char* expr2, const char* expr2,
const char* abs_error_expr, const char* abs_error_expr,
double val1, double val1, double val2,
double val2,
double abs_error); double abs_error);
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@ -1770,9 +1579,7 @@ GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
class GTEST_API_ AssertHelper { class GTEST_API_ AssertHelper {
public: public:
// Constructor. // Constructor.
AssertHelper(TestPartResult::Type type, AssertHelper(TestPartResult::Type type, const char* file, int line,
const char* file,
int line,
const char* message); const char* message);
~AssertHelper(); ~AssertHelper();
@ -1786,11 +1593,9 @@ class GTEST_API_ AssertHelper {
// re-using stack space even for temporary variables, so every EXPECT_EQ // re-using stack space even for temporary variables, so every EXPECT_EQ
// reserves stack space for another AssertHelper. // reserves stack space for another AssertHelper.
struct AssertHelperData { struct AssertHelperData {
AssertHelperData(TestPartResult::Type t, AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,
const char* srcfile,
int line_num,
const char* msg) const char* msg)
: type(t), file(srcfile), line(line_num), message(msg) { } : type(t), file(srcfile), line(line_num), message(msg) {}
TestPartResult::Type const type; TestPartResult::Type const type;
const char* const file; const char* const file;
@ -1798,12 +1603,14 @@ class GTEST_API_ AssertHelper {
std::string const message; std::string const message;
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); AssertHelperData(const AssertHelperData&) = delete;
AssertHelperData& operator=(const AssertHelperData&) = delete;
}; };
AssertHelperData* const data_; AssertHelperData* const data_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); AssertHelper(const AssertHelper&) = delete;
AssertHelper& operator=(const AssertHelper&) = delete;
}; };
} // namespace internal } // namespace internal
@ -1860,15 +1667,14 @@ class WithParamInterface {
private: private:
// Sets parameter value. The caller is responsible for making sure the value // Sets parameter value. The caller is responsible for making sure the value
// remains alive and unchanged throughout the current test. // remains alive and unchanged throughout the current test.
static void SetParam(const ParamType* parameter) { static void SetParam(const ParamType* parameter) { parameter_ = parameter; }
parameter_ = parameter;
}
// Static value used for accessing parameter during a test lifetime. // Static value used for accessing parameter during a test lifetime.
static const ParamType* parameter_; static const ParamType* parameter_;
// TestClass must be a subclass of WithParamInterface<T> and Test. // TestClass must be a subclass of WithParamInterface<T> and Test.
template <class TestClass> friend class internal::ParameterizedTestFactory; template <class TestClass>
friend class internal::ParameterizedTestFactory;
}; };
template <typename T> template <typename T>
@ -1878,8 +1684,7 @@ const T* WithParamInterface<T>::parameter_ = nullptr;
// WithParamInterface, and can just inherit from ::testing::TestWithParam. // WithParamInterface, and can just inherit from ::testing::TestWithParam.
template <typename T> template <typename T>
class TestWithParam : public Test, public WithParamInterface<T> { class TestWithParam : public Test, public WithParamInterface<T> {};
};
// Macros for indicating success/failure in test code. // Macros for indicating success/failure in test code.
@ -1925,7 +1730,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// Define this macro to 1 to omit the definition of FAIL(), which is a // Define this macro to 1 to omit the definition of FAIL(), which is a
// generic name and clashes with some other libraries. // generic name and clashes with some other libraries.
#if !GTEST_DONT_DEFINE_FAIL #if !GTEST_DONT_DEFINE_FAIL
# define FAIL() GTEST_FAIL() #define FAIL() GTEST_FAIL()
#endif #endif
// Generates a success with a generic message. // Generates a success with a generic message.
@ -1934,7 +1739,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// Define this macro to 1 to omit the definition of SUCCEED(), which // Define this macro to 1 to omit the definition of SUCCEED(), which
// is a generic name and clashes with some other libraries. // is a generic name and clashes with some other libraries.
#if !GTEST_DONT_DEFINE_SUCCEED #if !GTEST_DONT_DEFINE_SUCCEED
# define SUCCEED() GTEST_SUCCEED() #define SUCCEED() GTEST_SUCCEED()
#endif #endif
// Macros for testing exceptions. // Macros for testing exceptions.
@ -1969,8 +1774,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_NONFATAL_FAILURE_) GTEST_NONFATAL_FAILURE_)
#define GTEST_ASSERT_TRUE(condition) \ #define GTEST_ASSERT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)
GTEST_FATAL_FAILURE_)
#define GTEST_ASSERT_FALSE(condition) \ #define GTEST_ASSERT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_FATAL_FAILURE_) GTEST_FATAL_FAILURE_)
@ -2070,27 +1874,27 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// ASSERT_XY(), which clashes with some users' own code. // ASSERT_XY(), which clashes with some users' own code.
#if !GTEST_DONT_DEFINE_ASSERT_EQ #if !GTEST_DONT_DEFINE_ASSERT_EQ
# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)
#endif #endif
#if !GTEST_DONT_DEFINE_ASSERT_NE #if !GTEST_DONT_DEFINE_ASSERT_NE
# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)
#endif #endif
#if !GTEST_DONT_DEFINE_ASSERT_LE #if !GTEST_DONT_DEFINE_ASSERT_LE
# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)
#endif #endif
#if !GTEST_DONT_DEFINE_ASSERT_LT #if !GTEST_DONT_DEFINE_ASSERT_LT
# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)
#endif #endif
#if !GTEST_DONT_DEFINE_ASSERT_GE #if !GTEST_DONT_DEFINE_ASSERT_GE
# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)
#endif #endif
#if !GTEST_DONT_DEFINE_ASSERT_GT #if !GTEST_DONT_DEFINE_ASSERT_GT
# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)
#endif #endif
// C-string Comparisons. All tests treat NULL and any non-NULL string // C-string Comparisons. All tests treat NULL and any non-NULL string
@ -2115,7 +1919,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
#define EXPECT_STRCASEEQ(s1, s2) \ #define EXPECT_STRCASEEQ(s1, s2) \
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)
#define EXPECT_STRCASENE(s1, s2)\ #define EXPECT_STRCASENE(s1, s2) \
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
#define ASSERT_STREQ(s1, s2) \ #define ASSERT_STREQ(s1, s2) \
@ -2124,7 +1928,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
#define ASSERT_STRCASEEQ(s1, s2) \ #define ASSERT_STRCASEEQ(s1, s2) \
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)
#define ASSERT_STRCASENE(s1, s2)\ #define ASSERT_STRCASENE(s1, s2) \
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
// Macros for comparing floating-point numbers. // Macros for comparing floating-point numbers.
@ -2141,29 +1945,29 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// FloatingPoint template class in gtest-internal.h if you are // FloatingPoint template class in gtest-internal.h if you are
// interested in the implementation details. // interested in the implementation details.
#define EXPECT_FLOAT_EQ(val1, val2)\ #define EXPECT_FLOAT_EQ(val1, val2) \
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
val1, val2) val1, val2)
#define EXPECT_DOUBLE_EQ(val1, val2)\ #define EXPECT_DOUBLE_EQ(val1, val2) \
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
val1, val2) val1, val2)
#define ASSERT_FLOAT_EQ(val1, val2)\ #define ASSERT_FLOAT_EQ(val1, val2) \
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
val1, val2) val1, val2)
#define ASSERT_DOUBLE_EQ(val1, val2)\ #define ASSERT_DOUBLE_EQ(val1, val2) \
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
val1, val2) val1, val2)
#define EXPECT_NEAR(val1, val2, abs_error)\ #define EXPECT_NEAR(val1, val2, abs_error) \
EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \
val1, val2, abs_error) abs_error)
#define ASSERT_NEAR(val1, val2, abs_error)\ #define ASSERT_NEAR(val1, val2, abs_error) \
ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \
val1, val2, abs_error) abs_error)
// These predicate format functions work on floating-point values, and // These predicate format functions work on floating-point values, and
// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
@ -2177,7 +1981,6 @@ GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
double val1, double val2); double val1, double val2);
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// Macros that test for HRESULT failure and success, these are only useful // Macros that test for HRESULT failure and success, these are only useful
@ -2189,16 +1992,16 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
// expected result and the actual result with both a human-readable // expected result and the actual result with both a human-readable
// string representation of the error, if available, as well as the // string representation of the error, if available, as well as the
// hex result code. // hex result code.
# define EXPECT_HRESULT_SUCCEEDED(expr) \ #define EXPECT_HRESULT_SUCCEEDED(expr) \
EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
# define ASSERT_HRESULT_SUCCEEDED(expr) \ #define ASSERT_HRESULT_SUCCEEDED(expr) \
ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
# define EXPECT_HRESULT_FAILED(expr) \ #define EXPECT_HRESULT_FAILED(expr) \
EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
# define ASSERT_HRESULT_FAILED(expr) \ #define ASSERT_HRESULT_FAILED(expr) \
ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
@ -2258,7 +2061,8 @@ class GTEST_API_ ScopedTrace {
private: private:
void PushTrace(const char* file, int line, std::string message); void PushTrace(const char* file, int line, std::string message);
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); ScopedTrace(const ScopedTrace&) = delete;
ScopedTrace& operator=(const ScopedTrace&) = delete;
} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
// c'tor and d'tor. Therefore it doesn't // c'tor and d'tor. Therefore it doesn't
// need to be used otherwise. // need to be used otherwise.
@ -2279,7 +2083,7 @@ class GTEST_API_ ScopedTrace {
// Therefore, a SCOPED_TRACE() would (correctly) only affect the // Therefore, a SCOPED_TRACE() would (correctly) only affect the
// assertions in its own thread. // assertions in its own thread.
#define SCOPED_TRACE(message) \ #define SCOPED_TRACE(message) \
::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \
__FILE__, __LINE__, (message)) __FILE__, __LINE__, (message))
// Compile-time assertion for type equality. // Compile-time assertion for type equality.
@ -2378,20 +2182,19 @@ constexpr bool StaticAssertTypeEq() noexcept {
// EXPECT_EQ(a_.size(), 0); // EXPECT_EQ(a_.size(), 0);
// EXPECT_EQ(b_.size(), 1); // EXPECT_EQ(b_.size(), 1);
// } // }
// #define GTEST_TEST_F(test_fixture, test_name) \
// GOOGLETEST_CM0011 DO NOT DELETE
#if !GTEST_DONT_DEFINE_TEST
#define TEST_F(test_fixture, test_name)\
GTEST_TEST_(test_fixture, test_name, test_fixture, \ GTEST_TEST_(test_fixture, test_name, test_fixture, \
::testing::internal::GetTypeId<test_fixture>()) ::testing::internal::GetTypeId<test_fixture>())
#endif // !GTEST_DONT_DEFINE_TEST #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. // Returns a path to temporary directory.
// Tries to determine an appropriate directory for the platform. // Tries to determine an appropriate directory for the platform.
GTEST_API_ std::string TempDir(); GTEST_API_ std::string TempDir();
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(pop) #pragma warning(pop)
#endif #endif
// Dynamically registers a test with the framework. // Dynamically registers a test with the framework.
@ -2445,6 +2248,7 @@ GTEST_API_ std::string TempDir();
// } // }
// ... // ...
// int main(int argc, char** argv) { // int main(int argc, char** argv) {
// ::testing::InitGoogleTest(&argc, argv);
// std::vector<int> values_to_test = LoadValuesFromConfig(); // std::vector<int> values_to_test = LoadValuesFromConfig();
// RegisterMyTests(values_to_test); // RegisterMyTests(values_to_test);
// ... // ...
@ -2486,9 +2290,7 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
// namespace and has an all-caps name. // namespace and has an all-caps name.
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
inline int RUN_ALL_TESTS() { inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }
return ::testing::UnitTest::GetInstance()->Run();
}
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251

View File

@ -26,17 +26,19 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
// //
// Implements a family of generic predicate assertion macros. // Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#include "gtest/gtest.h" #include "gtest/gtest-assertion-result.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
namespace testing { namespace testing {
@ -79,15 +81,11 @@ namespace testing {
else \ else \
on_failure(gtest_ar.failure_message()) on_failure(gtest_ar.failure_message())
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code. // this in your code.
template <typename Pred, template <typename Pred, typename T1>
typename T1> AssertionResult AssertPred1Helper(const char* pred_text, const char* e1,
AssertionResult AssertPred1Helper(const char* pred_text, Pred pred, const T1& v1) {
const char* e1,
Pred pred,
const T1& v1) {
if (pred(v1)) return AssertionSuccess(); if (pred(v1)) return AssertionSuccess();
return AssertionFailure() return AssertionFailure()
@ -98,40 +96,27 @@ AssertionResult AssertPred1Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \
GTEST_ASSERT_(pred_format(#v1, v1), \ GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code. // this in your code.
#define GTEST_PRED1_(pred, v1, on_failure)\ #define GTEST_PRED1_(pred, v1, on_failure) \
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)
#v1, \
pred, \
v1), on_failure)
// Unary predicate assertion macros. // Unary predicate assertion macros.
#define EXPECT_PRED_FORMAT1(pred_format, v1) \ #define EXPECT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED1(pred, v1) \ #define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT1(pred_format, v1) \ #define ASSERT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED1(pred, v1) \ #define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code. // this in your code.
template <typename Pred, template <typename Pred, typename T1, typename T2>
typename T1, AssertionResult AssertPred2Helper(const char* pred_text, const char* e1,
typename T2> const char* e2, Pred pred, const T1& v1,
AssertionResult AssertPred2Helper(const char* pred_text,
const char* e1,
const char* e2,
Pred pred,
const T1& v1,
const T2& v2) { const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess(); if (pred(v1, v2)) return AssertionSuccess();
@ -145,19 +130,14 @@ AssertionResult AssertPred2Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code. // this in your code.
#define GTEST_PRED2_(pred, v1, v2, on_failure)\ #define GTEST_PRED2_(pred, v1, v2, on_failure) \
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \
#v1, \ on_failure)
#v2, \
pred, \
v1, \
v2), on_failure)
// Binary predicate assertion macros. // Binary predicate assertion macros.
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
@ -169,22 +149,12 @@ AssertionResult AssertPred2Helper(const char* pred_text,
#define ASSERT_PRED2(pred, v1, v2) \ #define ASSERT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code. // this in your code.
template <typename Pred, template <typename Pred, typename T1, typename T2, typename T3>
typename T1, AssertionResult AssertPred3Helper(const char* pred_text, const char* e1,
typename T2, const char* e2, const char* e3, Pred pred,
typename T3> const T1& v1, const T2& v2, const T3& v3) {
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(); if (pred(v1, v2, v3)) return AssertionSuccess();
return AssertionFailure() return AssertionFailure()
@ -198,21 +168,15 @@ AssertionResult AssertPred3Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure)
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code. // this in your code.
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ #define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ GTEST_ASSERT_( \
#v1, \ ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \
#v2, \ on_failure)
#v3, \
pred, \
v1, \
v2, \
v3), on_failure)
// Ternary predicate assertion macros. // Ternary predicate assertion macros.
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
@ -224,25 +188,13 @@ AssertionResult AssertPred3Helper(const char* pred_text,
#define ASSERT_PRED3(pred, v1, v2, v3) \ #define ASSERT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code. // this in your code.
template <typename Pred, template <typename Pred, typename T1, typename T2, typename T3, typename T4>
typename T1, AssertionResult AssertPred4Helper(const char* pred_text, const char* e1,
typename T2, const char* e2, const char* e3,
typename T3, const char* e4, Pred pred, const T1& v1,
typename T4> const T2& v2, const T3& v3, const T4& v4) {
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(); if (pred(v1, v2, v3, v4)) return AssertionSuccess();
return AssertionFailure() return AssertionFailure()
@ -257,23 +209,15 @@ AssertionResult AssertPred4Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code. // this in your code.
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ #define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \
#v1, \ v1, v2, v3, v4), \
#v2, \ on_failure)
#v3, \
#v4, \
pred, \
v1, \
v2, \
v3, \
v4), on_failure)
// 4-ary predicate assertion macros. // 4-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
@ -285,28 +229,15 @@ AssertionResult AssertPred4Helper(const char* pred_text,
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ #define ASSERT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code. // this in your code.
template <typename Pred, template <typename Pred, typename T1, typename T2, typename T3, typename T4,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5> typename T5>
AssertionResult AssertPred5Helper(const char* pred_text, AssertionResult AssertPred5Helper(const char* pred_text, const char* e1,
const char* e1, const char* e2, const char* e3,
const char* e2, const char* e4, const char* e5, Pred pred,
const char* e3, const T1& v1, const T2& v2, const T3& v3,
const char* e4, const T4& v4, const T5& v5) {
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(); if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
return AssertionFailure() return AssertionFailure()
@ -322,25 +253,16 @@ AssertionResult AssertPred5Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
// Don't use this in your code. // Don't use this in your code.
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ #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), \ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
on_failure) on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code. // this in your code.
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ #define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \
#v1, \ pred, v1, v2, v3, v4, v5), \
#v2, \ on_failure)
#v3, \
#v4, \
#v5, \
pred, \
v1, \
v2, \
v3, \
v4, \
v5), on_failure)
// 5-ary predicate assertion macros. // 5-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
@ -352,8 +274,6 @@ AssertionResult AssertPred5Helper(const char* pred_text,
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
} // namespace testing } // namespace testing
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_

View File

@ -27,9 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// // Google C++ Testing and Mocking Framework definitions useful in production
// Google C++ Testing and Mocking Framework definitions useful in production code. // code.
// GOOGLETEST_CM0003 DO NOT DELETE
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
@ -55,7 +54,7 @@
// Note: The test class must be in the same namespace as the class being tested. // 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. // For example, putting MyClassTest in an anonymous namespace will not work.
#define FRIEND_TEST(test_case_name, test_name)\ #define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test friend class test_case_name##_##test_name##_Test
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_

View File

@ -15,18 +15,6 @@ The custom directory is an injection point for custom user configurations.
The following macros can be defined: The following macros can be defined:
### Flag related macros:
* `GTEST_FLAG(flag_name)`
* `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its
own flagfile flag parsing.
* `GTEST_DECLARE_bool_(name)`
* `GTEST_DECLARE_int32_(name)`
* `GTEST_DECLARE_string_(name)`
* `GTEST_DEFINE_bool_(name, default_val, doc)`
* `GTEST_DEFINE_int32_(name, default_val, doc)`
* `GTEST_DEFINE_string_(name, default_val, doc)`
### Logging: ### Logging:
* `GTEST_LOG_(severity)` * `GTEST_LOG_(severity)`

View File

@ -26,27 +26,31 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file defines internal utilities needed for implementing // This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice. // death tests. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE
// 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_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define 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/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include <stdio.h> GTEST_DECLARE_string_(internal_run_death_test);
#include <memory>
namespace testing { namespace testing {
namespace internal { namespace internal {
GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags). // Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style"; const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork"; const char kDeathTestUseFork[] = "death_test_use_fork";
@ -83,16 +87,18 @@ class GTEST_API_ DeathTest {
static bool Create(const char* statement, Matcher<const std::string&> matcher, static bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test); const char* file, int line, DeathTest** test);
DeathTest(); DeathTest();
virtual ~DeathTest() { } virtual ~DeathTest() {}
// A helper class that aborts a death test when it's deleted. // A helper class that aborts a death test when it's deleted.
class ReturnSentinel { class ReturnSentinel {
public: public:
explicit ReturnSentinel(DeathTest* test) : test_(test) { } explicit ReturnSentinel(DeathTest* test) : test_(test) {}
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
private: private:
DeathTest* const test_; DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); ReturnSentinel(const ReturnSentinel&) = delete;
ReturnSentinel& operator=(const ReturnSentinel&) = delete;
} GTEST_ATTRIBUTE_UNUSED_; } GTEST_ATTRIBUTE_UNUSED_;
// An enumeration of possible roles that may be taken when a death // An enumeration of possible roles that may be taken when a death
@ -137,7 +143,8 @@ class GTEST_API_ DeathTest {
// A string containing a description of the outcome of the last death test. // A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_; static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); DeathTest(const DeathTest&) = delete;
DeathTest& operator=(const DeathTest&) = delete;
}; };
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
@ -145,7 +152,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// Factory interface for death tests. May be mocked out for testing. // Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory { class DeathTestFactory {
public: public:
virtual ~DeathTestFactory() { } virtual ~DeathTestFactory() {}
virtual bool Create(const char* statement, virtual bool Create(const char* statement,
Matcher<const std::string&> matcher, const char* file, Matcher<const std::string&> matcher, const char* file,
int line, DeathTest** test) = 0; int line, DeathTest** test) = 0;
@ -186,12 +193,12 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
// Traps C++ exceptions escaping statement and reports them as test // Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here. // failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ #define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \ try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \ } catch (const ::std::exception& gtest_exception) { \
fprintf(\ fprintf( \
stderr, \ stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \ "\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \ "death test statement. Exception message: %s\n", \
@ -203,11 +210,11 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} }
# else #else
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ #define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
# endif #endif
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*. // ASSERT_EXIT*, and EXPECT_EXIT*.
@ -236,8 +243,6 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \ break; \
} \ } \
default: \
break; \
} \ } \
} \ } \
} else \ } else \
@ -265,16 +270,12 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
// RUN_ALL_TESTS was called. // RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag { class InternalRunDeathTestFlag {
public: public:
InternalRunDeathTestFlag(const std::string& a_file, InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
int a_line,
int an_index,
int a_write_fd) int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index), : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}
write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() { ~InternalRunDeathTestFlag() {
if (write_fd_ >= 0) if (write_fd_ >= 0) posix::Close(write_fd_);
posix::Close(write_fd_);
} }
const std::string& file() const { return file_; } const std::string& file() const { return file_; }
@ -288,7 +289,8 @@ class InternalRunDeathTestFlag {
int index_; int index_;
int write_fd_; int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete;
InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete;
}; };
// Returns a newly created InternalRunDeathTestFlag object with fields // Returns a newly created InternalRunDeathTestFlag object with fields

View File

@ -26,7 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Google Test filepath utilities // Google Test filepath utilities
// //
// This header file declares classes and functions used internally by // This header file declares classes and functions used internally by
@ -35,7 +35,9 @@
// This file is #included in gtest/internal/gtest-internal.h. // This file is #included in gtest/internal/gtest-internal.h.
// Do not include this header file separately! // Do not include this header file separately!
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
@ -61,8 +63,8 @@ namespace internal {
class GTEST_API_ FilePath { class GTEST_API_ FilePath {
public: public:
FilePath() : pathname_("") { } FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
explicit FilePath(const std::string& pathname) : pathname_(pathname) { explicit FilePath(const std::string& pathname) : pathname_(pathname) {
Normalize(); Normalize();
@ -73,9 +75,7 @@ class GTEST_API_ FilePath {
return *this; return *this;
} }
void Set(const FilePath& rhs) { void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
pathname_ = rhs.pathname_;
}
const std::string& string() const { return pathname_; } const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); } const char* c_str() const { return pathname_.c_str(); }
@ -88,8 +88,7 @@ class GTEST_API_ FilePath {
// than zero (e.g., 12), returns "dir/test_12.xml". // than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /. // On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory, static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name, const FilePath& base_name, int number,
int number,
const char* extension); const char* extension);
// Given directory = "dir", relative_path = "test.xml", // Given directory = "dir", relative_path = "test.xml",

View File

@ -26,13 +26,15 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file declares functions and macros used internally by // This header file declares functions and macros used internally by
// Google Test. They are subject to change without notice. // Google Test. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
@ -40,19 +42,20 @@
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#if GTEST_OS_LINUX #if GTEST_OS_LINUX
# include <stdlib.h> #include <stdlib.h>
# include <sys/types.h> #include <sys/types.h>
# include <sys/wait.h> #include <sys/wait.h>
# include <unistd.h> #include <unistd.h>
#endif // GTEST_OS_LINUX #endif // GTEST_OS_LINUX
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
# include <stdexcept> #include <stdexcept>
#endif #endif
#include <ctype.h> #include <ctype.h>
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>
#include <limits> #include <limits>
@ -76,7 +79,7 @@
// the current line number. For more details, see // the current line number. For more details, see
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 // 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_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
// Stringifies its argument. // Stringifies its argument.
// Work around a bug in visual studio which doesn't accept code like this: // Work around a bug in visual studio which doesn't accept code like this:
@ -121,6 +124,7 @@ GTEST_API_ extern const char kStackTraceMarker[];
// An IgnoredValue object can be implicitly constructed from ANY value. // An IgnoredValue object can be implicitly constructed from ANY value.
class IgnoredValue { class IgnoredValue {
struct Sink {}; struct Sink {};
public: public:
// This constructor template allows any value to be implicitly // This constructor template allows any value to be implicitly
// converted to IgnoredValue. The object has no data member and // converted to IgnoredValue. The object has no data member and
@ -136,13 +140,13 @@ class IgnoredValue {
}; };
// Appends the user-supplied message to the Google-Test-generated message. // Appends the user-supplied message to the Google-Test-generated message.
GTEST_API_ std::string AppendUserMessage( GTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg,
const std::string& gtest_msg, const Message& user_msg); const Message& user_msg);
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4275 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
/* an exported class was derived from a class that was not exported */) 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 // This exception is thrown by (and only by) a failed Google Test
// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions
@ -181,14 +185,6 @@ GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,
} // namespace edit_distance } // namespace edit_distance
// Calculate the diff between 'left' and 'right' and return it in unified diff
// format.
// If not null, stores in 'total_line_count' the total number of lines found
// in left + right.
GTEST_API_ std::string DiffStrings(const std::string& left,
const std::string& right,
size_t* total_line_count);
// Constructs and returns the message for an equality assertion // Constructs and returns the message for an equality assertion
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
// //
@ -212,10 +208,8 @@ GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. // Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
GTEST_API_ std::string GetBoolAssertionFailureMessage( GTEST_API_ std::string GetBoolAssertionFailureMessage(
const AssertionResult& assertion_result, const AssertionResult& assertion_result, const char* expression_text,
const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value);
const char* actual_predicate_value,
const char* expected_predicate_value);
// This template class represents an IEEE floating-point number // This template class represents an IEEE floating-point number
// (either single-precision or double-precision, depending on the // (either single-precision or double-precision, depending on the
@ -256,7 +250,7 @@ class FloatingPoint {
// Constants. // Constants.
// # of bits in a number. // # of bits in a number.
static const size_t kBitCount = 8*sizeof(RawType); static const size_t kBitCount = 8 * sizeof(RawType);
// # of fraction bits in a number. // # of fraction bits in a number.
static const size_t kFractionBitCount = static const size_t kFractionBitCount =
@ -269,8 +263,8 @@ class FloatingPoint {
static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1); static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
// The mask for the fraction bits. // The mask for the fraction bits.
static const Bits kFractionBitMask = static const Bits kFractionBitMask = ~static_cast<Bits>(0) >>
~static_cast<Bits>(0) >> (kExponentBitCount + 1); (kExponentBitCount + 1);
// The mask for the exponent bits. // The mask for the exponent bits.
static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
@ -309,9 +303,7 @@ class FloatingPoint {
} }
// Returns the floating-point number that represent positive infinity. // Returns the floating-point number that represent positive infinity.
static RawType Infinity() { static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }
return ReinterpretBits(kExponentBitMask);
}
// Returns the maximum representable finite floating-point number. // Returns the maximum representable finite floating-point number.
static RawType Max(); static RawType Max();
@ -319,7 +311,7 @@ class FloatingPoint {
// Non-static methods // Non-static methods
// Returns the bits that represents this number. // Returns the bits that represents this number.
const Bits &bits() const { return u_.bits_; } const Bits& bits() const { return u_.bits_; }
// Returns the exponent bits of this number. // Returns the exponent bits of this number.
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
@ -348,8 +340,8 @@ class FloatingPoint {
// a NAN must return false. // a NAN must return false.
if (is_nan() || rhs.is_nan()) return false; if (is_nan() || rhs.is_nan()) return false;
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
<= kMaxUlps; kMaxUlps;
} }
private: private:
@ -374,7 +366,7 @@ class FloatingPoint {
// //
// Read http://en.wikipedia.org/wiki/Signed_number_representations // Read http://en.wikipedia.org/wiki/Signed_number_representations
// for more details on signed number representations. // for more details on signed number representations.
static Bits SignAndMagnitudeToBiased(const Bits &sam) { static Bits SignAndMagnitudeToBiased(const Bits& sam) {
if (kSignBitMask & sam) { if (kSignBitMask & sam) {
// sam represents a negative number. // sam represents a negative number.
return ~sam + 1; return ~sam + 1;
@ -386,8 +378,8 @@ class FloatingPoint {
// Given two numbers in the sign-and-magnitude representation, // Given two numbers in the sign-and-magnitude representation,
// returns the distance between them as an unsigned number. // returns the distance between them as an unsigned number.
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
const Bits &sam2) { const Bits& sam2) {
const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased1 = SignAndMagnitudeToBiased(sam1);
const Bits biased2 = SignAndMagnitudeToBiased(sam2); const Bits biased2 = SignAndMagnitudeToBiased(sam2);
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
@ -399,9 +391,13 @@ class FloatingPoint {
// We cannot use std::numeric_limits<T>::max() as it clashes with the max() // We cannot use std::numeric_limits<T>::max() as it clashes with the max()
// macro defined by <windows.h>. // macro defined by <windows.h>.
template <> template <>
inline float FloatingPoint<float>::Max() { return FLT_MAX; } inline float FloatingPoint<float>::Max() {
return FLT_MAX;
}
template <> template <>
inline double FloatingPoint<double>::Max() { return DBL_MAX; } inline double FloatingPoint<double>::Max() {
return DBL_MAX;
}
// Typedefs the instances of the FloatingPoint template class that we // Typedefs the instances of the FloatingPoint template class that we
// care to use. // care to use.
@ -461,7 +457,8 @@ class TestFactoryBase {
TestFactoryBase() {} TestFactoryBase() {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); TestFactoryBase(const TestFactoryBase&) = delete;
TestFactoryBase& operator=(const TestFactoryBase&) = delete;
}; };
// This class provides implementation of TeastFactoryBase interface. // This class provides implementation of TeastFactoryBase interface.
@ -510,11 +507,11 @@ inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
template <typename T> template <typename T>
// Note that SuiteApiResolver inherits from T because // Note that SuiteApiResolver inherits from T because
// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way // SetUpTestSuite()/TearDownTestSuite() could be protected. This way
// SuiteApiResolver can access them. // SuiteApiResolver can access them.
struct SuiteApiResolver : T { struct SuiteApiResolver : T {
// testing::Test is only forward declared at this point. So we make it a // testing::Test is only forward declared at this point. So we make it a
// dependend class for the compiler to be OK with it. // dependent class for the compiler to be OK with it.
using Test = using Test =
typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type; typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
@ -654,7 +651,8 @@ inline const char* SkipComma(const char* str) {
if (comma == nullptr) { if (comma == nullptr) {
return nullptr; return nullptr;
} }
while (IsSpace(*(++comma))) {} while (IsSpace(*(++comma))) {
}
return comma; return comma;
} }
@ -668,7 +666,7 @@ inline std::string GetPrefixUntilComma(const char* str) {
// Splits a given string on a given delimiter, populating a given // Splits a given string on a given delimiter, populating a given
// vector with the fields. // vector with the fields.
void SplitString(const ::std::string& str, char delimiter, void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest); ::std::vector<::std::string>* dest);
// The default argument to the template below for the case when the user does // The default argument to the template below for the case when the user does
// not provide a name generator. // not provide a name generator.
@ -781,13 +779,13 @@ class TypeParameterizedTestSuite {
const std::vector<std::string>& type_names = const std::vector<std::string>& type_names =
GenerateNames<DefaultNameGenerator, Types>()) { GenerateNames<DefaultNameGenerator, Types>()) {
RegisterTypeParameterizedTestSuiteInstantiation(case_name); RegisterTypeParameterizedTestSuiteInstantiation(case_name);
std::string test_name = StripTrailingSpaces( std::string test_name =
GetPrefixUntilComma(test_names)); StripTrailingSpaces(GetPrefixUntilComma(test_names));
if (!state->TestExists(test_name)) { if (!state->TestExists(test_name)) {
fprintf(stderr, "Failed to get code location for test %s.%s at %s.", fprintf(stderr, "Failed to get code location for test %s.%s at %s.",
case_name, test_name.c_str(), case_name, test_name.c_str(),
FormatFileLocation(code_location.file.c_str(), FormatFileLocation(code_location.file.c_str(), code_location.line)
code_location.line).c_str()); .c_str());
fflush(stderr); fflush(stderr);
posix::Abort(); posix::Abort();
} }
@ -831,8 +829,8 @@ class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
// For example, if Foo() calls Bar(), which in turn calls // For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
UnitTest* unit_test, int skip_count); int skip_count);
// Helpers for suppressing warnings on unreachable code or constant // Helpers for suppressing warnings on unreachable code or constant
// condition. // condition.
@ -881,7 +879,8 @@ class GTEST_API_ Random {
private: private:
uint32_t state_; uint32_t state_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); Random(const Random&) = delete;
Random& operator=(const Random&) = delete;
}; };
// Turns const U&, U&, const U, and U all into U. // Turns const U&, U&, const U, and U all into U.
@ -954,7 +953,9 @@ IsContainer IsContainerTest(int /* dummy */) {
typedef char IsNotContainer; typedef char IsNotContainer;
template <class C> template <class C>
IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } IsNotContainer IsContainerTest(long /* dummy */) {
return '\0';
}
// Trait to detect whether a type T is a hash table. // 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 // The heuristic used is that the type contains an inner type `hasher` and does
@ -1017,11 +1018,13 @@ bool ArrayEq(const T* lhs, size_t size, const U* rhs);
// This generic version is used when k is 0. // This generic version is used when k is 0.
template <typename T, typename U> template <typename T, typename U>
inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } inline bool ArrayEq(const T& lhs, const U& rhs) {
return lhs == rhs;
}
// This overload is used when k >= 1. // This overload is used when k >= 1.
template <typename T, typename U, size_t N> template <typename T, typename U, size_t N>
inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {
return internal::ArrayEq(lhs, N, rhs); return internal::ArrayEq(lhs, N, rhs);
} }
@ -1031,8 +1034,7 @@ inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) {
template <typename T, typename U> template <typename T, typename U>
bool ArrayEq(const T* lhs, size_t size, const U* rhs) { bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
for (size_t i = 0; i != size; i++) { for (size_t i = 0; i != size; i++) {
if (!internal::ArrayEq(lhs[i], rhs[i])) if (!internal::ArrayEq(lhs[i], rhs[i])) return false;
return false;
} }
return true; return true;
} }
@ -1042,8 +1044,7 @@ bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
template <typename Iter, typename Element> template <typename Iter, typename Element>
Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {
for (Iter it = begin; it != end; ++it) { for (Iter it = begin; it != end; ++it) {
if (internal::ArrayEq(*it, elem)) if (internal::ArrayEq(*it, elem)) return it;
return it;
} }
return end; return end;
} }
@ -1057,11 +1058,13 @@ void CopyArray(const T* from, size_t size, U* to);
// This generic version is used when k is 0. // This generic version is used when k is 0.
template <typename T, typename U> template <typename T, typename U>
inline void CopyArray(const T& from, U* to) { *to = from; } inline void CopyArray(const T& from, U* to) {
*to = from;
}
// This overload is used when k >= 1. // This overload is used when k >= 1.
template <typename T, typename U, size_t N> template <typename T, typename U, size_t N>
inline void CopyArray(const T(&from)[N], U(*to)[N]) { inline void CopyArray(const T (&from)[N], U (*to)[N]) {
internal::CopyArray(from, N, *to); internal::CopyArray(from, N, *to);
} }
@ -1114,8 +1117,7 @@ class NativeArray {
} }
~NativeArray() { ~NativeArray() {
if (clone_ != &NativeArray::InitRef) if (clone_ != &NativeArray::InitRef) delete[] array_;
delete[] array_;
} }
// STL-style container methods. // STL-style container methods.
@ -1123,8 +1125,7 @@ class NativeArray {
const_iterator begin() const { return array_; } const_iterator begin() const { return array_; }
const_iterator end() const { return array_ + size_; } const_iterator end() const { return array_ + size_; }
bool operator==(const NativeArray& rhs) const { bool operator==(const NativeArray& rhs) const {
return size() == rhs.size() && return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin());
ArrayEq(begin(), size(), rhs.begin());
} }
private: private:
@ -1336,8 +1337,8 @@ struct tuple_size<testing::internal::FlatTuple<Ts...>>
} // namespace std } // namespace std
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ #define GTEST_MESSAGE_AT_(file, line, message, result_type) \
::testing::internal::AssertHelper(result_type, file, line, message) \ ::testing::internal::AssertHelper(result_type, file, line, message) = \
= ::testing::Message() ::testing::Message()
#define GTEST_MESSAGE_(message, result_type) \ #define GTEST_MESSAGE_(message, result_type) \
GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
@ -1470,9 +1471,11 @@ class NeverThrown {
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__) \
fail(("Expected: " #statement " doesn't throw an exception.\n" \ : fail(("Expected: " #statement " doesn't throw an exception.\n" \
" Actual: " + gtest_msg.value).c_str()) " Actual: " + \
gtest_msg.value) \
.c_str())
#define GTEST_TEST_ANY_THROW_(statement, fail) \ #define GTEST_TEST_ANY_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
@ -1480,19 +1483,18 @@ class NeverThrown {
bool gtest_caught_any = false; \ bool gtest_caught_any = false; \
try { \ try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \ } catch (...) { \
catch (...) { \
gtest_caught_any = true; \ gtest_caught_any = true; \
} \ } \
if (!gtest_caught_any) { \ if (!gtest_caught_any) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) \
fail("Expected: " #statement " throws an exception.\n" \ : fail("Expected: " #statement \
" throws an exception.\n" \
" Actual: it doesn't.") " Actual: it doesn't.")
// Implements Boolean test assertions such as EXPECT_TRUE. expression can be // Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual // either a boolean expression or an AssertionResult. text is a textual
// representation of expression as it was passed into the EXPECT_TRUE. // representation of expression as it was passed into the EXPECT_TRUE.
@ -1502,8 +1504,9 @@ class NeverThrown {
::testing::AssertionResult(expression)) \ ::testing::AssertionResult(expression)) \
; \ ; \
else \ else \
fail(::testing::internal::GetBoolAssertionFailureMessage(\ fail(::testing::internal::GetBoolAssertionFailureMessage( \
gtest_ar_, text, #actual, #expected).c_str()) gtest_ar_, text, #actual, #expected) \
.c_str())
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
@ -1514,8 +1517,9 @@ class NeverThrown {
goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \
fail("Expected: " #statement " doesn't generate new fatal " \ : fail("Expected: " #statement \
" doesn't generate new fatal " \
"failures in the current thread.\n" \ "failures in the current thread.\n" \
" Actual: it does.") " Actual: it does.")
@ -1534,10 +1538,16 @@ class NeverThrown {
public: \ public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \ 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)() override = default; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
test_name)); \ (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
test_name)); \ 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: \ private: \
void TestBody() override; \ void TestBody() override; \

View File

@ -27,10 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Type and function utilities for implementing parameterized tests. // Type and function utilities for implementing parameterized tests.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
@ -46,19 +47,18 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h" #include "gtest/gtest-test-part.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
namespace testing { namespace testing {
// Input to a parameterized test name generator, describing a test parameter. // Input to a parameterized test name generator, describing a test parameter.
// Consists of the parameter value and the integer parameter index. // Consists of the parameter value and the integer parameter index.
template <class ParamType> template <class ParamType>
struct TestParamInfo { struct TestParamInfo {
TestParamInfo(const ParamType& a_param, size_t an_index) : TestParamInfo(const ParamType& a_param, size_t an_index)
param(a_param), : param(a_param), index(an_index) {}
index(an_index) {}
ParamType param; ParamType param;
size_t index; size_t index;
}; };
@ -84,8 +84,10 @@ namespace internal {
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name, GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location); CodeLocation code_location);
template <typename> class ParamGeneratorInterface; template <typename>
template <typename> class ParamGenerator; class ParamGeneratorInterface;
template <typename>
class ParamGenerator;
// Interface for iterating over elements provided by an implementation // Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>. // of ParamGeneratorInterface<T>.
@ -129,8 +131,7 @@ class ParamIterator {
// ParamIterator assumes ownership of the impl_ pointer. // ParamIterator assumes ownership of the impl_ pointer.
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
ParamIterator& operator=(const ParamIterator& other) { ParamIterator& operator=(const ParamIterator& other) {
if (this != &other) if (this != &other) impl_.reset(other.impl_->Clone());
impl_.reset(other.impl_->Clone());
return *this; return *this;
} }
@ -157,7 +158,7 @@ class ParamIterator {
private: private:
friend class ParamGenerator<T>; friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
std::unique_ptr<ParamIteratorInterface<T> > impl_; std::unique_ptr<ParamIteratorInterface<T>> impl_;
}; };
// ParamGeneratorInterface<T> is the binary interface to access generators // ParamGeneratorInterface<T> is the binary interface to access generators
@ -179,7 +180,7 @@ class ParamGeneratorInterface {
// This class implements copy initialization semantics and the contained // This class implements copy initialization semantics and the contained
// ParamGeneratorInterface<T> instance is shared among all copies // ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable. // of the original object. This is possible because that instance is immutable.
template<typename T> template <typename T>
class ParamGenerator { class ParamGenerator {
public: public:
typedef ParamIterator<T> iterator; typedef ParamIterator<T> iterator;
@ -196,7 +197,7 @@ class ParamGenerator {
iterator end() const { return iterator(impl_->End()); } iterator end() const { return iterator(impl_->End()); }
private: private:
std::shared_ptr<const ParamGeneratorInterface<T> > impl_; std::shared_ptr<const ParamGeneratorInterface<T>> impl_;
}; };
// Generates values from a range of two comparable values. Can be used to // Generates values from a range of two comparable values. Can be used to
@ -207,8 +208,10 @@ template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> { class RangeGenerator : public ParamGeneratorInterface<T> {
public: public:
RangeGenerator(T begin, T end, IncrementT step) RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end), : begin_(begin),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} end_(end),
step_(step),
end_index_(CalculateEndIndex(begin, end, step)) {}
~RangeGenerator() override {} ~RangeGenerator() override {}
ParamIteratorInterface<T>* Begin() const override { ParamIteratorInterface<T>* Begin() const override {
@ -251,7 +254,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
private: private:
Iterator(const Iterator& other) Iterator(const Iterator& other)
: ParamIteratorInterface<T>(), : ParamIteratorInterface<T>(),
base_(other.base_), value_(other.value_), index_(other.index_), base_(other.base_),
value_(other.value_),
index_(other.index_),
step_(other.step_) {} step_(other.step_) {}
// No implementation - assignment is unsupported. // No implementation - assignment is unsupported.
@ -263,12 +268,10 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
const IncrementT step_; const IncrementT step_;
}; // class RangeGenerator::Iterator }; // class RangeGenerator::Iterator
static int CalculateEndIndex(const T& begin, static int CalculateEndIndex(const T& begin, const T& end,
const T& end,
const IncrementT& step) { const IncrementT& step) {
int end_index = 0; int end_index = 0;
for (T i = begin; i < end; i = static_cast<T>(i + step)) for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;
end_index++;
return end_index; return end_index;
} }
@ -283,7 +286,6 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
const int end_index_; const int end_index_;
}; // class RangeGenerator }; // class RangeGenerator
// Generates values from a pair of STL-style iterators. Used in the // Generates values from a pair of STL-style iterators. Used in the
// ValuesIn() function. The elements are copied from the source range // ValuesIn() function. The elements are copied from the source range
// since the source can be located on the stack, and the generator // since the source can be located on the stack, and the generator
@ -394,8 +396,8 @@ template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase { class ParameterizedTestFactory : public TestFactoryBase {
public: public:
typedef typename TestClass::ParamType ParamType; typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) : explicit ParameterizedTestFactory(ParamType parameter)
parameter_(parameter) {} : parameter_(parameter) {}
Test* CreateTest() override { Test* CreateTest() override {
TestClass::SetParam(&parameter_); TestClass::SetParam(&parameter_);
return new TestClass(); return new TestClass();
@ -404,7 +406,8 @@ class ParameterizedTestFactory : public TestFactoryBase {
private: private:
const ParamType parameter_; const ParamType parameter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;
ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;
}; };
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@ -440,7 +443,8 @@ class TestMetaFactory
} }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); TestMetaFactory(const TestMetaFactory&) = delete;
TestMetaFactory& operator=(const TestMetaFactory&) = delete;
}; };
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@ -471,7 +475,10 @@ class ParameterizedTestSuiteInfoBase {
ParameterizedTestSuiteInfoBase() {} ParameterizedTestSuiteInfoBase() {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase); ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =
delete;
ParameterizedTestSuiteInfoBase& operator=(
const ParameterizedTestSuiteInfoBase&) = delete;
}; };
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@ -547,8 +554,8 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
test_it != tests_.end(); ++test_it) { test_it != tests_.end(); ++test_it) {
std::shared_ptr<TestInfo> test_info = *test_it; std::shared_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it = for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end(); instantiations_.begin();
++gen_it) { gen_it != instantiations_.end(); ++gen_it) {
const std::string& instantiation_name = gen_it->name; const std::string& instantiation_name = gen_it->name;
ParamGenerator<ParamType> generator((*gen_it->generator)()); ParamGenerator<ParamType> generator((*gen_it->generator)());
ParamNameGeneratorFunc* name_func = gen_it->name_func; ParamNameGeneratorFunc* name_func = gen_it->name_func;
@ -556,7 +563,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
int line = gen_it->line; int line = gen_it->line;
std::string test_suite_name; std::string test_suite_name;
if ( !instantiation_name.empty() ) if (!instantiation_name.empty())
test_suite_name = instantiation_name + "/"; test_suite_name = instantiation_name + "/";
test_suite_name += test_info->test_suite_base_name; test_suite_name += test_info->test_suite_base_name;
@ -569,17 +576,16 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
Message test_name_stream; Message test_name_stream;
std::string param_name = name_func( std::string param_name =
TestParamInfo<ParamType>(*param_it, i)); name_func(TestParamInfo<ParamType>(*param_it, i));
GTEST_CHECK_(IsValidParamName(param_name)) GTEST_CHECK_(IsValidParamName(param_name))
<< "Parameterized test name '" << param_name << "Parameterized test name '" << param_name
<< "' is invalid, in " << file << "' is invalid, in " << file << " line " << line << std::endl;
<< " line " << line << std::endl;
GTEST_CHECK_(test_param_names.count(param_name) == 0) GTEST_CHECK_(test_param_names.count(param_name) == 0)
<< "Duplicate parameterized test name '" << param_name << "Duplicate parameterized test name '" << param_name << "', in "
<< "', in " << file << " line " << line << std::endl; << file << " line " << line << std::endl;
test_param_names.insert(param_name); test_param_names.insert(param_name);
@ -620,18 +626,17 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
const std::string test_suite_base_name; const std::string test_suite_base_name;
const std::string test_base_name; const std::string test_base_name;
const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
const CodeLocation code_location; const CodeLocation code_location;
}; };
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >; using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;
// Records data received from INSTANTIATE_TEST_SUITE_P macros: // Records data received from INSTANTIATE_TEST_SUITE_P macros:
// <Instantiation name, Sequence generator creation function, // <Instantiation name, Sequence generator creation function,
// Name generator function, Source file, Source line> // Name generator function, Source file, Source line>
struct InstantiationInfo { struct InstantiationInfo {
InstantiationInfo(const std::string &name_in, InstantiationInfo(const std::string& name_in,
GeneratorCreationFunc* generator_in, GeneratorCreationFunc* generator_in,
ParamNameGeneratorFunc* name_func_in, ParamNameGeneratorFunc* name_func_in, const char* file_in,
const char* file_in,
int line_in) int line_in)
: name(name_in), : name(name_in),
generator(generator_in), generator(generator_in),
@ -649,13 +654,11 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
static bool IsValidParamName(const std::string& name) { static bool IsValidParamName(const std::string& name) {
// Check for empty string // Check for empty string
if (name.empty()) if (name.empty()) return false;
return false;
// Check for invalid characters // Check for invalid characters
for (std::string::size_type index = 0; index < name.size(); ++index) { for (std::string::size_type index = 0; index < name.size(); ++index) {
if (!IsAlNum(name[index]) && name[index] != '_') if (!IsAlNum(name[index]) && name[index] != '_') return false;
return false;
} }
return true; return true;
@ -666,7 +669,9 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
TestInfoContainer tests_; TestInfoContainer tests_;
InstantiationContainer instantiations_; InstantiationContainer instantiations_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo); ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;
ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =
delete;
}; // class ParameterizedTestSuiteInfo }; // class ParameterizedTestSuiteInfo
// Legacy API is deprecated but still available // Legacy API is deprecated but still available
@ -709,7 +714,7 @@ class ParameterizedTestSuiteRegistry {
// type we are looking for, so we downcast it to that type // type we are looking for, so we downcast it to that type
// without further checks. // without further checks.
typed_test_info = CheckedDowncastToActualType< typed_test_info = CheckedDowncastToActualType<
ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info); ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
} }
break; break;
} }
@ -741,7 +746,10 @@ class ParameterizedTestSuiteRegistry {
TestSuiteInfoContainer test_suite_infos_; TestSuiteInfoContainer test_suite_infos_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry); ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
delete;
ParameterizedTestSuiteRegistry& operator=(
const ParameterizedTestSuiteRegistry&) = delete;
}; };
// Keep track of what type-parameterized test suite are defined and // Keep track of what type-parameterized test suite are defined and
@ -836,7 +844,8 @@ class CartesianProductGenerator
: public ParamIteratorInterface<ParamType> { : public ParamIteratorInterface<ParamType> {
public: public:
IteratorImpl(const ParamGeneratorInterface<ParamType>* base, IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
const std::tuple<ParamGenerator<T>...>& generators, bool is_end) const std::tuple<ParamGenerator<T>...>& generators,
bool is_end)
: base_(base), : base_(base),
begin_(std::get<I>(generators).begin()...), begin_(std::get<I>(generators).begin()...),
end_(std::get<I>(generators).end()...), end_(std::get<I>(generators).end()...),

View File

@ -26,7 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file defines the GTEST_OS_* macro. // This header file defines the GTEST_OS_* macro.
@ -37,70 +37,72 @@
// Determines the platform on which Google Test is compiled. // Determines the platform on which Google Test is compiled.
#ifdef __CYGWIN__ #ifdef __CYGWIN__
# define GTEST_OS_CYGWIN 1 #define GTEST_OS_CYGWIN 1
# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) #elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
# define GTEST_OS_WINDOWS_MINGW 1 #define GTEST_OS_WINDOWS_MINGW 1
# define GTEST_OS_WINDOWS 1 #define GTEST_OS_WINDOWS 1
#elif defined _WIN32 #elif defined _WIN32
# define GTEST_OS_WINDOWS 1 #define GTEST_OS_WINDOWS 1
# ifdef _WIN32_WCE #ifdef _WIN32_WCE
# define GTEST_OS_WINDOWS_MOBILE 1 #define GTEST_OS_WINDOWS_MOBILE 1
# elif defined(WINAPI_FAMILY) #elif defined(WINAPI_FAMILY)
# include <winapifamily.h> #include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define GTEST_OS_WINDOWS_DESKTOP 1 #define GTEST_OS_WINDOWS_DESKTOP 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
# define GTEST_OS_WINDOWS_PHONE 1 #define GTEST_OS_WINDOWS_PHONE 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
# define GTEST_OS_WINDOWS_RT 1 #define GTEST_OS_WINDOWS_RT 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
# define GTEST_OS_WINDOWS_PHONE 1 #define GTEST_OS_WINDOWS_PHONE 1
# define GTEST_OS_WINDOWS_TV_TITLE 1 #define GTEST_OS_WINDOWS_TV_TITLE 1
# else #else
// WINAPI_FAMILY defined but no known partition matched. // WINAPI_FAMILY defined but no known partition matched.
// Default to desktop. // Default to desktop.
# define GTEST_OS_WINDOWS_DESKTOP 1 #define GTEST_OS_WINDOWS_DESKTOP 1
# endif #endif
# else #else
# define GTEST_OS_WINDOWS_DESKTOP 1 #define GTEST_OS_WINDOWS_DESKTOP 1
# endif // _WIN32_WCE #endif // _WIN32_WCE
#elif defined __OS2__ #elif defined __OS2__
# define GTEST_OS_OS2 1 #define GTEST_OS_OS2 1
#elif defined __APPLE__ #elif defined __APPLE__
# define GTEST_OS_MAC 1 #define GTEST_OS_MAC 1
# include <TargetConditionals.h> #include <TargetConditionals.h>
# if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1 #define GTEST_OS_IOS 1
# endif #endif
#elif defined __DragonFly__ #elif defined __DragonFly__
# define GTEST_OS_DRAGONFLY 1 #define GTEST_OS_DRAGONFLY 1
#elif defined __FreeBSD__ #elif defined __FreeBSD__
# define GTEST_OS_FREEBSD 1 #define GTEST_OS_FREEBSD 1
#elif defined __Fuchsia__ #elif defined __Fuchsia__
# define GTEST_OS_FUCHSIA 1 #define GTEST_OS_FUCHSIA 1
#elif defined(__GNU__)
#define GTEST_OS_GNU_HURD 1
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) #elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
# define GTEST_OS_GNU_KFREEBSD 1 #define GTEST_OS_GNU_KFREEBSD 1
#elif defined __linux__ #elif defined __linux__
# define GTEST_OS_LINUX 1 #define GTEST_OS_LINUX 1
# if defined __ANDROID__ #if defined __ANDROID__
# define GTEST_OS_LINUX_ANDROID 1 #define GTEST_OS_LINUX_ANDROID 1
# endif #endif
#elif defined __MVS__ #elif defined __MVS__
# define GTEST_OS_ZOS 1 #define GTEST_OS_ZOS 1
#elif defined(__sun) && defined(__SVR4) #elif defined(__sun) && defined(__SVR4)
# define GTEST_OS_SOLARIS 1 #define GTEST_OS_SOLARIS 1
#elif defined(_AIX) #elif defined(_AIX)
# define GTEST_OS_AIX 1 #define GTEST_OS_AIX 1
#elif defined(__hpux) #elif defined(__hpux)
# define GTEST_OS_HPUX 1 #define GTEST_OS_HPUX 1
#elif defined __native_client__ #elif defined __native_client__
# define GTEST_OS_NACL 1 #define GTEST_OS_NACL 1
#elif defined __NetBSD__ #elif defined __NetBSD__
# define GTEST_OS_NETBSD 1 #define GTEST_OS_NETBSD 1
#elif defined __OpenBSD__ #elif defined __OpenBSD__
# define GTEST_OS_OPENBSD 1 #define GTEST_OS_OPENBSD 1
#elif defined __QNX__ #elif defined __QNX__
# define GTEST_OS_QNX 1 #define GTEST_OS_QNX 1
#elif defined(__HAIKU__) #elif defined(__HAIKU__)
#define GTEST_OS_HAIKU 1 #define GTEST_OS_HAIKU 1
#elif defined ESP8266 #elif defined ESP8266

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test) // The Google C++ Testing and Mocking Framework (Google Test)
// //
// This header file declares the String class and functions used internally by // This header file declares the String class and functions used internally by
@ -36,17 +36,20 @@
// This header file is #included by gtest-internal.h. // This header file is #included by gtest-internal.h.
// It should not be #included by other files. // It should not be #included by other files.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder. // string.h is not guaranteed to provide strcpy on C++ Builder.
# include <mem.h> #include <mem.h>
#endif #endif
#include <string.h> #include <string.h>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
@ -123,8 +126,7 @@ class GTEST_API_ String {
// Unlike strcasecmp(), this function can handle NULL argument(s). // Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string, // A NULL C string is considered different to any non-NULL C string,
// including the empty string. // including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs, static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs);
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true if and only if // Compares two wide C strings, ignoring case. Returns true if and only if
// they have the same content. // they have the same content.
@ -143,8 +145,8 @@ class GTEST_API_ String {
// Returns true if and only if the given string ends with the given suffix, // Returns true if and only if the given string ends with the given suffix,
// ignoring case. Any string is considered to end with an empty suffix. // ignoring case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive( static bool EndsWithCaseInsensitive(const std::string& str,
const std::string& str, const std::string& suffix); const std::string& suffix);
// Formats an int value as "%02d". // Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2 static std::string FormatIntWidth2(int value); // "%02d" for width == 2

View File

@ -30,7 +30,9 @@
// Type utilities needed for implementing typed and type-parameterized // Type utilities needed for implementing typed and type-parameterized
// tests. // tests.
// GOOGLETEST_CM0001 DO NOT DELETE // IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
@ -39,11 +41,11 @@
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using // #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from). // libstdc++ (which is where cxxabi.h comes from).
# if GTEST_HAS_CXXABI_H_ #if GTEST_HAS_CXXABI_H_
# include <cxxabi.h> #include <cxxabi.h>
# elif defined(__HP_aCC) #elif defined(__HP_aCC)
# include <acxx_demangle.h> #include <acxx_demangle.h>
# endif // GTEST_HASH_CXXABI_H_ #endif // GTEST_HASH_CXXABI_H_
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -101,7 +103,9 @@ std::string GetTypeName() {
// A unique type indicating an empty node // A unique type indicating an empty node
struct None {}; struct None {};
# define GTEST_TEMPLATE_ template <typename T> class #define GTEST_TEMPLATE_ \
template <typename T> \
class
// The template "selector" struct TemplateSel<Tmpl> is used to // The template "selector" struct TemplateSel<Tmpl> is used to
// represent Tmpl, which must be a class template with one type // represent Tmpl, which must be a class template with one type
@ -119,8 +123,7 @@ struct TemplateSel {
}; };
}; };
# define GTEST_BIND_(TmplSel, T) \ #define GTEST_BIND_(TmplSel, T) TmplSel::template Bind<T>::type
TmplSel::template Bind<T>::type
template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_> template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
struct Templates { struct Templates {

View File

@ -27,8 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This provides interface PrimeTable that determines whether a number is a // This provides interface PrimeTable that determines whether a number is a
// prime and determines a next prime number. This interface is used // prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests. // in Google Test samples demonstrating use of parameterized tests.
@ -57,7 +55,7 @@ class OnTheFlyPrimeTable : public PrimeTable {
bool IsPrime(int n) const override { bool IsPrime(int n) const override {
if (n <= 1) return false; if (n <= 1) return false;
for (int i = 2; i*i <= n; i++) { for (int i = 2; i * i <= n; i++) {
// n is divisible by an integer other than 1 and itself. // n is divisible by an integer other than 1 and itself.
if ((n % i) == 0) return false; if ((n % i) == 0) return false;
} }
@ -104,13 +102,13 @@ class PreCalculatedPrimeTable : public PrimeTable {
// Checks every candidate for prime number (we know that 2 is the only even // Checks every candidate for prime number (we know that 2 is the only even
// prime). // prime).
for (int i = 2; i*i <= max; i += i%2+1) { for (int i = 2; i * i <= max; i += i % 2 + 1) {
if (!is_prime_[i]) continue; if (!is_prime_[i]) continue;
// Marks all multiples of i (except i itself) as non-prime. // Marks all multiples of i (except i itself) as non-prime.
// We are starting here from i-th multiplier, because all smaller // We are starting here from i-th multiplier, because all smaller
// complex numbers were already marked. // complex numbers were already marked.
for (int j = i*i; j <= max; j += i) { for (int j = i * i; j <= max; j += i) {
is_prime_[j] = false; is_prime_[j] = false;
} }
} }

View File

@ -52,9 +52,9 @@ bool IsPrime(int n) {
// Now, we have that n is odd and n >= 3. // Now, we have that n is odd and n >= 3.
// Try to divide n by every odd number i, starting from 3 // Try to divide n by every odd number i, starting from 3
for (int i = 3; ; i += 2) { for (int i = 3;; i += 2) {
// We only have to try i up to the square root of n // We only have to try i up to the square root of n
if (i > n/i) break; if (i > n / i) break;
// Now, we have i <= n/i < n. // Now, we have i <= n/i < n.
// If n is divisible by i, n is not prime. // If n is divisible by i, n is not prime.

View File

@ -26,7 +26,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This sample shows how to use Google Test listener API to implement // This sample shows how to use Google Test listener API to implement
// a primitive leak checker. // a primitive leak checker.
@ -104,14 +103,15 @@ TEST(ListenersTest, LeaksWater) {
} }
} // namespace } // namespace
int main(int argc, char **argv) { int main(int argc, char** argv) {
InitGoogleTest(&argc, argv); InitGoogleTest(&argc, argv);
bool check_for_leaks = false; bool check_for_leaks = false;
if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 ) if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0)
check_for_leaks = true; check_for_leaks = true;
else else
printf("%s\n", "Run this program with --check_for_leaks to enable " printf("%s\n",
"Run this program with --check_for_leaks to enable "
"custom leak checking in the tests."); "custom leak checking in the tests.");
// If we are given the --check_for_leaks command line flag, installs the // If we are given the --check_for_leaks command line flag, installs the

View File

@ -34,14 +34,15 @@
// //
// Writing a unit test using Google C++ testing framework is easy as 1-2-3: // 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 // Step 1. Include necessary header files such that the stuff your
// test logic needs is declared. // test logic needs is declared.
// //
// Don't forget gtest.h, which declares the testing framework. // Don't forget gtest.h, which declares the testing framework.
#include <limits.h>
#include "sample1.h" #include "sample1.h"
#include <limits.h>
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace { namespace {
@ -69,7 +70,6 @@ namespace {
// //
// </TechnicalDetails> // </TechnicalDetails>
// Tests Factorial(). // Tests Factorial().
// Tests factorial of negative numbers. // Tests factorial of negative numbers.
@ -97,9 +97,7 @@ TEST(FactorialTest, Negative) {
} }
// Tests factorial of 0. // Tests factorial of 0.
TEST(FactorialTest, Zero) { TEST(FactorialTest, Zero) { EXPECT_EQ(1, Factorial(0)); }
EXPECT_EQ(1, Factorial(0));
}
// Tests factorial of positive numbers. // Tests factorial of positive numbers.
TEST(FactorialTest, Positive) { TEST(FactorialTest, Positive) {
@ -109,7 +107,6 @@ TEST(FactorialTest, Positive) {
EXPECT_EQ(40320, Factorial(8)); EXPECT_EQ(40320, Factorial(8));
} }
// Tests IsPrime() // Tests IsPrime()
// Tests negative input. // Tests negative input.

View File

@ -38,7 +38,7 @@ const char* MyString::CloneCString(const char* a_c_string) {
if (a_c_string == nullptr) return nullptr; if (a_c_string == nullptr) return nullptr;
const size_t len = strlen(a_c_string); const size_t len = strlen(a_c_string);
char* const clone = new char[ len + 1 ]; char* const clone = new char[len + 1];
memcpy(clone, a_c_string, len + 1); memcpy(clone, a_c_string, len + 1);
return clone; return clone;

View File

@ -34,7 +34,6 @@
#include <string.h> #include <string.h>
// A simple string class. // A simple string class.
class MyString { class MyString {
private: private:

View File

@ -38,6 +38,7 @@
// needed. // needed.
#include "sample2.h" #include "sample2.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace { namespace {
// In this example, we test the MyString class (a simple string). // In this example, we test the MyString class (a simple string).
@ -77,8 +78,7 @@ const char kHelloString[] = "Hello, world!";
TEST(MyString, ConstructorFromCString) { TEST(MyString, ConstructorFromCString) {
const MyString s(kHelloString); const MyString s(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1, EXPECT_EQ(sizeof(kHelloString) / sizeof(kHelloString[0]) - 1, s.Length());
s.Length());
} }
// Tests the copy c'tor. // Tests the copy c'tor.

View File

@ -34,7 +34,6 @@
#include <stddef.h> #include <stddef.h>
// Queue is a simple queue implemented as a singled-linked list. // Queue is a simple queue implemented as a singled-linked list.
// //
// The element type must support copy constructor. // The element type must support copy constructor.
@ -62,7 +61,7 @@ class QueueNode {
: element_(an_element), next_(nullptr) {} : element_(an_element), next_(nullptr) {}
// We disable the default assignment operator and copy c'tor. // We disable the default assignment operator and copy c'tor.
const QueueNode& operator = (const QueueNode&); const QueueNode& operator=(const QueueNode&);
QueueNode(const QueueNode&); QueueNode(const QueueNode&);
E element_; E element_;
@ -84,7 +83,7 @@ class Queue {
// 1. Deletes every node. // 1. Deletes every node.
QueueNode<E>* node = head_; QueueNode<E>* node = head_;
QueueNode<E>* next = node->next(); QueueNode<E>* next = node->next();
for (; ;) { for (;;) {
delete node; delete node;
node = next; node = next;
if (node == nullptr) break; if (node == nullptr) break;
@ -166,7 +165,7 @@ class Queue {
// We disallow copying a queue. // We disallow copying a queue.
Queue(const Queue&); Queue(const Queue&);
const Queue& operator = (const Queue&); const Queue& operator=(const Queue&);
}; };
#endif // GOOGLETEST_SAMPLES_SAMPLE3_INL_H_ #endif // GOOGLETEST_SAMPLES_SAMPLE3_INL_H_

View File

@ -67,7 +67,6 @@ namespace {
class QueueTestSmpl3 : public testing::Test { class QueueTestSmpl3 : public testing::Test {
protected: // You should make the members protected s.t. they can be protected: // You should make the members protected s.t. they can be
// accessed from sub-classes. // accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You // virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the variables. // should define it if you need to initialize the variables.
// Otherwise, this can be skipped. // Otherwise, this can be skipped.
@ -85,15 +84,13 @@ class QueueTestSmpl3 : public testing::Test {
// } // }
// A helper function that some test uses. // A helper function that some test uses.
static int Double(int n) { static int Double(int n) { return 2 * n; }
return 2*n;
}
// A helper function for testing Queue::Map(). // A helper function for testing Queue::Map().
void MapTester(const Queue<int> * q) { void MapTester(const Queue<int>* q) {
// Creates a new queue, where each element is twice as big as the // Creates a new queue, where each element is twice as big as the
// corresponding one in q. // corresponding one in q.
const Queue<int> * const new_q = q->Map(Double); const Queue<int>* const new_q = q->Map(Double);
// Verifies that the new queue has the same size as q. // Verifies that the new queue has the same size as q.
ASSERT_EQ(q->Size(), new_q->Size()); ASSERT_EQ(q->Size(), new_q->Size());
@ -124,7 +121,7 @@ TEST_F(QueueTestSmpl3, DefaultConstructor) {
// Tests Dequeue(). // Tests Dequeue().
TEST_F(QueueTestSmpl3, Dequeue) { TEST_F(QueueTestSmpl3, Dequeue) {
int * n = q0_.Dequeue(); int* n = q0_.Dequeue();
EXPECT_TRUE(n == nullptr); EXPECT_TRUE(n == nullptr);
n = q1_.Dequeue(); n = q1_.Dequeue();

View File

@ -29,14 +29,12 @@
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
#include <stdio.h>
#include "sample4.h" #include "sample4.h"
#include <stdio.h>
// Returns the current counter value, and increments it. // Returns the current counter value, and increments it.
int Counter::Increment() { int Counter::Increment() { return counter_++; }
return counter_++;
}
// Returns the current counter value, and decrements it. // Returns the current counter value, and decrements it.
// counter can not be less than 0, return 0 in this case // counter can not be less than 0, return 0 in this case
@ -49,6 +47,4 @@ int Counter::Decrement() {
} }
// Prints the current counter value to STDOUT. // Prints the current counter value to STDOUT.
void Counter::Print() const { void Counter::Print() const { printf("%d", counter_); }
printf("%d", counter_);
}

View File

@ -27,8 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "sample4.h" #include "sample4.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace { namespace {

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This sample teaches how to reuse a test fixture in multiple test // This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it. // cases by deriving sub-fixtures from it.
// //
@ -45,9 +44,10 @@
#include <limits.h> #include <limits.h>
#include <time.h> #include <time.h>
#include "gtest/gtest.h"
#include "sample1.h" #include "sample1.h"
#include "sample3-inl.h" #include "sample3-inl.h"
#include "gtest/gtest.h"
namespace { namespace {
// In this sample, we want to ensure that every test finishes within // In this sample, we want to ensure that every test finishes within
// ~5 seconds. If a test takes longer to run, we consider it a // ~5 seconds. If a test takes longer to run, we consider it a
@ -81,7 +81,6 @@ class QuickTest : public testing::Test {
time_t start_time_; time_t start_time_;
}; };
// We derive a fixture named IntegerFunctionTest from the QuickTest // We derive a fixture named IntegerFunctionTest from the QuickTest
// fixture. All tests using this fixture will be automatically // fixture. All tests using this fixture will be automatically
// required to be quick. // required to be quick.
@ -90,7 +89,6 @@ class IntegerFunctionTest : public QuickTest {
// Therefore the body is empty. // Therefore the body is empty.
}; };
// Now we can write tests in the IntegerFunctionTest test case. // Now we can write tests in the IntegerFunctionTest test case.
// Tests Factorial() // Tests Factorial()
@ -110,7 +108,6 @@ TEST_F(IntegerFunctionTest, Factorial) {
EXPECT_EQ(40320, Factorial(8)); EXPECT_EQ(40320, Factorial(8));
} }
// Tests IsPrime() // Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) { TEST_F(IntegerFunctionTest, IsPrime) {
// Tests negative input. // Tests negative input.
@ -131,7 +128,6 @@ TEST_F(IntegerFunctionTest, IsPrime) {
EXPECT_TRUE(IsPrime(23)); EXPECT_TRUE(IsPrime(23));
} }
// The next test case (named "QueueTest") also needs to be quick, so // The next test case (named "QueueTest") also needs to be quick, so
// we derive another fixture from QuickTest. // we derive another fixture from QuickTest.
// //
@ -163,13 +159,10 @@ class QueueTest : public QuickTest {
Queue<int> q2_; Queue<int> q2_;
}; };
// Now, let's write tests using the QueueTest fixture. // Now, let's write tests using the QueueTest fixture.
// Tests the default constructor. // Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) { TEST_F(QueueTest, DefaultConstructor) { EXPECT_EQ(0u, q0_.Size()); }
EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue(). // Tests Dequeue().
TEST_F(QueueTest, Dequeue) { TEST_F(QueueTest, Dequeue) {

View File

@ -27,13 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This sample shows how to test common properties of multiple // This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests). // implementations of the same interface (aka interface tests).
// The interface and its implementations are in this header. // The interface and its implementations are in this header.
#include "prime_tables.h" #include "prime_tables.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace { namespace {
// First, we define some factory functions for creating instances of // First, we define some factory functions for creating instances of
@ -151,8 +149,7 @@ using testing::Types;
// the PrimeTableTest fixture defined earlier: // the PrimeTableTest fixture defined earlier:
template <class T> template <class T>
class PrimeTableTest2 : public PrimeTableTest<T> { class PrimeTableTest2 : public PrimeTableTest<T> {};
};
// Then, declare the test case. The argument is the name of the test // Then, declare the test case. The argument is the name of the test
// fixture, and also the name of the test case (as usual). The _P // fixture, and also the name of the test case (as usual). The _P

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This sample shows how to test common properties of multiple // This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using // implementations of an interface (aka interface tests) using
// value-parameterized tests. Each test in the test case has // value-parameterized tests. Each test in the test case has
@ -36,7 +35,6 @@
// The interface and its implementations are in this header. // The interface and its implementations are in this header.
#include "prime_tables.h" #include "prime_tables.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace { namespace {
@ -50,9 +48,7 @@ using ::testing::Values;
// SetUp() method and delete them in TearDown() method. // SetUp() method and delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc(); typedef PrimeTable* CreatePrimeTableFunc();
PrimeTable* CreateOnTheFlyPrimeTable() { PrimeTable* CreateOnTheFlyPrimeTable() { return new OnTheFlyPrimeTable(); }
return new OnTheFlyPrimeTable();
}
template <size_t max_precalculated> template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() { PrimeTable* CreatePreCalculatedPrimeTable() {

View File

@ -27,14 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This sample shows how to test code relying on some global flag variables. // This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags, // Combine() helps with generating all possible combinations of such flags,
// and each test is given one combination as a parameter. // and each test is given one combination as a parameter.
// Use class definitions to test from this header. // Use class definitions to test from this header.
#include "prime_tables.h" #include "prime_tables.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace { namespace {
@ -79,10 +77,10 @@ class HybridPrimeTable : public PrimeTable {
int max_precalculated_; int max_precalculated_;
}; };
using ::testing::TestWithParam;
using ::testing::Bool; using ::testing::Bool;
using ::testing::Values;
using ::testing::Combine; using ::testing::Combine;
using ::testing::TestWithParam;
using ::testing::Values;
// To test all code paths for HybridPrimeTable we must test it with numbers // To test all code paths for HybridPrimeTable we must test it with numbers
// both within and outside PreCalculatedPrimeTable's capacity and also with // both within and outside PreCalculatedPrimeTable's capacity and also with

View File

@ -26,10 +26,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This sample shows how to use Google Test listener API to implement // This sample shows how to use Google Test listener API to implement
// an alternative console output and how to use the UnitTest reflection API // an alternative console output and how to use the UnitTest reflection API
// to enumerate test cases and tests and to inspect their results. // to enumerate test suites and tests and to inspect their results.
#include <stdio.h> #include <stdio.h>
@ -38,10 +37,10 @@
using ::testing::EmptyTestEventListener; using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest; using ::testing::InitGoogleTest;
using ::testing::Test; using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners; using ::testing::TestEventListeners;
using ::testing::TestInfo; using ::testing::TestInfo;
using ::testing::TestPartResult; using ::testing::TestPartResult;
using ::testing::TestSuite;
using ::testing::UnitTest; using ::testing::UnitTest;
namespace { namespace {
// Provides alternative output mode which produces minimal amount of // Provides alternative output mode which produces minimal amount of
@ -59,29 +58,23 @@ class TersePrinter : public EmptyTestEventListener {
// Called before a test starts. // Called before a test starts.
void OnTestStart(const TestInfo& test_info) override { void OnTestStart(const TestInfo& test_info) override {
fprintf(stdout, fprintf(stdout, "*** Test %s.%s starting.\n", test_info.test_suite_name(),
"*** Test %s.%s starting.\n",
test_info.test_case_name(),
test_info.name()); test_info.name());
fflush(stdout); fflush(stdout);
} }
// Called after a failed assertion or a SUCCEED() invocation. // Called after a failed assertion or a SUCCEED() invocation.
void OnTestPartResult(const TestPartResult& test_part_result) override { void OnTestPartResult(const TestPartResult& test_part_result) override {
fprintf(stdout, fprintf(stdout, "%s in %s:%d\n%s\n",
"%s in %s:%d\n%s\n",
test_part_result.failed() ? "*** Failure" : "Success", test_part_result.failed() ? "*** Failure" : "Success",
test_part_result.file_name(), test_part_result.file_name(), test_part_result.line_number(),
test_part_result.line_number(),
test_part_result.summary()); test_part_result.summary());
fflush(stdout); fflush(stdout);
} }
// Called after a test ends. // Called after a test ends.
void OnTestEnd(const TestInfo& test_info) override { void OnTestEnd(const TestInfo& test_info) override {
fprintf(stdout, fprintf(stdout, "*** Test %s.%s ending.\n", test_info.test_suite_name(),
"*** Test %s.%s ending.\n",
test_info.test_case_name(),
test_info.name()); test_info.name());
fflush(stdout); fflush(stdout);
} }
@ -101,14 +94,15 @@ TEST(CustomOutputTest, Fails) {
} }
} // namespace } // namespace
int main(int argc, char **argv) { int main(int argc, char** argv) {
InitGoogleTest(&argc, argv); InitGoogleTest(&argc, argv);
bool terse_output = false; bool terse_output = false;
if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 ) if (argc > 1 && strcmp(argv[1], "--terse_output") == 0)
terse_output = true; terse_output = true;
else else
printf("%s\n", "Run this program with --terse_output to change the way " printf("%s\n",
"Run this program with --terse_output to change the way "
"it prints its output."); "it prints its output.");
UnitTest& unit_test = *UnitTest::GetInstance(); UnitTest& unit_test = *UnitTest::GetInstance();
@ -149,8 +143,7 @@ int main(int argc, char **argv) {
} }
// Test that were meant to fail should not affect the test program outcome. // Test that were meant to fail should not affect the test program outcome.
if (unexpectedly_failed_tests == 0) if (unexpectedly_failed_tests == 0) ret_val = 0;
ret_val = 0;
return ret_val; return ret_val;
} }

View File

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

View File

@ -1,83 +0,0 @@
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Shared utilities for writing scripts for Google Test/Mock."""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
# Matches the line from 'svn info .' output that describes what SVN
# path the current local directory corresponds to. For example, in
# a googletest SVN workspace's trunk/test directory, the output will be:
#
# URL: https://googletest.googlecode.com/svn/trunk/test
_SVN_INFO_URL_RE = re.compile(r'^URL: https://(\w+)\.googlecode\.com/svn(.*)')
def GetCommandOutput(command):
"""Runs the shell command and returns its stdout as a list of lines."""
f = os.popen(command, 'r')
lines = [line.strip() for line in f.readlines()]
f.close()
return lines
def GetSvnInfo():
"""Returns the project name and the current SVN workspace's root path."""
for line in GetCommandOutput('svn info .'):
m = _SVN_INFO_URL_RE.match(line)
if m:
project = m.group(1) # googletest or googlemock
rel_path = m.group(2)
root = os.path.realpath(rel_path.count('/') * '../')
return project, root
return None, None
def GetSvnTrunk():
"""Returns the current SVN workspace's trunk root path."""
_, root = GetSvnInfo()
return root + '/trunk' if root else None
def IsInGTestSvn():
project, _ = GetSvnInfo()
return project == 'googletest'
def IsInGMockSvn():
project, _ = GetSvnInfo()
return project == 'googlemock'

View File

@ -1,253 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2009, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""fuse_gtest_files.py v0.2.0
Fuses Google Test source code into a .h file and a .cc file.
SYNOPSIS
fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR
Scans GTEST_ROOT_DIR for Google Test source code, and generates
two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc.
Then you can build your tests by adding OUTPUT_DIR to the include
search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These
two files contain everything you need to use Google Test. Hence
you can "install" Google Test by copying them to wherever you want.
GTEST_ROOT_DIR can be omitted and defaults to the parent
directory of the directory holding this script.
EXAMPLES
./fuse_gtest_files.py fused_gtest
./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest
This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Test headers. Please report any
problems to googletestframework@googlegroups.com. You can read
https://github.com/google/googletest/blob/master/googletest/docs/advanced.md for
more information.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
try:
from sets import Set as set # For Python 2.3 compatibility
except ImportError:
pass
import sys
# We assume that this file is in the scripts/ directory in the Google
# Test root directory.
DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
# Regex for matching '#include "gtest/..."'.
INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"')
# Regex for matching '#include "src/..."'.
INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"')
# Where to find the source seed files.
GTEST_H_SEED = 'include/gtest/gtest.h'
GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h'
GTEST_ALL_CC_SEED = 'src/gtest-all.cc'
# Where to put the generated files.
GTEST_H_OUTPUT = 'gtest/gtest.h'
GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc'
def VerifyFileExists(directory, relative_path):
"""Verifies that the given file exists; aborts on failure.
relative_path is the file path relative to the given directory.
"""
if not os.path.isfile(os.path.join(directory, relative_path)):
print('ERROR: Cannot find %s in directory %s.' % (relative_path,
directory))
print('Please either specify a valid project root directory '
'or omit it on the command line.')
sys.exit(1)
def ValidateGTestRootDir(gtest_root):
"""Makes sure gtest_root points to a valid gtest root directory.
The function aborts the program on failure.
"""
VerifyFileExists(gtest_root, GTEST_H_SEED)
VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
def VerifyOutputFile(output_dir, relative_path):
"""Verifies that the given output file path is valid.
relative_path is relative to the output_dir directory.
"""
# Makes sure the output file either doesn't exist or can be overwritten.
output_file = os.path.join(output_dir, relative_path)
if os.path.exists(output_file):
# TODO(wan@google.com): The following user-interaction doesn't
# work with automated processes. We should provide a way for the
# Makefile to force overwriting the files.
print('%s already exists in directory %s - overwrite it? (y/N) ' %
(relative_path, output_dir))
answer = sys.stdin.readline().strip()
if answer not in ['y', 'Y']:
print('ABORTED.')
sys.exit(1)
# Makes sure the directory holding the output file exists; creates
# it and all its ancestors if necessary.
parent_directory = os.path.dirname(output_file)
if not os.path.isdir(parent_directory):
os.makedirs(parent_directory)
def ValidateOutputDir(output_dir):
"""Makes sure output_dir points to a valid output directory.
The function aborts the program on failure.
"""
VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
def FuseGTestH(gtest_root, output_dir):
"""Scans folder gtest_root to generate gtest/gtest.h in output_dir."""
output_file = open(os.path.join(output_dir, GTEST_H_OUTPUT), 'w')
processed_files = set() # Holds all gtest headers we've processed.
def ProcessFile(gtest_header_path):
"""Processes the given gtest header file."""
# We don't process the same header twice.
if gtest_header_path in processed_files:
return
processed_files.add(gtest_header_path)
# Reads each line in the given gtest header.
for line in open(os.path.join(gtest_root, gtest_header_path), 'r'):
m = INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# It's '#include "gtest/..."' - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
ProcessFile(GTEST_H_SEED)
output_file.close()
def FuseGTestAllCcToFile(gtest_root, output_file):
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_file."""
processed_files = set()
def ProcessFile(gtest_source_file):
"""Processes the given gtest source file."""
# We don't process the same #included file twice.
if gtest_source_file in processed_files:
return
processed_files.add(gtest_source_file)
# Reads each line in the given gtest source file.
for line in open(os.path.join(gtest_root, gtest_source_file), 'r'):
m = INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
if 'include/' + m.group(1) == GTEST_SPI_H_SEED:
# It's '#include "gtest/gtest-spi.h"'. This file is not
# #included by "gtest/gtest.h", so we need to process it.
ProcessFile(GTEST_SPI_H_SEED)
else:
# It's '#include "gtest/foo.h"' where foo is not gtest-spi.
# We treat it as '#include "gtest/gtest.h"', as all other
# gtest headers are being fused into gtest.h and cannot be
# #included directly.
# There is no need to #include "gtest/gtest.h" more than once.
if not GTEST_H_SEED in processed_files:
processed_files.add(GTEST_H_SEED)
output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,))
else:
m = INCLUDE_SRC_FILE_REGEX.match(line)
if m:
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
else:
output_file.write(line)
ProcessFile(GTEST_ALL_CC_SEED)
def FuseGTestAllCc(gtest_root, output_dir):
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
output_file = open(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
FuseGTestAllCcToFile(gtest_root, output_file)
output_file.close()
def FuseGTest(gtest_root, output_dir):
"""Fuses gtest.h and gtest-all.cc."""
ValidateGTestRootDir(gtest_root)
ValidateOutputDir(output_dir)
FuseGTestH(gtest_root, output_dir)
FuseGTestAllCc(gtest_root, output_dir)
def main():
argc = len(sys.argv)
if argc == 2:
# fuse_gtest_files.py OUTPUT_DIR
FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
elif argc == 3:
# fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
FuseGTest(sys.argv[1], sys.argv[2])
else:
print(__doc__)
sys.exit(1)
if __name__ == '__main__':
main()

View File

@ -1,733 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2006, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""gen_gtest_pred_impl.py v0.1
Generates the implementation of Google Test predicate assertions and
accompanying tests.
Usage:
gen_gtest_pred_impl.py MAX_ARITY
where MAX_ARITY is a positive integer.
The command generates the implementation of up-to MAX_ARITY-ary
predicate assertions, and writes it to file gtest_pred_impl.h in the
directory where the script is. It also generates the accompanying
unit test in file gtest_pred_impl_unittest.cc.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
import time
# Where this script is.
SCRIPT_DIR = os.path.dirname(sys.argv[0])
# Where to store the generated header.
HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h')
# Where to store the generated unit test.
UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc')
def HeaderPreamble(n):
"""Returns the preamble for the header file.
Args:
n: the maximum arity of the predicate macros to be generated.
"""
# A map that defines the values used in the preamble template.
DEFS = {
'today' : time.strftime('%m/%d/%Y'),
'year' : time.strftime('%Y'),
'command' : '%s %s' % (os.path.basename(sys.argv[0]), n),
'n' : n
}
return (
"""// 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.
// This file is AUTOMATICALLY GENERATED on %(today)s by command
// '%(command)s'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#include "gtest/gtest.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 %(n)s.
// 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())
""" % DEFS)
def Arity(n):
"""Returns the English name of the given arity."""
if n < 0:
return None
elif n <= 3:
return ['nullary', 'unary', 'binary', 'ternary'][n]
else:
return '%s-ary' % n
def Title(word):
"""Returns the given word in title case. The difference between
this and string's title() method is that Title('4-ary') is '4-ary'
while '4-ary'.title() is '4-Ary'."""
return word[0].upper() + word[1:]
def OneTo(n):
"""Returns the list [1, 2, 3, ..., n]."""
return range(1, n + 1)
def Iter(n, format, sep=''):
"""Given a positive integer n, a format string that contains 0 or
more '%s' format specs, and optionally a separator string, returns
the join of n strings, each formatted with the format string on an
iterator ranged from 1 to n.
Example:
Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'.
"""
# How many '%s' specs are in format?
spec_count = len(format.split('%s')) - 1
return sep.join([format % (spec_count * (i,)) for i in OneTo(n)])
def ImplementationForArity(n):
"""Returns the implementation of n-ary predicate assertions."""
# A map the defines the values used in the implementation template.
DEFS = {
'n' : str(n),
'vs' : Iter(n, 'v%s', sep=', '),
'vts' : Iter(n, '#v%s', sep=', '),
'arity' : Arity(n),
'Arity' : Title(Arity(n))
}
impl = """
// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
// this in your code.
template <typename Pred""" % DEFS
impl += Iter(n, """,
typename T%s""")
impl += """>
AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
impl += Iter(n, """,
const char* e%s""")
impl += """,
Pred pred"""
impl += Iter(n, """,
const T%s& v%s""")
impl += """) {
if (pred(%(vs)s)) return AssertionSuccess();
""" % DEFS
impl += ' return AssertionFailure() << pred_text << "("'
impl += Iter(n, """
<< e%s""", sep=' << ", "')
impl += ' << ") evaluates to false, where"'
impl += Iter(
n, """
<< "\\n" << e%s << " evaluates to " << ::testing::PrintToString(v%s)"""
)
impl += """;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
// Don't use this in your code.
#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\
GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
// this in your code.
#define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\
GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS
impl += Iter(n, """, \\
#v%s""")
impl += """, \\
pred"""
impl += Iter(n, """, \\
v%s""")
impl += """), on_failure)
// %(Arity)s predicate assertion macros.
#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED%(n)s(pred, %(vs)s) \\
GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED%(n)s(pred, %(vs)s) \\
GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_)
""" % DEFS
return impl
def HeaderPostamble():
"""Returns the postamble for the header file."""
return """
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
"""
def GenerateFile(path, content):
"""Given a file path and a content string
overwrites it with the given content.
"""
print 'Updating file %s . . .' % path
f = file(path, 'w+')
print >>f, content,
f.close()
print 'File %s has been updated.' % path
def GenerateHeader(n):
"""Given the maximum arity n, updates the header file that implements
the predicate assertions.
"""
GenerateFile(HEADER,
HeaderPreamble(n)
+ ''.join([ImplementationForArity(i) for i in OneTo(n)])
+ HeaderPostamble())
def UnitTestPreamble():
"""Returns the preamble for the unit test file."""
# A map that defines the values used in the preamble template.
DEFS = {
'today' : time.strftime('%m/%d/%Y'),
'year' : time.strftime('%Y'),
'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]),
}
return (
"""// 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.
// This file is AUTOMATICALLY GENERATED on %(today)s by command
// '%(command)s'. DO NOT EDIT BY HAND!
// Regression test for gtest_pred_impl.h
//
// This file is generated by a script and quite long. If you intend to
// learn how Google Test works by reading its unit tests, read
// gtest_unittest.cc instead.
//
// This is intended as a regression test for the Google Test predicate
// assertions. We compile it as part of the gtest_unittest target
// only to keep the implementation tidy and compact, as it is quite
// involved to set up the stage for testing Google Test using Google
// Test itself.
//
// Currently, gtest_unittest takes ~11 seconds to run in the testing
// daemon. In the future, if it grows too large and needs much more
// time to finish, we should consider separating this file into a
// stand-alone regression test.
#include <iostream>
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
// A user-defined data type.
struct Bool {
explicit Bool(int val) : value(val != 0) {}
bool operator>(int n) const { return value > Bool(n).value; }
Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); }
bool operator==(const Bool& rhs) const { return value == rhs.value; }
bool value;
};
// Enables Bool to be used in assertions.
std::ostream& operator<<(std::ostream& os, const Bool& x) {
return os << (x.value ? "true" : "false");
}
""" % DEFS)
def TestsForArity(n):
"""Returns the tests for n-ary predicate assertions."""
# A map that defines the values used in the template for the tests.
DEFS = {
'n' : n,
'es' : Iter(n, 'e%s', sep=', '),
'vs' : Iter(n, 'v%s', sep=', '),
'vts' : Iter(n, '#v%s', sep=', '),
'tvs' : Iter(n, 'T%s v%s', sep=', '),
'int_vs' : Iter(n, 'int v%s', sep=', '),
'Bool_vs' : Iter(n, 'Bool v%s', sep=', '),
'types' : Iter(n, 'typename T%s', sep=', '),
'v_sum' : Iter(n, 'v%s', sep=' + '),
'arity' : Arity(n),
'Arity' : Title(Arity(n)),
}
tests = (
"""// Sample functions/functors for testing %(arity)s predicate assertions.
// A %(arity)s predicate function.
template <%(types)s>
bool PredFunction%(n)s(%(tvs)s) {
return %(v_sum)s > 0;
}
// The following two functions are needed because a compiler doesn't have
// a context yet to know which template function must be instantiated.
bool PredFunction%(n)sInt(%(int_vs)s) {
return %(v_sum)s > 0;
}
bool PredFunction%(n)sBool(%(Bool_vs)s) {
return %(v_sum)s > 0;
}
""" % DEFS)
tests += """
// A %(arity)s predicate functor.
struct PredFunctor%(n)s {
template <%(types)s>
bool operator()(""" % DEFS
tests += Iter(n, 'const T%s& v%s', sep=""",
""")
tests += """) {
return %(v_sum)s > 0;
}
};
""" % DEFS
tests += """
// A %(arity)s predicate-formatter function.
template <%(types)s>
testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS
tests += Iter(n, 'const char* e%s', sep=""",
""")
tests += Iter(n, """,
const T%s& v%s""")
tests += """) {
if (PredFunction%(n)s(%(vs)s))
return testing::AssertionSuccess();
return testing::AssertionFailure()
<< """ % DEFS
tests += Iter(n, 'e%s', sep=' << " + " << ')
tests += """
<< " is expected to be positive, but evaluates to "
<< %(v_sum)s << ".";
}
""" % DEFS
tests += """
// A %(arity)s predicate-formatter functor.
struct PredFormatFunctor%(n)s {
template <%(types)s>
testing::AssertionResult operator()(""" % DEFS
tests += Iter(n, 'const char* e%s', sep=""",
""")
tests += Iter(n, """,
const T%s& v%s""")
tests += """) const {
return PredFormatFunction%(n)s(%(es)s, %(vs)s);
}
};
""" % DEFS
tests += """
// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
class Predicate%(n)sTest : public testing::Test {
protected:
void SetUp() override {
expected_to_finish_ = true;
finished_ = false;""" % DEFS
tests += """
""" + Iter(n, 'n%s_ = ') + """0;
}
"""
tests += """
void TearDown() override {
// Verifies that each of the predicate's arguments was evaluated
// exactly once."""
tests += ''.join(["""
EXPECT_EQ(1, n%s_) <<
"The predicate assertion didn't evaluate argument %s "
"exactly once.";""" % (i, i + 1) for i in OneTo(n)])
tests += """
// Verifies that the control flow in the test function is expected.
if (expected_to_finish_ && !finished_) {
FAIL() << "The predicate assertion unexpactedly aborted the test.";
} else if (!expected_to_finish_ && finished_) {
FAIL() << "The failed predicate assertion didn't abort the test "
"as expected.";
}
}
// true if and only if the test function is expected to run to finish.
static bool expected_to_finish_;
// true if and only if the test function did run to finish.
static bool finished_;
""" % DEFS
tests += Iter(n, """
static int n%s_;""")
tests += """
};
bool Predicate%(n)sTest::expected_to_finish_;
bool Predicate%(n)sTest::finished_;
""" % DEFS
tests += Iter(n, """int Predicate%%(n)sTest::n%s_;
""") % DEFS
tests += """
typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest;
typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest;
typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest;
typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
""" % DEFS
def GenTest(use_format, use_assert, expect_failure,
use_functor, use_user_type):
"""Returns the test for a predicate assertion macro.
Args:
use_format: true if and only if the assertion is a *_PRED_FORMAT*.
use_assert: true if and only if the assertion is a ASSERT_*.
expect_failure: true if and only if the assertion is expected to fail.
use_functor: true if and only if the first argument of the assertion is
a functor (as opposed to a function)
use_user_type: true if and only if the predicate functor/function takes
argument(s) of a user-defined type.
Example:
GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior
of a successful EXPECT_PRED_FORMATn() that takes a functor
whose arguments have built-in types."""
if use_assert:
assrt = 'ASSERT' # 'assert' is reserved, so we cannot use
# that identifier here.
else:
assrt = 'EXPECT'
assertion = assrt + '_PRED'
if use_format:
pred_format = 'PredFormat'
assertion += '_FORMAT'
else:
pred_format = 'Pred'
assertion += '%(n)s' % DEFS
if use_functor:
pred_format_type = 'functor'
pred_format += 'Functor%(n)s()'
else:
pred_format_type = 'function'
pred_format += 'Function%(n)s'
if not use_format:
if use_user_type:
pred_format += 'Bool'
else:
pred_format += 'Int'
test_name = pred_format_type.title()
if use_user_type:
arg_type = 'user-defined type (Bool)'
test_name += 'OnUserType'
if expect_failure:
arg = 'Bool(n%s_++)'
else:
arg = 'Bool(++n%s_)'
else:
arg_type = 'built-in type (int)'
test_name += 'OnBuiltInType'
if expect_failure:
arg = 'n%s_++'
else:
arg = '++n%s_'
if expect_failure:
successful_or_failed = 'failed'
expected_or_not = 'expected.'
test_name += 'Failure'
else:
successful_or_failed = 'successful'
expected_or_not = 'UNEXPECTED!'
test_name += 'Success'
# A map that defines the values used in the test template.
defs = DEFS.copy()
defs.update({
'assert' : assrt,
'assertion' : assertion,
'test_name' : test_name,
'pf_type' : pred_format_type,
'pf' : pred_format,
'arg_type' : arg_type,
'arg' : arg,
'successful' : successful_or_failed,
'expected' : expected_or_not,
})
test = """
// Tests a %(successful)s %(assertion)s where the
// predicate-formatter is a %(pf_type)s on a %(arg_type)s.
TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs
indent = (len(assertion) + 3)*' '
extra_indent = ''
if expect_failure:
extra_indent = ' '
if use_assert:
test += """
expected_to_finish_ = false;
EXPECT_FATAL_FAILURE({ // NOLINT"""
else:
test += """
EXPECT_NONFATAL_FAILURE({ // NOLINT"""
test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs
test = test % defs
test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs)
test += ');\n' + extra_indent + ' finished_ = true;\n'
if expect_failure:
test += ' }, "");\n'
test += '}\n'
return test
# Generates tests for all 2**6 = 64 combinations.
tests += ''.join([GenTest(use_format, use_assert, expect_failure,
use_functor, use_user_type)
for use_format in [0, 1]
for use_assert in [0, 1]
for expect_failure in [0, 1]
for use_functor in [0, 1]
for use_user_type in [0, 1]
])
return tests
def UnitTestPostamble():
"""Returns the postamble for the tests."""
return ''
def GenerateUnitTest(n):
"""Returns the tests for up-to n-ary predicate assertions."""
GenerateFile(UNIT_TEST,
UnitTestPreamble()
+ ''.join([TestsForArity(i) for i in OneTo(n)])
+ UnitTestPostamble())
def _Main():
"""The entry point of the script. Generates the header file and its
unit test."""
if len(sys.argv) != 2:
print __doc__
print 'Author: ' + __author__
sys.exit(1)
n = int(sys.argv[1])
GenerateHeader(n)
GenerateUnitTest(n)
if __name__ == '__main__':
_Main()

View File

@ -1,274 +0,0 @@
#!/bin/sh
# These variables are automatically filled in by the configure script.
name="@PACKAGE_TARNAME@"
version="@PACKAGE_VERSION@"
show_usage()
{
echo "Usage: gtest-config [OPTIONS...]"
}
show_help()
{
show_usage
cat <<\EOF
The `gtest-config' script provides access to the necessary compile and linking
flags to connect with Google C++ Testing Framework, both in a build prior to
installation, and on the system proper after installation. The installation
overrides may be issued in combination with any other queries, but will only
affect installation queries if called on a built but not installed gtest. The
installation queries may not be issued with any other types of queries, and
only one installation query may be made at a time. The version queries and
compiler flag queries may be combined as desired but not mixed. Different
version queries are always combined with logical "and" semantics, and only the
last of any particular query is used while all previous ones ignored. All
versions must be specified as a sequence of numbers separated by periods.
Compiler flag queries output the union of the sets of flags when combined.
Examples:
gtest-config --min-version=1.0 || echo "Insufficient Google Test version."
g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp
g++ $(gtest-config --ldflags --libs) -o foo foo.o
# When using a built but not installed Google Test:
g++ $(../../my_gtest_build/scripts/gtest-config ...) ...
# When using an installed Google Test, but with installation overrides:
export GTEST_PREFIX="/opt"
g++ $(gtest-config --libdir="/opt/lib64" ...) ...
Help:
--usage brief usage information
--help display this help message
Installation Overrides:
--prefix=<dir> overrides the installation prefix
--exec-prefix=<dir> overrides the executable installation prefix
--libdir=<dir> overrides the library installation prefix
--includedir=<dir> overrides the header file installation prefix
Installation Queries:
--prefix installation prefix
--exec-prefix executable installation prefix
--libdir library installation directory
--includedir header file installation directory
--version the version of the Google Test installation
Version Queries:
--min-version=VERSION return 0 if the version is at least VERSION
--exact-version=VERSION return 0 if the version is exactly VERSION
--max-version=VERSION return 0 if the version is at most VERSION
Compilation Flag Queries:
--cppflags compile flags specific to the C-like preprocessors
--cxxflags compile flags appropriate for C++ programs
--ldflags linker flags
--libs libraries for linking
EOF
}
# This function bounds our version with a min and a max. It uses some clever
# POSIX-compliant variable expansion to portably do all the work in the shell
# and avoid any dependency on a particular "sed" or "awk" implementation.
# Notable is that it will only ever compare the first 3 components of versions.
# Further components will be cleanly stripped off. All versions must be
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
# continuing to maintain our own shell version.
check_versions()
{
major_version=${version%%.*}
minor_version="0"
point_version="0"
if test "${version#*.}" != "${version}"; then
minor_version=${version#*.}
minor_version=${minor_version%%.*}
fi
if test "${version#*.*.}" != "${version}"; then
point_version=${version#*.*.}
point_version=${point_version%%.*}
fi
min_version="$1"
min_major_version=${min_version%%.*}
min_minor_version="0"
min_point_version="0"
if test "${min_version#*.}" != "${min_version}"; then
min_minor_version=${min_version#*.}
min_minor_version=${min_minor_version%%.*}
fi
if test "${min_version#*.*.}" != "${min_version}"; then
min_point_version=${min_version#*.*.}
min_point_version=${min_point_version%%.*}
fi
max_version="$2"
max_major_version=${max_version%%.*}
max_minor_version="0"
max_point_version="0"
if test "${max_version#*.}" != "${max_version}"; then
max_minor_version=${max_version#*.}
max_minor_version=${max_minor_version%%.*}
fi
if test "${max_version#*.*.}" != "${max_version}"; then
max_point_version=${max_version#*.*.}
max_point_version=${max_point_version%%.*}
fi
test $(($major_version)) -lt $(($min_major_version)) && exit 1
if test $(($major_version)) -eq $(($min_major_version)); then
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
if test $(($minor_version)) -eq $(($min_minor_version)); then
test $(($point_version)) -lt $(($min_point_version)) && exit 1
fi
fi
test $(($major_version)) -gt $(($max_major_version)) && exit 1
if test $(($major_version)) -eq $(($max_major_version)); then
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
if test $(($minor_version)) -eq $(($max_minor_version)); then
test $(($point_version)) -gt $(($max_point_version)) && exit 1
fi
fi
exit 0
}
# Show the usage line when no arguments are specified.
if test $# -eq 0; then
show_usage
exit 1
fi
while test $# -gt 0; do
case $1 in
--usage) show_usage; exit 0;;
--help) show_help; exit 0;;
# Installation overrides
--prefix=*) GTEST_PREFIX=${1#--prefix=};;
--exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};;
--libdir=*) GTEST_LIBDIR=${1#--libdir=};;
--includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};;
# Installation queries
--prefix|--exec-prefix|--libdir|--includedir|--version)
if test -n "${do_query}"; then
show_usage
exit 1
fi
do_query=${1#--}
;;
# Version checking
--min-version=*)
do_check_versions=yes
min_version=${1#--min-version=}
;;
--max-version=*)
do_check_versions=yes
max_version=${1#--max-version=}
;;
--exact-version=*)
do_check_versions=yes
exact_version=${1#--exact-version=}
;;
# Compiler flag output
--cppflags) echo_cppflags=yes;;
--cxxflags) echo_cxxflags=yes;;
--ldflags) echo_ldflags=yes;;
--libs) echo_libs=yes;;
# Everything else is an error
*) show_usage; exit 1;;
esac
shift
done
# These have defaults filled in by the configure script but can also be
# overridden by environment variables or command line parameters.
prefix="${GTEST_PREFIX:-@prefix@}"
exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}"
libdir="${GTEST_LIBDIR:-@libdir@}"
includedir="${GTEST_INCLUDEDIR:-@includedir@}"
# We try and detect if our binary is not located at its installed location. If
# it's not, we provide variables pointing to the source and build tree rather
# than to the install tree. This allows building against a just-built gtest
# rather than an installed gtest.
bindir="@bindir@"
this_relative_bindir=`dirname $0`
this_bindir=`cd ${this_relative_bindir}; pwd -P`
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# The path to the script doesn't end in the bindir sequence from Autoconf,
# assume that we are in a build tree.
build_dir=`dirname ${this_bindir}`
src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P`
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it
# with direct references to the library and a link path.
gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_ldflags=""
# We provide hooks to include from either the source or build dir, where the
# build dir is always preferred. This will potentially allow us to write
# build rules for generated headers and have them automatically be preferred
# over provided versions.
gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
gtest_cxxflags="@PTHREAD_CFLAGS@"
else
# We're using an installed gtest, although it may be staged under some
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
# and are present in the dynamic link paths.
gtest_ldflags="-L${libdir}"
gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_cppflags="-I${includedir}"
gtest_cxxflags="@PTHREAD_CFLAGS@"
fi
# Do an installation query if requested.
if test -n "$do_query"; then
case $do_query in
prefix) echo $prefix; exit 0;;
exec-prefix) echo $exec_prefix; exit 0;;
libdir) echo $libdir; exit 0;;
includedir) echo $includedir; exit 0;;
version) echo $version; exit 0;;
*) show_usage; exit 1;;
esac
fi
# Do a version check if requested.
if test "$do_check_versions" = "yes"; then
# Make sure we didn't receive a bad combination of parameters.
test "$echo_cppflags" = "yes" && show_usage && exit 1
test "$echo_cxxflags" = "yes" && show_usage && exit 1
test "$echo_ldflags" = "yes" && show_usage && exit 1
test "$echo_libs" = "yes" && show_usage && exit 1
if test "$exact_version" != ""; then
check_versions $exact_version $exact_version
# unreachable
else
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
# unreachable
fi
fi
# Do the output in the correct order so that these can be used in-line of
# a compiler invocation.
output=""
test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags"
test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags"
test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags"
test "$echo_libs" = "yes" && output="$output $gtest_libs"
echo $output
exit 0

View File

@ -1,855 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""pump v0.2.0 - Pretty Useful for Meta Programming.
A tool for preprocessor meta programming. Useful for generating
repetitive boilerplate code. Especially useful for writing C++
classes, functions, macros, and templates that need to work with
various number of arguments.
USAGE:
pump.py SOURCE_FILE
EXAMPLES:
pump.py foo.cc.pump
Converts foo.cc.pump to foo.cc.
GRAMMAR:
CODE ::= ATOMIC_CODE*
ATOMIC_CODE ::= $var ID = EXPRESSION
| $var ID = [[ CODE ]]
| $range ID EXPRESSION..EXPRESSION
| $for ID SEPARATOR [[ CODE ]]
| $($)
| $ID
| $(EXPRESSION)
| $if EXPRESSION [[ CODE ]] ELSE_BRANCH
| [[ CODE ]]
| RAW_CODE
SEPARATOR ::= RAW_CODE | EMPTY
ELSE_BRANCH ::= $else [[ CODE ]]
| $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
| EMPTY
EXPRESSION has Python syntax.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sys
TOKEN_TABLE = [
(re.compile(r'\$var\s+'), '$var'),
(re.compile(r'\$elif\s+'), '$elif'),
(re.compile(r'\$else\s+'), '$else'),
(re.compile(r'\$for\s+'), '$for'),
(re.compile(r'\$if\s+'), '$if'),
(re.compile(r'\$range\s+'), '$range'),
(re.compile(r'\$[_A-Za-z]\w*'), '$id'),
(re.compile(r'\$\(\$\)'), '$($)'),
(re.compile(r'\$'), '$'),
(re.compile(r'\[\[\n?'), '[['),
(re.compile(r'\]\]\n?'), ']]'),
]
class Cursor:
"""Represents a position (line and column) in a text file."""
def __init__(self, line=-1, column=-1):
self.line = line
self.column = column
def __eq__(self, rhs):
return self.line == rhs.line and self.column == rhs.column
def __ne__(self, rhs):
return not self == rhs
def __lt__(self, rhs):
return self.line < rhs.line or (
self.line == rhs.line and self.column < rhs.column)
def __le__(self, rhs):
return self < rhs or self == rhs
def __gt__(self, rhs):
return rhs < self
def __ge__(self, rhs):
return rhs <= self
def __str__(self):
if self == Eof():
return 'EOF'
else:
return '%s(%s)' % (self.line + 1, self.column)
def __add__(self, offset):
return Cursor(self.line, self.column + offset)
def __sub__(self, offset):
return Cursor(self.line, self.column - offset)
def Clone(self):
"""Returns a copy of self."""
return Cursor(self.line, self.column)
# Special cursor to indicate the end-of-file.
def Eof():
"""Returns the special cursor to denote the end-of-file."""
return Cursor(-1, -1)
class Token:
"""Represents a token in a Pump source file."""
def __init__(self, start=None, end=None, value=None, token_type=None):
if start is None:
self.start = Eof()
else:
self.start = start
if end is None:
self.end = Eof()
else:
self.end = end
self.value = value
self.token_type = token_type
def __str__(self):
return 'Token @%s: \'%s\' type=%s' % (
self.start, self.value, self.token_type)
def Clone(self):
"""Returns a copy of self."""
return Token(self.start.Clone(), self.end.Clone(), self.value,
self.token_type)
def StartsWith(lines, pos, string):
"""Returns True iff the given position in lines starts with 'string'."""
return lines[pos.line][pos.column:].startswith(string)
def FindFirstInLine(line, token_table):
best_match_start = -1
for (regex, token_type) in token_table:
m = regex.search(line)
if m:
# We found regex in lines
if best_match_start < 0 or m.start() < best_match_start:
best_match_start = m.start()
best_match_length = m.end() - m.start()
best_match_token_type = token_type
if best_match_start < 0:
return None
return (best_match_start, best_match_length, best_match_token_type)
def FindFirst(lines, token_table, cursor):
"""Finds the first occurrence of any string in strings in lines."""
start = cursor.Clone()
cur_line_number = cursor.line
for line in lines[start.line:]:
if cur_line_number == start.line:
line = line[start.column:]
m = FindFirstInLine(line, token_table)
if m:
# We found a regex in line.
(start_column, length, token_type) = m
if cur_line_number == start.line:
start_column += start.column
found_start = Cursor(cur_line_number, start_column)
found_end = found_start + length
return MakeToken(lines, found_start, found_end, token_type)
cur_line_number += 1
# We failed to find str in lines
return None
def SubString(lines, start, end):
"""Returns a substring in lines."""
if end == Eof():
end = Cursor(len(lines) - 1, len(lines[-1]))
if start >= end:
return ''
if start.line == end.line:
return lines[start.line][start.column:end.column]
result_lines = ([lines[start.line][start.column:]] +
lines[start.line + 1:end.line] +
[lines[end.line][:end.column]])
return ''.join(result_lines)
def StripMetaComments(str):
"""Strip meta comments from each line in the given string."""
# First, completely remove lines containing nothing but a meta
# comment, including the trailing \n.
str = re.sub(r'^\s*\$\$.*\n', '', str)
# Then, remove meta comments from contentful lines.
return re.sub(r'\s*\$\$.*', '', str)
def MakeToken(lines, start, end, token_type):
"""Creates a new instance of Token."""
return Token(start, end, SubString(lines, start, end), token_type)
def ParseToken(lines, pos, regex, token_type):
line = lines[pos.line][pos.column:]
m = regex.search(line)
if m and not m.start():
return MakeToken(lines, pos, pos + m.end(), token_type)
else:
print 'ERROR: %s expected at %s.' % (token_type, pos)
sys.exit(1)
ID_REGEX = re.compile(r'[_A-Za-z]\w*')
EQ_REGEX = re.compile(r'=')
REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
WHITE_SPACE_REGEX = re.compile(r'\s')
DOT_DOT_REGEX = re.compile(r'\.\.')
def Skip(lines, pos, regex):
line = lines[pos.line][pos.column:]
m = re.search(regex, line)
if m and not m.start():
return pos + m.end()
else:
return pos
def SkipUntil(lines, pos, regex, token_type):
line = lines[pos.line][pos.column:]
m = re.search(regex, line)
if m:
return pos + m.start()
else:
print ('ERROR: %s expected on line %s after column %s.' %
(token_type, pos.line + 1, pos.column))
sys.exit(1)
def ParseExpTokenInParens(lines, pos):
def ParseInParens(pos):
pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
pos = Skip(lines, pos, r'\(')
pos = Parse(pos)
pos = Skip(lines, pos, r'\)')
return pos
def Parse(pos):
pos = SkipUntil(lines, pos, r'\(|\)', ')')
if SubString(lines, pos, pos + 1) == '(':
pos = Parse(pos + 1)
pos = Skip(lines, pos, r'\)')
return Parse(pos)
else:
return pos
start = pos.Clone()
pos = ParseInParens(pos)
return MakeToken(lines, start, pos, 'exp')
def RStripNewLineFromToken(token):
if token.value.endswith('\n'):
return Token(token.start, token.end, token.value[:-1], token.token_type)
else:
return token
def TokenizeLines(lines, pos):
while True:
found = FindFirst(lines, TOKEN_TABLE, pos)
if not found:
yield MakeToken(lines, pos, Eof(), 'code')
return
if found.start == pos:
prev_token = None
prev_token_rstripped = None
else:
prev_token = MakeToken(lines, pos, found.start, 'code')
prev_token_rstripped = RStripNewLineFromToken(prev_token)
if found.token_type == '$var':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
yield eq_token
pos = Skip(lines, eq_token.end, r'\s*')
if SubString(lines, pos, pos + 2) != '[[':
exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
yield exp_token
pos = Cursor(exp_token.end.line + 1, 0)
elif found.token_type == '$for':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
elif found.token_type == '$range':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
yield MakeToken(lines, pos, dots_pos, 'exp')
yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
pos = dots_pos + 2
new_pos = Cursor(pos.line + 1, 0)
yield MakeToken(lines, pos, new_pos, 'exp')
pos = new_pos
elif found.token_type == '$':
if prev_token:
yield prev_token
yield found
exp_token = ParseExpTokenInParens(lines, found.end)
yield exp_token
pos = exp_token.end
elif (found.token_type == ']]' or found.token_type == '$if' or
found.token_type == '$elif' or found.token_type == '$else'):
if prev_token_rstripped:
yield prev_token_rstripped
yield found
pos = found.end
else:
if prev_token:
yield prev_token
yield found
pos = found.end
def Tokenize(s):
"""A generator that yields the tokens in the given string."""
if s != '':
lines = s.splitlines(True)
for token in TokenizeLines(lines, Cursor(0, 0)):
yield token
class CodeNode:
def __init__(self, atomic_code_list=None):
self.atomic_code = atomic_code_list
class VarNode:
def __init__(self, identifier=None, atomic_code=None):
self.identifier = identifier
self.atomic_code = atomic_code
class RangeNode:
def __init__(self, identifier=None, exp1=None, exp2=None):
self.identifier = identifier
self.exp1 = exp1
self.exp2 = exp2
class ForNode:
def __init__(self, identifier=None, sep=None, code=None):
self.identifier = identifier
self.sep = sep
self.code = code
class ElseNode:
def __init__(self, else_branch=None):
self.else_branch = else_branch
class IfNode:
def __init__(self, exp=None, then_branch=None, else_branch=None):
self.exp = exp
self.then_branch = then_branch
self.else_branch = else_branch
class RawCodeNode:
def __init__(self, token=None):
self.raw_code = token
class LiteralDollarNode:
def __init__(self, token):
self.token = token
class ExpNode:
def __init__(self, token, python_exp):
self.token = token
self.python_exp = python_exp
def PopFront(a_list):
head = a_list[0]
a_list[:1] = []
return head
def PushFront(a_list, elem):
a_list[:0] = [elem]
def PopToken(a_list, token_type=None):
token = PopFront(a_list)
if token_type is not None and token.token_type != token_type:
print 'ERROR: %s expected at %s' % (token_type, token.start)
print 'ERROR: %s found instead' % (token,)
sys.exit(1)
return token
def PeekToken(a_list):
if not a_list:
return None
return a_list[0]
def ParseExpNode(token):
python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
return ExpNode(token, python_exp)
def ParseElseNode(tokens):
def Pop(token_type=None):
return PopToken(tokens, token_type)
next = PeekToken(tokens)
if not next:
return None
if next.token_type == '$else':
Pop('$else')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return code_node
elif next.token_type == '$elif':
Pop('$elif')
exp = Pop('code')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
inner_else_node = ParseElseNode(tokens)
return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
elif not next.value.strip():
Pop('code')
return ParseElseNode(tokens)
else:
return None
def ParseAtomicCodeNode(tokens):
def Pop(token_type=None):
return PopToken(tokens, token_type)
head = PopFront(tokens)
t = head.token_type
if t == 'code':
return RawCodeNode(head)
elif t == '$var':
id_token = Pop('id')
Pop('=')
next = PeekToken(tokens)
if next.token_type == 'exp':
exp_token = Pop()
return VarNode(id_token, ParseExpNode(exp_token))
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return VarNode(id_token, code_node)
elif t == '$for':
id_token = Pop('id')
next_token = PeekToken(tokens)
if next_token.token_type == 'code':
sep_token = next_token
Pop('code')
else:
sep_token = None
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return ForNode(id_token, sep_token, code_node)
elif t == '$if':
exp_token = Pop('code')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
else_node = ParseElseNode(tokens)
return IfNode(ParseExpNode(exp_token), code_node, else_node)
elif t == '$range':
id_token = Pop('id')
exp1_token = Pop('exp')
Pop('..')
exp2_token = Pop('exp')
return RangeNode(id_token, ParseExpNode(exp1_token),
ParseExpNode(exp2_token))
elif t == '$id':
return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
elif t == '$($)':
return LiteralDollarNode(head)
elif t == '$':
exp_token = Pop('exp')
return ParseExpNode(exp_token)
elif t == '[[':
code_node = ParseCodeNode(tokens)
Pop(']]')
return code_node
else:
PushFront(tokens, head)
return None
def ParseCodeNode(tokens):
atomic_code_list = []
while True:
if not tokens:
break
atomic_code_node = ParseAtomicCodeNode(tokens)
if atomic_code_node:
atomic_code_list.append(atomic_code_node)
else:
break
return CodeNode(atomic_code_list)
def ParseToAST(pump_src_text):
"""Convert the given Pump source text into an AST."""
tokens = list(Tokenize(pump_src_text))
code_node = ParseCodeNode(tokens)
return code_node
class Env:
def __init__(self):
self.variables = []
self.ranges = []
def Clone(self):
clone = Env()
clone.variables = self.variables[:]
clone.ranges = self.ranges[:]
return clone
def PushVariable(self, var, value):
# If value looks like an int, store it as an int.
try:
int_value = int(value)
if ('%s' % int_value) == value:
value = int_value
except Exception:
pass
self.variables[:0] = [(var, value)]
def PopVariable(self):
self.variables[:1] = []
def PushRange(self, var, lower, upper):
self.ranges[:0] = [(var, lower, upper)]
def PopRange(self):
self.ranges[:1] = []
def GetValue(self, identifier):
for (var, value) in self.variables:
if identifier == var:
return value
print 'ERROR: meta variable %s is undefined.' % (identifier,)
sys.exit(1)
def EvalExp(self, exp):
try:
result = eval(exp.python_exp)
except Exception, e:
print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
print ('ERROR: failed to evaluate meta expression %s at %s' %
(exp.python_exp, exp.token.start))
sys.exit(1)
return result
def GetRange(self, identifier):
for (var, lower, upper) in self.ranges:
if identifier == var:
return (lower, upper)
print 'ERROR: range %s is undefined.' % (identifier,)
sys.exit(1)
class Output:
def __init__(self):
self.string = ''
def GetLastLine(self):
index = self.string.rfind('\n')
if index < 0:
return ''
return self.string[index + 1:]
def Append(self, s):
self.string += s
def RunAtomicCode(env, node, output):
if isinstance(node, VarNode):
identifier = node.identifier.value.strip()
result = Output()
RunAtomicCode(env.Clone(), node.atomic_code, result)
value = result.string
env.PushVariable(identifier, value)
elif isinstance(node, RangeNode):
identifier = node.identifier.value.strip()
lower = int(env.EvalExp(node.exp1))
upper = int(env.EvalExp(node.exp2))
env.PushRange(identifier, lower, upper)
elif isinstance(node, ForNode):
identifier = node.identifier.value.strip()
if node.sep is None:
sep = ''
else:
sep = node.sep.value
(lower, upper) = env.GetRange(identifier)
for i in range(lower, upper + 1):
new_env = env.Clone()
new_env.PushVariable(identifier, i)
RunCode(new_env, node.code, output)
if i != upper:
output.Append(sep)
elif isinstance(node, RawCodeNode):
output.Append(node.raw_code.value)
elif isinstance(node, IfNode):
cond = env.EvalExp(node.exp)
if cond:
RunCode(env.Clone(), node.then_branch, output)
elif node.else_branch is not None:
RunCode(env.Clone(), node.else_branch, output)
elif isinstance(node, ExpNode):
value = env.EvalExp(node)
output.Append('%s' % (value,))
elif isinstance(node, LiteralDollarNode):
output.Append('$')
elif isinstance(node, CodeNode):
RunCode(env.Clone(), node, output)
else:
print 'BAD'
print node
sys.exit(1)
def RunCode(env, code_node, output):
for atomic_code in code_node.atomic_code:
RunAtomicCode(env, atomic_code, output)
def IsSingleLineComment(cur_line):
return '//' in cur_line
def IsInPreprocessorDirective(prev_lines, cur_line):
if cur_line.lstrip().startswith('#'):
return True
return prev_lines and prev_lines[-1].endswith('\\')
def WrapComment(line, output):
loc = line.find('//')
before_comment = line[:loc].rstrip()
if before_comment == '':
indent = loc
else:
output.append(before_comment)
indent = len(before_comment) - len(before_comment.lstrip())
prefix = indent*' ' + '// '
max_len = 80 - len(prefix)
comment = line[loc + 2:].strip()
segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
cur_line = ''
for seg in segs:
if len((cur_line + seg).rstrip()) < max_len:
cur_line += seg
else:
if cur_line.strip() != '':
output.append(prefix + cur_line.rstrip())
cur_line = seg.lstrip()
if cur_line.strip() != '':
output.append(prefix + cur_line.strip())
def WrapCode(line, line_concat, output):
indent = len(line) - len(line.lstrip())
prefix = indent*' ' # Prefix of the current line
max_len = 80 - indent - len(line_concat) # Maximum length of the current line
new_prefix = prefix + 4*' ' # Prefix of a continuation line
new_max_len = max_len - 4 # Maximum length of a continuation line
# Prefers to wrap a line after a ',' or ';'.
segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
cur_line = '' # The current line without leading spaces.
for seg in segs:
# If the line is still too long, wrap at a space.
while cur_line == '' and len(seg.strip()) > max_len:
seg = seg.lstrip()
split_at = seg.rfind(' ', 0, max_len)
output.append(prefix + seg[:split_at].strip() + line_concat)
seg = seg[split_at + 1:]
prefix = new_prefix
max_len = new_max_len
if len((cur_line + seg).rstrip()) < max_len:
cur_line = (cur_line + seg).lstrip()
else:
output.append(prefix + cur_line.rstrip() + line_concat)
prefix = new_prefix
max_len = new_max_len
cur_line = seg.lstrip()
if cur_line.strip() != '':
output.append(prefix + cur_line.strip())
def WrapPreprocessorDirective(line, output):
WrapCode(line, ' \\', output)
def WrapPlainCode(line, output):
WrapCode(line, '', output)
def IsMultiLineIWYUPragma(line):
return re.search(r'/\* IWYU pragma: ', line)
def IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
re.match(r'^#include\s', line) or
# Don't break IWYU pragmas, either; that causes iwyu.py problems.
re.search(r'// IWYU pragma: ', line))
def WrapLongLine(line, output):
line = line.rstrip()
if len(line) <= 80:
output.append(line)
elif IsSingleLineComment(line):
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines,
# includes and IWYU pragmas.
output.append(line)
else:
WrapComment(line, output)
elif IsInPreprocessorDirective(output, line):
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines,
# includes and IWYU pragmas.
output.append(line)
else:
WrapPreprocessorDirective(line, output)
elif IsMultiLineIWYUPragma(line):
output.append(line)
else:
WrapPlainCode(line, output)
def BeautifyCode(string):
lines = string.splitlines()
output = []
for line in lines:
WrapLongLine(line, output)
output2 = [line.rstrip() for line in output]
return '\n'.join(output2) + '\n'
def ConvertFromPumpSource(src_text):
"""Return the text generated from the given Pump source text."""
ast = ParseToAST(StripMetaComments(src_text))
output = Output()
RunCode(Env(), ast, output)
return BeautifyCode(output.string)
def main(argv):
if len(argv) == 1:
print __doc__
sys.exit(1)
file_path = argv[-1]
output_str = ConvertFromPumpSource(file(file_path, 'r').read())
if file_path.endswith('.pump'):
output_file_path = file_path[:-5]
else:
output_file_path = '-'
if output_file_path == '-':
print output_str,
else:
output_file = file(output_file_path, 'w')
output_file.write('// This file was GENERATED by command:\n')
output_file.write('// %s %s\n' %
(os.path.basename(__file__), os.path.basename(file_path)))
output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
output_file.write(output_str)
output_file.close()
if __name__ == '__main__':
main(sys.argv)

View File

@ -1,158 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Script for branching Google Test/Mock wiki pages for a new version.
SYNOPSIS
release_docs.py NEW_RELEASE_VERSION
Google Test and Google Mock's external user documentation is in
interlinked wiki files. When we release a new version of
Google Test or Google Mock, we need to branch the wiki files
such that users of a specific version of Google Test/Mock can
look up documentation relevant for that version. This script
automates that process by:
- branching the current wiki pages (which document the
behavior of the SVN trunk head) to pages for the specified
version (e.g. branching FAQ.wiki to V2_6_FAQ.wiki when
NEW_RELEASE_VERSION is 2.6);
- updating the links in the branched files to point to the branched
version (e.g. a link in V2_6_FAQ.wiki that pointed to
Primer.wiki#Anchor will now point to V2_6_Primer.wiki#Anchor).
NOTE: NEW_RELEASE_VERSION must be a NEW version number for
which the wiki pages don't yet exist; otherwise you'll get SVN
errors like "svn: Path 'V1_7_PumpManual.wiki' is not a
directory" when running the script.
EXAMPLE
$ cd PATH/TO/GTEST_SVN_WORKSPACE/trunk
$ scripts/release_docs.py 2.6 # create wiki pages for v2.6
$ svn status # verify the file list
$ svn diff # verify the file contents
$ svn commit -m "release wiki pages for v2.6"
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sys
import common
# Wiki pages that shouldn't be branched for every gtest/gmock release.
GTEST_UNVERSIONED_WIKIS = ['DevGuide.wiki']
GMOCK_UNVERSIONED_WIKIS = [
'DesignDoc.wiki',
'DevGuide.wiki',
'KnownIssues.wiki'
]
def DropWikiSuffix(wiki_filename):
"""Removes the .wiki suffix (if any) from the given filename."""
return (wiki_filename[:-len('.wiki')] if wiki_filename.endswith('.wiki')
else wiki_filename)
class WikiBrancher(object):
"""Branches ..."""
def __init__(self, dot_version):
self.project, svn_root_path = common.GetSvnInfo()
if self.project not in ('googletest', 'googlemock'):
sys.exit('This script must be run in a gtest or gmock SVN workspace.')
self.wiki_dir = svn_root_path + '/wiki'
# Turn '2.6' to 'V2_6_'.
self.version_prefix = 'V' + dot_version.replace('.', '_') + '_'
self.files_to_branch = self.GetFilesToBranch()
page_names = [DropWikiSuffix(f) for f in self.files_to_branch]
# A link to Foo.wiki is in one of the following forms:
# [Foo words]
# [Foo#Anchor words]
# [http://code.google.com/.../wiki/Foo words]
# [http://code.google.com/.../wiki/Foo#Anchor words]
# We want to replace 'Foo' with 'V2_6_Foo' in the above cases.
self.search_for_re = re.compile(
# This regex matches either
# [Foo
# or
# /wiki/Foo
# followed by a space or a #, where Foo is the name of an
# unversioned wiki page.
r'(\[|/wiki/)(%s)([ #])' % '|'.join(page_names))
self.replace_with = r'\1%s\2\3' % (self.version_prefix,)
def GetFilesToBranch(self):
"""Returns a list of .wiki file names that need to be branched."""
unversioned_wikis = (GTEST_UNVERSIONED_WIKIS if self.project == 'googletest'
else GMOCK_UNVERSIONED_WIKIS)
return [f for f in os.listdir(self.wiki_dir)
if (f.endswith('.wiki') and
not re.match(r'^V\d', f) and # Excluded versioned .wiki files.
f not in unversioned_wikis)]
def BranchFiles(self):
"""Branches the .wiki files needed to be branched."""
print 'Branching %d .wiki files:' % (len(self.files_to_branch),)
os.chdir(self.wiki_dir)
for f in self.files_to_branch:
command = 'svn cp %s %s%s' % (f, self.version_prefix, f)
print command
os.system(command)
def UpdateLinksInBranchedFiles(self):
for f in self.files_to_branch:
source_file = os.path.join(self.wiki_dir, f)
versioned_file = os.path.join(self.wiki_dir, self.version_prefix + f)
print 'Updating links in %s.' % (versioned_file,)
text = file(source_file, 'r').read()
new_text = self.search_for_re.sub(self.replace_with, text)
file(versioned_file, 'w').write(new_text)
def main():
if len(sys.argv) != 2:
sys.exit(__doc__)
brancher = WikiBrancher(sys.argv[1])
brancher.BranchFiles()
brancher.UpdateLinksInBranchedFiles()
if __name__ == '__main__':
main()

View File

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

View File

@ -1,59 +0,0 @@
# A Makefile for fusing Google Test and building a sample test against it.
#
# SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make check - makes everything and runs the built sample test.
# make clean - removes all files generated by make.
# Points to the root of fused Google Test, relative to where this file is.
FUSED_GTEST_DIR = output
# Paths to the fused gtest files.
FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h
FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
# Where to find the sample test.
SAMPLE_DIR = ../../samples
# Where to find gtest_main.cc.
GTEST_MAIN_CC = ../../src/gtest_main.cc
# Flags passed to the preprocessor.
# We have no idea here whether pthreads is available in the system, so
# disable its use.
CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0
# Flags passed to the C++ compiler.
CXXFLAGS += -g
all : sample1_unittest
check : all
./sample1_unittest
clean :
rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o
$(FUSED_GTEST_H) :
../fuse_gtest_files.py $(FUSED_GTEST_DIR)
$(FUSED_GTEST_ALL_CC) :
../fuse_gtest_files.py $(FUSED_GTEST_DIR)
gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC)
sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc
sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \
$(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc
sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2009, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""upload_gtest.py v0.1.0 -- uploads a Google Test patch for review.
This simple wrapper passes all command line flags and
--cc=googletestframework@googlegroups.com to upload.py.
USAGE: upload_gtest.py [options for upload.py]
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
CC_FLAG = '--cc='
GTEST_GROUP = 'googletestframework@googlegroups.com'
def main():
# Finds the path to upload.py, assuming it is in the same directory
# as this file.
my_dir = os.path.dirname(os.path.abspath(__file__))
upload_py_path = os.path.join(my_dir, 'upload.py')
# Adds Google Test discussion group to the cc line if it's not there
# already.
upload_py_argv = [upload_py_path]
found_cc_flag = False
for arg in sys.argv[1:]:
if arg.startswith(CC_FLAG):
found_cc_flag = True
cc_line = arg[len(CC_FLAG):]
cc_list = [addr for addr in cc_line.split(',') if addr]
if GTEST_GROUP not in cc_list:
cc_list.append(GTEST_GROUP)
upload_py_argv.append(CC_FLAG + ','.join(cc_list))
else:
upload_py_argv.append(arg)
if not found_cc_flag:
upload_py_argv.append(CC_FLAG + GTEST_GROUP)
# Invokes upload.py with the modified command line flags.
os.execv(upload_py_path, upload_py_argv)
if __name__ == '__main__':
main()

View File

@ -38,7 +38,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
// The following lines pull in the real gtest *.cc files. // The following lines pull in the real gtest *.cc files.
#include "src/gtest.cc" #include "src/gtest-assertion-result.cc"
#include "src/gtest-death-test.cc" #include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc" #include "src/gtest-filepath.cc"
#include "src/gtest-matchers.cc" #include "src/gtest-matchers.cc"
@ -46,3 +46,4 @@
#include "src/gtest-printers.cc" #include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc" #include "src/gtest-test-part.cc"
#include "src/gtest-typed-test.cc" #include "src/gtest-typed-test.cc"
#include "src/gtest.cc"

View File

@ -35,49 +35,49 @@
#include <functional> #include <functional>
#include <utility> #include <utility>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/custom/gtest.h" #include "gtest/internal/custom/gtest.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
# if GTEST_OS_MAC #if GTEST_OS_MAC
# include <crt_externs.h> #include <crt_externs.h>
# endif // GTEST_OS_MAC #endif // GTEST_OS_MAC
# include <errno.h> #include <errno.h>
# include <fcntl.h> #include <fcntl.h>
# include <limits.h> #include <limits.h>
# if GTEST_OS_LINUX #if GTEST_OS_LINUX
# include <signal.h> #include <signal.h>
# endif // GTEST_OS_LINUX #endif // GTEST_OS_LINUX
# include <stdarg.h> #include <stdarg.h>
# if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# include <windows.h> #include <windows.h>
# else #else
# include <sys/mman.h> #include <sys/mman.h>
# include <sys/wait.h> #include <sys/wait.h>
# endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
# if GTEST_OS_QNX #if GTEST_OS_QNX
# include <spawn.h> #include <spawn.h>
# endif // GTEST_OS_QNX #endif // GTEST_OS_QNX
# if GTEST_OS_FUCHSIA #if GTEST_OS_FUCHSIA
# include <lib/fdio/fd.h> #include <lib/fdio/fd.h>
# include <lib/fdio/io.h> #include <lib/fdio/io.h>
# include <lib/fdio/spawn.h> #include <lib/fdio/spawn.h>
# include <lib/zx/channel.h> #include <lib/zx/channel.h>
# include <lib/zx/port.h> #include <lib/zx/port.h>
# include <lib/zx/process.h> #include <lib/zx/process.h>
# include <lib/zx/socket.h> #include <lib/zx/socket.h>
# include <zircon/processargs.h> #include <zircon/processargs.h>
# include <zircon/syscalls.h> #include <zircon/syscalls.h>
# include <zircon/syscalls/policy.h> #include <zircon/syscalls/policy.h>
# include <zircon/syscalls/port.h> #include <zircon/syscalls/port.h>
# endif // GTEST_OS_FUCHSIA #endif // GTEST_OS_FUCHSIA
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
@ -96,9 +96,12 @@ namespace testing {
// used internally at Google, is "threadsafe". // used internally at Google, is "threadsafe".
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
} // namespace testing
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
death_test_style, death_test_style,
internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), testing::internal::StringFromGTestEnv("death_test_style",
testing::kDefaultDeathTestStyle),
"Indicates how to run a death test in a forked child process: " "Indicates how to run a death test in a forked child process: "
"\"threadsafe\" (child process re-executes the test binary " "\"threadsafe\" (child process re-executes the test binary "
"from the beginning, running only the specific death test) or " "from the beginning, running only the specific death test) or "
@ -107,7 +110,7 @@ GTEST_DEFINE_string_(
GTEST_DEFINE_bool_( GTEST_DEFINE_bool_(
death_test_use_fork, death_test_use_fork,
internal::BoolFromGTestEnv("death_test_use_fork", false), testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
"Instructs to use fork()/_exit() instead of clone() in death tests. " "Instructs to use fork()/_exit() instead of clone() in death tests. "
"Ignored and always uses fork() on POSIX systems where clone() is not " "Ignored and always uses fork() on POSIX systems where clone() is not "
"implemented. Useful when running under valgrind or similar tools if " "implemented. Useful when running under valgrind or similar tools if "
@ -117,7 +120,6 @@ GTEST_DEFINE_bool_(
"work in 99% of the cases. Once valgrind is fixed, this flag will " "work in 99% of the cases. Once valgrind is fixed, this flag will "
"most likely be removed."); "most likely be removed.");
namespace internal {
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
internal_run_death_test, "", internal_run_death_test, "",
"Indicates the file, line number, temporal index of " "Indicates the file, line number, temporal index of "
@ -126,7 +128,8 @@ GTEST_DEFINE_string_(
"the '|' characters. This flag is specified if and only if the " "the '|' characters. This flag is specified if and only if the "
"current process is a sub-process launched for running a thread-safe " "current process is a sub-process launched for running a thread-safe "
"death test. FOR INTERNAL USE ONLY."); "death test. FOR INTERNAL USE ONLY.");
} // namespace internal
namespace testing {
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
@ -134,9 +137,9 @@ namespace internal {
// Valid only for fast death tests. Indicates the code is running in the // Valid only for fast death tests. Indicates the code is running in the
// child process of a fast style death test. // child process of a fast style death test.
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA #if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
static bool g_in_fast_death_test_child = false; static bool g_in_fast_death_test_child = false;
# endif #endif
// Returns a Boolean value indicating whether the caller is currently // Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as // executing in the context of the death test child process. Tools such as
@ -144,16 +147,16 @@ static bool g_in_fast_death_test_child = false;
// tests. IMPORTANT: This is an internal utility. Using it may break the // tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it. // implementation of death tests. User code MUST NOT use it.
bool InDeathTestChild() { bool InDeathTestChild() {
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA #if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
// On Windows and Fuchsia, death tests are thread-safe regardless of the value // On Windows and Fuchsia, death tests are thread-safe regardless of the value
// of the death_test_style flag. // of the death_test_style flag.
return !GTEST_FLAG(internal_run_death_test).empty(); return !GTEST_FLAG_GET(internal_run_death_test).empty();
# else #else
if (GTEST_FLAG(death_test_style) == "threadsafe") if (GTEST_FLAG_GET(death_test_style) == "threadsafe")
return !GTEST_FLAG(internal_run_death_test).empty(); return !GTEST_FLAG_GET(internal_run_death_test).empty();
else else
return g_in_fast_death_test_child; return g_in_fast_death_test_child;
#endif #endif
@ -162,40 +165,38 @@ bool InDeathTestChild() {
} // namespace internal } // namespace internal
// ExitedWithCode constructor. // ExitedWithCode constructor.
ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {}
}
// ExitedWithCode function-call operator. // ExitedWithCode function-call operator.
bool ExitedWithCode::operator()(int exit_status) const { bool ExitedWithCode::operator()(int exit_status) const {
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA #if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
return exit_status == exit_code_; return exit_status == exit_code_;
# else #else
return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA #endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
} }
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA #if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// KilledBySignal constructor. // KilledBySignal constructor.
KilledBySignal::KilledBySignal(int signum) : signum_(signum) { KilledBySignal::KilledBySignal(int signum) : signum_(signum) {}
}
// KilledBySignal function-call operator. // KilledBySignal function-call operator.
bool KilledBySignal::operator()(int exit_status) const { bool KilledBySignal::operator()(int exit_status) const {
# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) #if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
{ {
bool result; bool result;
if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) {
return result; return result;
} }
} }
# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) #endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
} }
# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA #endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
namespace internal { namespace internal {
@ -206,23 +207,23 @@ namespace internal {
static std::string ExitSummary(int exit_code) { static std::string ExitSummary(int exit_code) {
Message m; Message m;
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA #if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
m << "Exited with exit status " << exit_code; m << "Exited with exit status " << exit_code;
# else #else
if (WIFEXITED(exit_code)) { if (WIFEXITED(exit_code)) {
m << "Exited with exit status " << WEXITSTATUS(exit_code); m << "Exited with exit status " << WEXITSTATUS(exit_code);
} else if (WIFSIGNALED(exit_code)) { } else if (WIFSIGNALED(exit_code)) {
m << "Terminated by signal " << WTERMSIG(exit_code); m << "Terminated by signal " << WTERMSIG(exit_code);
} }
# ifdef WCOREDUMP #ifdef WCOREDUMP
if (WCOREDUMP(exit_code)) { if (WCOREDUMP(exit_code)) {
m << " (core dumped)"; m << " (core dumped)";
} }
# endif #endif
# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA #endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
return m.GetString(); return m.GetString();
} }
@ -233,7 +234,7 @@ bool ExitedUnsuccessfully(int exit_status) {
return !ExitedWithCode(0)(exit_status); return !ExitedWithCode(0)(exit_status);
} }
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA #if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Generates a textual failure message when a death test finds more than // Generates a textual failure message when a death test finds more than
// one thread running, or cannot determine the number of threads, prior // one thread running, or cannot determine the number of threads, prior
// to executing the given statement. It is the responsibility of the // to executing the given statement. It is the responsibility of the
@ -254,7 +255,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
<< " this is the last message you see before your test times out."; << " this is the last message you see before your test times out.";
return msg.GetString(); return msg.GetString();
} }
# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA #endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Flag characters for reporting a death test that did not die. // Flag characters for reporting a death test that did not die.
static const char kDeathTestLived = 'L'; static const char kDeathTestLived = 'L';
@ -304,13 +305,13 @@ static void DeathTestAbort(const std::string& message) {
// A replacement for CHECK that calls DeathTestAbort if the assertion // A replacement for CHECK that calls DeathTestAbort if the assertion
// fails. // fails.
# define GTEST_DEATH_TEST_CHECK_(expression) \ #define GTEST_DEATH_TEST_CHECK_(expression) \
do { \ do { \
if (!::testing::internal::IsTrue(expression)) { \ if (!::testing::internal::IsTrue(expression)) { \
DeathTestAbort( \ DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \
::std::string("CHECK failed: File ") + __FILE__ + ", line " \ ", line " + \
+ ::testing::internal::StreamableToString(__LINE__) + ": " \ ::testing::internal::StreamableToString(__LINE__) + \
+ #expression); \ ": " + #expression); \
} \ } \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
@ -321,17 +322,17 @@ static void DeathTestAbort(const std::string& message) {
// evaluates the expression as long as it evaluates to -1 and sets // evaluates the expression as long as it evaluates to -1 and sets
// errno to EINTR. If the expression evaluates to -1 but errno is // errno to EINTR. If the expression evaluates to -1 but errno is
// something other than EINTR, DeathTestAbort is called. // something other than EINTR, DeathTestAbort is called.
# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ #define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \
do { \ do { \
int gtest_retval; \ int gtest_retval; \
do { \ do { \
gtest_retval = (expression); \ gtest_retval = (expression); \
} while (gtest_retval == -1 && errno == EINTR); \ } while (gtest_retval == -1 && errno == EINTR); \
if (gtest_retval == -1) { \ if (gtest_retval == -1) { \
DeathTestAbort( \ DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \
::std::string("CHECK failed: File ") + __FILE__ + ", line " \ ", line " + \
+ ::testing::internal::StreamableToString(__LINE__) + ": " \ ::testing::internal::StreamableToString(__LINE__) + \
+ #expression + " != -1"); \ ": " + #expression + " != -1"); \
} \ } \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
@ -370,7 +371,8 @@ static void FailFromInternalError(int fd) {
DeathTest::DeathTest() { DeathTest::DeathTest() {
TestInfo* const info = GetUnitTestImpl()->current_test_info(); TestInfo* const info = GetUnitTestImpl()->current_test_info();
if (info == nullptr) { if (info == nullptr) {
DeathTestAbort("Cannot run a death test outside of a TEST or " DeathTestAbort(
"Cannot run a death test outside of a TEST or "
"TEST_F construct"); "TEST_F construct");
} }
} }
@ -500,9 +502,7 @@ void DeathTestImpl::ReadAndInterpretStatusByte() {
set_read_fd(-1); set_read_fd(-1);
} }
std::string DeathTestImpl::GetErrorLogs() { std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
return GetCapturedStderr();
}
// Signals that the death test code which should have exited, didn't. // Signals that the death test code which should have exited, didn't.
// Should be called only in a death test child process. // Should be called only in a death test child process.
@ -512,9 +512,9 @@ void DeathTestImpl::Abort(AbortReason reason) {
// The parent process considers the death test to be a failure if // 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 // it finds any data in our pipe. So, here we write a single flag byte
// to the pipe, then exit. // to the pipe, then exit.
const char status_ch = const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived
reason == TEST_DID_NOT_DIE ? kDeathTestLived : : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew
reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; : kDeathTestReturned;
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
// We are leaking the descriptor here because on some platforms (i.e., // We are leaking the descriptor here because on some platforms (i.e.,
@ -533,7 +533,7 @@ void DeathTestImpl::Abort(AbortReason reason) {
// much easier. // much easier.
static ::std::string FormatDeathTestOutput(const ::std::string& output) { static ::std::string FormatDeathTestOutput(const ::std::string& output) {
::std::string ret; ::std::string ret;
for (size_t at = 0; ; ) { for (size_t at = 0;;) {
const size_t line_end = output.find('\n', at); const size_t line_end = output.find('\n', at);
ret += "[ DEATH ] "; ret += "[ DEATH ] ";
if (line_end == ::std::string::npos) { if (line_end == ::std::string::npos) {
@ -568,8 +568,7 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) {
// the first failing condition, in the order given above, is the one that is // the first failing condition, in the order given above, is the one that is
// reported. Also sets the last death test message string. // reported. Also sets the last death test message string.
bool DeathTestImpl::Passed(bool status_ok) { bool DeathTestImpl::Passed(bool status_ok) {
if (!spawned()) if (!spawned()) return false;
return false;
const std::string error_message = GetErrorLogs(); const std::string error_message = GetErrorLogs();
@ -580,15 +579,18 @@ bool DeathTestImpl::Passed(bool status_ok) {
switch (outcome()) { switch (outcome()) {
case LIVED: case LIVED:
buffer << " Result: failed to die.\n" buffer << " Result: failed to die.\n"
<< " Error msg:\n" << FormatDeathTestOutput(error_message); << " Error msg:\n"
<< FormatDeathTestOutput(error_message);
break; break;
case THREW: case THREW:
buffer << " Result: threw an exception.\n" buffer << " Result: threw an exception.\n"
<< " Error msg:\n" << FormatDeathTestOutput(error_message); << " Error msg:\n"
<< FormatDeathTestOutput(error_message);
break; break;
case RETURNED: case RETURNED:
buffer << " Result: illegal return in test statement.\n" buffer << " Result: illegal return in test statement.\n"
<< " Error msg:\n" << FormatDeathTestOutput(error_message); << " Error msg:\n"
<< FormatDeathTestOutput(error_message);
break; break;
case DIED: case DIED:
if (status_ok) { if (status_ok) {
@ -605,7 +607,8 @@ bool DeathTestImpl::Passed(bool status_ok) {
} else { } else {
buffer << " Result: died but not with expected exit code:\n" buffer << " Result: died but not with expected exit code:\n"
<< " " << ExitSummary(status()) << "\n" << " " << ExitSummary(status()) << "\n"
<< "Actual msg:\n" << FormatDeathTestOutput(error_message); << "Actual msg:\n"
<< FormatDeathTestOutput(error_message);
} }
break; break;
case IN_PROGRESS: case IN_PROGRESS:
@ -618,7 +621,7 @@ bool DeathTestImpl::Passed(bool status_ok) {
return success; return success;
} }
# if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// WindowsDeathTest implements death tests on Windows. Due to the // WindowsDeathTest implements death tests on Windows. Due to the
// specifics of starting new processes on Windows, death tests there are // specifics of starting new processes on Windows, death tests there are
// always threadsafe, and Google Test considers the // always threadsafe, and Google Test considers the
@ -679,14 +682,12 @@ class WindowsDeathTest : public DeathTestImpl {
// status, or 0 if no child process exists. As a side effect, sets the // status, or 0 if no child process exists. As a side effect, sets the
// outcome data member. // outcome data member.
int WindowsDeathTest::Wait() { int WindowsDeathTest::Wait() {
if (!spawned()) if (!spawned()) return 0;
return 0;
// Wait until the child either signals that it has acquired the write end // Wait until the child either signals that it has acquired the write end
// of the pipe or it dies. // of the pipe or it dies.
const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()};
switch (::WaitForMultipleObjects(2, switch (::WaitForMultipleObjects(2, wait_handles,
wait_handles,
FALSE, // Waits for any of the handles. FALSE, // Waits for any of the handles.
INFINITE)) { INFINITE)) {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
@ -707,9 +708,8 @@ int WindowsDeathTest::Wait() {
// returns immediately if the child has already exited, regardless of // returns immediately if the child has already exited, regardless of
// whether previous calls to WaitForMultipleObjects synchronized on this // whether previous calls to WaitForMultipleObjects synchronized on this
// handle or not. // handle or not.
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(WAIT_OBJECT_0 ==
WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), ::WaitForSingleObject(child_handle_.Get(), INFINITE));
INFINITE));
DWORD status_code; DWORD status_code;
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(
::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);
@ -742,12 +742,12 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES), SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),
nullptr, TRUE}; nullptr, TRUE};
HANDLE read_handle, write_handle; HANDLE read_handle, write_handle;
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle,
::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, &handles_are_inheritable,
0) // Default buffer size. 0) // Default buffer size.
!= FALSE); != FALSE);
set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), set_read_fd(
O_RDONLY)); ::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), O_RDONLY));
write_handle_.Reset(write_handle); write_handle_.Reset(write_handle);
event_handle_.Reset(::CreateEvent( event_handle_.Reset(::CreateEvent(
&handles_are_inheritable, &handles_are_inheritable,
@ -756,27 +756,26 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
nullptr)); // The even is unnamed. nullptr)); // The even is unnamed.
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr); GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
kFilterFlag + "=" + info->test_suite_name() + "filter=" + info->test_suite_name() + "." +
"." + info->name(); info->name();
const std::string internal_flag = const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + std::string("--") + GTEST_FLAG_PREFIX_ +
"=" + file_ + "|" + StreamableToString(line_) + "|" + "internal_run_death_test=" + file_ + "|" + StreamableToString(line_) +
StreamableToString(death_test_index) + "|" + "|" + StreamableToString(death_test_index) + "|" +
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) + StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
// size_t has the same width as pointers on both 32-bit and 64-bit // size_t has the same width as pointers on both 32-bit and 64-bit
// Windows platforms. // Windows platforms.
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
"|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get())); StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
char executable_path[_MAX_PATH + 1]; // NOLINT char executable_path[_MAX_PATH + 1]; // NOLINT
GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr, GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
executable_path, executable_path,
_MAX_PATH)); _MAX_PATH));
std::string command_line = std::string command_line = std::string(::GetCommandLineA()) + " " +
std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + filter_flag + " \"" + internal_flag + "\"";
internal_flag + "\"";
DeathTest::set_last_death_test_message(""); DeathTest::set_last_death_test_message("");
@ -796,8 +795,8 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
GTEST_DEATH_TEST_CHECK_( GTEST_DEATH_TEST_CHECK_(
::CreateProcessA( ::CreateProcessA(
executable_path, const_cast<char*>(command_line.c_str()), executable_path, const_cast<char*>(command_line.c_str()),
nullptr, // Retuned process handle is not inheritable. nullptr, // Returned process handle is not inheritable.
nullptr, // Retuned thread handle is not inheritable. nullptr, // Returned thread handle is not inheritable.
TRUE, // Child inherits all inheritable handles (for write_handle_). TRUE, // Child inherits all inheritable handles (for write_handle_).
0x0, // Default creation flags. 0x0, // Default creation flags.
nullptr, // Inherit the parent's environment. nullptr, // Inherit the parent's environment.
@ -809,7 +808,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
return OVERSEE_TEST; return OVERSEE_TEST;
} }
# elif GTEST_OS_FUCHSIA #elif GTEST_OS_FUCHSIA
class FuchsiaDeathTest : public DeathTestImpl { class FuchsiaDeathTest : public DeathTestImpl {
public: public:
@ -855,18 +854,13 @@ class Arguments {
template <typename Str> template <typename Str>
void AddArguments(const ::std::vector<Str>& arguments) { void AddArguments(const ::std::vector<Str>& arguments) {
for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
i != arguments.end(); i != arguments.end(); ++i) {
++i) {
args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
} }
} }
char* const* Argv() { char* const* Argv() { return &args_[0]; }
return &args_[0];
}
int size() { int size() { return static_cast<int>(args_.size()) - 1; }
return static_cast<int>(args_.size()) - 1;
}
private: private:
std::vector<char*> args_; std::vector<char*> args_;
@ -880,8 +874,7 @@ int FuchsiaDeathTest::Wait() {
const int kSocketKey = 1; const int kSocketKey = 1;
const int kExceptionKey = 2; const int kExceptionKey = 2;
if (!spawned()) if (!spawned()) return 0;
return 0;
// Create a port to wait for socket/task/exception events. // Create a port to wait for socket/task/exception events.
zx_status_t status_zx; zx_status_t status_zx;
@ -890,8 +883,8 @@ int FuchsiaDeathTest::Wait() {
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Register to wait for the child process to terminate. // Register to wait for the child process to terminate.
status_zx = child_process_.wait_async( status_zx =
port, kProcessKey, ZX_PROCESS_TERMINATED, 0); child_process_.wait_async(port, kProcessKey, ZX_PROCESS_TERMINATED, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Register to wait for the socket to be readable or closed. // Register to wait for the socket to be readable or closed.
@ -900,8 +893,8 @@ int FuchsiaDeathTest::Wait() {
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Register to wait for an exception. // Register to wait for an exception.
status_zx = exception_channel_.wait_async( status_zx = exception_channel_.wait_async(port, kExceptionKey,
port, kExceptionKey, ZX_CHANNEL_READABLE, 0); ZX_CHANNEL_READABLE, 0);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
bool process_terminated = false; bool process_terminated = false;
@ -931,9 +924,9 @@ int FuchsiaDeathTest::Wait() {
size_t old_length = captured_stderr_.length(); size_t old_length = captured_stderr_.length();
size_t bytes_read = 0; size_t bytes_read = 0;
captured_stderr_.resize(old_length + kBufferSize); captured_stderr_.resize(old_length + kBufferSize);
status_zx = stderr_socket_.read( status_zx =
0, &captured_stderr_.front() + old_length, kBufferSize, stderr_socket_.read(0, &captured_stderr_.front() + old_length,
&bytes_read); kBufferSize, &bytes_read);
captured_stderr_.resize(old_length + bytes_read); captured_stderr_.resize(old_length + bytes_read);
} while (status_zx == ZX_OK); } while (status_zx == ZX_OK);
if (status_zx == ZX_ERR_PEER_CLOSED) { if (status_zx == ZX_ERR_PEER_CLOSED) {
@ -987,13 +980,12 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
// Build the child process command line. // Build the child process command line.
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
kFilterFlag + "=" + info->test_suite_name() + "filter=" + info->test_suite_name() + "." +
"." + info->name(); info->name();
const std::string internal_flag = const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" kInternalRunDeathTestFlag + "=" + file_ +
+ file_ + "|" "|" + StreamableToString(line_) + "|" +
+ StreamableToString(line_) + "|" StreamableToString(death_test_index);
+ StreamableToString(death_test_index);
Arguments args; Arguments args;
args.AddArguments(GetInjectableArgvs()); args.AddArguments(GetInjectableArgvs());
args.AddArgument(filter_flag.c_str()); args.AddArgument(filter_flag.c_str());
@ -1016,8 +1008,7 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
// Create a socket pair will be used to receive the child process' stderr. // Create a socket pair will be used to receive the child process' stderr.
zx::socket stderr_producer_socket; zx::socket stderr_producer_socket;
status = status = zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);
zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);
GTEST_DEATH_TEST_CHECK_(status >= 0); GTEST_DEATH_TEST_CHECK_(status >= 0);
int stderr_producer_fd = -1; int stderr_producer_fd = -1;
status = status =
@ -1034,35 +1025,32 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
// Create a child job. // Create a child job.
zx_handle_t child_job = ZX_HANDLE_INVALID; zx_handle_t child_job = ZX_HANDLE_INVALID;
status = zx_job_create(zx_job_default(), 0, & child_job); status = zx_job_create(zx_job_default(), 0, &child_job);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
zx_policy_basic_t policy; zx_policy_basic_t policy;
policy.condition = ZX_POL_NEW_ANY; policy.condition = ZX_POL_NEW_ANY;
policy.policy = ZX_POL_ACTION_ALLOW; policy.policy = ZX_POL_ACTION_ALLOW;
status = zx_job_set_policy( status = zx_job_set_policy(child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC,
child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1); &policy, 1);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Create an exception channel attached to the |child_job|, to allow // Create an exception channel attached to the |child_job|, to allow
// us to suppress the system default exception handler from firing. // us to suppress the system default exception handler from firing.
status = status = zx_task_create_exception_channel(
zx_task_create_exception_channel(
child_job, 0, exception_channel_.reset_and_get_address()); child_job, 0, exception_channel_.reset_and_get_address());
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Spawn the child process. // Spawn the child process.
status = fdio_spawn_etc( status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0],
child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr, args.Argv(), nullptr, 2, spawn_actions,
2, spawn_actions, child_process_.reset_and_get_address(), nullptr); child_process_.reset_and_get_address(), nullptr);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
set_spawned(true); set_spawned(true);
return OVERSEE_TEST; return OVERSEE_TEST;
} }
std::string FuchsiaDeathTest::GetErrorLogs() { std::string FuchsiaDeathTest::GetErrorLogs() { return captured_stderr_; }
return captured_stderr_;
}
#else // We are neither on Windows, nor on Fuchsia. #else // We are neither on Windows, nor on Fuchsia.
@ -1093,8 +1081,7 @@ ForkingDeathTest::ForkingDeathTest(const char* a_statement,
// status, or 0 if no child process exists. As a side effect, sets the // status, or 0 if no child process exists. As a side effect, sets the
// outcome data member. // outcome data member.
int ForkingDeathTest::Wait() { int ForkingDeathTest::Wait() {
if (!spawned()) if (!spawned()) return 0;
return 0;
ReadAndInterpretStatusByte(); ReadAndInterpretStatusByte();
@ -1173,11 +1160,11 @@ class ExecDeathTest : public ForkingDeathTest {
private: private:
static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() { static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {
::std::vector<std::string> args = GetInjectableArgvs(); ::std::vector<std::string> args = GetInjectableArgvs();
# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) #if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
::std::vector<std::string> extra_args = ::std::vector<std::string> extra_args =
GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();
args.insert(args.end(), extra_args.begin(), extra_args.end()); args.insert(args.end(), extra_args.begin(), extra_args.end());
# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) #endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
return args; return args;
} }
// The name of the file in which the death test is located. // The name of the file in which the death test is located.
@ -1204,14 +1191,11 @@ class Arguments {
template <typename Str> template <typename Str>
void AddArguments(const ::std::vector<Str>& arguments) { void AddArguments(const ::std::vector<Str>& arguments) {
for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
i != arguments.end(); i != arguments.end(); ++i) {
++i) {
args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
} }
} }
char* const* Argv() { char* const* Argv() { return &args_[0]; }
return &args_[0];
}
private: private:
std::vector<char*> args_; std::vector<char*> args_;
@ -1224,9 +1208,9 @@ struct ExecDeathTestArgs {
int close_fd; // File descriptor to close; the read end of a pipe int close_fd; // File descriptor to close; the read end of a pipe
}; };
# if GTEST_OS_QNX #if GTEST_OS_QNX
extern "C" char** environ; extern "C" char** environ;
# else // GTEST_OS_QNX #else // GTEST_OS_QNX
// The main function for a threadsafe-style death test child process. // The main function for a threadsafe-style death test child process.
// This function is called in a clone()-ed process and thus must avoid // This function is called in a clone()-ed process and thus must avoid
// any potentially unsafe operations like malloc or libc functions. // any potentially unsafe operations like malloc or libc functions.
@ -1241,8 +1225,8 @@ static int ExecDeathTestChildMain(void* child_arg) {
UnitTest::GetInstance()->original_working_dir(); UnitTest::GetInstance()->original_working_dir();
// We can safely call chdir() as it's a direct system call. // We can safely call chdir() as it's a direct system call.
if (chdir(original_dir) != 0) { if (chdir(original_dir) != 0) {
DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + DeathTestAbort(std::string("chdir(\"") + original_dir +
GetLastErrnoDescription()); "\") failed: " + GetLastErrnoDescription());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -1253,13 +1237,12 @@ static int ExecDeathTestChildMain(void* child_arg) {
// one path separator. // one path separator.
execv(args->argv[0], args->argv); execv(args->argv[0], args->argv);
DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " + DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " +
original_dir + " failed: " + original_dir + " failed: " + GetLastErrnoDescription());
GetLastErrnoDescription());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
# endif // GTEST_OS_QNX #endif // GTEST_OS_QNX
# if GTEST_HAS_CLONE #if GTEST_HAS_CLONE
// Two utility routines that together determine the direction the stack // Two utility routines that together determine the direction the stack
// grows. // grows.
// This could be accomplished more elegantly by a single recursive // This could be accomplished more elegantly by a single recursive
@ -1293,7 +1276,7 @@ static bool StackGrowsDown() {
StackLowerThanAddress(&dummy, &result); StackLowerThanAddress(&dummy, &result);
return result; return result;
} }
# endif // GTEST_HAS_CLONE #endif // GTEST_HAS_CLONE
// Spawns a child process with the same executable as the current process in // Spawns a child process with the same executable as the current process in
// a thread-safe manner and instructs it to run the death test. The // a thread-safe manner and instructs it to run the death test. The
@ -1303,10 +1286,10 @@ static bool StackGrowsDown() {
// spawn(2) there instead. The function dies with an error message if // spawn(2) there instead. The function dies with an error message if
// anything goes wrong. // anything goes wrong.
static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
ExecDeathTestArgs args = { argv, close_fd }; ExecDeathTestArgs args = {argv, close_fd};
pid_t child_pid = -1; pid_t child_pid = -1;
# if GTEST_OS_QNX #if GTEST_OS_QNX
// Obtains the current directory and sets it to be closed in the child // Obtains the current directory and sets it to be closed in the child
// process. // process.
const int cwd_fd = open(".", O_RDONLY); const int cwd_fd = open(".", O_RDONLY);
@ -1319,16 +1302,16 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
UnitTest::GetInstance()->original_working_dir(); UnitTest::GetInstance()->original_working_dir();
// We can safely call chdir() as it's a direct system call. // We can safely call chdir() as it's a direct system call.
if (chdir(original_dir) != 0) { if (chdir(original_dir) != 0) {
DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + DeathTestAbort(std::string("chdir(\"") + original_dir +
GetLastErrnoDescription()); "\") failed: " + GetLastErrnoDescription());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
int fd_flags; int fd_flags;
// Set close_fd to be closed after spawn. // 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_(fd_flags = fcntl(close_fd, F_GETFD));
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, GTEST_DEATH_TEST_CHECK_SYSCALL_(
fd_flags | FD_CLOEXEC)); fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC));
struct inheritance inherit = {0}; struct inheritance inherit = {0};
// spawn is a system call. // spawn is a system call.
child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ); child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ);
@ -1336,8 +1319,8 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
# else // GTEST_OS_QNX #else // GTEST_OS_QNX
# if GTEST_OS_LINUX #if GTEST_OS_LINUX
// When a SIGPROF signal is received while fork() or clone() are executing, // 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 // the process may hang. To avoid this, we ignore SIGPROF here and re-enable
// it after the call to fork()/clone() is complete. // it after the call to fork()/clone() is complete.
@ -1346,12 +1329,12 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));
sigemptyset(&ignore_sigprof_action.sa_mask); sigemptyset(&ignore_sigprof_action.sa_mask);
ignore_sigprof_action.sa_handler = SIG_IGN; ignore_sigprof_action.sa_handler = SIG_IGN;
GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( GTEST_DEATH_TEST_CHECK_SYSCALL_(
SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); sigaction(SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));
# endif // GTEST_OS_LINUX #endif // GTEST_OS_LINUX
# if GTEST_HAS_CLONE #if GTEST_HAS_CLONE
const bool use_fork = GTEST_FLAG(death_test_use_fork); const bool use_fork = GTEST_FLAG_GET(death_test_use_fork);
if (!use_fork) { if (!use_fork) {
static const bool stack_grows_down = StackGrowsDown(); static const bool stack_grows_down = StackGrowsDown();
@ -1379,19 +1362,19 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
} }
# else #else
const bool use_fork = true; const bool use_fork = true;
# endif // GTEST_HAS_CLONE #endif // GTEST_HAS_CLONE
if (use_fork && (child_pid = fork()) == 0) { if (use_fork && (child_pid = fork()) == 0) {
ExecDeathTestChildMain(&args); ExecDeathTestChildMain(&args);
_exit(0); _exit(0);
} }
# endif // GTEST_OS_QNX #endif // GTEST_OS_QNX
# if GTEST_OS_LINUX #if GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_SYSCALL_( GTEST_DEATH_TEST_CHECK_SYSCALL_(
sigaction(SIGPROF, &saved_sigprof_action, nullptr)); sigaction(SIGPROF, &saved_sigprof_action, nullptr));
# endif // GTEST_OS_LINUX #endif // GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_(child_pid != -1); GTEST_DEATH_TEST_CHECK_(child_pid != -1);
return child_pid; return child_pid;
@ -1420,13 +1403,13 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
kFilterFlag + "=" + info->test_suite_name() + "filter=" + info->test_suite_name() + "." +
"." + info->name(); info->name();
const std::string internal_flag = const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" "internal_run_death_test=" + file_ + "|" +
+ file_ + "|" + StreamableToString(line_) + "|" StreamableToString(line_) + "|" +
+ StreamableToString(death_test_index) + "|" StreamableToString(death_test_index) + "|" +
+ StreamableToString(pipe_fd[1]); StreamableToString(pipe_fd[1]);
Arguments args; Arguments args;
args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArguments(GetArgvsForDeathTestChildProcess());
args.AddArgument(filter_flag.c_str()); args.AddArgument(filter_flag.c_str());
@ -1447,7 +1430,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
return OVERSEE_TEST; return OVERSEE_TEST;
} }
# endif // !GTEST_OS_WINDOWS #endif // !GTEST_OS_WINDOWS
// Creates a concrete DeathTest-derived class that depends on the // Creates a concrete DeathTest-derived class that depends on the
// --gtest_death_test_style flag, and sets the pointer pointed to // --gtest_death_test_style flag, and sets the pointer pointed to
@ -1461,15 +1444,15 @@ bool DefaultDeathTestFactory::Create(const char* statement,
UnitTestImpl* const impl = GetUnitTestImpl(); UnitTestImpl* const impl = GetUnitTestImpl();
const InternalRunDeathTestFlag* const flag = const InternalRunDeathTestFlag* const flag =
impl->internal_run_death_test_flag(); impl->internal_run_death_test_flag();
const int death_test_index = impl->current_test_info() const int death_test_index =
->increment_death_test_count(); impl->current_test_info()->increment_death_test_count();
if (flag != nullptr) { if (flag != nullptr) {
if (death_test_index > flag->index()) { if (death_test_index > flag->index()) {
DeathTest::set_last_death_test_message( DeathTest::set_last_death_test_message(
"Death test count (" + StreamableToString(death_test_index) "Death test count (" + StreamableToString(death_test_index) +
+ ") somehow exceeded expected maximum (" ") somehow exceeded expected maximum (" +
+ StreamableToString(flag->index()) + ")"); StreamableToString(flag->index()) + ")");
return false; return false;
} }
@ -1480,41 +1463,41 @@ bool DefaultDeathTestFactory::Create(const char* statement,
} }
} }
# if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
if (GTEST_FLAG(death_test_style) == "threadsafe" || if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
GTEST_FLAG(death_test_style) == "fast") { GTEST_FLAG_GET(death_test_style) == "fast") {
*test = new WindowsDeathTest(statement, std::move(matcher), file, line); *test = new WindowsDeathTest(statement, std::move(matcher), file, line);
} }
# elif GTEST_OS_FUCHSIA #elif GTEST_OS_FUCHSIA
if (GTEST_FLAG(death_test_style) == "threadsafe" || if (GTEST_FLAG_GET(death_test_style) == "threadsafe" ||
GTEST_FLAG(death_test_style) == "fast") { GTEST_FLAG_GET(death_test_style) == "fast") {
*test = new FuchsiaDeathTest(statement, std::move(matcher), file, line); *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
} }
# else #else
if (GTEST_FLAG(death_test_style) == "threadsafe") { if (GTEST_FLAG_GET(death_test_style) == "threadsafe") {
*test = new ExecDeathTest(statement, std::move(matcher), file, line); *test = new ExecDeathTest(statement, std::move(matcher), file, line);
} else if (GTEST_FLAG(death_test_style) == "fast") { } else if (GTEST_FLAG_GET(death_test_style) == "fast") {
*test = new NoExecDeathTest(statement, std::move(matcher)); *test = new NoExecDeathTest(statement, std::move(matcher));
} }
# endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
else { // NOLINT - this is more readable than unbalanced brackets inside #if. else { // NOLINT - this is more readable than unbalanced brackets inside #if.
DeathTest::set_last_death_test_message( DeathTest::set_last_death_test_message("Unknown death test style \"" +
"Unknown death test style \"" + GTEST_FLAG(death_test_style) GTEST_FLAG_GET(death_test_style) +
+ "\" encountered"); "\" encountered");
return false; return false;
} }
return true; return true;
} }
# if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// Recreates the pipe and event handles from the provided parameters, // Recreates the pipe and event handles from the provided parameters,
// signals the event, and returns a file descriptor wrapped around the pipe // signals the event, and returns a file descriptor wrapped around the pipe
// handle. This function is called in the child process only. // handle. This function is called in the child process only.
@ -1531,8 +1514,7 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
const HANDLE write_handle = const HANDLE write_handle = reinterpret_cast<HANDLE>(write_handle_as_size_t);
reinterpret_cast<HANDLE>(write_handle_as_size_t);
HANDLE dup_write_handle; HANDLE dup_write_handle;
// The newly initialized handle is accessible only in the parent // The newly initialized handle is accessible only in the parent
@ -1554,9 +1536,7 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
HANDLE dup_event_handle; HANDLE dup_event_handle;
if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
::GetCurrentProcess(), &dup_event_handle, ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE,
0x0,
FALSE,
DUPLICATE_SAME_ACCESS)) { DUPLICATE_SAME_ACCESS)) {
DeathTestAbort("Unable to duplicate the event handle " + DeathTestAbort("Unable to duplicate the event handle " +
StreamableToString(event_handle_as_size_t) + StreamableToString(event_handle_as_size_t) +
@ -1578,61 +1558,57 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
return write_fd; return write_fd;
} }
# endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
// Returns a newly created InternalRunDeathTestFlag object with fields // Returns a newly created InternalRunDeathTestFlag object with fields
// initialized from the GTEST_FLAG(internal_run_death_test) flag if // initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL. // the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
if (GTEST_FLAG(internal_run_death_test) == "") return nullptr; if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr;
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
// can use it here. // can use it here.
int line = -1; int line = -1;
int index = -1; int index = -1;
::std::vector< ::std::string> fields; ::std::vector< ::std::string> fields;
SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);
int write_fd = -1; int write_fd = -1;
# if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
unsigned int parent_process_id = 0; unsigned int parent_process_id = 0;
size_t write_handle_as_size_t = 0; size_t write_handle_as_size_t = 0;
size_t event_handle_as_size_t = 0; size_t event_handle_as_size_t = 0;
if (fields.size() != 6 if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) ||
|| !ParseNaturalNumber(fields[1], &line) !ParseNaturalNumber(fields[2], &index) ||
|| !ParseNaturalNumber(fields[2], &index) !ParseNaturalNumber(fields[3], &parent_process_id) ||
|| !ParseNaturalNumber(fields[3], &parent_process_id) !ParseNaturalNumber(fields[4], &write_handle_as_size_t) ||
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t) !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
GTEST_FLAG(internal_run_death_test)); GTEST_FLAG_GET(internal_run_death_test));
} }
write_fd = GetStatusFileDescriptor(parent_process_id, write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t,
write_handle_as_size_t,
event_handle_as_size_t); event_handle_as_size_t);
# elif GTEST_OS_FUCHSIA #elif GTEST_OS_FUCHSIA
if (fields.size() != 3 if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) ||
|| !ParseNaturalNumber(fields[1], &line) !ParseNaturalNumber(fields[2], &index)) {
|| !ParseNaturalNumber(fields[2], &index)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " GTEST_FLAG_GET(internal_run_death_test));
+ GTEST_FLAG(internal_run_death_test));
} }
# else #else
if (fields.size() != 4 if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) ||
|| !ParseNaturalNumber(fields[1], &line) !ParseNaturalNumber(fields[2], &index) ||
|| !ParseNaturalNumber(fields[2], &index) !ParseNaturalNumber(fields[3], &write_fd)) {
|| !ParseNaturalNumber(fields[3], &write_fd)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " +
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " GTEST_FLAG_GET(internal_run_death_test));
+ GTEST_FLAG(internal_run_death_test));
} }
# endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
} }

View File

@ -30,29 +30,31 @@
#include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-filepath.h"
#include <stdlib.h> #include <stdlib.h>
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
# include <windows.h> #include <windows.h>
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
# include <direct.h> #include <direct.h>
# include <io.h> #include <io.h>
#else #else
# include <limits.h> #include <limits.h>
# include <climits> // Some Linux distributions define PATH_MAX here.
#include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# define GTEST_PATH_MAX_ _MAX_PATH #define GTEST_PATH_MAX_ _MAX_PATH
#elif defined(PATH_MAX) #elif defined(PATH_MAX)
# define GTEST_PATH_MAX_ PATH_MAX #define GTEST_PATH_MAX_ PATH_MAX
#elif defined(_XOPEN_PATH_MAX) #elif defined(_XOPEN_PATH_MAX)
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
#else #else
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX #define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
namespace testing { namespace testing {
@ -66,16 +68,16 @@ namespace internal {
const char kPathSeparator = '\\'; const char kPathSeparator = '\\';
const char kAlternatePathSeparator = '/'; const char kAlternatePathSeparator = '/';
const char kAlternatePathSeparatorString[] = "/"; const char kAlternatePathSeparatorString[] = "/";
# if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't have a current directory. You should not use // Windows CE doesn't have a current directory. You should not use
// the current directory in tests on Windows CE, but this at least // the current directory in tests on Windows CE, but this at least
// provides a reasonable fallback. // provides a reasonable fallback.
const char kCurrentDirectoryString[] = "\\"; const char kCurrentDirectoryString[] = "\\";
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES // Windows CE doesn't define INVALID_FILE_ATTRIBUTES
const DWORD kInvalidFileAttributes = 0xffffffff; const DWORD kInvalidFileAttributes = 0xffffffff;
# else #else
const char kCurrentDirectoryString[] = ".\\"; const char kCurrentDirectoryString[] = ".\\";
# endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
#else #else
const char kPathSeparator = '/'; const char kPathSeparator = '/';
const char kCurrentDirectoryString[] = "./"; const char kCurrentDirectoryString[] = "./";
@ -99,17 +101,17 @@ FilePath FilePath::GetCurrentDir() {
// something reasonable. // something reasonable.
return FilePath(kCurrentDirectoryString); return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; char cwd[GTEST_PATH_MAX_ + 1] = {'\0'};
return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd); return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
#else #else
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; char cwd[GTEST_PATH_MAX_ + 1] = {'\0'};
char* result = getcwd(cwd, sizeof(cwd)); char* result = getcwd(cwd, sizeof(cwd));
# if GTEST_OS_NACL #if GTEST_OS_NACL
// getcwd will likely fail in NaCl due to the sandbox, so return something // getcwd will likely fail in NaCl due to the sandbox, so return something
// reasonable. The user may have provided a shim implementation for getcwd, // reasonable. The user may have provided a shim implementation for getcwd,
// however, so fallback only when failure is detected. // however, so fallback only when failure is detected.
return FilePath(result == nullptr ? kCurrentDirectoryString : cwd); return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
# endif // GTEST_OS_NACL #endif // GTEST_OS_NACL
return FilePath(result == nullptr ? "" : cwd); return FilePath(result == nullptr ? "" : cwd);
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
} }
@ -121,8 +123,8 @@ FilePath FilePath::GetCurrentDir() {
FilePath FilePath::RemoveExtension(const char* extension) const { FilePath FilePath::RemoveExtension(const char* extension) const {
const std::string dot_extension = std::string(".") + extension; const std::string dot_extension = std::string(".") + extension;
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
return FilePath(pathname_.substr( return FilePath(
0, pathname_.length() - dot_extension.length())); pathname_.substr(0, pathname_.length() - dot_extension.length()));
} }
return *this; return *this;
} }
@ -178,15 +180,14 @@ FilePath FilePath::RemoveFileName() const {
// than zero (e.g., 12), returns "dir/test_12.xml". // than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /. // On Windows platform, uses \ as the separator rather than /.
FilePath FilePath::MakeFileName(const FilePath& directory, FilePath FilePath::MakeFileName(const FilePath& directory,
const FilePath& base_name, const FilePath& base_name, int number,
int number,
const char* extension) { const char* extension) {
std::string file; std::string file;
if (number == 0) { if (number == 0) {
file = base_name.string() + "." + extension; file = base_name.string() + "." + extension;
} else { } else {
file = base_name.string() + "_" + StreamableToString(number) file =
+ "." + extension; base_name.string() + "_" + StreamableToString(number) + "." + extension;
} }
return ConcatPaths(directory, FilePath(file)); return ConcatPaths(directory, FilePath(file));
} }
@ -195,8 +196,7 @@ FilePath FilePath::MakeFileName(const FilePath& directory,
// On Windows, uses \ as the separator rather than /. // On Windows, uses \ as the separator rather than /.
FilePath FilePath::ConcatPaths(const FilePath& directory, FilePath FilePath::ConcatPaths(const FilePath& directory,
const FilePath& relative_path) { const FilePath& relative_path) {
if (directory.IsEmpty()) if (directory.IsEmpty()) return relative_path;
return relative_path;
const FilePath dir(directory.RemoveTrailingPathSeparator()); const FilePath dir(directory.RemoveTrailingPathSeparator());
return FilePath(dir.string() + kPathSeparator + relative_path.string()); return FilePath(dir.string() + kPathSeparator + relative_path.string());
} }
@ -207,7 +207,7 @@ bool FilePath::FileOrDirectoryExists() const {
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
const DWORD attributes = GetFileAttributes(unicode); const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode; delete[] unicode;
return attributes != kInvalidFileAttributes; return attributes != kInvalidFileAttributes;
#else #else
posix::StatStruct file_stat{}; posix::StatStruct file_stat{};
@ -222,8 +222,8 @@ bool FilePath::DirectoryExists() const {
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// Don't strip off trailing separator if path is a root directory on // Don't strip off trailing separator if path is a root directory on
// Windows (like "C:\\"). // Windows (like "C:\\").
const FilePath& path(IsRootDirectory() ? *this : const FilePath& path(IsRootDirectory() ? *this
RemoveTrailingPathSeparator()); : RemoveTrailingPathSeparator());
#else #else
const FilePath& path(*this); const FilePath& path(*this);
#endif #endif
@ -231,15 +231,15 @@ bool FilePath::DirectoryExists() const {
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
const DWORD attributes = GetFileAttributes(unicode); const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode; delete[] unicode;
if ((attributes != kInvalidFileAttributes) && if ((attributes != kInvalidFileAttributes) &&
(attributes & FILE_ATTRIBUTE_DIRECTORY)) { (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
result = true; result = true;
} }
#else #else
posix::StatStruct file_stat{}; posix::StatStruct file_stat{};
result = posix::Stat(path.c_str(), &file_stat) == 0 && result =
posix::IsDir(file_stat); posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat);
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
return result; return result;
@ -262,8 +262,7 @@ bool FilePath::IsAbsolutePath() const {
return pathname_.length() >= 3 && return pathname_.length() >= 3 &&
((name[0] >= 'a' && name[0] <= 'z') || ((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) && (name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' && name[1] == ':' && IsPathSeparator(name[2]);
IsPathSeparator(name[2]);
#else #else
return IsPathSeparator(name[0]); return IsPathSeparator(name[0]);
#endif #endif
@ -321,7 +320,7 @@ bool FilePath::CreateFolder() const {
FilePath removed_sep(this->RemoveTrailingPathSeparator()); FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
int result = CreateDirectory(unicode, nullptr) ? 0 : -1; int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
delete [] unicode; delete[] unicode;
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str()); int result = _mkdir(pathname_.c_str());
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA #elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA
@ -341,8 +340,7 @@ bool FilePath::CreateFolder() const {
// name, otherwise return the name string unmodified. // name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /. // On Windows platform, uses \ as the separator, other platforms use /.
FilePath FilePath::RemoveTrailingPathSeparator() const { FilePath FilePath::RemoveTrailingPathSeparator() const {
return IsDirectory() return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))
? FilePath(pathname_.substr(0, pathname_.length() - 1))
: *this; : *this;
} }

View File

@ -35,7 +35,7 @@
#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ #define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
# include <errno.h> #include <errno.h>
#endif // !_WIN32_WCE #endif // !_WIN32_WCE
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free. #include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
@ -50,22 +50,20 @@
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#if GTEST_CAN_STREAM_RESULTS_ #if GTEST_CAN_STREAM_RESULTS_
# include <arpa/inet.h> // NOLINT #include <arpa/inet.h> // NOLINT
# include <netdb.h> // NOLINT #include <netdb.h> // NOLINT
#endif #endif
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# include <windows.h> // NOLINT #include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
namespace testing {
// Declares the flags. // Declares the flags.
// //
// We don't want the users to modify this flag in the code, but want // We don't want the users to modify this flag in the code, but want
@ -73,32 +71,13 @@ namespace testing {
// declare it here as opposed to in gtest.h. // declare it here as opposed to in gtest.h.
GTEST_DECLARE_bool_(death_test_use_fork); GTEST_DECLARE_bool_(death_test_use_fork);
namespace testing {
namespace internal { namespace internal {
// The value of GetTestTypeId() as seen from within the Google Test // The value of GetTestTypeId() as seen from within the Google Test
// library. This is solely for testing GetTestTypeId(). // library. This is solely for testing GetTestTypeId().
GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
// Names of the flags (needed for parsing Google Test flags).
const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color";
const char kFailFast[] = "fail_fast";
const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kBriefFlag[] = "brief";
const char kPrintTimeFlag[] = "print_time";
const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
const char kStackTraceDepthFlag[] = "stack_trace_depth";
const char kStreamResultToFlag[] = "stream_result_to";
const char kThrowOnFailureFlag[] = "throw_on_failure";
const char kFlagfileFlag[] = "flagfile";
// A valid random seed must be in [1, kMaxRandomSeed]. // A valid random seed must be in [1, kMaxRandomSeed].
const int kMaxRandomSeed = 99999; const int kMaxRandomSeed = 99999;
@ -125,21 +104,21 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
// //
// On success, stores the value of the flag in *value, and returns // On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value. // true. On failure, returns false without changing *value.
GTEST_API_ bool ParseInt32Flag( GTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value);
const char* str, const char* flag, int32_t* value);
// Returns a random seed in range [1, kMaxRandomSeed] based on the // Returns a random seed in range [1, kMaxRandomSeed] based on the
// given --gtest_random_seed flag value. // given --gtest_random_seed flag value.
inline int GetRandomSeedFromFlag(int32_t random_seed_flag) { inline int GetRandomSeedFromFlag(int32_t random_seed_flag) {
const unsigned int raw_seed = (random_seed_flag == 0) ? const unsigned int raw_seed =
static_cast<unsigned int>(GetTimeInMillis()) : (random_seed_flag == 0) ? static_cast<unsigned int>(GetTimeInMillis())
static_cast<unsigned int>(random_seed_flag); : static_cast<unsigned int>(random_seed_flag);
// Normalizes the actual seed to range [1, kMaxRandomSeed] such that // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
// it's easy to type. // it's easy to type.
const int normalized_seed = const int normalized_seed =
static_cast<int>((raw_seed - 1U) % static_cast<int>((raw_seed - 1U) %
static_cast<unsigned int>(kMaxRandomSeed)) + 1; static_cast<unsigned int>(kMaxRandomSeed)) +
1;
return normalized_seed; return normalized_seed;
} }
@ -160,50 +139,54 @@ class GTestFlagSaver {
public: public:
// The c'tor. // The c'tor.
GTestFlagSaver() { GTestFlagSaver() {
also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);
break_on_failure_ = GTEST_FLAG(break_on_failure); break_on_failure_ = GTEST_FLAG_GET(break_on_failure);
catch_exceptions_ = GTEST_FLAG(catch_exceptions); catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);
color_ = GTEST_FLAG(color); color_ = GTEST_FLAG_GET(color);
death_test_style_ = GTEST_FLAG(death_test_style); death_test_style_ = GTEST_FLAG_GET(death_test_style);
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);
fail_fast_ = GTEST_FLAG(fail_fast); fail_fast_ = GTEST_FLAG_GET(fail_fast);
filter_ = GTEST_FLAG(filter); filter_ = GTEST_FLAG_GET(filter);
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);
list_tests_ = GTEST_FLAG(list_tests); list_tests_ = GTEST_FLAG_GET(list_tests);
output_ = GTEST_FLAG(output); output_ = GTEST_FLAG_GET(output);
brief_ = GTEST_FLAG(brief); brief_ = GTEST_FLAG_GET(brief);
print_time_ = GTEST_FLAG(print_time); print_time_ = GTEST_FLAG_GET(print_time);
print_utf8_ = GTEST_FLAG(print_utf8); print_utf8_ = GTEST_FLAG_GET(print_utf8);
random_seed_ = GTEST_FLAG(random_seed); random_seed_ = GTEST_FLAG_GET(random_seed);
repeat_ = GTEST_FLAG(repeat); repeat_ = GTEST_FLAG_GET(repeat);
shuffle_ = GTEST_FLAG(shuffle); recreate_environments_when_repeating_ =
stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); GTEST_FLAG_GET(recreate_environments_when_repeating);
stream_result_to_ = GTEST_FLAG(stream_result_to); shuffle_ = GTEST_FLAG_GET(shuffle);
throw_on_failure_ = GTEST_FLAG(throw_on_failure); 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. // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
~GTestFlagSaver() { ~GTestFlagSaver() {
GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);
GTEST_FLAG(break_on_failure) = break_on_failure_; GTEST_FLAG_SET(break_on_failure, break_on_failure_);
GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);
GTEST_FLAG(color) = color_; GTEST_FLAG_SET(color, color_);
GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG_SET(death_test_style, death_test_style_);
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);
GTEST_FLAG(filter) = filter_; GTEST_FLAG_SET(filter, filter_);
GTEST_FLAG(fail_fast) = fail_fast_; GTEST_FLAG_SET(fail_fast, fail_fast_);
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);
GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG_SET(list_tests, list_tests_);
GTEST_FLAG(output) = output_; GTEST_FLAG_SET(output, output_);
GTEST_FLAG(brief) = brief_; GTEST_FLAG_SET(brief, brief_);
GTEST_FLAG(print_time) = print_time_; GTEST_FLAG_SET(print_time, print_time_);
GTEST_FLAG(print_utf8) = print_utf8_; GTEST_FLAG_SET(print_utf8, print_utf8_);
GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG_SET(random_seed, random_seed_);
GTEST_FLAG(repeat) = repeat_; GTEST_FLAG_SET(repeat, repeat_);
GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG_SET(recreate_environments_when_repeating,
GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; recreate_environments_when_repeating_);
GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG_SET(shuffle, shuffle_);
GTEST_FLAG(throw_on_failure) = throw_on_failure_; 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: private:
@ -224,6 +207,7 @@ class GTestFlagSaver {
bool print_utf8_; bool print_utf8_;
int32_t random_seed_; int32_t random_seed_;
int32_t repeat_; int32_t repeat_;
bool recreate_environments_when_repeating_;
bool shuffle_; bool shuffle_;
int32_t stack_trace_depth_; int32_t stack_trace_depth_;
std::string stream_result_to_; std::string stream_result_to_;
@ -278,8 +262,8 @@ GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val);
// returns true if and only if the test should be run on this shard. 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 // is some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards. // method. Assumes that 0 <= shard_index < total_shards.
GTEST_API_ bool ShouldRunTestOnShard( GTEST_API_ bool ShouldRunTestOnShard(int total_shards, int shard_index,
int total_shards, int shard_index, int test_id); int test_id);
// STL container utilities. // STL container utilities.
@ -290,9 +274,8 @@ inline int CountIf(const Container& c, Predicate predicate) {
// Implemented as an explicit loop since std::count_if() in libCstd on // Implemented as an explicit loop since std::count_if() in libCstd on
// Solaris has a non-standard signature. // Solaris has a non-standard signature.
int count = 0; int count = 0;
for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { for (auto it = c.begin(); it != c.end(); ++it) {
if (predicate(*it)) if (predicate(*it)) ++count;
++count;
} }
return count; return count;
} }
@ -441,7 +424,9 @@ class OsStackTraceGetterInterface {
static const char* const kElidedFramesMarker; static const char* const kElidedFramesMarker;
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete;
OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) =
delete;
}; };
// A working implementation of the OsStackTraceGetterInterface interface. // A working implementation of the OsStackTraceGetterInterface interface.
@ -463,7 +448,8 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface {
void* caller_frame_ = nullptr; void* caller_frame_ = nullptr;
#endif // GTEST_HAS_ABSL #endif // GTEST_HAS_ABSL
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); OsStackTraceGetter(const OsStackTraceGetter&) = delete;
OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete;
}; };
// Information about a Google Test trace point. // Information about a Google Test trace point.
@ -486,7 +472,10 @@ class DefaultGlobalTestPartResultReporter
private: private:
UnitTestImpl* const unit_test_; UnitTestImpl* const unit_test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); DefaultGlobalTestPartResultReporter(
const DefaultGlobalTestPartResultReporter&) = delete;
DefaultGlobalTestPartResultReporter& operator=(
const DefaultGlobalTestPartResultReporter&) = delete;
}; };
// This is the default per thread test part result reporter used in // This is the default per thread test part result reporter used in
@ -502,7 +491,10 @@ class DefaultPerThreadTestPartResultReporter
private: private:
UnitTestImpl* const unit_test_; UnitTestImpl* const unit_test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); DefaultPerThreadTestPartResultReporter(
const DefaultPerThreadTestPartResultReporter&) = delete;
DefaultPerThreadTestPartResultReporter& operator=(
const DefaultPerThreadTestPartResultReporter&) = delete;
}; };
// The private implementation of the UnitTest class. We don't protect // The private implementation of the UnitTest class. We don't protect
@ -640,7 +632,8 @@ class GTEST_API_ UnitTestImpl {
// For example, if Foo() calls Bar(), which in turn calls // For example, if Foo() calls Bar(), which in turn calls
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
// trace but Bar() and CurrentOsStackTraceExceptTop() won't. // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; 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 // Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it. // exist, creates one and returns it.
@ -744,9 +737,7 @@ class GTEST_API_ UnitTestImpl {
} }
// Clears the results of ad-hoc test assertions. // Clears the results of ad-hoc test assertions.
void ClearAdHocTestResult() { void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); }
ad_hoc_test_result_.Clear();
}
// Adds a TestProperty to the current TestResult object when invoked in a // Adds a TestProperty to the current TestResult object when invoked in a
// context of a test or a test suite, or to the global property set. If the // context of a test or a test suite, or to the global property set. If the
@ -754,10 +745,7 @@ class GTEST_API_ UnitTestImpl {
// updated. // updated.
void RecordProperty(const TestProperty& test_property); void RecordProperty(const TestProperty& test_property);
enum ReactionToSharding { enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL };
HONOR_SHARDING_PROTOCOL,
IGNORE_SHARDING_PROTOCOL
};
// Matches the full name of each test against the user-specified // Matches the full name of each test against the user-specified
// filter to decide whether the test should run, then records the // filter to decide whether the test should run, then records the
@ -963,7 +951,8 @@ class GTEST_API_ UnitTestImpl {
// starts. // starts.
bool catch_exceptions_; bool catch_exceptions_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); UnitTestImpl(const UnitTestImpl&) = delete;
UnitTestImpl& operator=(const UnitTestImpl&) = delete;
}; // class UnitTestImpl }; // class UnitTestImpl
// Convenience function for accessing the global UnitTest // Convenience function for accessing the global UnitTest
@ -986,8 +975,9 @@ GTEST_API_ bool IsValidEscape(char ch);
GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool ValidateRegex(const char* regex);
GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
GTEST_API_ bool MatchRepetitionAndRegexAtHead( GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,
bool escaped, char ch, char repeat, const char* regex, const char* str); char repeat, const char* regex,
const char* str);
GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
#endif // GTEST_USES_SIMPLE_RE #endif // GTEST_USES_SIMPLE_RE
@ -1089,8 +1079,7 @@ class StreamingListener : public EmptyTestEventListener {
} }
~SocketWriter() override { ~SocketWriter() override {
if (sockfd_ != -1) if (sockfd_ != -1) CloseConnection();
CloseConnection();
} }
// Sends a string to the socket. // Sends a string to the socket.
@ -1100,8 +1089,7 @@ class StreamingListener : public EmptyTestEventListener {
const auto len = static_cast<size_t>(message.length()); const auto len = static_cast<size_t>(message.length());
if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) { if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
GTEST_LOG_(WARNING) GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to "
<< "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_; << host_name_ << ":" << port_num_;
} }
} }
@ -1123,7 +1111,8 @@ class StreamingListener : public EmptyTestEventListener {
const std::string host_name_; const std::string host_name_;
const std::string port_num_; const std::string port_num_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); SocketWriter(const SocketWriter&) = delete;
SocketWriter& operator=(const SocketWriter&) = delete;
}; // class SocketWriter }; // class SocketWriter
// Escapes '=', '&', '%', and '\n' characters in str as "%xx". // Escapes '=', '&', '%', and '\n' characters in str as "%xx".
@ -1135,7 +1124,9 @@ class StreamingListener : public EmptyTestEventListener {
} }
explicit StreamingListener(AbstractSocketWriter* socket_writer) explicit StreamingListener(AbstractSocketWriter* socket_writer)
: socket_writer_(socket_writer) { Start(); } : socket_writer_(socket_writer) {
Start();
}
void OnTestProgramStart(const UnitTest& /* unit_test */) override { void OnTestProgramStart(const UnitTest& /* unit_test */) override {
SendLn("event=TestProgramStart"); SendLn("event=TestProgramStart");
@ -1158,22 +1149,22 @@ class StreamingListener : public EmptyTestEventListener {
void OnTestIterationEnd(const UnitTest& unit_test, void OnTestIterationEnd(const UnitTest& unit_test,
int /* iteration */) override { int /* iteration */) override {
SendLn("event=TestIterationEnd&passed=" + SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) +
FormatBool(unit_test.Passed()) + "&elapsed_time=" + "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) +
StreamableToString(unit_test.elapsed_time()) + "ms"); "ms");
} }
// Note that "event=TestCaseStart" is a wire format and has to remain // Note that "event=TestCaseStart" is a wire format and has to remain
// "case" for compatibility // "case" for compatibility
void OnTestCaseStart(const TestCase& test_case) override { void OnTestSuiteStart(const TestSuite& test_suite) override {
SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); SendLn(std::string("event=TestCaseStart&name=") + test_suite.name());
} }
// Note that "event=TestCaseEnd" is a wire format and has to remain // Note that "event=TestCaseEnd" is a wire format and has to remain
// "case" for compatibility // "case" for compatibility
void OnTestCaseEnd(const TestCase& test_case) override { void OnTestSuiteEnd(const TestSuite& test_suite) override {
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_suite.Passed()) +
"&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "&elapsed_time=" + StreamableToString(test_suite.elapsed_time()) +
"ms"); "ms");
} }
@ -1183,8 +1174,7 @@ class StreamingListener : public EmptyTestEventListener {
void OnTestEnd(const TestInfo& test_info) override { void OnTestEnd(const TestInfo& test_info) override {
SendLn("event=TestEnd&passed=" + SendLn("event=TestEnd&passed=" +
FormatBool((test_info.result())->Passed()) + FormatBool((test_info.result())->Passed()) + "&elapsed_time=" +
"&elapsed_time=" +
StreamableToString((test_info.result())->elapsed_time()) + "ms"); StreamableToString((test_info.result())->elapsed_time()) + "ms");
} }
@ -1208,7 +1198,8 @@ class StreamingListener : public EmptyTestEventListener {
const std::unique_ptr<AbstractSocketWriter> socket_writer_; const std::unique_ptr<AbstractSocketWriter> socket_writer_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); StreamingListener(const StreamingListener&) = delete;
StreamingListener& operator=(const StreamingListener&) = delete;
}; // class StreamingListener }; // class StreamingListener
#endif // GTEST_CAN_STREAM_RESULTS_ #endif // GTEST_CAN_STREAM_RESULTS_

View File

@ -32,12 +32,13 @@
// This file implements just enough of the matcher interface to allow // This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument. // EXPECT_DEATH and friends to accept a matcher argument.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-matchers.h" #include "gtest/gtest-matchers.h"
#include <string> #include <string>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
namespace testing { namespace testing {
// Constructs a matcher that matches a const std::string& whose value is // Constructs a matcher that matches a const std::string& whose value is

View File

@ -27,61 +27,62 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <cstdint> #include <cstdint>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# include <windows.h> #include <io.h>
# include <io.h> #include <sys/stat.h>
# include <sys/stat.h> #include <windows.h>
# include <map> // Used in ThreadLocal.
# ifdef _MSC_VER #include <map> // Used in ThreadLocal.
# include <crtdbg.h> #ifdef _MSC_VER
# endif // _MSC_VER #include <crtdbg.h>
#endif // _MSC_VER
#else #else
# include <unistd.h> #include <unistd.h>
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#if GTEST_OS_MAC #if GTEST_OS_MAC
# include <mach/mach_init.h> #include <mach/mach_init.h>
# include <mach/task.h> #include <mach/task.h>
# include <mach/vm_map.h> #include <mach/vm_map.h>
#endif // GTEST_OS_MAC #endif // GTEST_OS_MAC
#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ #if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
GTEST_OS_NETBSD || GTEST_OS_OPENBSD GTEST_OS_NETBSD || GTEST_OS_OPENBSD
# include <sys/sysctl.h> #include <sys/sysctl.h>
# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD #if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
# include <sys/user.h> #include <sys/user.h>
# endif #endif
#endif #endif
#if GTEST_OS_QNX #if GTEST_OS_QNX
# include <devctl.h> #include <devctl.h>
# include <fcntl.h> #include <fcntl.h>
# include <sys/procfs.h> #include <sys/procfs.h>
#endif // GTEST_OS_QNX #endif // GTEST_OS_QNX
#if GTEST_OS_AIX #if GTEST_OS_AIX
# include <procinfo.h> #include <procinfo.h>
# include <sys/types.h> #include <sys/types.h>
#endif // GTEST_OS_AIX #endif // GTEST_OS_AIX
#if GTEST_OS_FUCHSIA #if GTEST_OS_FUCHSIA
# include <zircon/process.h> #include <zircon/process.h>
# include <zircon/syscalls.h> #include <zircon/syscalls.h>
#endif // GTEST_OS_FUCHSIA #endif // GTEST_OS_FUCHSIA
#include "gtest/gtest-spi.h"
#include "gtest/gtest-message.h" #include "gtest/gtest-message.h"
#include "gtest/gtest-spi.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
@ -89,16 +90,7 @@
namespace testing { namespace testing {
namespace internal { namespace internal {
#if defined(_MSC_VER) || defined(__BORLANDC__) #if GTEST_OS_LINUX || GTEST_OS_GNU_HURD
// 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 // _MSC_VER
#if GTEST_OS_LINUX
namespace { namespace {
template <typename T> template <typename T>
@ -131,8 +123,7 @@ size_t GetThreadCount() {
if (status == KERN_SUCCESS) { if (status == KERN_SUCCESS) {
// task_threads allocates resources in thread_list and we need to free them // task_threads allocates resources in thread_list and we need to free them
// to avoid leaks. // to avoid leaks.
vm_deallocate(task, vm_deallocate(task, reinterpret_cast<vm_address_t>(thread_list),
reinterpret_cast<vm_address_t>(thread_list),
sizeof(thread_t) * thread_count); sizeof(thread_t) * thread_count);
return static_cast<size_t>(thread_count); return static_cast<size_t>(thread_count);
} else { } else {
@ -210,8 +201,7 @@ size_t GetThreadCount() {
// exclude empty members // exclude empty members
size_t nthreads = 0; size_t nthreads = 0;
for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) { for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) {
if (info[i].p_tid != -1) if (info[i].p_tid != -1) nthreads++;
nthreads++;
} }
return nthreads; return nthreads;
} }
@ -254,13 +244,9 @@ size_t GetThreadCount() {
size_t GetThreadCount() { size_t GetThreadCount() {
int dummy_buffer; int dummy_buffer;
size_t avail; size_t avail;
zx_status_t status = zx_object_get_info( zx_status_t status =
zx_process_self(), zx_object_get_info(zx_process_self(), ZX_INFO_PROCESS_THREADS,
ZX_INFO_PROCESS_THREADS, &dummy_buffer, 0, nullptr, &avail);
&dummy_buffer,
0,
nullptr,
&avail);
if (status == ZX_OK) { if (status == ZX_OK) {
return avail; return avail;
} else { } else {
@ -280,27 +266,15 @@ size_t GetThreadCount() {
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
void SleepMilliseconds(int n) { AutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
::Sleep(static_cast<DWORD>(n));
}
AutoHandle::AutoHandle() AutoHandle::AutoHandle(Handle handle) : handle_(handle) {}
: handle_(INVALID_HANDLE_VALUE) {}
AutoHandle::AutoHandle(Handle handle) AutoHandle::~AutoHandle() { Reset(); }
: handle_(handle) {}
AutoHandle::~AutoHandle() { AutoHandle::Handle AutoHandle::Get() const { return handle_; }
Reset();
}
AutoHandle::Handle AutoHandle::Get() const { void AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); }
return handle_;
}
void AutoHandle::Reset() {
Reset(INVALID_HANDLE_VALUE);
}
void AutoHandle::Reset(HANDLE handle) { void AutoHandle::Reset(HANDLE handle) {
// Resetting with the same handle we already own is invalid. // Resetting with the same handle we already own is invalid.
@ -322,23 +296,6 @@ bool AutoHandle::IsCloseable() const {
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
} }
Notification::Notification()
: event_(::CreateEvent(nullptr, // Default security attributes.
TRUE, // Do not reset automatically.
FALSE, // Initially unset.
nullptr)) { // Anonymous event.
GTEST_CHECK_(event_.Get() != nullptr);
}
void Notification::Notify() {
GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE);
}
void Notification::WaitForNotification() {
GTEST_CHECK_(
::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
}
Mutex::Mutex() Mutex::Mutex()
: owner_thread_id_(0), : owner_thread_id_(0),
type_(kDynamic), type_(kDynamic),
@ -391,25 +348,25 @@ namespace {
// MemoryIsNotDeallocated memory_is_not_deallocated; // MemoryIsNotDeallocated memory_is_not_deallocated;
// critical_section_ = new CRITICAL_SECTION; // critical_section_ = new CRITICAL_SECTION;
// //
class MemoryIsNotDeallocated class MemoryIsNotDeallocated {
{
public: public:
MemoryIsNotDeallocated() : old_crtdbg_flag_(0) { MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
// doesn't report mem leak if there's no matching deallocation. // doesn't report mem leak if there's no matching deallocation.
_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); (void)_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
} }
~MemoryIsNotDeallocated() { ~MemoryIsNotDeallocated() {
// Restore the original _CRTDBG_ALLOC_MEM_DF flag // Restore the original _CRTDBG_ALLOC_MEM_DF flag
_CrtSetDbgFlag(old_crtdbg_flag_); (void)_CrtSetDbgFlag(old_crtdbg_flag_);
} }
private: private:
int old_crtdbg_flag_; int old_crtdbg_flag_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated); MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete;
MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) = delete;
}; };
#endif // _MSC_VER #endif // _MSC_VER
@ -435,15 +392,13 @@ void Mutex::ThreadSafeLazyInit() {
::InitializeCriticalSection(critical_section_); ::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal // Updates the critical_section_init_phase_ to 2 to signal
// initialization complete. // initialization complete.
GTEST_CHECK_(::InterlockedCompareExchange( GTEST_CHECK_(::InterlockedCompareExchange(&critical_section_init_phase_,
&critical_section_init_phase_, 2L, 1L) == 2L, 1L) == 1L);
1L);
break; break;
case 1: case 1:
// Somebody else is already initializing the mutex; spin until they // Somebody else is already initializing the mutex; spin until they
// are done. // are done.
while (::InterlockedCompareExchange(&critical_section_init_phase_, while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L,
2L,
2L) != 2L) { 2L) != 2L) {
// Possibly yields the rest of the thread's time slice to other // Possibly yields the rest of the thread's time slice to other
// threads. // threads.
@ -488,9 +443,7 @@ class ThreadWithParamSupport : public ThreadWithParamBase {
private: private:
struct ThreadMainParam { struct ThreadMainParam {
ThreadMainParam(Runnable* runnable, Notification* thread_can_start) ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
: runnable_(runnable), : runnable_(runnable), thread_can_start_(thread_can_start) {}
thread_can_start_(thread_can_start) {
}
std::unique_ptr<Runnable> runnable_; std::unique_ptr<Runnable> runnable_;
// Does not own. // Does not own.
Notification* thread_can_start_; Notification* thread_can_start_;
@ -508,20 +461,18 @@ class ThreadWithParamSupport : public ThreadWithParamBase {
// Prohibit instantiation. // Prohibit instantiation.
ThreadWithParamSupport(); ThreadWithParamSupport();
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); ThreadWithParamSupport(const ThreadWithParamSupport&) = delete;
ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) = delete;
}; };
} // namespace } // namespace
ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, ThreadWithParamBase::ThreadWithParamBase(Runnable* runnable,
Notification* thread_can_start) Notification* thread_can_start)
: thread_(ThreadWithParamSupport::CreateThread(runnable, : thread_(
thread_can_start)) { ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) {}
}
ThreadWithParamBase::~ThreadWithParamBase() { ThreadWithParamBase::~ThreadWithParamBase() { Join(); }
Join();
}
void ThreadWithParamBase::Join() { void ThreadWithParamBase::Join() {
GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)
@ -548,8 +499,10 @@ class ThreadLocalRegistryImpl {
ThreadIdToThreadLocals::iterator thread_local_pos = ThreadIdToThreadLocals::iterator thread_local_pos =
thread_to_thread_locals->find(current_thread); thread_to_thread_locals->find(current_thread);
if (thread_local_pos == thread_to_thread_locals->end()) { if (thread_local_pos == thread_to_thread_locals->end()) {
thread_local_pos = thread_to_thread_locals->insert( thread_local_pos =
std::make_pair(current_thread, ThreadLocalValues())).first; thread_to_thread_locals
->insert(std::make_pair(current_thread, ThreadLocalValues()))
.first;
StartWatcherThreadFor(current_thread); StartWatcherThreadFor(current_thread);
} }
ThreadLocalValues& thread_local_values = thread_local_pos->second; ThreadLocalValues& thread_local_values = thread_local_pos->second;
@ -578,8 +531,7 @@ class ThreadLocalRegistryImpl {
GetThreadLocalsMapLocked(); GetThreadLocalsMapLocked();
for (ThreadIdToThreadLocals::iterator it = for (ThreadIdToThreadLocals::iterator it =
thread_to_thread_locals->begin(); thread_to_thread_locals->begin();
it != thread_to_thread_locals->end(); it != thread_to_thread_locals->end(); ++it) {
++it) {
ThreadLocalValues& thread_local_values = it->second; ThreadLocalValues& thread_local_values = it->second;
ThreadLocalValues::iterator value_pos = ThreadLocalValues::iterator value_pos =
thread_local_values.find(thread_local_instance); thread_local_values.find(thread_local_instance);
@ -610,8 +562,7 @@ class ThreadLocalRegistryImpl {
ThreadLocalValues& thread_local_values = thread_local_pos->second; ThreadLocalValues& thread_local_values = thread_local_pos->second;
for (ThreadLocalValues::iterator value_pos = for (ThreadLocalValues::iterator value_pos =
thread_local_values.begin(); thread_local_values.begin();
value_pos != thread_local_values.end(); value_pos != thread_local_values.end(); ++value_pos) {
++value_pos) {
value_holders.push_back(value_pos->second); value_holders.push_back(value_pos->second);
} }
thread_to_thread_locals->erase(thread_local_pos); thread_to_thread_locals->erase(thread_local_pos);
@ -637,9 +588,8 @@ class ThreadLocalRegistryImpl {
static void StartWatcherThreadFor(DWORD thread_id) { static void StartWatcherThreadFor(DWORD thread_id) {
// The returned handle will be kept in thread_map and closed by // The returned handle will be kept in thread_map and closed by
// watcher_thread in WatcherThreadFunc. // watcher_thread in WatcherThreadFunc.
HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, HANDLE thread =
FALSE, ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
thread_id);
GTEST_CHECK_(thread != nullptr); GTEST_CHECK_(thread != nullptr);
// We need to pass a valid thread ID pointer into CreateThread for it // We need to pass a valid thread ID pointer into CreateThread for it
// to work correctly under Win98. // to work correctly under Win98.
@ -650,7 +600,8 @@ class ThreadLocalRegistryImpl {
&ThreadLocalRegistryImpl::WatcherThreadFunc, &ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
CREATE_SUSPENDED, &watcher_thread_id); CREATE_SUSPENDED, &watcher_thread_id);
GTEST_CHECK_(watcher_thread != nullptr); GTEST_CHECK_(watcher_thread != nullptr)
<< "CreateThread failed with error " << ::GetLastError() << ".";
// Give the watcher thread the same priority as ours to avoid being // Give the watcher thread the same priority as ours to avoid being
// blocked by it. // blocked by it.
::SetThreadPriority(watcher_thread, ::SetThreadPriority(watcher_thread,
@ -664,8 +615,7 @@ class ThreadLocalRegistryImpl {
static DWORD WINAPI WatcherThreadFunc(LPVOID param) { static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
const ThreadIdAndHandle* tah = const ThreadIdAndHandle* tah =
reinterpret_cast<const ThreadIdAndHandle*>(param); reinterpret_cast<const ThreadIdAndHandle*>(param);
GTEST_CHECK_( GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
OnThreadExit(tah->first); OnThreadExit(tah->first);
::CloseHandle(tah->second); ::CloseHandle(tah->second);
delete tah; delete tah;
@ -689,7 +639,8 @@ class ThreadLocalRegistryImpl {
}; };
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); // NOLINT Mutex ThreadLocalRegistryImpl::thread_map_mutex_(
Mutex::kStaticMutex); // NOLINT
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) { const ThreadLocalBase* thread_local_instance) {
@ -799,17 +750,28 @@ bool IsValidEscape(char c) {
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
if (escaped) { // "\\p" where p is pattern_char. if (escaped) { // "\\p" where p is pattern_char.
switch (pattern_char) { switch (pattern_char) {
case 'd': return IsAsciiDigit(ch); case 'd':
case 'D': return !IsAsciiDigit(ch); return IsAsciiDigit(ch);
case 'f': return ch == '\f'; case 'D':
case 'n': return ch == '\n'; return !IsAsciiDigit(ch);
case 'r': return ch == '\r'; case 'f':
case 's': return IsAsciiWhiteSpace(ch); return ch == '\f';
case 'S': return !IsAsciiWhiteSpace(ch); case 'n':
case 't': return ch == '\t'; return ch == '\n';
case 'v': return ch == '\v'; case 'r':
case 'w': return IsAsciiWordChar(ch); return ch == '\r';
case 'W': return !IsAsciiWordChar(ch); 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 IsAsciiPunct(pattern_char) && pattern_char == ch;
} }
@ -820,7 +782,8 @@ bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
// Helper function used by ValidateRegex() to format error messages. // Helper function used by ValidateRegex() to format error messages.
static std::string FormatRegexSyntaxError(const char* regex, int index) { static std::string FormatRegexSyntaxError(const char* regex, int index) {
return (Message() << "Syntax error at index " << index return (Message() << "Syntax error at index " << index
<< " in simple regular expression \"" << regex << "\": ").GetString(); << " in simple regular expression \"" << regex << "\": ")
.GetString();
} }
// Generates non-fatal failures and returns false if regex is invalid; // Generates non-fatal failures and returns false if regex is invalid;
@ -862,12 +825,12 @@ bool ValidateRegex(const char* regex) {
<< "'$' can only appear at the end."; << "'$' can only appear at the end.";
is_valid = false; is_valid = false;
} else if (IsInSet(ch, "()[]{}|")) { } else if (IsInSet(ch, "()[]{}|")) {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
<< "'" << ch << "' is unsupported."; << "' is unsupported.";
is_valid = false; is_valid = false;
} else if (IsRepeat(ch) && !prev_repeatable) { } else if (IsRepeat(ch) && !prev_repeatable) {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
<< "'" << ch << "' can only follow a repeatable token."; << "' can only follow a repeatable token.";
is_valid = false; is_valid = false;
} }
@ -885,12 +848,10 @@ bool ValidateRegex(const char* regex) {
// characters to be indexable by size_t, in which case the test will // characters to be indexable by size_t, in which case the test will
// probably time out anyway. We are fine with this limitation as // probably time out anyway. We are fine with this limitation as
// std::string has it too. // std::string has it too.
bool MatchRepetitionAndRegexAtHead( bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,
bool escaped, char c, char repeat, const char* regex, const char* regex, const char* str) {
const char* str) {
const size_t min_count = (repeat == '+') ? 1 : 0; const size_t min_count = (repeat == '+') ? 1 : 0;
const size_t max_count = (repeat == '?') ? 1 : const size_t max_count = (repeat == '?') ? 1 : static_cast<size_t>(-1) - 1;
static_cast<size_t>(-1) - 1;
// We cannot call numeric_limits::max() as it conflicts with the // We cannot call numeric_limits::max() as it conflicts with the
// max() macro on Windows. // max() macro on Windows.
@ -903,8 +864,7 @@ bool MatchRepetitionAndRegexAtHead(
// greedy match. // greedy match.
return true; return true;
} }
if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false;
return false;
} }
return false; return false;
} }
@ -918,19 +878,17 @@ bool MatchRegexAtHead(const char* regex, const char* str) {
// "$" only matches the end of a string. Note that regex being // "$" only matches the end of a string. Note that regex being
// valid guarantees that there's nothing after "$" in it. // valid guarantees that there's nothing after "$" in it.
if (*regex == '$') if (*regex == '$') return *str == '\0';
return *str == '\0';
// Is the first thing in regex an escape sequence? // Is the first thing in regex an escape sequence?
const bool escaped = *regex == '\\'; const bool escaped = *regex == '\\';
if (escaped) if (escaped) ++regex;
++regex;
if (IsRepeat(regex[1])) { if (IsRepeat(regex[1])) {
// MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
// here's an indirect recursion. It terminates as the regex gets // here's an indirect recursion. It terminates as the regex gets
// shorter in each recursion. // shorter in each recursion.
return MatchRepetitionAndRegexAtHead( return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2,
escaped, regex[0], regex[1], regex + 2, str); str);
} else { } else {
// regex isn't empty, isn't "$", and doesn't start with a // regex isn't empty, isn't "$", and doesn't start with a
// repetition. We match the first atom of regex with the first // repetition. We match the first atom of regex with the first
@ -951,13 +909,11 @@ bool MatchRegexAtHead(const char* regex, const char* str) {
bool MatchRegexAnywhere(const char* regex, const char* str) { bool MatchRegexAnywhere(const char* regex, const char* str) {
if (regex == nullptr || str == nullptr) return false; if (regex == nullptr || str == nullptr) return false;
if (*regex == '^') if (*regex == '^') return MatchRegexAtHead(regex + 1, str);
return MatchRegexAtHead(regex + 1, str);
// A successful match can be anywhere in str. // A successful match can be anywhere in str.
do { do {
if (MatchRegexAtHead(regex, str)) if (MatchRegexAtHead(regex, str)) return true;
return true;
} while (*str++ != '\0'); } while (*str++ != '\0');
return false; return false;
} }
@ -1038,8 +994,8 @@ GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
// FormatFileLocation in order to contrast the two functions. // FormatFileLocation in order to contrast the two functions.
// Note that FormatCompilerIndependentFileLocation() does NOT append colon // Note that FormatCompilerIndependentFileLocation() does NOT append colon
// to the file location it produces, unlike FormatFileLocation(). // to the file location it produces, unlike FormatFileLocation().
GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,
const char* file, int line) { int line) {
const std::string file_name(file == nullptr ? kUnknownFile : file); const std::string file_name(file == nullptr ? kUnknownFile : file);
if (line < 0) if (line < 0)
@ -1050,12 +1006,13 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
: severity_(severity) { : severity_(severity) {
const char* const marker = const char* const marker = severity == GTEST_INFO ? "[ INFO ]"
severity == GTEST_INFO ? "[ INFO ]" : : severity == GTEST_WARNING ? "[WARNING]"
severity == GTEST_WARNING ? "[WARNING]" : : severity == GTEST_ERROR ? "[ ERROR ]"
severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; : "[ FATAL ]";
GetStream() << ::std::endl << marker << " " GetStream() << ::std::endl
<< FormatFileLocation(file, line).c_str() << ": "; << marker << " " << FormatFileLocation(file, line).c_str()
<< ": ";
} }
// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
@ -1078,27 +1035,26 @@ class CapturedStream {
public: public:
// The ctor redirects the stream to a temporary file. // The ctor redirects the stream to a temporary file.
explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
# if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT
::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
const UINT success = ::GetTempFileNameA(temp_dir_path, const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir",
"gtest_redir",
0, // Generate unique file name. 0, // Generate unique file name.
temp_file_path); temp_file_path);
GTEST_CHECK_(success != 0) GTEST_CHECK_(success != 0)
<< "Unable to create a temporary file in " << temp_dir_path; << "Unable to create a temporary file in " << temp_dir_path;
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " GTEST_CHECK_(captured_fd != -1)
<< temp_file_path; << "Unable to open temporary file " << temp_file_path;
filename_ = temp_file_path; filename_ = temp_file_path;
# else #else
// There's no guarantee that a test has write access to the current // There's no guarantee that a test has write access to the current
// directory, so we create the temporary file in a temporary directory. // directory, so we create the temporary file in a temporary directory.
std::string name_template; std::string name_template;
# if GTEST_OS_LINUX_ANDROID #if GTEST_OS_LINUX_ANDROID
// Note: Android applications are expected to call the framework's // Note: Android applications are expected to call the framework's
// Context.getExternalStorageDirectory() method through JNI to get // Context.getExternalStorageDirectory() method through JNI to get
// the location of the world-writable SD Card directory. However, // the location of the world-writable SD Card directory. However,
@ -1111,7 +1067,7 @@ class CapturedStream {
// '/sdcard' and other variants cannot be relied on, as they are not // '/sdcard' and other variants cannot be relied on, as they are not
// guaranteed to be mounted, or may have a delay in mounting. // guaranteed to be mounted, or may have a delay in mounting.
name_template = "/data/local/tmp/"; name_template = "/data/local/tmp/";
# elif GTEST_OS_IOS #elif GTEST_OS_IOS
char user_temp_dir[PATH_MAX + 1]; char user_temp_dir[PATH_MAX + 1];
// Documented alternative to NSTemporaryDirectory() (for obtaining creating // Documented alternative to NSTemporaryDirectory() (for obtaining creating
@ -1132,9 +1088,9 @@ class CapturedStream {
name_template = user_temp_dir; name_template = user_temp_dir;
if (name_template.back() != GTEST_PATH_SEP_[0]) if (name_template.back() != GTEST_PATH_SEP_[0])
name_template.push_back(GTEST_PATH_SEP_[0]); name_template.push_back(GTEST_PATH_SEP_[0]);
# else #else
name_template = "/tmp/"; name_template = "/tmp/";
# endif #endif
name_template.append("gtest_captured_stream.XXXXXX"); name_template.append("gtest_captured_stream.XXXXXX");
// mkstemp() modifies the string bytes in place, and does not go beyond the // mkstemp() modifies the string bytes in place, and does not go beyond the
@ -1150,15 +1106,13 @@ class CapturedStream {
<< " for test; does the test have access to the /tmp directory?"; << " for test; does the test have access to the /tmp directory?";
} }
filename_ = std::move(name_template); filename_ = std::move(name_template);
# endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
fflush(nullptr); fflush(nullptr);
dup2(captured_fd, fd_); dup2(captured_fd, fd_);
close(captured_fd); close(captured_fd);
} }
~CapturedStream() { ~CapturedStream() { remove(filename_.c_str()); }
remove(filename_.c_str());
}
std::string GetCapturedString() { std::string GetCapturedString() {
if (uncaptured_fd_ != -1) { if (uncaptured_fd_ != -1) {
@ -1185,7 +1139,8 @@ class CapturedStream {
// Name of the temporary file holding the stderr output. // Name of the temporary file holding the stderr output.
::std::string filename_; ::std::string filename_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); CapturedStream(const CapturedStream&) = delete;
CapturedStream& operator=(const CapturedStream&) = delete;
}; };
GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_DEPRECATED_POP_()
@ -1213,6 +1168,15 @@ static std::string GetCapturedStream(CapturedStream** captured_stream) {
return content; 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. // Starts capturing stdout.
void CaptureStdout() { void CaptureStdout() {
CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
@ -1235,10 +1199,6 @@ std::string GetCapturedStderr() {
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
size_t GetFileSize(FILE* file) { size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file)); return static_cast<size_t>(ftell(file));
@ -1256,7 +1216,8 @@ std::string ReadEntireFile(FILE* file) {
// Keeps reading the file until we cannot read further or the // Keeps reading the file until we cannot read further or the
// pre-determined file size is reached. // pre-determined file size is reached.
do { do {
bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); bytes_last_read =
fread(buffer + bytes_read, 1, file_size - bytes_read, file);
bytes_read += bytes_last_read; bytes_read += bytes_last_read;
} while (bytes_last_read > 0 && bytes_read < file_size); } while (bytes_last_read > 0 && bytes_read < file_size);
@ -1388,8 +1349,8 @@ int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) {
} }
int32_t result = default_value; int32_t result = default_value;
if (!ParseInt32(Message() << "Environment variable " << env_var, if (!ParseInt32(Message() << "Environment variable " << env_var, string_value,
string_value, &result)) { &result)) {
printf("The default value %s is used.\n", printf("The default value %s is used.\n",
(Message() << default_value).GetString().c_str()); (Message() << default_value).GetString().c_str());
fflush(stdout); fflush(stdout);
@ -1408,7 +1369,7 @@ int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) {
// not check that the flag is 'output' // not check that the flag is 'output'
// In essence this checks an env variable called XML_OUTPUT_FILE // 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 "" // and if it is set we prepend "xml:" to its value, if it not set we return ""
std::string OutputFlagAlsoCheckEnvVar(){ std::string OutputFlagAlsoCheckEnvVar() {
std::string default_value_for_output_flag = ""; std::string default_value_for_output_flag = "";
const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
if (nullptr != xml_output_file_env) { if (nullptr != xml_output_file_env) {

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Test - The Google C++ Testing and Mocking Framework // Google Test - The Google C++ Testing and Mocking Framework
// //
// This file implements a universal value printer that can print a // This file implements a universal value printer that can print a
@ -101,7 +100,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
*os << " ... "; *os << " ... ";
// Rounds up to 2-byte boundary. // Rounds up to 2-byte boundary.
const size_t resume_pos = (count - kChunkSize + 1)/2*2; const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2;
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
} }
*os << ">"; *os << ">";
@ -136,11 +135,7 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
// - as a hexadecimal escape sequence (e.g. '\x7F'), or // - as a hexadecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n'). // - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat { enum CharFormat { kAsIs, kHexEscape, kSpecialEscape };
kAsIs,
kHexEscape,
kSpecialEscape
};
// Returns true if c is a printable ASCII character. We test the // Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on // value of c directly instead of calling isprint(), which is buggy on
@ -213,35 +208,21 @@ static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {
} }
} }
static const char* GetCharWidthPrefix(char) { static const char* GetCharWidthPrefix(char) { return ""; }
return "";
}
static const char* GetCharWidthPrefix(signed char) { static const char* GetCharWidthPrefix(signed char) { return ""; }
return "";
}
static const char* GetCharWidthPrefix(unsigned char) { static const char* GetCharWidthPrefix(unsigned char) { return ""; }
return "";
}
#ifdef __cpp_char8_t #ifdef __cpp_char8_t
static const char* GetCharWidthPrefix(char8_t) { static const char* GetCharWidthPrefix(char8_t) { return "u8"; }
return "u8";
}
#endif #endif
static const char* GetCharWidthPrefix(char16_t) { static const char* GetCharWidthPrefix(char16_t) { return "u"; }
return "u";
}
static const char* GetCharWidthPrefix(char32_t) { static const char* GetCharWidthPrefix(char32_t) { return "U"; }
return "U";
}
static const char* GetCharWidthPrefix(wchar_t) { static const char* GetCharWidthPrefix(wchar_t) { return "L"; }
return "L";
}
// Prints a char c as if it's part of a string literal, escaping it when // Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted. // necessary; returns how c was formatted.
@ -276,8 +257,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
// To aid user debugging, we also print c's code in decimal, unless // To aid user debugging, we also print c's code in decimal, unless
// it's 0 (in which case c was printed as '\\0', making the code // it's 0 (in which case c was printed as '\\0', making the code
// obvious). // obvious).
if (c == 0) if (c == 0) return;
return;
*os << " (" << static_cast<int>(c); *os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexadecimal, // For more convenience, we print c's code again in hexadecimal,
@ -304,17 +284,60 @@ void PrintTo(char32_t c, ::std::ostream* os) {
<< static_cast<uint32_t>(c); << 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 // Prints the given array of characters to the ostream. CharType must be either
// char, char8_t, char16_t, char32_t, or wchar_t. // char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters // The array starts at begin, the length is len, it may include '\0' characters
// and may not be NUL-terminated. // and may not be NUL-terminated.
template <typename CharType> template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const quote_prefix = GetCharWidthPrefix(*begin); const char* const quote_prefix = GetCharWidthPrefix(*begin);
*os << quote_prefix << "\""; *os << quote_prefix << "\"";
bool is_previous_hex = false; bool is_previous_hex = false;
@ -340,12 +363,11 @@ static CharFormat PrintCharsAsStringTo(
// Prints a (const) char/wchar_t array of 'len' elements, starting at address // Prints a (const) char/wchar_t array of 'len' elements, starting at address
// 'begin'. CharType must be either char or wchar_t. // 'begin'. CharType must be either char or wchar_t.
template <typename CharType> template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ UniversalPrintCharArray(const CharType* begin, size_t len,
static void UniversalPrintCharArray( ostream* os) {
const CharType* begin, size_t len, ostream* os) {
// The code // The code
// const char kFoo[] = "foo"; // const char kFoo[] = "foo";
// generates an array of 4, not 3, elements, with the last one being '\0'. // generates an array of 4, not 3, elements, with the last one being '\0'.
@ -436,7 +458,7 @@ void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
namespace { namespace {
bool ContainsUnprintableControlCodes(const char* str, size_t length) { bool ContainsUnprintableControlCodes(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str); const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++) {
unsigned char ch = *s++; unsigned char ch = *s++;
@ -454,10 +476,10 @@ bool ContainsUnprintableControlCodes(const char* str, size_t length) {
return false; return false;
} }
bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; } bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; }
bool IsValidUTF8(const char* str, size_t length) { bool IsValidUTF8(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str); const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
for (size_t i = 0; i < length;) { for (size_t i = 0; i < length;) {
unsigned char lead = s[i++]; unsigned char lead = s[i++];
@ -470,15 +492,13 @@ bool IsValidUTF8(const char* str, size_t length) {
} else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) { } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
++i; // 2-byte character ++i; // 2-byte character
} else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length && } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i + 1]) &&
// check for non-shortest form and surrogate // check for non-shortest form and surrogate
(lead != 0xe0 || s[i] >= 0xa0) && (lead != 0xe0 || s[i] >= 0xa0) &&
(lead != 0xed || s[i] < 0xa0)) { (lead != 0xed || s[i] < 0xa0)) {
i += 2; // 3-byte character i += 2; // 3-byte character
} else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length && } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i + 2]) && IsUTF8TrailByte(s[i + 2]) &&
// check for non-shortest form // check for non-shortest form
(lead != 0xf0 || s[i] >= 0x90) && (lead != 0xf0 || s[i] >= 0x90) &&
@ -502,7 +522,7 @@ void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
void PrintStringTo(const ::std::string& s, ostream* os) { void PrintStringTo(const ::std::string& s, ostream* os) {
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG(print_utf8)) { if (GTEST_FLAG_GET(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os); ConditionalPrintAsText(s.data(), s.size(), os);
} }
} }

View File

@ -51,10 +51,8 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
return os << internal::FormatFileLocation(result.file_name(), return os << internal::FormatFileLocation(result.file_name(),
result.line_number()) result.line_number())
<< " " << " "
<< (result.type() == TestPartResult::kSuccess << (result.type() == TestPartResult::kSuccess ? "Success"
? "Success" : result.type() == TestPartResult::kSkip ? "Skipped"
: result.type() == TestPartResult::kSkip
? "Skipped"
: result.type() == TestPartResult::kFatalFailure : result.type() == TestPartResult::kFatalFailure
? "Fatal failure" ? "Fatal failure"
: "Non-fatal failure") : "Non-fatal failure")
@ -86,8 +84,8 @@ namespace internal {
HasNewFatalFailureHelper::HasNewFatalFailureHelper() HasNewFatalFailureHelper::HasNewFatalFailureHelper()
: has_new_fatal_failure_(false), : has_new_fatal_failure_(false),
original_reporter_(GetUnitTestImpl()-> original_reporter_(
GetTestPartResultReporterForCurrentThread()) { GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) {
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
} }
@ -98,8 +96,7 @@ HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
void HasNewFatalFailureHelper::ReportTestPartResult( void HasNewFatalFailureHelper::ReportTestPartResult(
const TestPartResult& result) { const TestPartResult& result) {
if (result.fatally_failed()) if (result.fatally_failed()) has_new_fatal_failure_ = true;
has_new_fatal_failure_ = true;
original_reporter_->ReportTestPartResult(result); original_reporter_->ReportTestPartResult(result);
} }

View File

@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gtest/gtest-typed-test.h" #include "gtest/gtest-typed-test.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -38,8 +37,7 @@ namespace internal {
// Skips to the first non-space char in str. Returns an empty string if str // Skips to the first non-space char in str. Returns an empty string if str
// contains only whitespace characters. // contains only whitespace characters.
static const char* SkipSpaces(const char* str) { static const char* SkipSpaces(const char* str) {
while (IsSpace(*str)) while (IsSpace(*str)) str++;
str++;
return str; return str;
} }
@ -85,8 +83,7 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
} }
for (RegisteredTestIter it = registered_tests_.begin(); for (RegisteredTestIter it = registered_tests_.begin();
it != registered_tests_.end(); it != registered_tests_.end(); ++it) {
++it) {
if (tests.count(it->first) == 0) { if (tests.count(it->first) == 0) {
errors << "You forgot to list test " << it->first << ".\n"; errors << "You forgot to list test " << it->first << ".\n";
} }

File diff suppressed because it is too large Load Diff

View File

@ -28,15 +28,14 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdio> #include <cstdio>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32 #if GTEST_OS_ESP8266 || GTEST_OS_ESP32
#if GTEST_OS_ESP8266 #if GTEST_OS_ESP8266
extern "C" { extern "C" {
#endif #endif
void setup() { void setup() { testing::InitGoogleTest(); }
testing::InitGoogleTest();
}
void loop() { RUN_ALL_TESTS(); } void loop() { RUN_ALL_TESTS(); }