Updating to latest gmock & gtest

This commit is contained in:
Strahinja Val Markovic 2013-02-02 21:47:41 -08:00
parent 6d127c651e
commit fc1009913e
68 changed files with 1007 additions and 485 deletions

View File

@ -18,10 +18,11 @@
project( ycm_core_tests ) project( ycm_core_tests )
cmake_minimum_required( VERSION 2.8 ) cmake_minimum_required( VERSION 2.8 )
# The gtest library triggers these silly warnings, so we turn them off # The gtest library triggers these warnings, so we turn them off; it's not up to
# us to fix gtest warnings, it's up to upstream.
if ( COMPILER_IS_CLANG ) if ( COMPILER_IS_CLANG )
set( CMAKE_CXX_FLAGS set( CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wno-long-long -Wno-variadic-macros" ) "${CMAKE_CXX_FLAGS} -Wno-long-long -Wno-variadic-macros -Wno-missing-field-initializers -Wno-unused-private-field" )
endif() endif()
add_subdirectory( gmock ) add_subdirectory( gmock )
@ -32,8 +33,8 @@ include_directories(
include_directories( include_directories(
SYSTEM SYSTEM
${gtest_ycm_SOURCE_DIR} ${gtest_SOURCE_DIR}
${gtest_ycm_SOURCE_DIR}/include ${gtest_SOURCE_DIR}/include
${gmock_SOURCE_DIR} ${gmock_SOURCE_DIR}
${gmock_SOURCE_DIR}/include ${gmock_SOURCE_DIR}/include
) )

View File

@ -58,10 +58,10 @@ config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
# Adds Google Mock's and Google Test's header directories to the search path. # Adds Google Mock's and Google Test's header directories to the search path.
include_directories("${gmock_SOURCE_DIR}/include" include_directories("${gmock_SOURCE_DIR}/include"
"${gmock_SOURCE_DIR}" "${gmock_SOURCE_DIR}"
"${gtest_ycm_SOURCE_DIR}/include" "${gtest_SOURCE_DIR}/include"
# This directory is needed to build directly from Google # This directory is needed to build directly from Google
# Test sources. # Test sources.
"${gtest_ycm_SOURCE_DIR}") "${gtest_SOURCE_DIR}")
######################################################################## ########################################################################
# #

View File

@ -1,7 +1,7 @@
# Automake file # Automake file
# Nonstandard package files for distribution. # Nonstandard package files for distribution.
EXTRA_DIST = EXTRA_DIST = LICENSE
# We may need to build our internally packaged gtest. If so, it will be # We may need to build our internally packaged gtest. If so, it will be
# included in the 'subdirs' variable. # included in the 'subdirs' variable.

View File

@ -39,7 +39,7 @@ endif()
# as ${gtest_SOURCE_DIR} and to the root binary directory as # as ${gtest_SOURCE_DIR} and to the root binary directory as
# ${gtest_BINARY_DIR}. # ${gtest_BINARY_DIR}.
# Language "C" is required for find_package(Threads). # Language "C" is required for find_package(Threads).
project(gtest_ycm CXX C) project(gtest CXX C)
cmake_minimum_required(VERSION 2.6.2) cmake_minimum_required(VERSION 2.6.2)
if (COMMAND set_up_hermetic_build) if (COMMAND set_up_hermetic_build)
@ -53,11 +53,11 @@ config_compiler_and_linker() # Defined in internal_utils.cmake.
# Where Google Test's .h files can be found. # Where Google Test's .h files can be found.
include_directories( include_directories(
${gtest_ycm_SOURCE_DIR}/include ${gtest_SOURCE_DIR}/include
${gtest_ycm_SOURCE_DIR}) ${gtest_SOURCE_DIR})
# Where Google Test's libraries can be found. # Where Google Test's libraries can be found.
link_directories(${gtest_ycm_BINARY_DIR}/src) link_directories(${gtest_BINARY_DIR}/src)
######################################################################## ########################################################################
# #
@ -67,9 +67,9 @@ link_directories(${gtest_ycm_BINARY_DIR}/src)
# Google Test libraries. We build them using more strict warnings than what # Google Test libraries. We build them using more strict warnings than what
# are used for other targets, to ensure that gtest can be compiled by a user # are used for other targets, to ensure that gtest can be compiled by a user
# aggressive about warnings. # aggressive about warnings.
cxx_library(gtest_ycm "${cxx_strict}" src/gtest-all.cc) cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
cxx_library(gtest_ycm_main "${cxx_strict}" src/gtest_main.cc) cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
target_link_libraries(gtest_ycm_main gtest_ycm) target_link_libraries(gtest_main gtest)
######################################################################## ########################################################################
# #
@ -80,16 +80,16 @@ target_link_libraries(gtest_ycm_main gtest_ycm)
# or specifying the -Dbuild_gtest_samples=ON flag when running cmake. # or specifying the -Dbuild_gtest_samples=ON flag when running cmake.
if (gtest_build_samples) if (gtest_build_samples)
cxx_executable(sample1_unittest samples gtest_ycm_main samples/sample1.cc) cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
cxx_executable(sample2_unittest samples gtest_ycm_main samples/sample2.cc) cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)
cxx_executable(sample3_unittest samples gtest_ycm_main) cxx_executable(sample3_unittest samples gtest_main)
cxx_executable(sample4_unittest samples gtest_ycm_main samples/sample4.cc) cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)
cxx_executable(sample5_unittest samples gtest_ycm_main samples/sample1.cc) cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)
cxx_executable(sample6_unittest samples gtest_ycm_main) cxx_executable(sample6_unittest samples gtest_main)
cxx_executable(sample7_unittest samples gtest_ycm_main) cxx_executable(sample7_unittest samples gtest_main)
cxx_executable(sample8_unittest samples gtest_ycm_main) cxx_executable(sample8_unittest samples gtest_main)
cxx_executable(sample9_unittest samples gtest_ycm) cxx_executable(sample9_unittest samples gtest)
cxx_executable(sample10_unittest samples gtest_ycm) cxx_executable(sample10_unittest samples gtest)
endif() endif()
######################################################################## ########################################################################
@ -111,31 +111,31 @@ if (gtest_build_tests)
############################################################ ############################################################
# C++ tests built with standard compiler flags. # C++ tests built with standard compiler flags.
cxx_test(gtest-death-test_test gtest_ycm_main) cxx_test(gtest-death-test_test gtest_main)
cxx_test(gtest_environment_test gtest_ycm) cxx_test(gtest_environment_test gtest)
cxx_test(gtest-filepath_test gtest_ycm_main) cxx_test(gtest-filepath_test gtest_main)
cxx_test(gtest-linked_ptr_test gtest_ycm_main) cxx_test(gtest-linked_ptr_test gtest_main)
cxx_test(gtest-listener_test gtest_ycm_main) cxx_test(gtest-listener_test gtest_main)
cxx_test(gtest_main_unittest gtest_ycm_main) cxx_test(gtest_main_unittest gtest_main)
cxx_test(gtest-message_test gtest_ycm_main) cxx_test(gtest-message_test gtest_main)
cxx_test(gtest_no_test_unittest gtest_ycm) cxx_test(gtest_no_test_unittest gtest)
cxx_test(gtest-options_test gtest_ycm_main) cxx_test(gtest-options_test gtest_main)
cxx_test(gtest-param-test_test gtest_ycm cxx_test(gtest-param-test_test gtest
test/gtest-param-test2_test.cc) test/gtest-param-test2_test.cc)
cxx_test(gtest-port_test gtest_ycm_main) cxx_test(gtest-port_test gtest_main)
cxx_test(gtest_pred_impl_unittest gtest_ycm_main) cxx_test(gtest_pred_impl_unittest gtest_main)
cxx_test(gtest-printers_test gtest_ycm_main) cxx_test(gtest-printers_test gtest_main)
cxx_test(gtest_prod_test gtest_ycm_main cxx_test(gtest_prod_test gtest_main
test/production.cc) test/production.cc)
cxx_test(gtest_repeat_test gtest_ycm) cxx_test(gtest_repeat_test gtest)
cxx_test(gtest_sole_header_test gtest_ycm_main) cxx_test(gtest_sole_header_test gtest_main)
cxx_test(gtest_stress_test gtest_ycm) cxx_test(gtest_stress_test gtest)
cxx_test(gtest-test-part_test gtest_ycm_main) cxx_test(gtest-test-part_test gtest_main)
cxx_test(gtest_throw_on_failure_ex_test gtest_ycm) cxx_test(gtest_throw_on_failure_ex_test gtest)
cxx_test(gtest-typed-test_test gtest_ycm_main cxx_test(gtest-typed-test_test gtest_main
test/gtest-typed-test2_test.cc) test/gtest-typed-test2_test.cc)
cxx_test(gtest_unittest gtest_ycm_main) cxx_test(gtest_unittest gtest_main)
cxx_test(gtest-unittest-api_test gtest_ycm) cxx_test(gtest-unittest-api_test gtest)
############################################################ ############################################################
# C++ tests built with non-standard compiler flags. # C++ tests built with non-standard compiler flags.
@ -152,10 +152,10 @@ if (gtest_build_tests)
cxx_test_with_flags(gtest-death-test_ex_nocatch_test cxx_test_with_flags(gtest-death-test_ex_nocatch_test
"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0"
gtest_ycm test/gtest-death-test_ex_test.cc) gtest test/gtest-death-test_ex_test.cc)
cxx_test_with_flags(gtest-death-test_ex_catch_test cxx_test_with_flags(gtest-death-test_ex_catch_test
"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1"
gtest_ycm test/gtest-death-test_ex_test.cc) gtest test/gtest-death-test_ex_test.cc)
cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
gtest_main_no_rtti test/gtest_unittest.cc) gtest_main_no_rtti test/gtest_unittest.cc)
@ -189,7 +189,7 @@ if (gtest_build_tests)
############################################################ ############################################################
# Python tests. # Python tests.
cxx_executable(gtest_break_on_failure_unittest_ test gtest_ycm) cxx_executable(gtest_break_on_failure_unittest_ test gtest)
py_test(gtest_break_on_failure_unittest) py_test(gtest_break_on_failure_unittest)
# MSVC 7.1 does not support STL with exceptions disabled. # MSVC 7.1 does not support STL with exceptions disabled.
@ -204,29 +204,29 @@ if (gtest_build_tests)
cxx_executable_with_flags( cxx_executable_with_flags(
gtest_catch_exceptions_ex_test_ gtest_catch_exceptions_ex_test_
"${cxx_exception}" "${cxx_exception}"
gtest_ycm_main gtest_main
test/gtest_catch_exceptions_test_.cc) test/gtest_catch_exceptions_test_.cc)
py_test(gtest_catch_exceptions_test) py_test(gtest_catch_exceptions_test)
cxx_executable(gtest_color_test_ test gtest_ycm) cxx_executable(gtest_color_test_ test gtest)
py_test(gtest_color_test) py_test(gtest_color_test)
cxx_executable(gtest_env_var_test_ test gtest_ycm) cxx_executable(gtest_env_var_test_ test gtest)
py_test(gtest_env_var_test) py_test(gtest_env_var_test)
cxx_executable(gtest_filter_unittest_ test gtest_ycm) cxx_executable(gtest_filter_unittest_ test gtest)
py_test(gtest_filter_unittest) py_test(gtest_filter_unittest)
cxx_executable(gtest_help_test_ test gtest_ycm_main) cxx_executable(gtest_help_test_ test gtest_main)
py_test(gtest_help_test) py_test(gtest_help_test)
cxx_executable(gtest_list_tests_unittest_ test gtest_ycm) cxx_executable(gtest_list_tests_unittest_ test gtest)
py_test(gtest_list_tests_unittest) py_test(gtest_list_tests_unittest)
cxx_executable(gtest_output_test_ test gtest_ycm) cxx_executable(gtest_output_test_ test gtest)
py_test(gtest_output_test) py_test(gtest_output_test)
cxx_executable(gtest_shuffle_test_ test gtest_ycm) cxx_executable(gtest_shuffle_test_ test gtest)
py_test(gtest_shuffle_test) py_test(gtest_shuffle_test)
# MSVC 7.1 does not support STL with exceptions disabled. # MSVC 7.1 does not support STL with exceptions disabled.
@ -238,13 +238,13 @@ if (gtest_build_tests)
py_test(gtest_throw_on_failure_test) py_test(gtest_throw_on_failure_test)
endif() endif()
cxx_executable(gtest_uninitialized_test_ test gtest_ycm) cxx_executable(gtest_uninitialized_test_ test gtest)
py_test(gtest_uninitialized_test) py_test(gtest_uninitialized_test)
cxx_executable(gtest_xml_outfile1_test_ test gtest_ycm_main) cxx_executable(gtest_xml_outfile1_test_ test gtest_main)
cxx_executable(gtest_xml_outfile2_test_ test gtest_ycm_main) cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
py_test(gtest_xml_outfiles_test) py_test(gtest_xml_outfiles_test)
cxx_executable(gtest_xml_output_unittest_ test gtest_ycm) cxx_executable(gtest_xml_output_unittest_ test gtest)
py_test(gtest_xml_output_unittest) py_test(gtest_xml_output_unittest)
endif() endif()

View File

@ -79,7 +79,8 @@ macro(config_compiler_and_linker)
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly. # explicitly.
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags "-Wextra") set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except") set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and # Sun Pro doesn't provide macros to indicate whether exceptions and

View File

