Merge pull request #4731 from assimp/kimkulling/add_check_for_wall_enable_issue-4652
Add check for wall switch from cmakepull/4730/head^2
commit
8d9a0f777d
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
|
@ -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) { ... }
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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_
|
|
@ -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)); \
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
>est_##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 {} \
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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, >est_failures);\
|
INTERCEPT_ONLY_CURRENT_THREAD, \
|
||||||
|
>est_failures); \
|
||||||
GTestExpectFatalFailureHelper::Execute(); \
|
GTestExpectFatalFailureHelper::Execute(); \
|
||||||
} \
|
} \
|
||||||
} while (::testing::internal::AlwaysFalse())
|
} while (::testing::internal::AlwaysFalse())
|
||||||
|
@ -169,16 +173,17 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
|
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
|
||||||
{ \
|
{ \
|
||||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
||||||
::testing::ScopedFakeTestPartResultReporter:: \
|
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||||
INTERCEPT_ALL_THREADS, >est_failures);\
|
>est_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, >est_failures);\
|
INTERCEPT_ONLY_CURRENT_THREAD, \
|
||||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
>est_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, \
|
||||||
>est_failures); \
|
>est_failures); \
|
||||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
if (::testing::internal::AlwaysTrue()) { \
|
||||||
|
statement; \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} while (::testing::internal::AlwaysFalse())
|
} while (::testing::internal::AlwaysFalse())
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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)`
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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; \
|
||||||
|
|
|
@ -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(¶meter_);
|
TestClass::SetParam(¶meter_);
|
||||||
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()...),
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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(>EST_FLAG(name), value))
|
||||||
|
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
|
||||||
|
|
||||||
|
#else // GTEST_HAS_ABSL
|
||||||
|
|
||||||
|
// Macros for defining flags.
|
||||||
|
#define GTEST_DEFINE_bool_(name, default_val, doc) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ bool GTEST_FLAG(name) = (default_val); \
|
||||||
|
} \
|
||||||
|
static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GTEST_DEFINE_int32_(name, default_val, doc) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \
|
||||||
|
} \
|
||||||
|
static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GTEST_DEFINE_string_(name, default_val, doc) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
|
||||||
|
} \
|
||||||
|
static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
|
||||||
|
// Macros for declaring flags.
|
||||||
|
#define GTEST_DECLARE_bool_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern bool GTEST_FLAG(name); \
|
||||||
|
} \
|
||||||
|
static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GTEST_DECLARE_int32_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern std::int32_t GTEST_FLAG(name); \
|
||||||
|
} \
|
||||||
|
static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
#define GTEST_DECLARE_string_(name) \
|
||||||
|
namespace testing { \
|
||||||
|
GTEST_API_ extern ::std::string GTEST_FLAG(name); \
|
||||||
|
} \
|
||||||
|
static_assert(true, "no-op to require trailing semicolon")
|
||||||
|
|
||||||
|
#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver
|
||||||
|
|
||||||
|
#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name)
|
||||||
|
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
|
||||||
|
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_ABSL
|
||||||
|
|
||||||
// Thread annotations
|
// 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
// A simple string class.
|
// A simple string class.
|
||||||
class MyString {
|
class MyString {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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_);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
|
@ -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'
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -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
|
|
|
@ -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)
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -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
|
@ -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()
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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(); }
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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})
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue