Merge pull request #4731 from assimp/kimkulling/add_check_for_wall_enable_issue-4652

Add check for wall switch from cmake
pull/4730/head^2
Kim Kulling 2022-09-18 18:57:44 +02:00 committed by GitHub
commit 8d9a0f777d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
69 changed files with 3225 additions and 7046 deletions

View File

@ -305,19 +305,16 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
} }
} }
if (nodes.size()) { if (nodes.empty()) {
parent->mChildren = new aiNode *[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
for (unsigned int i = 0; i < nodes.size(); ++i)
{
parent->mChildren[i] = nodes[i].mOwnership.release();
}
nodes.clear();
} else {
parent->mNumChildren = 0; parent->mNumChildren = 0;
parent->mChildren = nullptr; parent->mChildren = nullptr;
} }
parent->mChildren = new aiNode *[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
for (unsigned int i = 0; i < nodes.size(); ++i) {
parent->mChildren[i] = nodes[i].mOwnership.release();
}
} }
void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) { void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) {

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)
set(PROJECT_VERSION ${GOOGLETEST_VERSION})
else()
cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0048 NEW)
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) 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

@ -0,0 +1,237 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file implements the AssertionResult type.
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-port.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing {
// A class for indicating whether an assertion was successful. When
// the assertion wasn't successful, the AssertionResult object
// remembers a non-empty message that describes how it failed.
//
// To create an instance of this class, use one of the factory functions
// (AssertionSuccess() and AssertionFailure()).
//
// This class is useful for two purposes:
// 1. Defining predicate functions to be used with Boolean test assertions
// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
// 2. Defining predicate-format functions to be
// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
//
// For example, if you define IsEven predicate:
//
// testing::AssertionResult IsEven(int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess();
// else
// return testing::AssertionFailure() << n << " is odd";
// }
//
// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
// will print the message
//
// Value of: IsEven(Fib(5))
// Actual: false (5 is odd)
// Expected: true
//
// instead of a more opaque
//
// Value of: IsEven(Fib(5))
// Actual: false
// Expected: true
//
// in case IsEven is a simple Boolean predicate.
//
// If you expect your predicate to be reused and want to support informative
// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
// about half as often as positive ones in our tests), supply messages for
// both success and failure cases:
//
// testing::AssertionResult IsEven(int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess() << n << " is even";
// else
// return testing::AssertionFailure() << n << " is odd";
// }
//
// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
//
// Value of: IsEven(Fib(6))
// Actual: true (8 is even)
// Expected: false
//
// NB: Predicates that support negative Boolean assertions have reduced
// performance in positive ones so be careful not to use them in tests
// that have lots (tens of thousands) of positive Boolean assertions.
//
// To use this class with EXPECT_PRED_FORMAT assertions such as:
//
// // Verifies that Foo() returns an even number.
// EXPECT_PRED_FORMAT1(IsEven, Foo());
//
// you need to define:
//
// testing::AssertionResult IsEven(const char* expr, int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess();
// else
// return testing::AssertionFailure()
// << "Expected: " << expr << " is even\n Actual: it's " << n;
// }
//
// If Foo() returns 5, you will see the following message:
//
// Expected: Foo() is even
// Actual: it's 5
//
class GTEST_API_ AssertionResult {
public:
// Copy constructor.
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult(const AssertionResult& other);
// C4800 is a level 3 warning in Visual Studio 2015 and earlier.
// This warning is not emitted in Visual Studio 2017.
// This warning is off by default starting in Visual Studio 2019 but can be
// enabled with command-line options.
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
#endif
// Used in the EXPECT_TRUE/FALSE(bool_expression).
//
// T must be contextually convertible to bool.
//
// The second parameter prevents this overload from being considered if
// the argument is implicitly convertible to AssertionResult. In that case
// we want AssertionResult's copy constructor to be used.
template <typename T>
explicit AssertionResult(
const T& success,
typename std::enable_if<
!std::is_convertible<T, AssertionResult>::value>::type*
/*enabler*/
= nullptr)
: success_(success) {}
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
// Assignment operator.
AssertionResult& operator=(AssertionResult other) {
swap(other);
return *this;
}
// Returns true if and only if the assertion succeeded.
operator bool() const { return success_; } // NOLINT
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult operator!() const;
// Returns the text streamed into this AssertionResult. Test assertions
// use it when they fail (i.e., the predicate's outcome doesn't match the
// assertion's expectation). When nothing has been streamed into the
// object, returns an empty string.
const char* message() const {
return message_.get() != nullptr ? message_->c_str() : "";
}
// Deprecated; please use message() instead.
const char* failure_message() const { return message(); }
// Streams a custom failure message into this object.
template <typename T>
AssertionResult& operator<<(const T& value) {
AppendMessage(Message() << value);
return *this;
}
// Allows streaming basic output manipulators such as endl or flush into
// this object.
AssertionResult& operator<<(
::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
AppendMessage(Message() << basic_manipulator);
return *this;
}
private:
// Appends the contents of message to message_.
void AppendMessage(const Message& a_message) {
if (message_.get() == nullptr) message_.reset(new ::std::string);
message_->append(a_message.GetString().c_str());
}
// Swap the contents of this AssertionResult with other.
void swap(AssertionResult& other);
// Stores result of the assertion predicate.
bool success_;
// Stores the message describing the condition in case the expectation
// construct is not satisfied with the predicate's outcome.
// Referenced via a pointer to avoid taking too much stack frame space
// with test assertions.
std::unique_ptr< ::std::string> message_;
};
// Makes a successful assertion result.
GTEST_API_ AssertionResult AssertionSuccess();
// Makes a failed assertion result.
GTEST_API_ AssertionResult AssertionFailure();
// Makes a failed assertion result with the given failure message.
// Deprecated; use AssertionFailure() << msg.
GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
} // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_

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.
// //
@ -197,6 +198,7 @@ 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_;
}; };
@ -204,11 +206,11 @@ class GTEST_API_ ExitedWithCode {
#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_;
}; };
@ -267,11 +269,9 @@ class GTEST_API_ KilledBySignal {
#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
@ -314,8 +314,7 @@ class GTEST_API_ KilledBySignal {
#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)); \

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) {
@ -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_
@ -165,9 +166,7 @@ class GTEST_API_ Message {
} }
// 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.

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

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.
// //
@ -153,7 +156,8 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
{ \ { \
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter:: \ ::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\ INTERCEPT_ONLY_CURRENT_THREAD, \
&gtest_failures); \
GTestExpectFatalFailureHelper::Execute(); \ GTestExpectFatalFailureHelper::Execute(); \
} \ } \
} while (::testing::internal::AlwaysFalse()) } while (::testing::internal::AlwaysFalse())
@ -169,16 +173,17 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
&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
@ -216,8 +221,11 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
{ \ { \
::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())
@ -231,7 +239,9 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
::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())

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.
@ -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);
} }
@ -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,9 +1593,7 @@ 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) {}
@ -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.
@ -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_)
@ -2158,12 +1962,12 @@ class TestWithParam : public Test, public WithParamInterface<T> {
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
@ -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.
@ -2378,13 +2182,12 @@ 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.
@ -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()
@ -99,39 +97,26 @@ 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();
@ -146,18 +131,13 @@ 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()
@ -199,20 +169,14 @@ 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()
@ -258,22 +210,14 @@ 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()
@ -329,18 +260,9 @@ AssertionResult AssertPred5Helper(const char* pred_text,
// 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_

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";
@ -90,9 +94,11 @@ class GTEST_API_ DeathTest {
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
@ -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_
@ -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_
@ -53,6 +55,7 @@
#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>
@ -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
@ -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();
@ -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:
@ -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;
} }
@ -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,7 +1018,9 @@ 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>
@ -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,7 +1058,9 @@ 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>
@ -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.
@ -1503,7 +1505,8 @@ class NeverThrown {
; \ ; \
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;
} }
@ -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;
@ -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);
@ -630,8 +636,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
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
@ -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.
@ -78,6 +78,8 @@
#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__

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.
//
// Low-level types and utilities for porting Google Test to various // Low-level types and utilities for porting Google Test to various
// platforms. All macros ending with _ and symbols defined in an // platforms. All macros ending with _ and symbols defined in an
// internal namespace are subject to change without notice. Code // internal namespace are subject to change without notice. Code
@ -38,7 +38,9 @@
// files are expected to #include this. Therefore, it cannot #include // files are expected to #include this. Therefore, it cannot #include
// any other Google Test header. // any other Google Test header.
// 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_PORT_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
@ -116,6 +118,7 @@
// GTEST_OS_DRAGONFLY - DragonFlyBSD // GTEST_OS_DRAGONFLY - DragonFlyBSD
// GTEST_OS_FREEBSD - FreeBSD // GTEST_OS_FREEBSD - FreeBSD
// GTEST_OS_FUCHSIA - Fuchsia // GTEST_OS_FUCHSIA - Fuchsia
// GTEST_OS_GNU_HURD - GNU/Hurd
// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD // GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
// GTEST_OS_HAIKU - Haiku // GTEST_OS_HAIKU - Haiku
// GTEST_OS_HPUX - HP-UX // GTEST_OS_HPUX - HP-UX
@ -167,7 +170,7 @@
// GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST - typed tests
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests
// GTEST_IS_THREADSAFE - Google Test is thread-safe. // GTEST_IS_THREADSAFE - Google Test is thread-safe.
// GOOGLETEST_CM0007 DO NOT DELETE // GTEST_USES_RE2 - the RE2 regular expression library is used
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
// GTEST_HAS_POSIX_RE (see above) which users can // GTEST_HAS_POSIX_RE (see above) which users can
// define themselves. // define themselves.
@ -190,10 +193,6 @@
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
// variable don't have to be used. // variable don't have to be used.
// GTEST_DISALLOW_ASSIGN_ - disables copy operator=.
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
// GTEST_DISALLOW_MOVE_ASSIGN_ - disables move operator=.
// GTEST_DISALLOW_MOVE_AND_ASSIGN_ - disables move ctor and operator=.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
// suppressed (constant conditional). // suppressed (constant conditional).
@ -217,11 +216,13 @@
// - synchronization primitives. // - synchronization primitives.
// //
// Regular expressions: // Regular expressions:
// RE - a simple regular expression class using the POSIX // RE - a simple regular expression class using
// Extended Regular Expression syntax on UNIX-like platforms // 1) the RE2 syntax on all platforms when built with RE2
// GOOGLETEST_CM0008 DO NOT DELETE // and Abseil as dependencies
// or a reduced regular exception syntax on other // 2) the POSIX Extended Regular Expression syntax on
// platforms, including Windows. // UNIX-like platforms,
// 3) A reduced regular exception syntax on other platforms,
// including Windows.
// Logging: // Logging:
// GTEST_LOG_() - logs messages at the specified severity level. // GTEST_LOG_() - logs messages at the specified severity level.
// LogToStderr() - directs all log messages to stderr. // LogToStderr() - directs all log messages to stderr.
@ -241,8 +242,6 @@
// BiggestInt - the biggest signed integer type. // BiggestInt - the biggest signed integer type.
// //
// Command-line utilities: // Command-line utilities:
// GTEST_DECLARE_*() - declares a flag.
// GTEST_DEFINE_*() - defines a flag.
// GetInjectableArgvs() - returns the command line as a vector of strings. // GetInjectableArgvs() - returns the command line as a vector of strings.
// //
// Environment variable utilities: // Environment variable utilities:
@ -263,13 +262,21 @@
#include <string.h> #include <string.h>
#include <cerrno> #include <cerrno>
// #include <condition_variable> // Guarded by GTEST_IS_THREADSAFE below
#include <cstdint> #include <cstdint>
#include <iostream>
#include <limits> #include <limits>
#include <locale>
#include <memory>
#include <string>
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
#include <tuple>
#include <type_traits> #include <type_traits>
#include <vector>
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
# include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#endif // !_WIN32_WCE #endif // !_WIN32_WCE
#if defined __APPLE__ #if defined __APPLE__
@ -277,16 +284,15 @@
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#include <iostream> // NOLINT
#include <locale>
#include <memory>
#include <string> // NOLINT
#include <tuple>
#include <vector> // NOLINT
#include "gtest/internal/custom/gtest-port.h" #include "gtest/internal/custom/gtest-port.h"
#include "gtest/internal/gtest-port-arch.h" #include "gtest/internal/gtest-port-arch.h"
#if GTEST_HAS_ABSL
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#include "absl/flags/reflection.h"
#endif
#if !defined(GTEST_DEV_EMAIL_) #if !defined(GTEST_DEV_EMAIL_)
#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
#define GTEST_FLAG_PREFIX_ "gtest_" #define GTEST_FLAG_PREFIX_ "gtest_"
@ -314,10 +320,8 @@
// GTEST_DISABLE_MSC_WARNINGS_POP_() // GTEST_DISABLE_MSC_WARNINGS_POP_()
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ #define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \
__pragma(warning(push)) \ __pragma(warning(push)) __pragma(warning(disable : warnings))
__pragma(warning(disable: warnings)) #define GTEST_DISABLE_MSC_WARNINGS_POP_() __pragma(warning(pop))
# define GTEST_DISABLE_MSC_WARNINGS_POP_() \
__pragma(warning(pop))
#else #else
// Not all compilers are MSVC // Not all compilers are MSVC
#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) #define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)
@ -331,13 +335,11 @@
_Pragma("clang diagnostic push") \ _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"") _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"")
#define GTEST_DISABLE_MSC_DEPRECATED_POP_() \ #define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma("clang diagnostic pop")
_Pragma("clang diagnostic pop")
#else #else
#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ #define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
# define GTEST_DISABLE_MSC_DEPRECATED_POP_() \ #define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif #endif
// Brings in definitions for functions used in the testing::internal::posix // Brings in definitions for functions used in the testing::internal::posix
@ -367,8 +369,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// This assumes that non-Windows OSes provide unistd.h. For OSes where this // This assumes that non-Windows OSes provide unistd.h. For OSes where this
// is not the case, we need to include headers that provide the functions // is not the case, we need to include headers that provide the functions
// mentioned above. // mentioned above.
# include <unistd.h>
#include <strings.h> #include <strings.h>
#include <unistd.h>
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#if GTEST_OS_LINUX_ANDROID #if GTEST_OS_LINUX_ANDROID
@ -387,32 +389,19 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif #endif
#endif #endif
#if GTEST_USES_PCRE // Select the regular expression implementation.
// The appropriate headers have already been included. #if GTEST_HAS_ABSL
// When using Abseil, RE2 is required.
#include "absl/strings/string_view.h"
#include "re2/re2.h"
#define GTEST_USES_RE2 1
#elif GTEST_HAS_POSIX_RE #elif GTEST_HAS_POSIX_RE
// On some platforms, <regex.h> needs someone to define size_t, and
// won't compile otherwise. We can #include it here as we already
// included <stdlib.h>, which is guaranteed to define size_t through
// <stddef.h>.
#include <regex.h> // NOLINT #include <regex.h> // NOLINT
#define GTEST_USES_POSIX_RE 1 #define GTEST_USES_POSIX_RE 1
#elif GTEST_OS_WINDOWS
// <regex.h> is not available on Windows. Use our own simple regex
// implementation instead.
# define GTEST_USES_SIMPLE_RE 1
#else #else
// Use our own simple regex implementation.
// <regex.h> may not be available on this platform. Use our own
// simple regex implementation instead.
#define GTEST_USES_SIMPLE_RE 1 #define GTEST_USES_SIMPLE_RE 1
#endif
#endif // GTEST_USES_PCRE
#ifndef GTEST_HAS_EXCEPTIONS #ifndef GTEST_HAS_EXCEPTIONS
// The user didn't tell us whether exceptions are enabled, so we need // The user didn't tell us whether exceptions are enabled, so we need
@ -494,8 +483,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// -frtti -fno-exceptions, the build fails at link time with undefined // -frtti -fno-exceptions, the build fails at link time with undefined
// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // references to __cxa_bad_typeid. Note sure if STL or toolchain bug,
// so disable RTTI when detected. // so disable RTTI when detected.
# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ #if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && !defined(__EXCEPTIONS)
!defined(__EXCEPTIONS)
#define GTEST_HAS_RTTI 0 #define GTEST_HAS_RTTI 0
#else #else
#define GTEST_HAS_RTTI 1 #define GTEST_HAS_RTTI 1
@ -547,7 +535,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
(GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \ (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \ GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \
GTEST_OS_HAIKU) GTEST_OS_HAIKU || GTEST_OS_GNU_HURD)
#endif // GTEST_HAS_PTHREAD #endif // GTEST_HAS_PTHREAD
#if GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD
@ -570,8 +558,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#if GTEST_OS_LINUX_ANDROID #if GTEST_OS_LINUX_ANDROID
// On Android, clone() became available at different API levels for each 32-bit // On Android, clone() became available at different API levels for each 32-bit
// architecture. // architecture.
# if defined(__LP64__) || \ #if defined(__LP64__) || (defined(__arm__) && __ANDROID_API__ >= 9) || \
(defined(__arm__) && __ANDROID_API__ >= 9) || \
(defined(__mips__) && __ANDROID_API__ >= 12) || \ (defined(__mips__) && __ANDROID_API__ >= 12) || \
(defined(__i386__) && __ANDROID_API__ >= 17) (defined(__i386__) && __ANDROID_API__ >= 17)
#define GTEST_HAS_CLONE 1 #define GTEST_HAS_CLONE 1
@ -607,7 +594,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \
GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \ GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU) GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \
GTEST_OS_GNU_HURD)
#define GTEST_HAS_DEATH_TEST 1 #define GTEST_HAS_DEATH_TEST 1
#endif #endif
@ -627,7 +615,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Determines whether test results can be streamed to a socket. // Determines whether test results can be streamed to a socket.
#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \ #if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD || \
GTEST_OS_GNU_HURD
#define GTEST_CAN_STREAM_RESULTS_ 1 #define GTEST_CAN_STREAM_RESULTS_ 1
#endif #endif
@ -644,7 +633,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifdef __INTEL_COMPILER #ifdef __INTEL_COMPILER
#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #define GTEST_AMBIGUOUS_ELSE_BLOCKER_
#else #else
# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT #define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
switch (0) \
case 0: \
default: // NOLINT
#endif #endif
// Use this annotation at the end of a struct/class definition to // Use this annotation at the end of a struct/class definition to
@ -676,8 +668,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// matches the selected implementation. See // matches the selected implementation. See
// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. // https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
__attribute__((__format__(__MINGW_PRINTF_FORMAT, string_index, \ __attribute__(( \
first_to_check))) __format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))
#else #else
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
__attribute__((__format__(__printf__, string_index, first_to_check))) __attribute__((__format__(__printf__, string_index, first_to_check)))
@ -686,29 +678,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
#endif #endif
// A macro to disallow copy operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_ASSIGN_(type) \
type& operator=(type const &) = delete
// A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
type(type const&) = delete; \
type& operator=(type const&) = delete
// A macro to disallow move operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_MOVE_ASSIGN_(type) \
type& operator=(type &&) noexcept = delete
// A macro to disallow move constructor and operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_MOVE_AND_ASSIGN_(type) \
type(type&&) noexcept = delete; \
type& operator=(type&&) noexcept = delete
// Tell the compiler to warn about unused return values for functions declared // Tell the compiler to warn about unused return values for functions declared
// with this macro. The macro should be used on function declarations // with this macro. The macro should be used on function declarations
// following the argument list: // following the argument list:
@ -730,8 +699,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// } // }
#define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ #define GTEST_INTENTIONAL_CONST_COND_PUSH_() \
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127)
# define GTEST_INTENTIONAL_CONST_COND_POP_() \ #define GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
GTEST_DISABLE_MSC_WARNINGS_POP_()
// Determine whether the compiler supports Microsoft's Structured Exception // Determine whether the compiler supports Microsoft's Structured Exception
// Handling. This is supported by several Windows compilers but generally // Handling. This is supported by several Windows compilers but generally
@ -758,6 +726,12 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif // GTEST_IS_THREADSAFE #endif // GTEST_IS_THREADSAFE
#if GTEST_IS_THREADSAFE
// Some platforms don't support including these threading related headers.
#include <condition_variable> // NOLINT
#include <mutex> // NOLINT
#endif // GTEST_IS_THREADSAFE
// GTEST_API_ qualifies all symbols that must be exported. The definitions below // GTEST_API_ qualifies all symbols that must be exported. The definitions below
// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in // are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
// gtest/internal/custom/gtest-port.h // gtest/internal/custom/gtest-port.h
@ -790,6 +764,20 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_NO_INLINE_ #define GTEST_NO_INLINE_
#endif #endif
#if defined(__clang__)
// Nested ifs to avoid triggering MSVC warning.
#if __has_attribute(disable_tail_calls)
// Ask the compiler not to perform tail call optimization inside
// the marked function.
#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))
#endif
#elif __GNUC__
#define GTEST_NO_TAIL_CALL_ \
__attribute__((optimize("no-optimize-sibling-calls")))
#else
#define GTEST_NO_TAIL_CALL_
#endif
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
#if !defined(GTEST_HAS_CXXABI_H_) #if !defined(GTEST_HAS_CXXABI_H_)
#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) #if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
@ -803,8 +791,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// memory when built with MemorySanitizer. // memory when built with MemorySanitizer.
#if defined(__clang__) #if defined(__clang__)
#if __has_feature(memory_sanitizer) #if __has_feature(memory_sanitizer)
# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ \ #define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))
__attribute__((no_sanitize_memory))
#else #else
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ #define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
#endif // __has_feature(memory_sanitizer) #endif // __has_feature(memory_sanitizer)
@ -839,8 +826,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// A function level attribute to disable ThreadSanitizer instrumentation. // A function level attribute to disable ThreadSanitizer instrumentation.
#if defined(__clang__) #if defined(__clang__)
#if __has_feature(thread_sanitizer) #if __has_feature(thread_sanitizer)
# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ #define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread))
__attribute__((no_sanitize_thread))
#else #else
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ #define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
#endif // __has_feature(thread_sanitizer) #endif // __has_feature(thread_sanitizer)
@ -867,25 +853,37 @@ namespace internal {
// Secret object, which is what we want. // Secret object, which is what we want.
class Secret; class Secret;
// The GTEST_COMPILE_ASSERT_ is a legacy macro used to verify that a compile
// time expression is true (in new code, use static_assert instead). For
// example, you could use it to verify the size of a static array:
//
// GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES,
// names_incorrect_size);
//
// The second argument to the macro must be a valid C++ identifier. If the
// expression is false, compiler will issue an error containing this identifier.
#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
// A helper for suppressing warnings on constant condition. It just // A helper for suppressing warnings on constant condition. It just
// returns 'condition'. // returns 'condition'.
GTEST_API_ bool IsTrue(bool condition); GTEST_API_ bool IsTrue(bool condition);
// Defines RE. // Defines RE.
#if GTEST_USES_PCRE #if GTEST_USES_RE2
// if used, PCRE is injected by custom/gtest-port.h
// This is almost `using RE = ::RE2`, except it is copy-constructible, and it
// needs to disambiguate the `std::string`, `absl::string_view`, and `const
// char*` constructors.
class GTEST_API_ RE {
public:
RE(absl::string_view regex) : regex_(regex) {} // NOLINT
RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT
RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT
RE(const RE& other) : RE(other.pattern()) {}
const std::string& pattern() const { return regex_.pattern(); }
static bool FullMatch(absl::string_view str, const RE& re) {
return RE2::FullMatch(str, re.regex_);
}
static bool PartialMatch(absl::string_view str, const RE& re) {
return RE2::PartialMatch(str, re.regex_);
}
private:
RE2 regex_;
};
#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE #elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended // A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
@ -936,7 +934,7 @@ class GTEST_API_ RE {
#endif #endif
}; };
#endif // GTEST_USES_PCRE #endif // ::testing::internal::RE implementation
// Formats a source file path and a line number as they would appear // Formats a source file path and a line number as they would appear
// in an error message from the compiler used to compile this code. // in an error message from the compiler used to compile this code.
@ -954,12 +952,7 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,
// LogToStderr() - directs all log messages to stderr. // LogToStderr() - directs all log messages to stderr.
// FlushInfoLog() - flushes informational log messages. // FlushInfoLog() - flushes informational log messages.
enum GTestLogSeverity { enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };
GTEST_INFO,
GTEST_WARNING,
GTEST_ERROR,
GTEST_FATAL
};
// Formats log entry severity, provides a stream object for streaming the // Formats log entry severity, provides a stream object for streaming the
// log message, and terminates the message with a newline when going out of // log message, and terminates the message with a newline when going out of
@ -976,14 +969,16 @@ class GTEST_API_ GTestLog {
private: private:
const GTestLogSeverity severity_; const GTestLogSeverity severity_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); GTestLog(const GTestLog&) = delete;
GTestLog& operator=(const GTestLog&) = delete;
}; };
#if !defined(GTEST_LOG_) #if !defined(GTEST_LOG_)
#define GTEST_LOG_(severity) \ #define GTEST_LOG_(severity) \
::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
__FILE__, __LINE__).GetStream() __FILE__, __LINE__) \
.GetStream()
inline void LogToStderr() {} inline void LogToStderr() {}
inline void FlushInfoLog() { fflush(nullptr); } inline void FlushInfoLog() { fflush(nullptr); }
@ -995,7 +990,7 @@ inline void FlushInfoLog() { fflush(nullptr); }
// //
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
// is not satisfied. // is not satisfied.
// Synopsys: // Synopsis:
// GTEST_CHECK_(boolean_condition); // GTEST_CHECK_(boolean_condition);
// or // or
// GTEST_CHECK_(boolean_condition) << "Additional message"; // GTEST_CHECK_(boolean_condition) << "Additional message";
@ -1020,8 +1015,7 @@ inline void FlushInfoLog() { fflush(nullptr); }
// branch. // branch.
#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ #define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
if (const int gtest_error = (posix_call)) \ if (const int gtest_error = (posix_call)) \
GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ GTEST_LOG_(FATAL) << #posix_call << "failed with error " << gtest_error
<< gtest_error
// Transforms "T" into "const T&" according to standard reference collapsing // Transforms "T" into "const T&" according to standard reference collapsing
// rules (this is only needed as a backport for C++98 compilers that do not // rules (this is only needed as a backport for C++98 compilers that do not
@ -1035,9 +1029,13 @@ inline void FlushInfoLog() { fflush(nullptr); }
// Note that the non-const reference will not have "const" added. This is // Note that the non-const reference will not have "const" added. This is
// standard, and necessary so that "T" can always bind to "const T&". // standard, and necessary so that "T" can always bind to "const T&".
template <typename T> template <typename T>
struct ConstRef { typedef const T& type; }; struct ConstRef {
typedef const T& type;
};
template <typename T> template <typename T>
struct ConstRef<T&> { typedef T& type; }; struct ConstRef<T&> {
typedef T& type;
};
// The argument T must depend on some template parameters. // The argument T must depend on some template parameters.
#define GTEST_REFERENCE_TO_CONST_(T) \ #define GTEST_REFERENCE_TO_CONST_(T) \
@ -1050,7 +1048,7 @@ struct ConstRef<T&> { typedef T& type; };
// const Foo*). When you use ImplicitCast_, the compiler checks that // const Foo*). When you use ImplicitCast_, the compiler checks that
// the cast is safe. Such explicit ImplicitCast_s are necessary in // the cast is safe. Such explicit ImplicitCast_s are necessary in
// surprisingly many situations where C++ demands an exact type match // surprisingly many situations where C++ demands an exact type match
// instead of an argument type convertable to a target type. // instead of an argument type convertible to a target type.
// //
// The syntax for using ImplicitCast_ is the same as for static_cast: // The syntax for using ImplicitCast_ is the same as for static_cast:
// //
@ -1064,7 +1062,9 @@ struct ConstRef<T&> { typedef T& type; };
// similar functions users may have (e.g., implicit_cast). The internal // similar functions users may have (e.g., implicit_cast). The internal
// namespace alone is not enough because the function can be found by ADL. // namespace alone is not enough because the function can be found by ADL.
template <typename To> template <typename To>
inline To ImplicitCast_(To x) { return x; } inline To ImplicitCast_(To x) {
return x;
}
// When you upcast (that is, cast a pointer from type Foo to type // When you upcast (that is, cast a pointer from type Foo to type
// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts
@ -1162,71 +1162,8 @@ void ClearInjectableArgvs();
// Defines synchronization primitives. // Defines synchronization primitives.
#if GTEST_IS_THREADSAFE #if GTEST_IS_THREADSAFE
# if GTEST_HAS_PTHREAD
// Sleeps for (roughly) n milliseconds. This function is only for testing
// Google Test's own constructs. Don't use it in user tests, either
// directly or indirectly.
inline void SleepMilliseconds(int n) {
const timespec time = {
0, // 0 seconds.
n * 1000L * 1000L, // And n ms.
};
nanosleep(&time, nullptr);
}
# endif // GTEST_HAS_PTHREAD
# if GTEST_HAS_NOTIFICATION_
// Notification has already been imported into the namespace.
// Nothing to do here.
# elif GTEST_HAS_PTHREAD
// Allows a controller thread to pause execution of newly created
// threads until notified. Instances of this class must be created
// and destroyed in the controller thread.
//
// This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly.
class Notification {
public:
Notification() : notified_(false) {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
}
~Notification() {
pthread_mutex_destroy(&mutex_);
}
// Notifies all threads created with this notification to start. Must
// be called from the controller thread.
void Notify() {
pthread_mutex_lock(&mutex_);
notified_ = true;
pthread_mutex_unlock(&mutex_);
}
// Blocks until the controller thread notifies. Must be called from a test
// thread.
void WaitForNotification() {
for (;;) {
pthread_mutex_lock(&mutex_);
const bool notified = notified_;
pthread_mutex_unlock(&mutex_);
if (notified)
break;
SleepMilliseconds(10);
}
}
private:
pthread_mutex_t mutex_;
bool notified_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
};
# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
GTEST_API_ void SleepMilliseconds(int n);
#if GTEST_OS_WINDOWS
// Provides leak-safe Windows kernel handle ownership. // Provides leak-safe Windows kernel handle ownership.
// Used in death tests and in threading support. // Used in death tests and in threading support.
class GTEST_API_ AutoHandle { class GTEST_API_ AutoHandle {
@ -1253,8 +1190,18 @@ class GTEST_API_ AutoHandle {
Handle handle_; Handle handle_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); AutoHandle(const AutoHandle&) = delete;
AutoHandle& operator=(const AutoHandle&) = delete;
}; };
#endif
#if GTEST_HAS_NOTIFICATION_
// Notification has already been imported into the namespace.
// Nothing to do here.
#else
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
// Allows a controller thread to pause execution of newly created // Allows a controller thread to pause execution of newly created
// threads until notified. Instances of this class must be created // threads until notified. Instances of this class must be created
@ -1262,17 +1209,34 @@ class GTEST_API_ AutoHandle {
// //
// This class is only for testing Google Test's own constructs. Do not // This class is only for testing Google Test's own constructs. Do not
// use it in user tests, either directly or indirectly. // use it in user tests, either directly or indirectly.
// TODO(b/203539622): Replace unconditionally with absl::Notification.
class GTEST_API_ Notification { class GTEST_API_ Notification {
public: public:
Notification(); Notification() : notified_(false) {}
void Notify(); Notification(const Notification&) = delete;
void WaitForNotification(); Notification& operator=(const Notification&) = delete;
// Notifies all threads created with this notification to start. Must
// be called from the controller thread.
void Notify() {
std::lock_guard<std::mutex> lock(mu_);
notified_ = true;
cv_.notify_all();
}
// Blocks until the controller thread notifies. Must be called from a test
// thread.
void WaitForNotification() {
std::unique_lock<std::mutex> lock(mu_);
cv_.wait(lock, [this]() { return notified_; });
}
private: private:
AutoHandle event_; std::mutex mu_;
std::condition_variable cv_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); bool notified_;
}; };
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_HAS_NOTIFICATION_ #endif // GTEST_HAS_NOTIFICATION_
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD // On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
@ -1354,7 +1318,8 @@ class ThreadWithParam : public ThreadWithParamBase {
// finished. // finished.
pthread_t thread_; // The native thread object. pthread_t thread_; // The native thread object.
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); ThreadWithParam(const ThreadWithParam&) = delete;
ThreadWithParam& operator=(const ThreadWithParam&) = delete;
}; };
#endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || #endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD ||
// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
@ -1417,7 +1382,8 @@ class GTEST_API_ Mutex {
long critical_section_init_phase_; // NOLINT long critical_section_init_phase_; // NOLINT
GTEST_CRITICAL_SECTION* critical_section_; GTEST_CRITICAL_SECTION* critical_section_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); Mutex(const Mutex&) = delete;
Mutex& operator=(const Mutex&) = delete;
}; };
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ #define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
@ -1433,15 +1399,15 @@ class GTEST_API_ Mutex {
// "MutexLock l(&mu)". Hence the typedef trick below. // "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock { class GTestMutexLock {
public: public:
explicit GTestMutexLock(Mutex* mutex) explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
: mutex_(mutex) { mutex_->Lock(); }
~GTestMutexLock() { mutex_->Unlock(); } ~GTestMutexLock() { mutex_->Unlock(); }
private: private:
Mutex* const mutex_; Mutex* const mutex_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
}; };
typedef GTestMutexLock MutexLock; typedef GTestMutexLock MutexLock;
@ -1468,7 +1434,8 @@ class ThreadLocalBase {
virtual ~ThreadLocalBase() {} virtual ~ThreadLocalBase() {}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); ThreadLocalBase(const ThreadLocalBase&) = delete;
ThreadLocalBase& operator=(const ThreadLocalBase&) = delete;
}; };
// Maps a thread to a set of ThreadLocals that have values instantiated on that // Maps a thread to a set of ThreadLocals that have values instantiated on that
@ -1511,30 +1478,26 @@ class ThreadWithParam : public ThreadWithParamBase {
typedef void UserThreadFunc(T); typedef void UserThreadFunc(T);
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}
}
virtual ~ThreadWithParam() {} virtual ~ThreadWithParam() {}
private: private:
class RunnableImpl : public Runnable { class RunnableImpl : public Runnable {
public: public:
RunnableImpl(UserThreadFunc* func, T param) RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}
: func_(func),
param_(param) {
}
virtual ~RunnableImpl() {} virtual ~RunnableImpl() {}
virtual void Run() { virtual void Run() { func_(param_); }
func_(param_);
}
private: private:
UserThreadFunc* const func_; UserThreadFunc* const func_;
const T param_; const T param_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); RunnableImpl(const RunnableImpl&) = delete;
RunnableImpl& operator=(const RunnableImpl&) = delete;
}; };
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); ThreadWithParam(const ThreadWithParam&) = delete;
ThreadWithParam& operator=(const ThreadWithParam&) = delete;
}; };
// Implements thread-local storage on Windows systems. // Implements thread-local storage on Windows systems.
@ -1571,7 +1534,7 @@ class ThreadLocal : public ThreadLocalBase {
explicit ThreadLocal(const T& value) explicit ThreadLocal(const T& value)
: default_factory_(new InstanceValueHolderFactory(value)) {} : default_factory_(new InstanceValueHolderFactory(value)) {}
~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } ~ThreadLocal() override { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }
T* pointer() { return GetOrCreateValue(); } T* pointer() { return GetOrCreateValue(); }
const T* pointer() const { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); }
@ -1590,16 +1553,17 @@ class ThreadLocal : public ThreadLocalBase {
private: private:
T value_; T value_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); ValueHolder(const ValueHolder&) = delete;
ValueHolder& operator=(const ValueHolder&) = delete;
}; };
T* GetOrCreateValue() const { T* GetOrCreateValue() const {
return static_cast<ValueHolder*>( return static_cast<ValueHolder*>(
ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); ThreadLocalRegistry::GetValueOnCurrentThread(this))
->pointer();
} }
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { ThreadLocalValueHolderBase* NewValueForCurrentThread() const override {
return default_factory_->MakeNewHolder(); return default_factory_->MakeNewHolder();
} }
@ -1610,7 +1574,8 @@ class ThreadLocal : public ThreadLocalBase {
virtual ValueHolder* MakeNewHolder() const = 0; virtual ValueHolder* MakeNewHolder() const = 0;
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); ValueHolderFactory(const ValueHolderFactory&) = delete;
ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;
}; };
class DefaultValueHolderFactory : public ValueHolderFactory { class DefaultValueHolderFactory : public ValueHolderFactory {
@ -1619,7 +1584,9 @@ class ThreadLocal : public ThreadLocalBase {
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;
DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =
delete;
}; };
class InstanceValueHolderFactory : public ValueHolderFactory { class InstanceValueHolderFactory : public ValueHolderFactory {
@ -1632,12 +1599,15 @@ class ThreadLocal : public ThreadLocalBase {
private: private:
const T value_; // The value for each thread. const T value_; // The value for each thread.
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;
InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =
delete;
}; };
std::unique_ptr<ValueHolderFactory> default_factory_; std::unique_ptr<ValueHolderFactory> default_factory_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); ThreadLocal(const ThreadLocal&) = delete;
ThreadLocal& operator=(const ThreadLocal&) = delete;
}; };
#elif GTEST_HAS_PTHREAD #elif GTEST_HAS_PTHREAD
@ -1707,12 +1677,11 @@ class Mutex : public MutexBase {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
has_owner_ = false; has_owner_ = false;
} }
~Mutex() { ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); }
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
}
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); Mutex(const Mutex&) = delete;
Mutex& operator=(const Mutex&) = delete;
}; };
// We cannot name this class MutexLock because the ctor declaration would // We cannot name this class MutexLock because the ctor declaration would
@ -1722,15 +1691,15 @@ class Mutex : public MutexBase {
// "MutexLock l(&mu)". Hence the typedef trick below. // "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock { class GTestMutexLock {
public: public:
explicit GTestMutexLock(MutexBase* mutex) explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }
: mutex_(mutex) { mutex_->Lock(); }
~GTestMutexLock() { mutex_->Unlock(); } ~GTestMutexLock() { mutex_->Unlock(); }
private: private:
MutexBase* const mutex_; MutexBase* const mutex_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
}; };
typedef GTestMutexLock MutexLock; typedef GTestMutexLock MutexLock;
@ -1787,7 +1756,8 @@ class GTEST_API_ ThreadLocal {
private: private:
T value_; T value_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); ValueHolder(const ValueHolder&) = delete;
ValueHolder& operator=(const ValueHolder&) = delete;
}; };
static pthread_key_t CreateKey() { static pthread_key_t CreateKey() {
@ -1819,7 +1789,8 @@ class GTEST_API_ ThreadLocal {
virtual ValueHolder* MakeNewHolder() const = 0; virtual ValueHolder* MakeNewHolder() const = 0;
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); ValueHolderFactory(const ValueHolderFactory&) = delete;
ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;
}; };
class DefaultValueHolderFactory : public ValueHolderFactory { class DefaultValueHolderFactory : public ValueHolderFactory {
@ -1828,7 +1799,9 @@ class GTEST_API_ ThreadLocal {
ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;
DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =
delete;
}; };
class InstanceValueHolderFactory : public ValueHolderFactory { class InstanceValueHolderFactory : public ValueHolderFactory {
@ -1841,14 +1814,17 @@ class GTEST_API_ ThreadLocal {
private: private:
const T value_; // The value for each thread. const T value_; // The value for each thread.
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;
InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =
delete;
}; };
// A key pthreads uses for looking up per-thread values. // A key pthreads uses for looking up per-thread values.
const pthread_key_t key_; const pthread_key_t key_;
std::unique_ptr<ValueHolderFactory> default_factory_; std::unique_ptr<ValueHolderFactory> default_factory_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); ThreadLocal(const ThreadLocal&) = delete;
ThreadLocal& operator=(const ThreadLocal&) = delete;
}; };
#endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ #endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_
@ -1894,6 +1870,7 @@ class GTEST_API_ ThreadLocal {
const T* pointer() const { return &value_; } const T* pointer() const { return &value_; }
const T& get() const { return value_; } const T& get() const { return value_; }
void set(const T& value) { value_ = value; } void set(const T& value) { value_ = value; }
private: private:
T value_; T value_;
}; };
@ -1967,8 +1944,7 @@ inline char ToUpper(char ch) {
inline std::string StripTrailingSpaces(std::string str) { inline std::string StripTrailingSpaces(std::string str) {
std::string::iterator it = str.end(); std::string::iterator it = str.end();
while (it != str.begin() && IsSpace(*--it)) while (it != str.begin() && IsSpace(*--it)) it = str.erase(it);
it = str.erase(it);
return str; return str;
} }
@ -1993,7 +1969,8 @@ inline int StrCaseCmp(const char* s1, const char* s2) {
} }
inline char* StrDup(const char* src) { return strdup(src); } inline char* StrDup(const char* src) { return strdup(src); }
#else // !__BORLANDC__ #else // !__BORLANDC__
# if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \
GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM)
inline int DoIsATTY(int /* fd */) { return 0; } inline int DoIsATTY(int /* fd */) { return 0; }
#else #else
inline int DoIsATTY(int fd) { return _isatty(fd); } inline int DoIsATTY(int fd) { return _isatty(fd); }
@ -2012,9 +1989,7 @@ inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
inline int FileNo(FILE* file) { return _fileno(file); } inline int FileNo(FILE* file) { return _fileno(file); }
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
inline int RmDir(const char* dir) { return _rmdir(dir); } inline int RmDir(const char* dir) { return _rmdir(dir); }
inline bool IsDir(const StatStruct& st) { inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
return (_S_IFDIR & st.st_mode) != 0;
}
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
#elif GTEST_OS_ESP8266 #elif GTEST_OS_ESP8266
@ -2202,32 +2177,79 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
// Macro for referencing flags. // Macro for referencing flags.
#if !defined(GTEST_FLAG) #if !defined(GTEST_FLAG)
#define GTEST_FLAG_NAME_(name) gtest_##name
#define GTEST_FLAG(name) FLAGS_gtest_##name #define GTEST_FLAG(name) FLAGS_gtest_##name
#endif // !defined(GTEST_FLAG) #endif // !defined(GTEST_FLAG)
#if !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) // Pick a command line flags implementation.
# define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 #if GTEST_HAS_ABSL
#endif // !defined(GTEST_USE_OWN_FLAGFILE_FLAG_)
#if !defined(GTEST_DECLARE_bool_)
# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
// Macros for declaring flags.
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
# define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern std::int32_t GTEST_FLAG(name)
# define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::std::string GTEST_FLAG(name)
// Macros for defining flags. // Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \ #define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GTEST_FLAG(name) = (default_val) ABSL_FLAG(bool, GTEST_FLAG_NAME_(name), default_val, doc)
#define GTEST_DEFINE_int32_(name, default_val, doc) \ #define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val) ABSL_FLAG(int32_t, GTEST_FLAG_NAME_(name), default_val, doc)
#define GTEST_DEFINE_string_(name, default_val, doc) \ #define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) ABSL_FLAG(std::string, GTEST_FLAG_NAME_(name), default_val, doc)
#endif // !defined(GTEST_DECLARE_bool_) // Macros for declaring flags.
#define GTEST_DECLARE_bool_(name) \
ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))
#define GTEST_DECLARE_int32_(name) \
ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))
#define GTEST_DECLARE_string_(name) \
ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))
#define GTEST_FLAG_SAVER_ ::absl::FlagSaver
#define GTEST_FLAG_GET(name) ::absl::GetFlag(GTEST_FLAG(name))
#define GTEST_FLAG_SET(name, value) \
(void)(::absl::SetFlag(&GTEST_FLAG(name), value))
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
#else // GTEST_HAS_ABSL
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
namespace testing { \
GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_int32_(name, default_val, doc) \
namespace testing { \
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_string_(name, default_val, doc) \
namespace testing { \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
// Macros for declaring flags.
#define GTEST_DECLARE_bool_(name) \
namespace testing { \
GTEST_API_ extern bool GTEST_FLAG(name); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DECLARE_int32_(name) \
namespace testing { \
GTEST_API_ extern std::int32_t GTEST_FLAG(name); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DECLARE_string_(name) \
namespace testing { \
GTEST_API_ extern ::std::string GTEST_FLAG(name); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name)
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
#endif // GTEST_HAS_ABSL
// Thread annotations // Thread annotations
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) #if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
@ -2308,6 +2330,7 @@ namespace testing {
namespace internal { namespace internal {
template <typename T> template <typename T>
using Optional = ::absl::optional<T>; using Optional = ::absl::optional<T>;
inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#else #else
@ -2321,6 +2344,7 @@ namespace testing {
namespace internal { namespace internal {
template <typename T> template <typename T>
using Optional = ::std::optional<T>; using Optional = ::std::optional<T>;
inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
// The case where absl is configured NOT to alias std::optional is not // The case where absl is configured NOT to alias std::optional is not

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,7 +36,9 @@
// 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_
@ -47,6 +49,7 @@
#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_
@ -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.

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.
@ -111,7 +110,8 @@ int main(int argc, char **argv) {
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

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

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,9 +84,7 @@ 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) {

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);
} }
@ -108,7 +101,8 @@ int main(int argc, char **argv) {
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

@ -0,0 +1,77 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file defines the AssertionResult type.
#include "gtest/gtest-assertion-result.h"
#include <string>
#include <utility>
#include "gtest/gtest-message.h"
namespace testing {
// AssertionResult constructors.
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult::AssertionResult(const AssertionResult& other)
: success_(other.success_),
message_(other.message_.get() != nullptr
? new ::std::string(*other.message_)
: static_cast< ::std::string*>(nullptr)) {}
// Swaps two AssertionResults.
void AssertionResult::swap(AssertionResult& other) {
using std::swap;
swap(success_, other.success_);
swap(message_, other.message_);
}
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult AssertionResult::operator!() const {
AssertionResult negation(!success_);
if (message_.get() != nullptr) negation << *message_;
return negation;
}
// Makes a successful assertion result.
AssertionResult AssertionSuccess() { return AssertionResult(true); }
// Makes a failed assertion result.
AssertionResult AssertionFailure() { return AssertionResult(false); }
// Makes a failed assertion result with the given failure message.
// Deprecated; use AssertionFailure() << message.
AssertionResult AssertionFailure(const Message& message) {
return AssertionFailure() << message;
}
} // namespace testing

View File

@ -35,8 +35,8 @@
#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
@ -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
@ -148,12 +151,12 @@ bool InDeathTestChild() {
// 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,8 +165,7 @@ 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 {
@ -180,8 +182,7 @@ bool ExitedWithCode::operator()(int exit_status) const {
#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 {
@ -307,10 +308,10 @@ static void DeathTestAbort(const std::string& message) {
#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())
@ -328,10 +329,10 @@ static void DeathTestAbort(const std::string& message) {
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.,
@ -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:
@ -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.
@ -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 =
@ -1039,30 +1030,27 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
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();
@ -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_;
@ -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,8 +1237,7 @@ 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
@ -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);
@ -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();
@ -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());
@ -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;
} }
@ -1482,32 +1465,32 @@ 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;
} }
@ -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) +
@ -1584,14 +1564,14 @@ static int GetStatusFileDescriptor(unsigned int parent_process_id,
// initialized from the GTEST_FLAG(internal_run_death_test) flag if // initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL. // the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
if (GTEST_FLAG(internal_run_death_test) == "") return 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
@ -1600,36 +1580,32 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
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

View File

@ -30,8 +30,9 @@
#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>
@ -40,6 +41,7 @@
#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
@ -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());
} }
@ -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
@ -238,8 +238,8 @@ bool FilePath::DirectoryExists() const {
} }
#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
@ -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

@ -58,14 +58,12 @@
#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,21 +27,22 @@
// (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. #include <map> // Used in ThreadLocal.
#ifdef _MSC_VER #ifdef _MSC_VER
#include <crtdbg.h> #include <crtdbg.h>
@ -80,8 +81,8 @@
#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.
@ -1083,15 +1040,14 @@ class CapturedStream {
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
@ -1156,9 +1112,7 @@ class CapturedStream {
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);

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
@ -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_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
static CharFormat PrintCharsAsStringTo( PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
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_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void
static void UniversalPrintCharArray( UniversalPrintCharArray(const CharType* begin, size_t len,
const CharType* begin, size_t len, ostream* os) { 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'.
@ -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(); }

View File

@ -263,6 +263,14 @@ IF(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
ENDIF() ENDIF()
IF (ASSIMP_WARNINGS_AS_ERRORS)
IF (MSVC)
TARGET_COMPILE_OPTIONS(unit PRIVATE /W4 /WX)
ELSE()
TARGET_COMPILE_OPTIONS(unit PRIVATE -Wall -Werror)
ENDIF()
ENDIF()
target_link_libraries( unit assimp ${platform_libs} ) target_link_libraries( unit assimp ${platform_libs} )
add_subdirectory(headercheck) add_subdirectory(headercheck)

View File

@ -64,7 +64,7 @@ public:
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
EXPECT_NE(nullptr, scene->mMaterials); EXPECT_NE(nullptr, scene->mMaterials);
aiShadingMode shading_mode; aiShadingMode shading_mode = aiShadingMode_Flat;
scene->mMaterials[0]->Get(AI_MATKEY_SHADING_MODEL, shading_mode); scene->mMaterials[0]->Get(AI_MATKEY_SHADING_MODEL, shading_mode);
EXPECT_EQ(aiShadingMode_Flat, shading_mode); EXPECT_EQ(aiShadingMode_Flat, shading_mode);
} }
@ -90,7 +90,7 @@ public:
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
EXPECT_NE(nullptr, scene->mMaterials); EXPECT_NE(nullptr, scene->mMaterials);
aiBlendMode blend_mode; aiBlendMode blend_mode = aiBlendMode_Default;
scene->mMaterials[0]->Get(AI_MATKEY_BLEND_FUNC, blend_mode); scene->mMaterials[0]->Get(AI_MATKEY_BLEND_FUNC, blend_mode);
EXPECT_EQ(aiBlendMode_Additive, blend_mode); EXPECT_EQ(aiBlendMode_Additive, blend_mode);
} }
@ -104,14 +104,14 @@ public:
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
EXPECT_NE(nullptr, scene->mMaterials); EXPECT_NE(nullptr, scene->mMaterials);
int texture_flags; int texture_flags = 0;
scene->mMaterials[0]->Get(AI_MATKEY_TEXFLAGS_DIFFUSE(0), texture_flags); scene->mMaterials[0]->Get(AI_MATKEY_TEXFLAGS_DIFFUSE(0), texture_flags);
EXPECT_EQ(aiTextureFlags_UseAlpha, texture_flags); EXPECT_EQ(aiTextureFlags_UseAlpha, texture_flags);
// The model has only one texture, a 256 color bitmap with // The model has only one texture, a 256 color bitmap with
// a palette. Pure blue is the last color in the palette, // a palette. Pure blue is the last color in the palette,
// and should be the transparency color. // and should be the transparency color.
aiColor3D transparency_color; aiColor3D transparency_color = {};
scene->mMaterials[0]->Get(AI_MATKEY_COLOR_TRANSPARENT, transparency_color); scene->mMaterials[0]->Get(AI_MATKEY_COLOR_TRANSPARENT, transparency_color);
EXPECT_EQ(aiColor3D(0, 0, 255), transparency_color); EXPECT_EQ(aiColor3D(0, 0, 255), transparency_color);
} }

View File

@ -53,6 +53,11 @@ protected:
void checkMesh(const aiMesh &mesh); void checkMesh(const aiMesh &mesh);
}; };
// ------------------------------------------------------------------------------------------------
static unsigned int foo() {
return static_cast<unsigned int>(((float)rand() / static_cast<float>(RAND_MAX)) * 499);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
TEST_F(VTAdjacencyTest, largeRandomDataSet) { TEST_F(VTAdjacencyTest, largeRandomDataSet) {
// build a test mesh with randomized input data // build a test mesh with randomized input data
@ -72,11 +77,8 @@ TEST_F(VTAdjacencyTest, largeRandomDataSet) {
if (499 == iCurrent) iCurrent = 0; if (499 == iCurrent) iCurrent = 0;
face.mIndices[0] = iCurrent++; face.mIndices[0] = iCurrent++;
while (face.mIndices[0] == (face.mIndices[1] = (unsigned int)(((float)rand() / RAND_MAX) * 499))) while (face.mIndices[0] == (face.mIndices[1] = foo()));
; while (face.mIndices[0] == (face.mIndices[2] = foo()) || face.mIndices[1] == face.mIndices[2]);
while (face.mIndices[0] == (face.mIndices[2] = (unsigned int)(((float)rand() / RAND_MAX) * 499)) ||
face.mIndices[1] == face.mIndices[2])
;
} }
checkMesh(mesh); checkMesh(mesh);

View File

@ -2,8 +2,6 @@
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# #
# Copyright (c) 2006-2022, assimp team # Copyright (c) 2006-2022, assimp team
# All rights reserved. # All rights reserved.
# #
# Redistribution and use of this software in source and binary forms, # Redistribution and use of this software in source and binary forms,
@ -62,6 +60,14 @@ ADD_EXECUTABLE( assimp_cmd
${ASSIMP_CMD_RC} ${ASSIMP_CMD_RC}
) )
IF (ASSIMP_WARNINGS_AS_ERRORS)
IF (MSVC)
TARGET_COMPILE_OPTIONS(assimp_cmd PRIVATE /W4 /WX)
ELSE()
TARGET_COMPILE_OPTIONS(assimp_cmd PRIVATE -Wall -Werror)
ENDIF()
ENDIF()
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp_cmd) TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp_cmd)
SET_PROPERTY(TARGET assimp_cmd PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) SET_PROPERTY(TARGET assimp_cmd PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})

View File

@ -95,6 +95,14 @@ IF ( MSVC )
REMOVE_DEFINITIONS( -DUNICODE -D_UNICODE ) REMOVE_DEFINITIONS( -DUNICODE -D_UNICODE )
ENDIF () ENDIF ()
IF (ASSIMP_WARNINGS_AS_ERRORS)
IF (MSVC)
TARGET_COMPILE_OPTIONS(assimp_viewer PRIVATE /W4 /WX)
ELSE()
TARGET_COMPILE_OPTIONS(assimp_viewer PRIVATE -Wall -Werror)
ENDIF()
ENDIF()
# Link the executable to the assimp + dx libs. # Link the executable to the assimp + dx libs.
TARGET_LINK_LIBRARIES ( assimp_viewer assimp ${DirectX_LIBRARY} ${DirectX_D3DX9_LIBRARY} comctl32 winmm ) TARGET_LINK_LIBRARIES ( assimp_viewer assimp ${DirectX_LIBRARY} ${DirectX_D3DX9_LIBRARY} comctl32 winmm )