@ -51,6 +51,17 @@ GTEST_DECLARE_string_(death_test_style);
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
namespace internal {
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
GTEST_API_ bool InDeathTestChild();
} // namespace internal
// The following macros are useful for writing death tests. // The following macros are useful for writing death tests.
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
@ -75,7 +86,7 @@ GTEST_DECLARE_string_(death_test_style);
// for (int i = 0; i < 5; i++) { // for (int i = 0; i < 5; i++) {
// EXPECT_DEATH(server.ProcessRequest(i), // EXPECT_DEATH(server.ProcessRequest(i),
// "Invalid request .* in ProcessRequest()") // "Invalid request .* in ProcessRequest()")
// << "Failed to die on request " << i); // << "Failed to die on request " << i;
// } // }
// //
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
@ -245,10 +256,10 @@ class GTEST_API_ KilledBySignal {
# ifdef NDEBUG # ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \ # define EXPECT_DEBUG_DEATH(statement, regex) \
do { statement; } while (::testing::internal::AlwaysFalse()) GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \ # define ASSERT_DEBUG_DEATH(statement, regex) \
do { statement; } while (::testing::internal::AlwaysFalse()) GTEST_EXECUTE_STATEMENT_(statement, regex)
# else # else

View File

@ -1257,7 +1257,7 @@ inline internal::ParamGenerator<bool> Bool() {
// Boolean flags: // Boolean flags:
// //
// class FlagDependentTest // class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > { // : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() { // virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple. // // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam(); // tie(external_flag_1, external_flag_2) = GetParam();

View File

@ -414,7 +414,7 @@ inline internal::ParamGenerator<bool> Bool() {
// Boolean flags: // Boolean flags:
// //
// class FlagDependentTest // class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > { // : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() { // virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple. // // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam(); // tie(external_flag_1, external_flag_2) = GetParam();

View File

@ -96,6 +96,7 @@ class GTEST_API_ TestPartResult {
// Returns true iff the test part fatally failed. // Returns true iff the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; } bool fatally_failed() const { return type_ == kFatalFailure; }
private: private:
Type type_; Type type_;

View File

@ -52,6 +52,7 @@
#define GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_
#include <limits> #include <limits>
#include <ostream>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
@ -672,7 +673,6 @@ class GTEST_API_ TestInfo {
const TestResult* result() const { return &result_; } const TestResult* result() const { return &result_; }
private: private:
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
friend class internal::DefaultDeathTestFactory; friend class internal::DefaultDeathTestFactory;
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
@ -1731,12 +1731,6 @@ class TestWithParam : public Test, public WithParamInterface<T> {
// usually want the fail-fast behavior of FAIL and ASSERT_*, but those // usually want the fail-fast behavior of FAIL and ASSERT_*, but those
// writing data-driven tests often find themselves using ADD_FAILURE // writing data-driven tests often find themselves using ADD_FAILURE
// and EXPECT_* more. // and EXPECT_* more.
//
// Examples:
//
// EXPECT_TRUE(server.StatusIsOK());
// ASSERT_FALSE(server.HasPendingRequest(port))
// << "There are still pending requests " << "on port " << port;
// Generates a nonfatal failure with a generic message. // Generates a nonfatal failure with a generic message.
#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")

View File

@ -27,7 +27,7 @@
// (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 09/24/2010 by command // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // '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.

View File

@ -217,6 +217,17 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// The symbol "fail" here expands to something into which a message // The symbol "fail" here expands to something into which a message
// can be streamed. // can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is
// ignored, and the macro must accept a streamed message even though the message
// is never printed.
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else \
::testing::Message()
// A class representing the parsed contents of the // A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when // --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called. // RUN_ALL_TESTS was called.

View File

@ -396,6 +396,13 @@
# define GTEST_HAS_RTTI 0 # define GTEST_HAS_RTTI 0
# endif // __GXX_RTTI # endif // __GXX_RTTI
// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends
// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the
// first version with C++ support.
# elif defined(__clang__)
# define GTEST_HAS_RTTI __has_feature(cxx_rtti)
// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
// both the typeid and dynamic_cast features are present. // both the typeid and dynamic_cast features are present.
# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) # elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
@ -832,6 +839,7 @@ class scoped_ptr {
ptr_ = p; ptr_ = p;
} }
} }
private: private:
T* ptr_; T* ptr_;
@ -1121,22 +1129,37 @@ inline void SleepMilliseconds(int n) {
// use it in user tests, either directly or indirectly. // use it in user tests, either directly or indirectly.
class Notification { class Notification {
public: public:
Notification() : notified_(false) {} Notification() : notified_(false) {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
}
~Notification() {
pthread_mutex_destroy(&mutex_);
}
// Notifies all threads created with this notification to start. Must // Notifies all threads created with this notification to start. Must
// be called from the controller thread. // be called from the controller thread.
void Notify() { notified_ = true; } void Notify() {
pthread_mutex_lock(&mutex_);
notified_ = true;
pthread_mutex_unlock(&mutex_);
}
// Blocks until the controller thread notifies. Must be called from a test // Blocks until the controller thread notifies. Must be called from a test
// thread. // thread.
void WaitForNotification() { void WaitForNotification() {
while(!notified_) { for (;;) {
pthread_mutex_lock(&mutex_);
const bool notified = notified_;
pthread_mutex_unlock(&mutex_);
if (notified)
break;
SleepMilliseconds(10); SleepMilliseconds(10);
} }
} }
private: private:
volatile bool notified_; pthread_mutex_t mutex_;
bool notified_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
}; };
@ -1244,21 +1267,23 @@ class MutexBase {
void Lock() { void Lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self(); owner_ = pthread_self();
has_owner_ = true;
} }
// Releases this mutex. // Releases this mutex.
void Unlock() { void Unlock() {
// We don't protect writing to owner_ here, as it's the caller's // Since the lock is being released the owner_ field should no longer be
// responsibility to ensure that the current thread holds the // considered valid. We don't protect writing to has_owner_ here, as it's
// the caller's responsibility to ensure that the current thread holds the
// mutex when this is called. // mutex when this is called.
owner_ = 0; has_owner_ = false;
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
} }
// Does nothing if the current thread holds the mutex. Otherwise, crashes // Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability. // with high probability.
void AssertHeld() const { void AssertHeld() const {
GTEST_CHECK_(owner_ == pthread_self()) GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))
<< "The current thread is not holding the mutex @" << this; << "The current thread is not holding the mutex @" << this;
} }
@ -1269,7 +1294,14 @@ class MutexBase {
// have to be public. // have to be public.
public: public:
pthread_mutex_t mutex_; // The underlying pthread mutex. pthread_mutex_t mutex_; // The underlying pthread mutex.
pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. // has_owner_ indicates whether the owner_ field below contains a valid thread
// ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All
// accesses to the owner_ field should be protected by a check of this field.
// An alternative might be to memset() owner_ to all zeros, but there's no
// guarantee that a zero'd pthread_t is necessarily invalid or even different
// from pthread_self().
bool has_owner_;
pthread_t owner_; // The thread holding the mutex.
}; };
// Forward-declares a static mutex. // Forward-declares a static mutex.
@ -1277,8 +1309,13 @@ class MutexBase {
extern ::testing::internal::MutexBase mutex extern ::testing::internal::MutexBase mutex
// Defines and statically (i.e. at link time) initializes a static mutex. // Defines and statically (i.e. at link time) initializes a static mutex.
// The initialization list here does not explicitly initialize each field,
// instead relying on default initialization for the unspecified fields. In
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
// This allows initialization to work whether pthread_t is a scalar or struct.
// The flag -Wmissing-field-initializers must not be specified for this to work.
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ # define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
// The Mutex class can only be used for mutexes created at runtime. It // The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise. // shares its API with MutexBase otherwise.
@ -1286,7 +1323,7 @@ class Mutex : public MutexBase {
public: public:
Mutex() { Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
owner_ = 0; has_owner_ = false;
} }
~Mutex() { ~Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
@ -1774,7 +1811,6 @@ class TypeWithSize<4> {
template <> template <>
class TypeWithSize<8> { class TypeWithSize<8> {
public: public:
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
typedef __int64 Int; typedef __int64 Int;
typedef unsigned __int64 UInt; typedef unsigned __int64 UInt;

View File

@ -47,10 +47,10 @@
#endif #endif
#include <string.h> #include <string.h>
#include "gtest/internal/gtest-port.h"
#include <string> #include <string>
#include "gtest/internal/gtest-port.h"
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -223,14 +223,14 @@ class GTEST_API_ String {
// Converting a ::std::string or ::string containing an embedded NUL // Converting a ::std::string or ::string containing an embedded NUL
// character to a String will result in the prefix up to the first // character to a String will result in the prefix up to the first
// NUL character. // NUL character.
String(const ::std::string& str) { String(const ::std::string& str) { // NOLINT
ConstructNonNull(str.c_str(), str.length()); ConstructNonNull(str.c_str(), str.length());
} }
operator ::std::string() const { return ::std::string(c_str(), length()); } operator ::std::string() const { return ::std::string(c_str(), length()); }
#if GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_STRING
String(const ::string& str) { String(const ::string& str) { // NOLINT
ConstructNonNull(str.c_str(), str.length()); ConstructNonNull(str.c_str(), str.length());
} }

View File

@ -1,4 +1,6 @@
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! // This file was GENERATED by command:
// pump.py gtest-tuple.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2009 Google Inc. // Copyright 2009 Google Inc.
// All Rights Reserved. // All Rights Reserved.
@ -140,34 +142,54 @@ template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement; struct TupleElement;
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; }; struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> {
typedef T0 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; }; struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> {
typedef T1 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; }; struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> {
typedef T2 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; }; struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> {
typedef T3 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; }; struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> {
typedef T4 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; }; struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> {
typedef T5 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; }; struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> {
typedef T6 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; }; struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> {
typedef T7 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; }; struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> {
typedef T8 type;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; }; struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> {
typedef T9 type;
};
} // namespace gtest_internal } // namespace gtest_internal
@ -708,37 +730,59 @@ inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
template <typename Tuple> struct tuple_size; template <typename Tuple> struct tuple_size;
template <GTEST_0_TYPENAMES_(T)> template <GTEST_0_TYPENAMES_(T)>
struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; }; struct tuple_size<GTEST_0_TUPLE_(T)> {
static const int value = 0;
};
template <GTEST_1_TYPENAMES_(T)> template <GTEST_1_TYPENAMES_(T)>
struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; }; struct tuple_size<GTEST_1_TUPLE_(T)> {
static const int value = 1;
};
template <GTEST_2_TYPENAMES_(T)> template <GTEST_2_TYPENAMES_(T)>
struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; }; struct tuple_size<GTEST_2_TUPLE_(T)> {
static const int value = 2;
};
template <GTEST_3_TYPENAMES_(T)> template <GTEST_3_TYPENAMES_(T)>
struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; }; struct tuple_size<GTEST_3_TUPLE_(T)> {
static const int value = 3;
};
template <GTEST_4_TYPENAMES_(T)> template <GTEST_4_TYPENAMES_(T)>
struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; }; struct tuple_size<GTEST_4_TUPLE_(T)> {
static const int value = 4;
};
template <GTEST_5_TYPENAMES_(T)> template <GTEST_5_TYPENAMES_(T)>
struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; }; struct tuple_size<GTEST_5_TUPLE_(T)> {
static const int value = 5;
};
template <GTEST_6_TYPENAMES_(T)> template <GTEST_6_TYPENAMES_(T)>
struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; }; struct tuple_size<GTEST_6_TUPLE_(T)> {
static const int value = 6;
};
template <GTEST_7_TYPENAMES_(T)> template <GTEST_7_TYPENAMES_(T)>
struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; }; struct tuple_size<GTEST_7_TUPLE_(T)> {
static const int value = 7;
};
template <GTEST_8_TYPENAMES_(T)> template <GTEST_8_TYPENAMES_(T)>
struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; }; struct tuple_size<GTEST_8_TUPLE_(T)> {
static const int value = 8;
};
template <GTEST_9_TYPENAMES_(T)> template <GTEST_9_TYPENAMES_(T)>
struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; }; struct tuple_size<GTEST_9_TUPLE_(T)> {
static const int value = 9;
};
template <GTEST_10_TYPENAMES_(T)> template <GTEST_10_TYPENAMES_(T)>
struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; }; struct tuple_size<GTEST_10_TUPLE_(T)> {
static const int value = 10;
};
template <int k, class Tuple> template <int k, class Tuple>
struct tuple_element { struct tuple_element {

View File

@ -118,8 +118,9 @@ struct TupleElement;
$for i [[ $for i [[
template <GTEST_$(n)_TYPENAMES_(T)> template <GTEST_$(n)_TYPENAMES_(T)>
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T)> [[]] struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T)> {
{ typedef T$i type; }; typedef T$i type;
};
]] ]]
@ -220,7 +221,9 @@ template <typename Tuple> struct tuple_size;
$for j [[ $for j [[
template <GTEST_$(j)_TYPENAMES_(T)> template <GTEST_$(j)_TYPENAMES_(T)>
struct tuple_size<GTEST_$(j)_TUPLE_(T)> { static const int value = $j; }; struct tuple_size<GTEST_$(j)_TUPLE_(T)> {
static const int value = $j;
};
]] ]]

View File

@ -3300,7 +3300,9 @@ struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
// INSTANTIATE_TYPED_TEST_CASE_P(). // INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T> template <typename T>
struct TypeList { typedef Types1<T> type; }; struct TypeList {
typedef Types1<T> type;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5, template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10, typename T6, typename T7, typename T8, typename T9, typename T10,

View File

@ -279,7 +279,9 @@ struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
// INSTANTIATE_TYPED_TEST_CASE_P(). // INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T> template <typename T>
struct TypeList { typedef Types1<T> type; }; struct TypeList {
typedef Types1<T> type;
};
$range i 1..n $range i 1..n

View File

@ -89,8 +89,7 @@ class LeakChecker : public EmptyTestEventListener {
// You can generate a failure in any event handler except // You can generate a failure in any event handler except
// OnTestPartResult. Just use an appropriate Google Test assertion to do // OnTestPartResult. Just use an appropriate Google Test assertion to do
// it. // it.
EXPECT_TRUE(difference <= 0) EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
<< "Leaked " << difference << " unit(s) of Water!";
} }
int initially_allocated_; int initially_allocated_;

View File

@ -81,7 +81,7 @@ TEST(FactorialTest, Negative) {
// test case. // test case.
EXPECT_EQ(1, Factorial(-5)); EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1)); EXPECT_EQ(1, Factorial(-1));
EXPECT_TRUE(Factorial(-10) > 0); EXPECT_GT(Factorial(-10), 0);
// <TechnicalDetails> // <TechnicalDetails>
// //

View File

@ -44,7 +44,6 @@ class MyString {
const MyString& operator=(const MyString& rhs); const MyString& operator=(const MyString& rhs);
public: public:
// Clones a 0-terminated C string, allocating memory using new. // Clones a 0-terminated C string, allocating memory using new.
static const char* CloneCString(const char* a_c_string); static const char* CloneCString(const char* a_c_string);

View File

@ -79,7 +79,7 @@ const char kHelloString[] = "Hello, world!";
// Tests the c'tor that accepts a C string. // Tests the c'tor that accepts a C string.
TEST(MyString, ConstructorFromCString) { TEST(MyString, ConstructorFromCString) {
const MyString s(kHelloString); const MyString s(kHelloString);
EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0); 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());
} }
@ -88,7 +88,7 @@ TEST(MyString, ConstructorFromCString) {
TEST(MyString, CopyConstructor) { TEST(MyString, CopyConstructor) {
const MyString s1(kHelloString); const MyString s1(kHelloString);
const MyString s2 = s1; const MyString s2 = s1;
EXPECT_TRUE(strcmp(s2.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
} }
// Tests the Set method. // Tests the Set method.
@ -96,12 +96,12 @@ TEST(MyString, Set) {
MyString s; MyString s;
s.Set(kHelloString); s.Set(kHelloString);
EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Set should work when the input pointer is the same as the one // Set should work when the input pointer is the same as the one
// already in the MyString object. // already in the MyString object.
s.Set(s.c_string()); s.Set(s.c_string());
EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Can we set the MyString to NULL? // Can we set the MyString to NULL?
s.Set(NULL); s.Set(NULL);

View File

@ -60,7 +60,7 @@ class QueueNode {
private: private:
// Creates a node with a given element value. The next pointer is // Creates a node with a given element value. The next pointer is
// set to NULL. // set to NULL.
QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
// We disable the default assignment operator and copy c'tor. // We disable the default assignment operator and copy c'tor.
const QueueNode& operator = (const QueueNode&); const QueueNode& operator = (const QueueNode&);
@ -73,7 +73,6 @@ class QueueNode {
template <typename E> // E is the element type. template <typename E> // E is the element type.
class Queue { class Queue {
public: public:
// Creates an empty queue. // Creates an empty queue.
Queue() : head_(NULL), last_(NULL), size_(0) {} Queue() : head_(NULL), last_(NULL), size_(0) {}

View File

@ -101,7 +101,7 @@ TEST_F(IntegerFunctionTest, Factorial) {
// Tests factorial of negative numbers. // Tests factorial of negative numbers.
EXPECT_EQ(1, Factorial(-5)); EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1)); EXPECT_EQ(1, Factorial(-1));
EXPECT_TRUE(Factorial(-10) > 0); EXPECT_GT(Factorial(-10), 0);
// Tests factorial of 0. // Tests factorial of 0.
EXPECT_EQ(1, Factorial(0)); EXPECT_EQ(1, Factorial(0));

View File

@ -109,13 +109,42 @@ GTEST_DEFINE_string_(
"Indicates the file, line number, temporal index of " "Indicates the file, line number, temporal index of "
"the single death test to run, and a file descriptor to " "the single death test to run, and a file descriptor to "
"which a success code may be sent, all separated by " "which a success code may be sent, all separated by "
"colons. This flag is specified if and only if the current " "the '|' characters. This flag is specified if and only if the current "
"process is a sub-process launched for running a thread-safe " "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 internal
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
namespace internal {
// Valid only for fast death tests. Indicates the code is running in the
// child process of a fast style death test.
static bool g_in_fast_death_test_child = false;
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
bool InDeathTestChild() {
# if GTEST_OS_WINDOWS
// On Windows, death tests are thread-safe regardless of the value of the
// death_test_style flag.
return !GTEST_FLAG(internal_run_death_test).empty();
# else
if (GTEST_FLAG(death_test_style) == "threadsafe")
return !GTEST_FLAG(internal_run_death_test).empty();
else
return g_in_fast_death_test_child;
#endif
}
} // namespace internal
// ExitedWithCode constructor. // ExitedWithCode constructor.
ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
} }
@ -825,6 +854,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// Event forwarding to the listeners of event listener API mush be shut // Event forwarding to the listeners of event listener API mush be shut
// down in death test subprocesses. // down in death test subprocesses.
GetUnitTestImpl()->listeners()->SuppressEventForwarding(); GetUnitTestImpl()->listeners()->SuppressEventForwarding();
g_in_fast_death_test_child = true;
return EXECUTE_TEST; return EXECUTE_TEST;
} else { } else {
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
@ -883,6 +913,7 @@ class Arguments {
char* const* Argv() { char* const* Argv() {
return &args_[0]; return &args_[0];
} }
private: private:
std::vector<char*> args_; std::vector<char*> args_;
}; };

View File

@ -196,6 +196,7 @@ class GTestFlagSaver {
GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(stream_result_to) = stream_result_to_;
GTEST_FLAG(throw_on_failure) = throw_on_failure_; GTEST_FLAG(throw_on_failure) = throw_on_failure_;
} }
private: private:
// Fields for saving the original values of flags. // Fields for saving the original values of flags.
bool also_run_disabled_tests_; bool also_run_disabled_tests_;
@ -442,8 +443,7 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface {
virtual String CurrentStackTrace(int max_depth, int skip_count) virtual String CurrentStackTrace(int max_depth, int skip_count)
GTEST_LOCK_EXCLUDED_(mutex_); GTEST_LOCK_EXCLUDED_(mutex_);
virtual void UponLeavingGTest(); virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);
GTEST_LOCK_EXCLUDED_(mutex_);
// This string is inserted in place of stack frames that are part of // This string is inserted in place of stack frames that are part of
// Google Test's implementation. // Google Test's implementation.
@ -620,7 +620,7 @@ 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.
String CurrentOsStackTraceExceptTop(int skip_count); String CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
// Finds and returns a TestCase with the given name. If one doesn't // Finds and returns a TestCase with the given name. If one doesn't
// exist, creates one and returns it. // exist, creates one and returns it.

View File

@ -514,7 +514,6 @@ class CapturedStream {
public: public:
// The ctor redirects the stream to a temporary file. // The ctor redirects the stream to a temporary file.
CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
# if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
@ -531,10 +530,15 @@ class CapturedStream {
<< temp_file_path; << 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 // There's no guarantee that a test has write access to the current
// current directory, so we create the temporary file in the /tmp // directory, so we create the temporary file in the /tmp directory instead.
// directory instead. // We use /tmp on most systems, and /mnt/sdcard on Android. That's because
// Android doesn't have /tmp.
# if GTEST_OS_LINUX_ANDROID
char name_template[] = "/mnt/sdcard/gtest_captured_stream.XXXXXX";
# else
char name_template[] = "/tmp/captured_stream.XXXXXX"; char name_template[] = "/tmp/captured_stream.XXXXXX";
# endif // GTEST_OS_LINUX_ANDROID
const int captured_fd = mkstemp(name_template); const int captured_fd = mkstemp(name_template);
filename_ = name_template; filename_ = name_template;
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS

View File

@ -3271,16 +3271,17 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
for (int i = 0; i < result.total_part_count(); ++i) { for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i); const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) { if (part.failed()) {
if (++failures == 1) if (++failures == 1) {
*stream << ">\n"; *stream << ">\n";
*stream << " <failure message=\"" }
<< EscapeXmlAttribute(part.summary()).c_str()
<< "\" type=\"\">";
const string location = internal::FormatCompilerIndependentFileLocation( const string location = internal::FormatCompilerIndependentFileLocation(
part.file_name(), part.line_number()); part.file_name(), part.line_number());
const string message = location + "\n" + part.message(); const string summary = location + "\n" + part.summary();
OutputXmlCDataSection(stream, *stream << " <failure message=\""
RemoveInvalidXmlCharacters(message).c_str()); << EscapeXmlAttribute(summary.c_str())
<< "\" type=\"\">";
const string detail = location + "\n" + part.message();
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
*stream << "</failure>\n"; *stream << "</failure>\n";
} }
} }
@ -3529,7 +3530,7 @@ void StreamingListener::MakeConnection() {
// Pushes the given source file location and message onto a per-thread // Pushes the given source file location and message onto a per-thread
// trace stack maintained by Google Test. // trace stack maintained by Google Test.
ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) ScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
GTEST_LOCK_EXCLUDED_(UnitTest::mutex_) { GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
TraceInfo trace; TraceInfo trace;
trace.file = file; trace.file = file;
trace.line = line; trace.line = line;
@ -3540,7 +3541,7 @@ ScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
// Pops the info pushed by the c'tor. // Pops the info pushed by the c'tor.
ScopedTrace::~ScopedTrace() ScopedTrace::~ScopedTrace()
GTEST_LOCK_EXCLUDED_(UnitTest::mutex_) { GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
UnitTest::GetInstance()->PopGTestTrace(); UnitTest::GetInstance()->PopGTestTrace();
} }
@ -3864,7 +3865,6 @@ int UnitTest::Run() {
// process. In either case the user does not want to see pop-up dialogs // process. In either case the user does not want to see pop-up dialogs
// about crashes - they are expected. // about crashes - they are expected.
if (impl()->catch_exceptions() || in_death_test_child_process) { if (impl()->catch_exceptions() || in_death_test_child_process) {
# if !GTEST_OS_WINDOWS_MOBILE # if !GTEST_OS_WINDOWS_MOBILE
// SetErrorMode doesn't exist on CE. // SetErrorMode doesn't exist on CE.
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
@ -3895,7 +3895,6 @@ int UnitTest::Run() {
0x0, // Clear the following flags: 0x0, // Clear the following flags:
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
# endif # endif
} }
#endif // GTEST_HAS_SEH #endif // GTEST_HAS_SEH

View File

@ -27,13 +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.
#include <iostream> #include <stdio.h>
#include "gtest/gtest.h" #include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) { GTEST_API_ int main(int argc, char **argv) {
std::cout << "Running main() from gtest_main.cc\n"; printf("Running main() from gtest_main.cc\n");
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -75,6 +75,7 @@ using testing::internal::DeathTestFactory;
using testing::internal::FilePath; using testing::internal::FilePath;
using testing::internal::GetLastErrnoDescription; using testing::internal::GetLastErrnoDescription;
using testing::internal::GetUnitTestImpl; using testing::internal::GetUnitTestImpl;
using testing::internal::InDeathTestChild;
using testing::internal::ParseNaturalNumber; using testing::internal::ParseNaturalNumber;
using testing::internal::String; using testing::internal::String;
@ -617,8 +618,8 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
"illegal return in test statement."); "illegal return in test statement.");
} }
// Tests that EXPECT_DEBUG_DEATH works as expected, // Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a
// that is, in debug mode, it: // message to it, and in debug mode it:
// 1. Asserts on death. // 1. Asserts on death.
// 2. Has no side effect. // 2. Has no side effect.
// //
@ -627,8 +628,8 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
TEST_F(TestForDeathTest, TestExpectDebugDeath) { TEST_F(TestForDeathTest, TestExpectDebugDeath) {
int sideeffect = 0; int sideeffect = 0;
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12")
"death.*DieInDebugElse12"); << "Must accept a streamed message";
# ifdef NDEBUG # ifdef NDEBUG
@ -643,22 +644,18 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) {
# endif # endif
} }
// Tests that ASSERT_DEBUG_DEATH works as expected // Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a
// In debug mode: // message to it, and in debug mode it:
// 1. Asserts on debug death. // 1. Asserts on death.
// 2. Has no side effect. // 2. Has no side effect.
// //
// In opt mode: // And in opt mode, it:
// 1. Has side effects and returns the expected value (12). // 1. Has side effects but does not assert.
TEST_F(TestForDeathTest, TestAssertDebugDeath) { TEST_F(TestForDeathTest, TestAssertDebugDeath) {
int sideeffect = 0; int sideeffect = 0;
ASSERT_DEBUG_DEATH({ // NOLINT ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12")
// Tests that the return value is 12 in opt mode. << "Must accept a streamed message";
EXPECT_EQ(12, DieInDebugElse12(&sideeffect));
// Tests that the side effect occurred in opt mode.
EXPECT_EQ(12, sideeffect);
}, "death.*DieInDebugElse12");
# ifdef NDEBUG # ifdef NDEBUG
@ -729,7 +726,7 @@ static void TestExitMacros() {
// Of all signals effects on the process exit code, only those of SIGABRT // Of all signals effects on the process exit code, only those of SIGABRT
// are documented on Windows. // are documented on Windows.
// See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx.
EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), ""); EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar";
# else # else
@ -895,6 +892,7 @@ class MockDeathTest : public DeathTest {
virtual void Abort(AbortReason reason) { virtual void Abort(AbortReason reason) {
parent_->abort_args_.push_back(reason); parent_->abort_args_.push_back(reason);
} }
private: private:
MockDeathTestFactory* const parent_; MockDeathTestFactory* const parent_;
const TestRole role_; const TestRole role_;
@ -1345,6 +1343,26 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) {
#endif // _MSC_VER #endif // _MSC_VER
} }
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
testing::GTEST_FLAG(death_test_style) = "fast";
EXPECT_FALSE(InDeathTestChild());
EXPECT_DEATH({
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
fflush(stderr);
_exit(1);
}, "Inside");
}
TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
EXPECT_FALSE(InDeathTestChild());
EXPECT_DEATH({
fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
fflush(stderr);
_exit(1);
}, "Inside");
}
// Tests that a test case whose name ends with "DeathTest" works fine // Tests that a test case whose name ends with "DeathTest" works fine
// on Windows. // on Windows.
TEST(NotADeathTest, Test) { TEST(NotADeathTest, Test) {

View File

@ -148,8 +148,7 @@ TEST_F(LinkedPtrTest, GeneralTest) {
"A0 dtor\n" "A0 dtor\n"
"A3 dtor\n" "A3 dtor\n"
"A1 dtor\n", "A1 dtor\n",
history->GetString().c_str() history->GetString().c_str());
);
} }
} // Unnamed namespace } // Unnamed namespace

View File

@ -55,7 +55,7 @@ namespace internal {
class EventRecordingListener : public TestEventListener { class EventRecordingListener : public TestEventListener {
public: public:
EventRecordingListener(const char* name) : name_(name) {} explicit EventRecordingListener(const char* name) : name_(name) {}
protected: protected:
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {

View File

@ -606,6 +606,7 @@ class TestGenerationEnvironment : public ::testing::Environment {
<< "has not been run as expected."; << "has not been run as expected.";
} }
} }
private: private:
TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0),
tear_down_count_(0), test_body_count_(0) {} tear_down_count_(0), test_body_count_(0) {}
@ -674,6 +675,7 @@ class TestGenerationTest : public TestWithParam<int> {
EXPECT_TRUE(collected_parameters_ == expected_values); EXPECT_TRUE(collected_parameters_ == expected_values);
} }
protected: protected:
int current_parameter_; int current_parameter_;
static vector<int> collected_parameters_; static vector<int> collected_parameters_;

View File

@ -43,12 +43,14 @@
// Test fixture for testing definition and instantiation of a test // Test fixture for testing definition and instantiation of a test
// in separate translation units. // in separate translation units.
class ExternalInstantiationTest : public ::testing::TestWithParam<int> {}; class ExternalInstantiationTest : public ::testing::TestWithParam<int> {
};
// Test fixture for testing instantiation of a test in multiple // Test fixture for testing instantiation of a test in multiple
// translation units. // translation units.
class InstantiationInMultipleTranslaionUnitsTest class InstantiationInMultipleTranslaionUnitsTest
: public ::testing::TestWithParam<int> {}; : public ::testing::TestWithParam<int> {
};
#endif // GTEST_HAS_PARAM_TEST #endif // GTEST_HAS_PARAM_TEST

View File

@ -92,7 +92,7 @@ TEST(ImplicitCastTest, CanUseInheritance) {
class Castable { class Castable {
public: public:
Castable(bool* converted) : converted_(converted) {} explicit Castable(bool* converted) : converted_(converted) {}
operator Base() { operator Base() {
*converted_ = true; *converted_ = true;
return Base(); return Base();
@ -111,7 +111,7 @@ TEST(ImplicitCastTest, CanUseNonConstCastOperator) {
class ConstCastable { class ConstCastable {
public: public:
ConstCastable(bool* converted) : converted_(converted) {} explicit ConstCastable(bool* converted) : converted_(converted) {}
operator Base() const { operator Base() const {
*converted_ = true; *converted_ = true;
return Base(); return Base();
@ -929,7 +929,7 @@ TEST(CaptureTest, CapturesStdoutAndStderr) {
TEST(CaptureDeathTest, CannotReenterStdoutCapture) { TEST(CaptureDeathTest, CannotReenterStdoutCapture) {
CaptureStdout(); CaptureStdout();
EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();, EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(),
"Only one stdout capturer can exist at a time"); "Only one stdout capturer can exist at a time");
GetCapturedStdout(); GetCapturedStdout();

View File

@ -841,7 +841,7 @@ TEST(PrintStlContainerTest, HashMultiSet) {
std::vector<int> numbers; std::vector<int> numbers;
for (size_t i = 0; i != result.length(); i++) { for (size_t i = 0; i != result.length(); i++) {
if (expected_pattern[i] == 'd') { if (expected_pattern[i] == 'd') {
ASSERT_TRUE(isdigit(static_cast<unsigned char>(result[i])) != 0); ASSERT_NE(isdigit(static_cast<unsigned char>(result[i])), 0);
numbers.push_back(result[i] - '0'); numbers.push_back(result[i] - '0');
} else { } else {
EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " EXPECT_EQ(expected_pattern[i], result[i]) << " where result is "

View File

@ -117,6 +117,9 @@ class CatchCxxExceptionsTest(gtest_test_utils.TestCase):
'"CxxExceptionInConstructorTest" (no quotes) ' '"CxxExceptionInConstructorTest" (no quotes) '
'appears on the same line as words "called unexpectedly"') 'appears on the same line as words "called unexpectedly"')
if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in
EX_BINARY_OUTPUT):
def testCatchesCxxExceptionsInFixtureDestructor(self): def testCatchesCxxExceptionsInFixtureDestructor(self):
self.assert_('C++ exception with description ' self.assert_('C++ exception with description '
'"Standard C++ exception" thrown ' '"Standard C++ exception" thrown '

View File

@ -137,6 +137,8 @@ TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) {
<< "called unexpectedly."; << "called unexpectedly.";
} }
// Exceptions in destructors are not supported in C++11.
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
class CxxExceptionInDestructorTest : public Test { class CxxExceptionInDestructorTest : public Test {
public: public:
static void TearDownTestCase() { static void TearDownTestCase() {
@ -153,6 +155,7 @@ class CxxExceptionInDestructorTest : public Test {
}; };
TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {}
#endif // C++11 mode
class CxxExceptionInSetUpTestCaseTest : public Test { class CxxExceptionInSetUpTestCaseTest : public Test {
public: public:

View File

@ -67,7 +67,8 @@ def GetFlag(flag):
args = [COMMAND] args = [COMMAND]
if flag is not None: if flag is not None:
args += [flag] args += [flag]
return gtest_test_utils.Subprocess(args, env=environ).output return gtest_test_utils.Subprocess(args, env=environ,
capture_stderr=False).output
def TestFlag(flag, test_val, default_val): def TestFlag(flag, test_val, default_val):

View File

@ -96,6 +96,7 @@ class MyEnvironment : public testing::Environment {
// Was TearDown() run? // Was TearDown() run?
bool tear_down_was_run() const { return tear_down_was_run_; } bool tear_down_was_run() const { return tear_down_was_run_; }
private: private:
FailureType failure_in_set_up_; FailureType failure_in_set_up_;
bool set_up_was_run_; bool set_up_was_run_;

View File

@ -34,7 +34,6 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);

View File

@ -213,7 +213,7 @@ def GetShellCommandOutput(env_cmd):
# Set and save the environment properly. # Set and save the environment properly.
environ = os.environ.copy() environ = os.environ.copy()
environ.update(env_cmd[0]) environ.update(env_cmd[0])
p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) p = gtest_test_utils.Subprocess(env_cmd[1], env=environ, capture_stderr=False)
return p.output return p.output

View File

@ -221,13 +221,13 @@ TEST(SCOPED_TRACETest, CanBeRepeated) {
{ {
SCOPED_TRACE("C"); SCOPED_TRACE("C");
ADD_FAILURE() << "This failure is expected, and should contain " ADD_FAILURE() << "This failure is expected, and should "
<< "trace point A, B, and C."; << "contain trace point A, B, and C.";
} }
SCOPED_TRACE("D"); SCOPED_TRACE("D");
ADD_FAILURE() << "This failure is expected, and should contain " ADD_FAILURE() << "This failure is expected, and should "
<< "trace point A, B, and D."; << "contain trace point A, B, and D.";
} }
#if GTEST_IS_THREADSAFE #if GTEST_IS_THREADSAFE
@ -378,6 +378,7 @@ class FatalFailureInFixtureConstructorTest : public testing::Test {
<< "We should never get here, as the test fixture c'tor " << "We should never get here, as the test fixture c'tor "
<< "had a fatal failure."; << "had a fatal failure.";
} }
private: private:
void Init() { void Init() {
FAIL() << "Expected failure #1, in the test fixture c'tor."; FAIL() << "Expected failure #1, in the test fixture c'tor.";

View File

@ -27,7 +27,7 @@
// (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 09/24/2010 by command // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
// Regression test for gtest_pred_impl.h // Regression test for gtest_pred_impl.h

View File

@ -81,7 +81,8 @@ def RunAndReturnOutput(extra_env, args):
environ_copy = os.environ.copy() environ_copy = os.environ.copy()
environ_copy.update(extra_env) environ_copy.update(extra_env)
return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy,
capture_stderr=False).output
def GetTestsForAllIterations(extra_env, args): def GetTestsForAllIterations(extra_env, args):

View File

@ -33,8 +33,6 @@
// Google Test work. // Google Test work.
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <vector>
#include <ostream>
// Verifies that the command line flag variables can be accessed // Verifies that the command line flag variables can be accessed
// in code once <gtest/gtest.h> has been #included. // in code once <gtest/gtest.h> has been #included.
@ -58,6 +56,15 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused.
} }
#include <limits.h> // For INT_MAX.
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <map>
#include <vector>
#include <ostream>
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
// Indicates that this translation unit is part of Google Test's // Indicates that this translation unit is part of Google Test's
@ -69,13 +76,6 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_ #undef GTEST_IMPLEMENTATION_
#include <limits.h> // For INT_MAX.
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <map>
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -1141,7 +1141,7 @@ TEST(StringTest, Equals) {
EXPECT_TRUE(foo == "foo"); // NOLINT EXPECT_TRUE(foo == "foo"); // NOLINT
const String bar("x\0y", 3); const String bar("x\0y", 3);
EXPECT_FALSE(bar == "x"); EXPECT_NE(bar, "x");
} }
// Tests String::operator!=(). // Tests String::operator!=().
@ -1163,7 +1163,7 @@ TEST(StringTest, NotEquals) {
EXPECT_FALSE(foo != "foo"); // NOLINT EXPECT_FALSE(foo != "foo"); // NOLINT
const String bar("x\0y", 3); const String bar("x\0y", 3);
EXPECT_TRUE(bar != "x"); EXPECT_NE(bar, "x");
} }
// Tests String::length(). // Tests String::length().
@ -1902,6 +1902,7 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG(stream_result_to) = "localhost:1234"; GTEST_FLAG(stream_result_to) = "localhost:1234";
GTEST_FLAG(throw_on_failure) = true; GTEST_FLAG(throw_on_failure) = true;
} }
private: private:
// For saving Google Test flags during this test case. // For saving Google Test flags during this test case.
static GTestFlagSaver* saver_; static GTestFlagSaver* saver_;
@ -2641,6 +2642,11 @@ TEST(StringAssertionTest, STREQ_Wide) {
// Strings containing wide characters. // Strings containing wide characters.
EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"),
"abc"); "abc");
// The streaming variation.
EXPECT_NONFATAL_FAILURE({ // NOLINT
EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure";
}, "Expected failure");
} }
// Tests *_STRNE on wide strings. // Tests *_STRNE on wide strings.
@ -2667,6 +2673,9 @@ TEST(StringAssertionTest, STRNE_Wide) {
// Strings containing wide characters. // Strings containing wide characters.
EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"),
"abc"); "abc");
// The streaming variation.
ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen";
} }
// Tests for ::testing::IsSubstring(). // Tests for ::testing::IsSubstring().
@ -2797,7 +2806,6 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) {
template <typename RawType> template <typename RawType>
class FloatingPointTest : public Test { class FloatingPointTest : public Test {
protected: protected:
// Pre-calculated numbers to be used by the tests. // Pre-calculated numbers to be used by the tests.
struct TestValues { struct TestValues {
RawType close_to_positive_zero; RawType close_to_positive_zero;
@ -4263,8 +4271,109 @@ TEST(SuccessfulAssertionTest, ASSERT_STR) {
namespace { namespace {
// Tests the message streaming variation of assertions.
TEST(AssertionWithMessageTest, EXPECT) {
EXPECT_EQ(1, 1) << "This should succeed.";
EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.",
"Expected failure #1");
EXPECT_LE(1, 2) << "This should succeed.";
EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.",
"Expected failure #2.");
EXPECT_GE(1, 0) << "This should succeed.";
EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.",
"Expected failure #3.");
EXPECT_STREQ("1", "1") << "This should succeed.";
EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.",
"Expected failure #4.");
EXPECT_STRCASEEQ("a", "A") << "This should succeed.";
EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.",
"Expected failure #5.");
EXPECT_FLOAT_EQ(1, 1) << "This should succeed.";
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.",
"Expected failure #6.");
EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed.";
}
TEST(AssertionWithMessageTest, ASSERT) {
ASSERT_EQ(1, 1) << "This should succeed.";
ASSERT_NE(1, 2) << "This should succeed.";
ASSERT_LE(1, 2) << "This should succeed.";
ASSERT_LT(1, 2) << "This should succeed.";
ASSERT_GE(1, 0) << "This should succeed.";
EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.",
"Expected failure.");
}
TEST(AssertionWithMessageTest, ASSERT_STR) {
ASSERT_STREQ("1", "1") << "This should succeed.";
ASSERT_STRNE("1", "2") << "This should succeed.";
ASSERT_STRCASEEQ("a", "A") << "This should succeed.";
EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.",
"Expected failure.");
}
TEST(AssertionWithMessageTest, ASSERT_FLOATING) {
ASSERT_FLOAT_EQ(1, 1) << "This should succeed.";
ASSERT_DOUBLE_EQ(1, 1) << "This should succeed.";
EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT
"Expect failure.");
// To work around a bug in gcc 2.95.0, there is intentionally no
// space after the first comma in the previous statement.
}
// Tests using ASSERT_FALSE with a streamed message.
TEST(AssertionWithMessageTest, ASSERT_FALSE) {
ASSERT_FALSE(false) << "This shouldn't fail.";
EXPECT_FATAL_FAILURE({ // NOLINT
ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1
<< " evaluates to " << true;
}, "Expected failure");
}
// Tests using FAIL with a streamed message.
TEST(AssertionWithMessageTest, FAIL) {
EXPECT_FATAL_FAILURE(FAIL() << 0,
"0");
}
// Tests using SUCCEED with a streamed message.
TEST(AssertionWithMessageTest, SUCCEED) {
SUCCEED() << "Success == " << 1;
}
// Tests using ASSERT_TRUE with a streamed message.
TEST(AssertionWithMessageTest, ASSERT_TRUE) {
ASSERT_TRUE(true) << "This should succeed.";
ASSERT_TRUE(true) << true;
EXPECT_FATAL_FAILURE({ // NOLINT
ASSERT_TRUE(false) << static_cast<const char *>(NULL)
<< static_cast<char *>(NULL);
}, "(null)(null)");
}
#if GTEST_OS_WINDOWS
// Tests using wide strings in assertion messages.
TEST(AssertionWithMessageTest, WideStringMessage) {
EXPECT_NONFATAL_FAILURE({ // NOLINT
EXPECT_TRUE(false) << L"This failure is expected.\x8119";
}, "This failure is expected.");
EXPECT_FATAL_FAILURE({ // NOLINT
ASSERT_EQ(1, 2) << "This failure is "
<< L"expected too.\x8120";
}, "This failure is expected too.");
}
#endif // GTEST_OS_WINDOWS
// Tests EXPECT_TRUE. // Tests EXPECT_TRUE.
TEST(ExpectTest, EXPECT_TRUE) { TEST(ExpectTest, EXPECT_TRUE) {
EXPECT_TRUE(true) << "Intentional success";
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.",
"Intentional failure #1.");
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.",
"Intentional failure #2.");
EXPECT_TRUE(2 > 1); // NOLINT EXPECT_TRUE(2 > 1); // NOLINT
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1),
"Value of: 2 < 1\n" "Value of: 2 < 1\n"
@ -4288,9 +4397,14 @@ TEST(ExpectTest, ExpectTrueWithAssertionResult) {
"Expected: true"); "Expected: true");
} }
// Tests EXPECT_FALSE. // Tests EXPECT_FALSE with a streamed message.
TEST(ExpectTest, EXPECT_FALSE) { TEST(ExpectTest, EXPECT_FALSE) {
EXPECT_FALSE(2 < 1); // NOLINT EXPECT_FALSE(2 < 1); // NOLINT
EXPECT_FALSE(false) << "Intentional success";
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.",
"Intentional failure #1.");
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.",
"Intentional failure #2.");
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1),
"Value of: 2 > 1\n" "Value of: 2 > 1\n"
" Actual: true\n" " Actual: true\n"
@ -4564,7 +4678,7 @@ TEST(StreamableTest, BasicIoManip) {
void AddFailureHelper(bool* aborted) { void AddFailureHelper(bool* aborted) {
*aborted = true; *aborted = true;
ADD_FAILURE() << "Failure"; ADD_FAILURE() << "Intentional failure.";
*aborted = false; *aborted = false;
} }
@ -4572,7 +4686,7 @@ void AddFailureHelper(bool* aborted) {
TEST(MacroTest, ADD_FAILURE) { TEST(MacroTest, ADD_FAILURE) {
bool aborted = true; bool aborted = true;
EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted),
"Failure"); "Intentional failure.");
EXPECT_FALSE(aborted); EXPECT_FALSE(aborted);
} }
@ -4605,7 +4719,6 @@ TEST(MacroTest, SUCCEED) {
SUCCEED() << "Explicit success."; SUCCEED() << "Explicit success.";
} }
// Tests for EXPECT_EQ() and ASSERT_EQ(). // Tests for EXPECT_EQ() and ASSERT_EQ().
// //
// These tests fail *intentionally*, s.t. the failure messages can be // These tests fail *intentionally*, s.t. the failure messages can be
@ -7278,6 +7391,7 @@ TEST(ArrayEqTest, WorksForDegeneratedArrays) {
} }
TEST(ArrayEqTest, WorksForOneDimensionalArrays) { TEST(ArrayEqTest, WorksForOneDimensionalArrays) {
// Note that a and b are distinct but compatible types.
const int a[] = { 0, 1 }; const int a[] = { 0, 1 };
long b[] = { 0, 1 }; long b[] = { 0, 1 };
EXPECT_TRUE(ArrayEq(a, b)); EXPECT_TRUE(ArrayEq(a, b));

View File

@ -63,7 +63,7 @@ EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
</testsuite> </testsuite>
<testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*"> <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
<testcase name="Fails" status="run" time="*" classname="FailedTest"> <testcase name="Fails" status="run" time="*" classname="FailedTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2 Value of: 2
Expected: 1%(stack)s]]></failure> Expected: 1%(stack)s]]></failure>
</testcase> </testcase>
@ -71,10 +71,10 @@ Expected: 1%(stack)s]]></failure>
<testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*"> <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/> <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
<testcase name="Fails" status="run" time="*" classname="MixedResultTest"> <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2 Value of: 2
Expected: 1%(stack)s]]></failure> Expected: 1%(stack)s]]></failure>
<failure message="Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 3 Value of: 3
Expected: 2%(stack)s]]></failure> Expected: 2%(stack)s]]></failure>
</testcase> </testcase>
@ -82,14 +82,14 @@ Expected: 2%(stack)s]]></failure>
</testsuite> </testsuite>
<testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*"> <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
<testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest"> <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
<failure message="Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Failed Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure> XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
</testcase> </testcase>
</testsuite> </testsuite>
<testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*"> <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
<testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest"> <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
<failure message="Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:* <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Failed Failed
Invalid characters in brackets []%(stack)s]]></failure> Invalid characters in brackets []%(stack)s]]></failure>
</testcase> </testcase>

View File

@ -156,8 +156,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* The "type_param" attribute of <testcase> elements is replaced with a * The "type_param" attribute of <testcase> elements is replaced with a
single asterisk (if it sn non-empty) as it is the type name returned single asterisk (if it sn non-empty) as it is the type name returned
by the compiler and is platform dependent. by the compiler and is platform dependent.
* The line number reported in the first line of the "message" * The line info reported in the first line of the "message"
attribute of <failure> elements is replaced with a single asterisk. attribute and CDATA section of <failure> elements is replaced with the
file's basename and a single asterisk for the line number.
* The directory names in file paths are removed. * The directory names in file paths are removed.
* The stack traces are removed. * The stack traces are removed.
""" """
@ -173,10 +174,14 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
if type_param and type_param.value: if type_param and type_param.value:
type_param.value = '*' type_param.value = '*'
elif element.tagName == 'failure': elif element.tagName == 'failure':
source_line_pat = r'^.*[/\\](.*:)\d+\n'
# Replaces the source line information with a normalized form.
message = element.getAttributeNode('message')
message.value = re.sub(source_line_pat, '\\1*\n', message.value)
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.CDATA_SECTION_NODE: if child.nodeType == Node.CDATA_SECTION_NODE:
# Removes the source line number. # Replaces the source line information with a normalized form.
cdata = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', child.nodeValue) cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue)
# Removes the actual stack trace. # Removes the actual stack trace.
child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*',
'', cdata) '', cdata)

View File

@ -2216,9 +2216,6 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
p9##_type>::gmock_Impl<F>::gmock_PerformImpl(\ p9##_type>::gmock_Impl<F>::gmock_PerformImpl(\
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
// TODO(wan@google.com): move the following to a different .h file
// such that we don't have to run 'pump' every time the code is
// updated.
namespace testing { namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal // The ACTION*() macros trigger warning C4100 (unreferenced formal

View File

@ -739,9 +739,6 @@ $$ } // This meta comment fixes auto-indentation in Emacs. It won't
$$ // show up in the generated code. $$ // show up in the generated code.
// TODO(wan@google.com): move the following to a different .h file
// such that we don't have to run 'pump' every time the code is
// updated.
namespace testing { namespace testing {
// The ACTION*() macros trigger warning C4100 (unreferenced formal // The ACTION*() macros trigger warning C4100 (unreferenced formal

View File

@ -38,6 +38,7 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#include <iterator>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -305,7 +306,9 @@ class ArgsMatcher {
GTEST_DISALLOW_ASSIGN_(ArgsMatcher); GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
}; };
// Implements ElementsAre() of 1-10 arguments. // Implements ElementsAre() of 1-10 arguments. The use of DecayArray in
// the implementation allows ElementsAre() to accept string literals, whose
// inferred type is const char[N] while we want to treat them as const char*.
template <typename T1> template <typename T1>
class ElementsAreMatcher1 { class ElementsAreMatcher1 {
@ -326,11 +329,12 @@ class ElementsAreMatcher1 {
// a local array. // a local array.
const Matcher<const Element&> matcher = const Matcher<const Element&> matcher =
MatcherCast<const Element&>(e1_); MatcherCast<const Element&>(e1_);
return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, 1)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher,
&matcher + 1));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher1); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher1);
}; };
@ -351,12 +355,13 @@ class ElementsAreMatcher2 {
MatcherCast<const Element&>(e2_), MatcherCast<const Element&>(e2_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 2)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 2));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher2); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher2);
}; };
@ -379,13 +384,14 @@ class ElementsAreMatcher3 {
MatcherCast<const Element&>(e3_), MatcherCast<const Element&>(e3_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 3)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 3));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher3); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher3);
}; };
@ -409,14 +415,15 @@ class ElementsAreMatcher4 {
MatcherCast<const Element&>(e4_), MatcherCast<const Element&>(e4_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 4)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 4));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher4); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher4);
}; };
@ -441,15 +448,16 @@ class ElementsAreMatcher5 {
MatcherCast<const Element&>(e5_), MatcherCast<const Element&>(e5_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 5)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 5));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
const T5& e5_; const typename DecayArray<T5>::type e5_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher5); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher5);
}; };
@ -477,16 +485,17 @@ class ElementsAreMatcher6 {
MatcherCast<const Element&>(e6_), MatcherCast<const Element&>(e6_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 6)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 6));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
const T5& e5_; const typename DecayArray<T5>::type e5_;
const T6& e6_; const typename DecayArray<T6>::type e6_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher6); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher6);
}; };
@ -515,17 +524,18 @@ class ElementsAreMatcher7 {
MatcherCast<const Element&>(e7_), MatcherCast<const Element&>(e7_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 7)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 7));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
const T5& e5_; const typename DecayArray<T5>::type e5_;
const T6& e6_; const typename DecayArray<T6>::type e6_;
const T7& e7_; const typename DecayArray<T7>::type e7_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher7); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher7);
}; };
@ -555,18 +565,19 @@ class ElementsAreMatcher8 {
MatcherCast<const Element&>(e8_), MatcherCast<const Element&>(e8_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 8)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 8));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
const T5& e5_; const typename DecayArray<T5>::type e5_;
const T6& e6_; const typename DecayArray<T6>::type e6_;
const T7& e7_; const typename DecayArray<T7>::type e7_;
const T8& e8_; const typename DecayArray<T8>::type e8_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher8); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher8);
}; };
@ -598,19 +609,20 @@ class ElementsAreMatcher9 {
MatcherCast<const Element&>(e9_), MatcherCast<const Element&>(e9_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 9)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 9));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
const T5& e5_; const typename DecayArray<T5>::type e5_;
const T6& e6_; const typename DecayArray<T6>::type e6_;
const T7& e7_; const typename DecayArray<T7>::type e7_;
const T8& e8_; const typename DecayArray<T8>::type e8_;
const T9& e9_; const typename DecayArray<T9>::type e9_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher9); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher9);
}; };
@ -643,20 +655,21 @@ class ElementsAreMatcher10 {
MatcherCast<const Element&>(e10_), MatcherCast<const Element&>(e10_),
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 10)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + 10));
} }
private: private:
const T1& e1_; const typename DecayArray<T1>::type e1_;
const T2& e2_; const typename DecayArray<T2>::type e2_;
const T3& e3_; const typename DecayArray<T3>::type e3_;
const T4& e4_; const typename DecayArray<T4>::type e4_;
const T5& e5_; const typename DecayArray<T5>::type e5_;
const T6& e6_; const typename DecayArray<T6>::type e6_;
const T7& e7_; const typename DecayArray<T7>::type e7_;
const T8& e8_; const typename DecayArray<T8>::type e8_;
const T9& e9_; const typename DecayArray<T9>::type e9_;
const T10& e10_; const typename DecayArray<T10>::type e10_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher10); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher10);
}; };
@ -1007,24 +1020,55 @@ inline internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
T10>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); T10>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
} }
// ElementsAreArray(array) and ElementAreArray(array, count) are like // ElementsAreArray(array)
// ElementsAre(), except that they take an array of values or // ElementsAreArray(pointer, count)
// matchers. The former form infers the size of 'array', which must // ElementsAreArray(vector)
// be a static C-style array. In the latter form, 'array' can either // ElementsAreArray(first, last)
// be a static array or a pointer to a dynamically created array. //
// The ElementsAreArray() functions are like ElementsAre(...), except that
// they are given a sequence of matchers or values rather than taking each
// element as a function argument. The sequence can be specified as a
// C-style array, a pointer and count, a vector, or an STL iterator range.
//
// * The array form infers the size of 'array', which must be of a
// statically-sized C-style array type.
//
// * The (pointer, count) form can take either a statically-sized C-style
// array or a pointer to a dynamically created array. It does not take
// ownership of the pointer.
//
// * The vector form can take a std::vector either of values or of matchers.
//
// * The (first, last) form can take any STL iterator range.
//
// All forms of ElementsAreArray() make a copy of the input sequence.
template <typename T> template <typename T>
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
const T* first, size_t count) { const T* first, size_t count) {
return internal::ElementsAreArrayMatcher<T>(first, count); return internal::ElementsAreArrayMatcher<T>(first, first + count);
} }
template <typename T, size_t N> template <typename T, size_t N>
inline internal::ElementsAreArrayMatcher<T> inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
ElementsAreArray(const T (&array)[N]) { const T (&array)[N]) {
return internal::ElementsAreArrayMatcher<T>(array, N); return internal::ElementsAreArrayMatcher<T>(array, array + N);
} }
template <typename T, typename A>
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
const std::vector<T, A>& vec) {
return internal::ElementsAreArrayMatcher<T>(vec.begin(), vec.end());
}
template <typename Iter>
inline internal::ElementsAreArrayMatcher<
typename std::iterator_traits<Iter>::value_type>
ElementsAreArray(Iter first, Iter last) {
typedef typename std::iterator_traits<Iter>::value_type T;
return internal::ElementsAreArrayMatcher<T>(first, last);
}
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given // AllOf(m1, m2, ..., mk) matches any value that matches all of the given
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. // sub-matchers. AllOf is called fully qualified to prevent ADL from firing.

View File

@ -40,6 +40,7 @@ $$ }} This line fixes auto-indentation of the following code in Emacs.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
#include <iterator>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -186,7 +187,9 @@ class ArgsMatcher {
GTEST_DISALLOW_ASSIGN_(ArgsMatcher); GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
}; };
// Implements ElementsAre() of 1-$n arguments. // Implements ElementsAre() of 1-$n arguments. The use of DecayArray in
// the implementation allows ElementsAre() to accept string literals, whose
// inferred type is const char[N] while we want to treat them as const char*.
$range i 1..n $range i 1..n
@ -214,7 +217,8 @@ $if i==1 [[
// a local array. // a local array.
const Matcher<const Element&> matcher = const Matcher<const Element&> matcher =
MatcherCast<const Element&>(e1_); MatcherCast<const Element&>(e1_);
return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, 1)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher,
&matcher + 1));
]] $else [[ ]] $else [[
const Matcher<const Element&> matchers[] = { const Matcher<const Element&> matchers[] = {
@ -225,7 +229,8 @@ $for j [[
]] ]]
}; };
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers + $i));
]] ]]
} }
@ -233,7 +238,7 @@ $for j [[
private: private:
$for j [[ $for j [[
const T$j& e$j[[]]_; const typename DecayArray<T$j>::type e$j[[]]_;
]] ]]
@ -344,24 +349,55 @@ inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[con
]] ]]
// ElementsAreArray(array) and ElementAreArray(array, count) are like // ElementsAreArray(array)
// ElementsAre(), except that they take an array of values or // ElementsAreArray(pointer, count)
// matchers. The former form infers the size of 'array', which must // ElementsAreArray(vector)
// be a static C-style array. In the latter form, 'array' can either // ElementsAreArray(first, last)
// be a static array or a pointer to a dynamically created array. //
// The ElementsAreArray() functions are like ElementsAre(...), except that
// they are given a sequence of matchers or values rather than taking each
// element as a function argument. The sequence can be specified as a
// C-style array, a pointer and count, a vector, or an STL iterator range.
//
// * The array form infers the size of 'array', which must be of a
// statically-sized C-style array type.
//
// * The (pointer, count) form can take either a statically-sized C-style
// array or a pointer to a dynamically created array. It does not take
// ownership of the pointer.
//
// * The vector form can take a std::vector either of values or of matchers.
//
// * The (first, last) form can take any STL iterator range.
//
// All forms of ElementsAreArray() make a copy of the input sequence.
template <typename T> template <typename T>
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
const T* first, size_t count) { const T* first, size_t count) {
return internal::ElementsAreArrayMatcher<T>(first, count); return internal::ElementsAreArrayMatcher<T>(first, first + count);
} }
template <typename T, size_t N> template <typename T, size_t N>
inline internal::ElementsAreArrayMatcher<T> inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
ElementsAreArray(const T (&array)[N]) { const T (&array)[N]) {
return internal::ElementsAreArrayMatcher<T>(array, N); return internal::ElementsAreArrayMatcher<T>(array, array + N);
} }
template <typename T, typename A>
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
const std::vector<T, A>& vec) {
return internal::ElementsAreArrayMatcher<T>(vec.begin(), vec.end());
}
template <typename Iter>
inline internal::ElementsAreArrayMatcher<
typename std::iterator_traits<Iter>::value_type>
ElementsAreArray(Iter first, Iter last) {
typedef typename std::iterator_traits<Iter>::value_type T;
return internal::ElementsAreArrayMatcher<T>(first, last);
}
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given // AllOf(m1, m2, ..., mk) matches any value that matches all of the given
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. // sub-matchers. AllOf is called fully qualified to prevent ADL from firing.

View File

@ -935,26 +935,33 @@ bool CaseInsensitiveStringEquals(const StringType& s1,
template <typename StringType> template <typename StringType>
class StrEqualityMatcher { class StrEqualityMatcher {
public: public:
typedef typename StringType::const_pointer ConstCharPointer;
StrEqualityMatcher(const StringType& str, bool expect_eq, StrEqualityMatcher(const StringType& str, bool expect_eq,
bool case_sensitive) bool case_sensitive)
: string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
// When expect_eq_ is true, returns true iff s is equal to string_; // Accepts pointer types, particularly:
// otherwise returns true iff s is not equal to string_. // const char*
bool MatchAndExplain(ConstCharPointer s, // char*
MatchResultListener* listener) const { // const wchar_t*
// wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
if (s == NULL) { if (s == NULL) {
return !expect_eq_; return !expect_eq_;
} }
return MatchAndExplain(StringType(s), listener); return MatchAndExplain(StringType(s), listener);
} }
bool MatchAndExplain(const StringType& s, // Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const bool eq = case_sensitive_ ? s == string_ : const StringType& s2(s);
CaseInsensitiveStringEquals(s, string_); const bool eq = case_sensitive_ ? s2 == string_ :
CaseInsensitiveStringEquals(s2, string_);
return expect_eq_ == eq; return expect_eq_ == eq;
} }
@ -989,22 +996,28 @@ class StrEqualityMatcher {
template <typename StringType> template <typename StringType>
class HasSubstrMatcher { class HasSubstrMatcher {
public: public:
typedef typename StringType::const_pointer ConstCharPointer;
explicit HasSubstrMatcher(const StringType& substring) explicit HasSubstrMatcher(const StringType& substring)
: substring_(substring) {} : substring_(substring) {}
// These overloaded methods allow HasSubstr(substring) to be used as a // Accepts pointer types, particularly:
// Matcher<T> as long as T can be converted to string. Returns true // const char*
// iff s contains substring_ as a substring. // char*
bool MatchAndExplain(ConstCharPointer s, // const wchar_t*
MatchResultListener* listener) const { // wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != NULL && MatchAndExplain(StringType(s), listener); return s != NULL && MatchAndExplain(StringType(s), listener);
} }
bool MatchAndExplain(const StringType& s, // Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
return s.find(substring_) != StringType::npos; const StringType& s2(s);
return s2.find(substring_) != StringType::npos;
} }
// Describes what this matcher matches. // Describes what this matcher matches.
@ -1030,23 +1043,29 @@ class HasSubstrMatcher {
template <typename StringType> template <typename StringType>
class StartsWithMatcher { class StartsWithMatcher {
public: public:
typedef typename StringType::const_pointer ConstCharPointer;
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
} }
// These overloaded methods allow StartsWith(prefix) to be used as a // Accepts pointer types, particularly:
// Matcher<T> as long as T can be converted to string. Returns true // const char*
// iff s starts with prefix_. // char*
bool MatchAndExplain(ConstCharPointer s, // const wchar_t*
MatchResultListener* listener) const { // wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != NULL && MatchAndExplain(StringType(s), listener); return s != NULL && MatchAndExplain(StringType(s), listener);
} }
bool MatchAndExplain(const StringType& s, // Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
return s.length() >= prefix_.length() && const StringType& s2(s);
s.substr(0, prefix_.length()) == prefix_; return s2.length() >= prefix_.length() &&
s2.substr(0, prefix_.length()) == prefix_;
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
@ -1071,22 +1090,28 @@ class StartsWithMatcher {
template <typename StringType> template <typename StringType>
class EndsWithMatcher { class EndsWithMatcher {
public: public:
typedef typename StringType::const_pointer ConstCharPointer;
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
// These overloaded methods allow EndsWith(suffix) to be used as a // Accepts pointer types, particularly:
// Matcher<T> as long as T can be converted to string. Returns true // const char*
// iff s ends with suffix_. // char*
bool MatchAndExplain(ConstCharPointer s, // const wchar_t*
MatchResultListener* listener) const { // wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != NULL && MatchAndExplain(StringType(s), listener); return s != NULL && MatchAndExplain(StringType(s), listener);
} }
bool MatchAndExplain(const StringType& s, // Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
return s.length() >= suffix_.length() && const StringType& s2(s);
s.substr(s.length() - suffix_.length()) == suffix_; return s2.length() >= suffix_.length() &&
s2.substr(s2.length() - suffix_.length()) == suffix_;
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
@ -1113,19 +1138,26 @@ class MatchesRegexMatcher {
MatchesRegexMatcher(const RE* regex, bool full_match) MatchesRegexMatcher(const RE* regex, bool full_match)
: regex_(regex), full_match_(full_match) {} : regex_(regex), full_match_(full_match) {}
// These overloaded methods allow MatchesRegex(regex) to be used as // Accepts pointer types, particularly:
// a Matcher<T> as long as T can be converted to string. Returns // const char*
// true iff s matches regular expression regex. When full_match_ is // char*
// true, a full match is done; otherwise a partial match is done. // const wchar_t*
bool MatchAndExplain(const char* s, // wchar_t*
MatchResultListener* listener) const { template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != NULL && MatchAndExplain(internal::string(s), listener); return s != NULL && MatchAndExplain(internal::string(s), listener);
} }
bool MatchAndExplain(const internal::string& s, // Matches anything that can convert to internal::string.
//
// This is a template, not just a plain function with const internal::string&,
// because StringPiece has some interfering non-explicit constructors.
template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
return full_match_ ? RE::FullMatch(s, *regex_) : const internal::string& s2(s);
RE::PartialMatch(s, *regex_); return full_match_ ? RE::FullMatch(s2, *regex_) :
RE::PartialMatch(s2, *regex_);
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
@ -2527,11 +2559,9 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
// Constructs the matcher from a sequence of element values or // Constructs the matcher from a sequence of element values or
// element matchers. // element matchers.
template <typename InputIter> template <typename InputIter>
ElementsAreMatcherImpl(InputIter first, size_t a_count) { ElementsAreMatcherImpl(InputIter first, InputIter last) {
matchers_.reserve(a_count); while (first != last) {
InputIter it = first; matchers_.push_back(MatcherCast<const Element&>(*first++));
for (size_t i = 0; i != a_count; ++i, ++it) {
matchers_.push_back(MatcherCast<const Element&>(*it));
} }
} }
@ -2642,7 +2672,8 @@ class ElementsAreMatcher0 {
Element; Element;
const Matcher<const Element&>* const matchers = NULL; const Matcher<const Element&>* const matchers = NULL;
return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0)); return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers,
matchers));
} }
}; };
@ -2650,21 +2681,17 @@ class ElementsAreMatcher0 {
template <typename T> template <typename T>
class ElementsAreArrayMatcher { class ElementsAreArrayMatcher {
public: public:
ElementsAreArrayMatcher(const T* first, size_t count) : template <typename Iter>
first_(first), count_(count) {} ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; return MakeMatcher(new ElementsAreMatcherImpl<Container>(
typedef typename internal::StlContainerView<RawContainer>::type::value_type matchers_.begin(), matchers_.end()));
Element;
return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_));
} }
private: private:
const T* const first_; const std::vector<T> matchers_;
const size_t count_;
GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher); GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
}; };

View File

@ -353,12 +353,11 @@ class OnCallSpec : public UntypedOnCallSpecBase {
Action<F> action_; Action<F> action_;
}; // class OnCallSpec }; // class OnCallSpec
// Possible reactions on uninteresting calls. TODO(wan@google.com): // Possible reactions on uninteresting calls.
// rename the enum values to the kFoo style.
enum CallReaction { enum CallReaction {
ALLOW, kAllow,
WARN, kWarn,
FAIL kFail
}; };
} // namespace internal } // namespace internal
@ -422,7 +421,7 @@ class GTEST_API_ Mock {
// Returns the reaction Google Mock will have on uninteresting calls // Returns the reaction Google Mock will have on uninteresting calls
// made on the given mock object. // made on the given mock object.
static internal::CallReaction GetReactionOnUninterestingCalls( static internal::CallReaction GetReactionOnUninterestingCalls(
const void* mock_obj); const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Verifies that all expectations on the given mock object have been // Verifies that all expectations on the given mock object have been
@ -1163,7 +1162,7 @@ class TypedExpectation : public ExpectationBase {
<< action_count << " WillOnce()" << action_count << " WillOnce()"
<< (action_count == 1 ? " is" : "s are") << " specified - "; << (action_count == 1 ? " is" : "s are") << " specified - ";
mocker->DescribeDefaultActionTo(args, &ss); mocker->DescribeDefaultActionTo(args, &ss);
Log(WARNING, ss.str(), 1); Log(kWarning, ss.str(), 1);
} }
return count <= action_count ? return count <= action_count ?
@ -1251,7 +1250,7 @@ class MockSpec {
// the newly created spec. // the newly created spec.
internal::OnCallSpec<F>& InternalDefaultActionSetAt( internal::OnCallSpec<F>& InternalDefaultActionSetAt(
const char* file, int line, const char* obj, const char* call) { const char* file, int line, const char* obj, const char* call) {
LogWithLocation(internal::INFO, file, line, LogWithLocation(internal::kInfo, file, line,
string("ON_CALL(") + obj + ", " + call + ") invoked"); string("ON_CALL(") + obj + ", " + call + ") invoked");
return function_mocker_->AddNewOnCallSpec(file, line, matchers_); return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
} }
@ -1261,7 +1260,7 @@ class MockSpec {
internal::TypedExpectation<F>& InternalExpectedAt( internal::TypedExpectation<F>& InternalExpectedAt(
const char* file, int line, const char* obj, const char* call) { const char* file, int line, const char* obj, const char* call) {
const string source_text(string("EXPECT_CALL(") + obj + ", " + call + ")"); const string source_text(string("EXPECT_CALL(") + obj + ", " + call + ")");
LogWithLocation(internal::INFO, file, line, source_text + " invoked"); LogWithLocation(internal::kInfo, file, line, source_text + " invoked");
return function_mocker_->AddNewExpectation( return function_mocker_->AddNewExpectation(
file, line, source_text, matchers_); file, line, source_text, matchers_);
} }

View File

@ -73,7 +73,7 @@ struct PointeeOf<T*> { typedef T type; }; // NOLINT
// smart pointer, or returns p itself when p is already a raw pointer. // smart pointer, or returns p itself when p is already a raw pointer.
// The following default implementation is for the smart pointer case. // The following default implementation is for the smart pointer case.
template <typename Pointer> template <typename Pointer>
inline typename Pointer::element_type* GetRawPointer(const Pointer& p) { inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
return p.get(); return p.get();
} }
// This overloaded version is for the raw pointer case. // This overloaded version is for the raw pointer case.
@ -260,7 +260,7 @@ class FailureReporterInterface {
public: public:
// The type of a failure (either non-fatal or fatal). // The type of a failure (either non-fatal or fatal).
enum FailureType { enum FailureType {
NONFATAL, FATAL kNonfatal, kFatal
}; };
virtual ~FailureReporterInterface() {} virtual ~FailureReporterInterface() {}
@ -281,7 +281,7 @@ GTEST_API_ FailureReporterInterface* GetFailureReporter();
inline void Assert(bool condition, const char* file, int line, inline void Assert(bool condition, const char* file, int line,
const string& msg) { const string& msg) {
if (!condition) { if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::FATAL, GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
file, line, msg); file, line, msg);
} }
} }
@ -294,7 +294,7 @@ inline void Assert(bool condition, const char* file, int line) {
inline void Expect(bool condition, const char* file, int line, inline void Expect(bool condition, const char* file, int line,
const string& msg) { const string& msg) {
if (!condition) { if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::NONFATAL, GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
file, line, msg); file, line, msg);
} }
} }
@ -304,8 +304,8 @@ inline void Expect(bool condition, const char* file, int line) {
// Severity level of a log. // Severity level of a log.
enum LogSeverity { enum LogSeverity {
INFO = 0, kInfo = 0,
WARNING = 1 kWarning = 1
}; };
// Valid values for the --gmock_verbose flag. // Valid values for the --gmock_verbose flag.
@ -348,6 +348,19 @@ template <typename T> struct type_equals<T, T> : public true_type {};
template <typename T> struct remove_reference { typedef T type; }; // NOLINT template <typename T> struct remove_reference { typedef T type; }; // NOLINT
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
// other types. Useful for saving a copy of a function argument.
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
template <typename T, size_t N> struct DecayArray<T[N]> {
typedef const T* type;
};
// Sometimes people use arrays whose size is not available at the use site
// (e.g. extern const char kNamePrefix[]). This specialization covers that
// case.
template <typename T> struct DecayArray<T[]> {
typedef const T* type;
};
// Invalid<T>() returns an invalid value of type T. This is useful // Invalid<T>() returns an invalid value of type T. This is useful
// when a value of type T is needed for compilation, but the statement // when a value of type T is needed for compilation, but the statement
// will not really be executed (or we don't care if the statement // will not really be executed (or we don't care if the statement

View File

@ -65,7 +65,7 @@
#define GMOCK_DECLARE_int32_(name) \ #define GMOCK_DECLARE_int32_(name) \
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
#define GMOCK_DECLARE_string_(name) \ #define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::testing::internal::String GMOCK_FLAG(name) extern GTEST_API_ ::std::string GMOCK_FLAG(name)
// Macros for defining flags. // Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \ #define GMOCK_DEFINE_bool_(name, default_val, doc) \
@ -73,6 +73,6 @@
#define GMOCK_DEFINE_int32_(name, default_val, doc) \ #define GMOCK_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
#define GMOCK_DEFINE_string_(name, default_val, doc) \ #define GMOCK_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::testing::internal::String GMOCK_FLAG(name) = (default_val) GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

View File

@ -332,7 +332,7 @@ def _OverloadedMethodActionDiagnoser(msg):
r'(.*\n)*?' r'(.*\n)*?'
r'.*\bgmock-\w+-actions\.h:\d+:\d+: ' r'.*\bgmock-\w+-actions\.h:\d+:\d+: '
r'note: candidate function template not viable: ' r'note: candidate function template not viable: '
r'requires 1 argument, but 2 were provided') r'requires .*, but 2 (arguments )?were provided')
diagnosis = """ diagnosis = """
The second argument you gave to Invoke() is an overloaded method. Please The second argument you gave to Invoke() is an overloaded method. Please
tell your compiler which overloaded version you want to use. tell your compiler which overloaded version you want to use.
@ -474,6 +474,10 @@ def _TypeInTemplatedBaseDiagnoser(msg):
r'(?P=file):(?P=line):(?P=column): error: ' r'(?P=file):(?P=line):(?P=column): error: '
r'C\+\+ requires a type specifier for all declarations' r'C\+\+ requires a type specifier for all declarations'
) )
clang_regex_unknown_type = (
_CLANG_FILE_LINE_RE +
r'error: unknown type name \'(?P<type>[^\']+)\''
)
diagnosis = """ diagnosis = """
In a mock class template, types or typedefs defined in the base class In a mock class template, types or typedefs defined in the base class
@ -483,7 +487,7 @@ need to make it visible. One way to do it is:
typedef typename Base<T>::%(type)s %(type)s;""" typedef typename Base<T>::%(type)s %(type)s;"""
return _GenericDiagnoser( for diag in _GenericDiagnoser(
'TTB', 'Type in Template Base', 'TTB', 'Type in Template Base',
[(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}), [(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
(gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}), (gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
@ -491,7 +495,13 @@ need to make it visible. One way to do it is:
(gcc_regex_type_of_a_param, diagnosis), (gcc_regex_type_of_a_param, diagnosis),
(clang_regex_type_of_retval_or_sole_param, diagnosis), (clang_regex_type_of_retval_or_sole_param, diagnosis),
(clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})], (clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
msg) msg):
yield diag
# Avoid overlap with the NUS pattern.
for m in _FindAllMatches(clang_regex_unknown_type, msg):
type_ = m.groupdict()['type']
if type_ not in _COMMON_GMOCK_SYMBOLS:
yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict())
def _WrongMockMethodMacroDiagnoser(msg): def _WrongMockMethodMacroDiagnoser(msg):

View File

@ -77,13 +77,13 @@ class GoogleTestFailureReporter : public FailureReporterInterface {
public: public:
virtual void ReportFailure(FailureType type, const char* file, int line, virtual void ReportFailure(FailureType type, const char* file, int line,
const string& message) { const string& message) {
AssertHelper(type == FATAL ? AssertHelper(type == kFatal ?
TestPartResult::kFatalFailure : TestPartResult::kFatalFailure :
TestPartResult::kNonFatalFailure, TestPartResult::kNonFatalFailure,
file, file,
line, line,
message.c_str()) = Message(); message.c_str()) = Message();
if (type == FATAL) { if (type == kFatal) {
posix::Abort(); posix::Abort();
} }
} }
@ -117,7 +117,7 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity) {
} else { } else {
// If --gmock_verbose is neither "info" nor "error", we treat it // If --gmock_verbose is neither "info" nor "error", we treat it
// as "warning" (its default value). // as "warning" (its default value).
return severity == WARNING; return severity == kWarning;
} }
} }
@ -140,7 +140,7 @@ GTEST_API_ void Log(LogSeverity severity,
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
// macro. // macro.
if (severity == WARNING) { if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable. // Prints a GMOCK WARNING marker to make the warnings easily searchable.
std::cout << "\nGMOCK WARNING:"; std::cout << "\nGMOCK WARNING:";
} }

View File

@ -217,7 +217,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
ss << " and a WillRepeatedly()"; ss << " and a WillRepeatedly()";
} }
ss << "."; ss << ".";
Log(WARNING, ss.str(), -1); // -1 means "don't print stack trace". Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
} }
} }
@ -246,11 +246,11 @@ GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
// manner specified by 'reaction'. // manner specified by 'reaction'.
void ReportUninterestingCall(CallReaction reaction, const string& msg) { void ReportUninterestingCall(CallReaction reaction, const string& msg) {
switch (reaction) { switch (reaction) {
case ALLOW: case kAllow:
Log(INFO, msg, 3); Log(kInfo, msg, 3);
break; break;
case WARN: case kWarn:
Log(WARNING, msg, 3); Log(kWarning, msg, 3);
break; break;
default: // FAIL default: // FAIL
Expect(false, NULL, -1, msg); Expect(false, NULL, -1, msg);
@ -345,10 +345,10 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
const bool need_to_report_uninteresting_call = const bool need_to_report_uninteresting_call =
// If the user allows this uninteresting call, we print it // If the user allows this uninteresting call, we print it
// only when he wants informational messages. // only when he wants informational messages.
reaction == ALLOW ? LogIsVisible(INFO) : reaction == kAllow ? LogIsVisible(kInfo) :
// If the user wants this to be a warning, we print it only // If the user wants this to be a warning, we print it only
// when he wants to see warnings. // when he wants to see warnings.
reaction == WARN ? LogIsVisible(WARNING) : reaction == kWarn ? LogIsVisible(kWarning) :
// Otherwise, the user wants this to be an error, and we // Otherwise, the user wants this to be an error, and we
// should always print detailed information in the error. // should always print detailed information in the error.
true; true;
@ -391,7 +391,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
// True iff we need to print the call's arguments and return value. // True iff we need to print the call's arguments and return value.
// This definition must be kept in sync with the uses of Expect() // This definition must be kept in sync with the uses of Expect()
// and Log() in this function. // and Log() in this function.
const bool need_to_report_call = !found || is_excessive || LogIsVisible(INFO); const bool need_to_report_call =
!found || is_excessive || LogIsVisible(kInfo);
if (!need_to_report_call) { if (!need_to_report_call) {
// Perform the action without printing the call information. // Perform the action without printing the call information.
return return
@ -427,7 +428,7 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
} else { } else {
// We had an expected call and the matching expectation is // We had an expected call and the matching expectation is
// described in ss. // described in ss.
Log(INFO, loc.str() + ss.str(), 2); Log(kInfo, loc.str() + ss.str(), 2);
} }
return result; return result;
@ -606,21 +607,21 @@ void SetReactionOnUninterestingCalls(const void* mock_obj,
// object. // object.
void Mock::AllowUninterestingCalls(const void* mock_obj) void Mock::AllowUninterestingCalls(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW); SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
} }
// Tells Google Mock to warn the user about uninteresting calls on the // Tells Google Mock to warn the user about uninteresting calls on the
// given mock object. // given mock object.
void Mock::WarnUninterestingCalls(const void* mock_obj) void Mock::WarnUninterestingCalls(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::WARN); SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
} }
// Tells Google Mock to fail uninteresting calls on the given mock // Tells Google Mock to fail uninteresting calls on the given mock
// object. // object.
void Mock::FailUninterestingCalls(const void* mock_obj) void Mock::FailUninterestingCalls(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
SetReactionOnUninterestingCalls(mock_obj, internal::FAIL); SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
} }
// Tells Google Mock the given mock object is being destroyed and its // Tells Google Mock the given mock object is being destroyed and its
@ -638,7 +639,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex); internal::MutexLock l(&internal::g_gmock_mutex);
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
internal::WARN : g_uninteresting_call_reaction[mock_obj]; internal::kWarn : g_uninteresting_call_reaction[mock_obj];
} }
// Tells Google Mock to ignore mock_obj when checking for leaked mock // Tells Google Mock to ignore mock_obj when checking for leaked mock

View File

@ -62,7 +62,7 @@ static const char* ParseGoogleMockFlagValue(const char* str,
if (str == NULL || flag == NULL) return NULL; if (str == NULL || flag == NULL) return NULL;
// The flag must start with "--gmock_". // The flag must start with "--gmock_".
const String flag_str = String::Format("--gmock_%s", flag); const std::string flag_str = std::string("--gmock_") + flag;
const size_t flag_len = flag_str.length(); const size_t flag_len = flag_str.length();
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
@ -107,7 +107,7 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
// 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.
static bool ParseGoogleMockStringFlag(const char* str, const char* flag, static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
String* value) { std::string* value) {
// Gets the value of the flag as a string. // Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
@ -131,7 +131,7 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
if (*argc <= 0) return; if (*argc <= 0) return;
for (int i = 1; i != *argc; i++) { for (int i = 1; i != *argc; i++) {
const String arg_string = StreamableToString(argv[i]); const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str(); const char* const arg = arg_string.c_str();
// Do we see a Google Mock flag? // Do we see a Google Mock flag?

View File

@ -77,6 +77,7 @@ using testing::Ref;
using testing::StaticAssertTypeEq; using testing::StaticAssertTypeEq;
using testing::StrEq; using testing::StrEq;
using testing::Value; using testing::Value;
using testing::internal::ElementsAreArrayMatcher;
using testing::internal::string; using testing::internal::string;
// Returns the description of the given matcher. // Returns the description of the given matcher.
@ -527,6 +528,51 @@ TEST(ElementsAreTest, WorksWithTwoDimensionalNativeArray) {
ElementsAre('l', 'o', '\0'))); ElementsAre('l', 'o', '\0')));
} }
TEST(ElementsAreTest, AcceptsStringLiteral) {
string array[] = { "hi", "one", "two" };
EXPECT_THAT(array, ElementsAre("hi", "one", "two"));
EXPECT_THAT(array, Not(ElementsAre("hi", "one", "too")));
}
#ifndef _MSC_VER
// The following test passes a value of type const char[] to a
// function template that expects const T&. Some versions of MSVC
// generates a compiler error C2665 for that. We believe it's a bug
// in MSVC. Therefore this test is #if-ed out for MSVC.
// Declared here with the size unknown. Defined AFTER the following test.
extern const char kHi[];
TEST(ElementsAreTest, AcceptsArrayWithUnknownSize) {
// The size of kHi is not known in this test, but ElementsAre() should
// still accept it.
string array1[] = { "hi" };
EXPECT_THAT(array1, ElementsAre(kHi));
string array2[] = { "ho" };
EXPECT_THAT(array2, Not(ElementsAre(kHi)));
}
const char kHi[] = "hi";
#endif // _MSC_VER
TEST(ElementsAreTest, MakesCopyOfArguments) {
int x = 1;
int y = 2;
// This should make a copy of x and y.
::testing::internal::ElementsAreMatcher2<int, int> polymorphic_matcher =
ElementsAre(x, y);
// Changing x and y now shouldn't affect the meaning of the above matcher.
x = y = 0;
const int array1[] = { 1, 2 };
EXPECT_THAT(array1, polymorphic_matcher);
const int array2[] = { 0, 0 };
EXPECT_THAT(array2, Not(polymorphic_matcher));
}
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most // Tests for ElementsAreArray(). Since ElementsAreArray() shares most
// of the implementation with ElementsAre(), we don't test it as // of the implementation with ElementsAre(), we don't test it as
// thoroughly here. // thoroughly here.
@ -576,6 +622,39 @@ TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray))); EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
} }
TEST(ElementsAreArrayTest, CanBeCreatedWithVector) {
const int a[] = { 1, 2, 3 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
const vector<int> expected(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(expected));
test_vector.push_back(4);
EXPECT_THAT(test_vector, Not(ElementsAreArray(expected)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherVector) {
const int a[] = { 1, 2, 3 };
const Matcher<int> kMatchers[] = { Eq(1), Eq(2), Eq(3) };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
const vector<Matcher<int> > expected(
kMatchers, kMatchers + GMOCK_ARRAY_SIZE_(kMatchers));
EXPECT_THAT(test_vector, ElementsAreArray(expected));
test_vector.push_back(4);
EXPECT_THAT(test_vector, Not(ElementsAreArray(expected)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithIteratorRange) {
const int a[] = { 1, 2, 3 };
const vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
const vector<int> expected(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(expected.begin(), expected.end()));
// Pointers are iterators, too.
EXPECT_THAT(test_vector, ElementsAreArray(a, a + GMOCK_ARRAY_SIZE_(a)));
// The empty range of NULL pointers should also be okay.
int* const null_int = NULL;
EXPECT_THAT(test_vector, Not(ElementsAreArray(null_int, null_int)));
EXPECT_THAT((vector<int>()), ElementsAreArray(null_int, null_int));
}
// Since ElementsAre() and ElementsAreArray() share much of the // Since ElementsAre() and ElementsAreArray() share much of the
// implementation, we only do a sanity test for native arrays here. // implementation, we only do a sanity test for native arrays here.
TEST(ElementsAreArrayTest, WorksWithNativeArray) { TEST(ElementsAreArrayTest, WorksWithNativeArray) {
@ -587,6 +666,22 @@ TEST(ElementsAreArrayTest, WorksWithNativeArray) {
EXPECT_THAT(a, Not(ElementsAreArray(b, 1))); EXPECT_THAT(a, Not(ElementsAreArray(b, 1)));
} }
TEST(ElementsAreArrayTest, SourceLifeSpan) {
const int a[] = { 1, 2, 3 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
vector<int> expect(a, a + GMOCK_ARRAY_SIZE_(a));
ElementsAreArrayMatcher<int> matcher_maker =
ElementsAreArray(expect.begin(), expect.end());
EXPECT_THAT(test_vector, matcher_maker);
// Changing in place the values that initialized matcher_maker should not
// affect matcher_maker anymore. It should have made its own copy of them.
typedef vector<int>::iterator Iter;
for (Iter it = expect.begin(); it != expect.end(); ++it) { *it += 10; }
EXPECT_THAT(test_vector, matcher_maker);
test_vector.push_back(3);
EXPECT_THAT(test_vector, Not(matcher_maker));
}
// Tests for the MATCHER*() macro family. // Tests for the MATCHER*() macro family.
// Tests that a simple MATCHER() definition works. // Tests that a simple MATCHER() definition works.

View File

@ -343,13 +343,7 @@ TEST(ExpectTest, FailsNonfatallyOnFalse) {
class LogIsVisibleTest : public ::testing::Test { class LogIsVisibleTest : public ::testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
// The code needs to work when both ::string and ::std::string are original_verbose_ = GMOCK_FLAG(verbose);
// defined and the flag is implemented as a
// testing::internal::String. In this case, without the call to
// c_str(), the compiler will complain that it cannot figure out
// whether the String flag should be converted to a ::string or an
// ::std::string before being assigned to original_verbose_.
original_verbose_ = GMOCK_FLAG(verbose).c_str();
} }
virtual void TearDown() { GMOCK_FLAG(verbose) = original_verbose_; } virtual void TearDown() { GMOCK_FLAG(verbose) = original_verbose_; }
@ -359,20 +353,20 @@ class LogIsVisibleTest : public ::testing::Test {
TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) { TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) {
GMOCK_FLAG(verbose) = kInfoVerbosity; GMOCK_FLAG(verbose) = kInfoVerbosity;
EXPECT_TRUE(LogIsVisible(INFO)); EXPECT_TRUE(LogIsVisible(kInfo));
EXPECT_TRUE(LogIsVisible(WARNING)); EXPECT_TRUE(LogIsVisible(kWarning));
} }
TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) { TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) {
GMOCK_FLAG(verbose) = kErrorVerbosity; GMOCK_FLAG(verbose) = kErrorVerbosity;
EXPECT_FALSE(LogIsVisible(INFO)); EXPECT_FALSE(LogIsVisible(kInfo));
EXPECT_FALSE(LogIsVisible(WARNING)); EXPECT_FALSE(LogIsVisible(kWarning));
} }
TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) { TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) {
GMOCK_FLAG(verbose) = kWarningVerbosity; GMOCK_FLAG(verbose) = kWarningVerbosity;
EXPECT_FALSE(LogIsVisible(INFO)); EXPECT_FALSE(LogIsVisible(kInfo));
EXPECT_TRUE(LogIsVisible(WARNING)); EXPECT_TRUE(LogIsVisible(kWarning));
} }
#if GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_STREAM_REDIRECTION
@ -390,7 +384,7 @@ void TestLogWithSeverity(const string& verbosity, LogSeverity severity,
if (should_print) { if (should_print) {
EXPECT_THAT(GetCapturedStdout().c_str(), EXPECT_THAT(GetCapturedStdout().c_str(),
ContainsRegex( ContainsRegex(
severity == WARNING ? severity == kWarning ?
"^\nGMOCK WARNING:\nTest log\\.\nStack trace:\n" : "^\nGMOCK WARNING:\nTest log\\.\nStack trace:\n" :
"^\nTest log\\.\nStack trace:\n")); "^\nTest log\\.\nStack trace:\n"));
} else { } else {
@ -405,7 +399,7 @@ TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
const string saved_flag = GMOCK_FLAG(verbose); const string saved_flag = GMOCK_FLAG(verbose);
GMOCK_FLAG(verbose) = kInfoVerbosity; GMOCK_FLAG(verbose) = kInfoVerbosity;
CaptureStdout(); CaptureStdout();
Log(INFO, "Test log.\n", -1); Log(kInfo, "Test log.\n", -1);
EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str()); EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str());
GMOCK_FLAG(verbose) = saved_flag; GMOCK_FLAG(verbose) = saved_flag;
} }
@ -414,8 +408,8 @@ TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) {
// treated as 0. // treated as 0.
TEST(LogTest, NoSkippingStackFrameInOptMode) { TEST(LogTest, NoSkippingStackFrameInOptMode) {
CaptureStdout(); CaptureStdout();
Log(WARNING, "Test log.\n", 100); Log(kWarning, "Test log.\n", 100);
const String log = GetCapturedStdout(); const string log = GetCapturedStdout();
# if defined(NDEBUG) && GTEST_GOOGLE3_MODE_ # if defined(NDEBUG) && GTEST_GOOGLE3_MODE_
@ -436,29 +430,29 @@ TEST(LogTest, NoSkippingStackFrameInOptMode) {
// Tests that all logs are printed when the value of the // Tests that all logs are printed when the value of the
// --gmock_verbose flag is "info". // --gmock_verbose flag is "info".
TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) { TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) {
TestLogWithSeverity(kInfoVerbosity, INFO, true); TestLogWithSeverity(kInfoVerbosity, kInfo, true);
TestLogWithSeverity(kInfoVerbosity, WARNING, true); TestLogWithSeverity(kInfoVerbosity, kWarning, true);
} }
// Tests that only warnings are printed when the value of the // Tests that only warnings are printed when the value of the
// --gmock_verbose flag is "warning". // --gmock_verbose flag is "warning".
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) { TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) {
TestLogWithSeverity(kWarningVerbosity, INFO, false); TestLogWithSeverity(kWarningVerbosity, kInfo, false);
TestLogWithSeverity(kWarningVerbosity, WARNING, true); TestLogWithSeverity(kWarningVerbosity, kWarning, true);
} }
// Tests that no logs are printed when the value of the // Tests that no logs are printed when the value of the
// --gmock_verbose flag is "error". // --gmock_verbose flag is "error".
TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) { TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) {
TestLogWithSeverity(kErrorVerbosity, INFO, false); TestLogWithSeverity(kErrorVerbosity, kInfo, false);
TestLogWithSeverity(kErrorVerbosity, WARNING, false); TestLogWithSeverity(kErrorVerbosity, kWarning, false);
} }
// Tests that only warnings are printed when the value of the // Tests that only warnings are printed when the value of the
// --gmock_verbose flag is invalid. // --gmock_verbose flag is invalid.
TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) { TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) {
TestLogWithSeverity("invalid", INFO, false); TestLogWithSeverity("invalid", kInfo, false);
TestLogWithSeverity("invalid", WARNING, true); TestLogWithSeverity("invalid", kWarning, true);
} }
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
@ -502,7 +496,7 @@ TEST(TypeTraitsTest, remove_reference) {
// Verifies that Log() behaves correctly for the given verbosity level // Verifies that Log() behaves correctly for the given verbosity level
// and log severity. // and log severity.
String GrabOutput(void(*logger)(), const char* verbosity) { std::string GrabOutput(void(*logger)(), const char* verbosity) {
const string saved_flag = GMOCK_FLAG(verbose); const string saved_flag = GMOCK_FLAG(verbose);
GMOCK_FLAG(verbose) = verbosity; GMOCK_FLAG(verbose) = verbosity;
CaptureStdout(); CaptureStdout();
@ -525,7 +519,7 @@ void ExpectCallLogger() {
// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info". // Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info".
TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) { TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) {
EXPECT_THAT(GrabOutput(ExpectCallLogger, kInfoVerbosity), EXPECT_THAT(std::string(GrabOutput(ExpectCallLogger, kInfoVerbosity)),
HasSubstr("EXPECT_CALL(mock, TestMethod())")); HasSubstr("EXPECT_CALL(mock, TestMethod())"));
} }
@ -548,7 +542,7 @@ void OnCallLogger() {
// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info". // Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info".
TEST(OnCallTest, LogsWhenVerbosityIsInfo) { TEST(OnCallTest, LogsWhenVerbosityIsInfo) {
EXPECT_THAT(GrabOutput(OnCallLogger, kInfoVerbosity), EXPECT_THAT(std::string(GrabOutput(OnCallLogger, kInfoVerbosity)),
HasSubstr("ON_CALL(mock, TestMethod())")); HasSubstr("ON_CALL(mock, TestMethod())"));
} }
@ -571,7 +565,7 @@ void OnCallAnyArgumentLogger() {
// Verifies that ON_CALL prints provided _ argument. // Verifies that ON_CALL prints provided _ argument.
TEST(OnCallTest, LogsAnythingArgument) { TEST(OnCallTest, LogsAnythingArgument) {
EXPECT_THAT(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity), EXPECT_THAT(std::string(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity)),
HasSubstr("ON_CALL(mock, TestMethodArg(_)")); HasSubstr("ON_CALL(mock, TestMethodArg(_)"));
} }

View File

@ -131,7 +131,6 @@ using testing::internal::IsReadableTypeName;
using testing::internal::JoinAsTuple; using testing::internal::JoinAsTuple;
using testing::internal::RE; using testing::internal::RE;
using testing::internal::StreamMatchResultListener; using testing::internal::StreamMatchResultListener;
using testing::internal::String;
using testing::internal::StringMatchResultListener; using testing::internal::StringMatchResultListener;
using testing::internal::Strings; using testing::internal::Strings;
using testing::internal::linked_ptr; using testing::internal::linked_ptr;
@ -2824,6 +2823,38 @@ TEST(PointeeTest, ReferenceToNonConstRawPointer) {
EXPECT_FALSE(m.Matches(p)); EXPECT_FALSE(m.Matches(p));
} }
// Minimal const-propagating pointer.
template <typename T>
class ConstPropagatingPtr {
public:
typedef T element_type;
ConstPropagatingPtr() : val_() {}
explicit ConstPropagatingPtr(T* t) : val_(t) {}
ConstPropagatingPtr(const ConstPropagatingPtr& other) : val_(other.val_) {}
T* get() { return val_; }
T& operator*() { return *val_; }
// Most smart pointers return non-const T* and T& from the next methods.
const T* get() const { return val_; }
const T& operator*() const { return *val_; }
private:
T* val_;
};
TEST(PointeeTest, WorksWithConstPropagatingPointers) {
const Matcher< ConstPropagatingPtr<int> > m = Pointee(Lt(5));
int three = 3;
const ConstPropagatingPtr<int> co(&three);
ConstPropagatingPtr<int> o(&three);
EXPECT_TRUE(m.Matches(o));
EXPECT_TRUE(m.Matches(co));
*o = 6;
EXPECT_FALSE(m.Matches(o));
EXPECT_FALSE(m.Matches(ConstPropagatingPtr<int>()));
}
TEST(PointeeTest, NeverMatchesNull) { TEST(PointeeTest, NeverMatchesNull) {
const Matcher<const char*> m = Pointee(_); const Matcher<const char*> m = Pointee(_);
EXPECT_FALSE(m.Matches(NULL)); EXPECT_FALSE(m.Matches(NULL));

View File

@ -141,12 +141,12 @@ TEST(NiceMockTest, InfoForUninterestingCall) {
GMOCK_FLAG(verbose) = "info"; GMOCK_FLAG(verbose) = "info";
CaptureStdout(); CaptureStdout();
nice_foo.DoThis(); nice_foo.DoThis();
EXPECT_THAT(GetCapturedStdout(), EXPECT_THAT(std::string(GetCapturedStdout()),
HasSubstr("Uninteresting mock function call")); HasSubstr("Uninteresting mock function call"));
CaptureStdout(); CaptureStdout();
nice_foo.DoThat(true); nice_foo.DoThat(true);
EXPECT_THAT(GetCapturedStdout(), EXPECT_THAT(std::string(GetCapturedStdout()),
HasSubstr("Uninteresting mock function call")); HasSubstr("Uninteresting mock function call"));
GMOCK_FLAG(verbose) = saved_flag; GMOCK_FLAG(verbose) = saved_flag;
} }

View File

@ -94,7 +94,6 @@ using testing::internal::FormatFileLocation;
using testing::internal::kErrorVerbosity; using testing::internal::kErrorVerbosity;
using testing::internal::kInfoVerbosity; using testing::internal::kInfoVerbosity;
using testing::internal::kWarningVerbosity; using testing::internal::kWarningVerbosity;
using testing::internal::String;
using testing::internal::linked_ptr; using testing::internal::linked_ptr;
using testing::internal::string; using testing::internal::string;
@ -632,7 +631,7 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) {
b.DoB(1); b.DoB(1);
b.DoB(2); b.DoB(2);
} }
const String output = GetCapturedStdout(); const std::string output = GetCapturedStdout();
EXPECT_PRED_FORMAT2( EXPECT_PRED_FORMAT2(
IsSubstring, IsSubstring,
"Too many actions specified in EXPECT_CALL(b, DoB())...\n" "Too many actions specified in EXPECT_CALL(b, DoB())...\n"
@ -674,7 +673,7 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
CaptureStdout(); CaptureStdout();
b.DoB(); b.DoB();
const String output = GetCapturedStdout(); const std::string output = GetCapturedStdout();
EXPECT_PRED_FORMAT2( EXPECT_PRED_FORMAT2(
IsSubstring, IsSubstring,
"Too few actions specified in EXPECT_CALL(b, DoB())...\n" "Too few actions specified in EXPECT_CALL(b, DoB())...\n"
@ -869,13 +868,13 @@ TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) {
// expectation has no action clause at all. // expectation has no action clause at all.
EXPECT_EQ(1, b.DoB()); EXPECT_EQ(1, b.DoB());
EXPECT_EQ(2, b.DoB()); EXPECT_EQ(2, b.DoB());
const String output1 = GetCapturedStdout(); const std::string output1 = GetCapturedStdout();
EXPECT_STREQ("", output1.c_str()); EXPECT_STREQ("", output1.c_str());
CaptureStdout(); CaptureStdout();
EXPECT_EQ(0, b.DoB()); EXPECT_EQ(0, b.DoB());
EXPECT_EQ(0, b.DoB()); EXPECT_EQ(0, b.DoB());
const String output2 = GetCapturedStdout(); const std::string output2 = GetCapturedStdout();
EXPECT_THAT(output2.c_str(), EXPECT_THAT(output2.c_str(),
HasSubstr("Actions ran out in EXPECT_CALL(b, DoB())...\n" HasSubstr("Actions ran out in EXPECT_CALL(b, DoB())...\n"
"Called 3 times, but only 2 WillOnce()s are specified" "Called 3 times, but only 2 WillOnce()s are specified"
@ -895,7 +894,7 @@ TEST(FunctionMockerTest, ReportsExpectCallLocationForExhausedActions) {
CaptureStdout(); CaptureStdout();
EXPECT_EQ(0, b.DoB()); EXPECT_EQ(0, b.DoB());
const String output = GetCapturedStdout(); const std::string output = GetCapturedStdout();
// The warning message should contain the call location. // The warning message should contain the call location.
EXPECT_PRED_FORMAT2(IsSubstring, expect_call_location, output); EXPECT_PRED_FORMAT2(IsSubstring, expect_call_location, output);
} }
@ -1873,14 +1872,8 @@ class MockC {
class VerboseFlagPreservingFixture : public testing::Test { class VerboseFlagPreservingFixture : public testing::Test {
protected: protected:
// The code needs to work when both ::string and ::std::string are defined
// and the flag is implemented as a testing::internal::String. In this
// case, without the call to c_str(), the compiler will complain that it
// cannot figure out what overload of string constructor to use.
// TODO(vladl@google.com): Use internal::string instead of String for
// string flags in Google Test.
VerboseFlagPreservingFixture() VerboseFlagPreservingFixture()
: saved_verbose_flag_(GMOCK_FLAG(verbose).c_str()) {} : saved_verbose_flag_(GMOCK_FLAG(verbose)) {}
~VerboseFlagPreservingFixture() { GMOCK_FLAG(verbose) = saved_verbose_flag_; } ~VerboseFlagPreservingFixture() { GMOCK_FLAG(verbose) = saved_verbose_flag_; }
@ -1898,7 +1891,7 @@ TEST(FunctionCallMessageTest, UninterestingCallGeneratesFyiWithStackTrace) {
MockC c; MockC c;
CaptureStdout(); CaptureStdout();
c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable()); c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable());
const String output = GetCapturedStdout(); const std::string output = GetCapturedStdout();
EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", output); EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", output);
EXPECT_PRED_FORMAT2(IsSubstring, "Stack trace:", output); EXPECT_PRED_FORMAT2(IsSubstring, "Stack trace:", output);
@ -1915,7 +1908,7 @@ TEST(FunctionCallMessageTest, UninterestingCallGeneratesFyiWithStackTrace) {
// stack trace. // stack trace.
CaptureStdout(); CaptureStdout();
c.NonVoidMethod(); c.NonVoidMethod();
const String output2 = GetCapturedStdout(); const std::string output2 = GetCapturedStdout();
EXPECT_PRED_FORMAT2(IsSubstring, "NonVoidMethod(", output2); EXPECT_PRED_FORMAT2(IsSubstring, "NonVoidMethod(", output2);
# endif // NDEBUG # endif // NDEBUG
@ -1928,7 +1921,7 @@ TEST(FunctionCallMessageTest, UninterestingCallPrintsArgumentsAndReturnValue) {
MockB b; MockB b;
CaptureStdout(); CaptureStdout();
b.DoB(); b.DoB();
const String output1 = GetCapturedStdout(); const std::string output1 = GetCapturedStdout();
EXPECT_PRED_FORMAT2( EXPECT_PRED_FORMAT2(
IsSubstring, IsSubstring,
"Uninteresting mock function call - returning default value.\n" "Uninteresting mock function call - returning default value.\n"
@ -1940,7 +1933,7 @@ TEST(FunctionCallMessageTest, UninterestingCallPrintsArgumentsAndReturnValue) {
MockC c; MockC c;
CaptureStdout(); CaptureStdout();
c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable()); c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable());
const String output2 = GetCapturedStdout(); const std::string output2 = GetCapturedStdout();
EXPECT_THAT(output2.c_str(), EXPECT_THAT(output2.c_str(),
ContainsRegex( ContainsRegex(
"Uninteresting mock function call - returning directly\\.\n" "Uninteresting mock function call - returning directly\\.\n"
@ -1958,7 +1951,7 @@ class GMockVerboseFlagTest : public VerboseFlagPreservingFixture {
// should_print is true, the output should match the given regex and // should_print is true, the output should match the given regex and
// contain the given function name in the stack trace. When it's // contain the given function name in the stack trace. When it's
// false, the output should be empty.) // false, the output should be empty.)
void VerifyOutput(const String& output, bool should_print, void VerifyOutput(const std::string& output, bool should_print,
const string& expected_substring, const string& expected_substring,
const string& function_name) { const string& function_name) {
if (should_print) { if (should_print) {