diff options
author | Tanzinul Islam <t_17_7@hotmail.com> | 2018-04-01 12:43:57 (GMT) |
---|---|---|
committer | Tanzinul Islam <t_17_7@hotmail.com> | 2018-04-01 12:43:57 (GMT) |
commit | 5c7c365d5f3e5467de350f2e81a31407a3f52505 (patch) | |
tree | 475f7996651558fde1e45d7f37b62bc3b9aca272 /googletest | |
parent | 6d089311ca2a6fd83dff9ed68c1d3eb00c1443d0 (diff) | |
parent | 7888184f28509dba839e3683409443e0b5bb8948 (diff) | |
download | googletest-5c7c365d5f3e5467de350f2e81a31407a3f52505.zip googletest-5c7c365d5f3e5467de350f2e81a31407a3f52505.tar.gz googletest-5c7c365d5f3e5467de350f2e81a31407a3f52505.tar.bz2 |
Merge branch 'master' into fix_death_test_child_mingw_wer_issue1116
Diffstat (limited to 'googletest')
21 files changed, 474 insertions, 243 deletions
diff --git a/googletest/include/gtest/gtest-param-test.h b/googletest/include/gtest/gtest-param-test.h index 19fae39..e155763 100644 --- a/googletest/include/gtest/gtest-param-test.h +++ b/googletest/include/gtest/gtest-param-test.h @@ -1371,8 +1371,6 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3, } # endif // GTEST_HAS_COMBINE - - # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ @@ -1386,8 +1384,8 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3, #test_case_name, \ ::testing::internal::CodeLocation(\ __FILE__, __LINE__))->AddTestPattern(\ - #test_case_name, \ - #test_name, \ + GTEST_STRINGIFY_(test_case_name), \ + GTEST_STRINGIFY_(test_name), \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(\ test_case_name, test_name)>()); \ diff --git a/googletest/include/gtest/gtest-param-test.h.pump b/googletest/include/gtest/gtest-param-test.h.pump index d8870af..8726fb3 100644 --- a/googletest/include/gtest/gtest-param-test.h.pump +++ b/googletest/include/gtest/gtest-param-test.h.pump @@ -436,8 +436,6 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( ]] # endif // GTEST_HAS_COMBINE - - # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ @@ -451,8 +449,8 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( #test_case_name, \ ::testing::internal::CodeLocation(\ __FILE__, __LINE__))->AddTestPattern(\ - #test_case_name, \ - #test_name, \ + GTEST_STRINGIFY_(test_case_name), \ + GTEST_STRINGIFY_(test_name), \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(\ test_case_name, test_name)>()); \ diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 2c83c3f..36f4042 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -509,17 +509,19 @@ void PrintTo(const T& value, ::std::ostream* os) { // function pointers so that the `*os << p` in the object pointer overload // doesn't cause that warning either. DefaultPrintTo( - WrapPrinterType< - (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) && !IsRecursiveContainer<T>::value - ? kPrintContainer : !is_pointer<T>::value - ? kPrintOther + WrapPrinterType < + (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) && + !IsRecursiveContainer<T>::value + ? kPrintContainer + : !is_pointer<T>::value + ? kPrintOther #if GTEST_LANG_CXX11 : std::is_function<typename std::remove_pointer<T>::type>::value #else : !internal::ImplicitlyConvertible<T, const void*>::value #endif ? kPrintFunctionPointer - : kPrintPointer>(), + : kPrintPointer > (), value, os); } diff --git a/googletest/include/gtest/internal/gtest-death-test-internal.h b/googletest/include/gtest/internal/gtest-death-test-internal.h index a9e6610..88e7799 100644 --- a/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -217,14 +217,18 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // 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 \ +// NDEBUG mode. In this case we need the statements to be executed and the macro +// must accept a streamed message even though the message is never printed. +// The regex object is not evaluated, but it is used to prevent "unused" +// warnings and to avoid an expression that doesn't compile in debug mode. +#define GTEST_EXECUTE_STATEMENT_(statement, regex) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } else if (!::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + static_cast<void>(gtest_regex); \ + } else \ ::testing::Message() // A class representing the parsed contents of the diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index db5a4ef..ffc22f9 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -75,6 +75,9 @@ #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar +// Stringifies its argument. +#define GTEST_STRINGIFY_(name) #name + class ProtocolMessage; namespace proto2 { class Message; } @@ -872,8 +875,11 @@ struct IsAProtocolMessage // a container class by checking the type of IsContainerTest<C>(0). // The value of the expression is insignificant. // -// Note that we look for both C::iterator and C::const_iterator. The -// reason is that C++ injects the name of a class as a member of the +// In C++11 mode we check the existence of a const_iterator and that an +// iterator is properly implemented for the container. +// +// For pre-C++11 that we look for both C::iterator and C::const_iterator. +// The reason is that C++ injects the name of a class as a member of the // class itself (e.g. you can refer to class iterator as either // 'iterator' or 'iterator::iterator'). If we look for C::iterator // only, for example, we would mistakenly think that a class named @@ -883,40 +889,94 @@ struct IsAProtocolMessage // IsContainerTest(typename C::const_iterator*) and // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. typedef int IsContainer; +#if GTEST_LANG_CXX11 +template <class C, + class Iterator = decltype(::std::declval<const C&>().begin()), + class = decltype(::std::declval<const C&>().end()), + class = decltype(++::std::declval<Iterator&>()), + class = decltype(*::std::declval<Iterator>()), + class = typename C::const_iterator> +IsContainer IsContainerTest(int /* dummy */) { + return 0; +} +#else template <class C> IsContainer IsContainerTest(int /* dummy */, typename C::iterator* /* it */ = NULL, typename C::const_iterator* /* const_it */ = NULL) { return 0; } +#endif // GTEST_LANG_CXX11 typedef char IsNotContainer; template <class C> IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } -template <typename C, bool = - sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer) -> +// Trait to detect whether a type T is a hash table. +// The heuristic used is that the type contains an inner type `hasher` and does +// not contain an inner type `reverse_iterator`. +// If the container is iterable in reverse, then order might actually matter. +template <typename T> +struct IsHashTable { + private: + template <typename U> + static char test(typename U::hasher*, typename U::reverse_iterator*); + template <typename U> + static int test(typename U::hasher*, ...); + template <typename U> + static char test(...); + + public: + static const bool value = sizeof(test<T>(0, 0)) == sizeof(int); +}; + +template <typename T> +const bool IsHashTable<T>::value; + +template<typename T> +struct VoidT { + typedef void value_type; +}; + +template <typename T, typename = void> +struct HasValueType : false_type {}; +template <typename T> +struct HasValueType<T, VoidT<typename T::value_type> > : true_type { +}; + +template <typename C, + bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer), + bool = HasValueType<C>::value> struct IsRecursiveContainerImpl; +template <typename C, bool HV> +struct IsRecursiveContainerImpl<C, false, HV> : public false_type {}; + +// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to +// obey the same inconsistencies as the IsContainerTest, namely check if +// something is a container is relying on only const_iterator in C++11 and +// is relying on both const_iterator and iterator otherwise template <typename C> -struct IsRecursiveContainerImpl<C, false> : public false_type {}; +struct IsRecursiveContainerImpl<C, true, false> : public false_type {}; template <typename C> -struct IsRecursiveContainerImpl<C, true> { - typedef - typename IteratorTraits<typename C::iterator>::value_type - value_type; +struct IsRecursiveContainerImpl<C, true, true> { + #if GTEST_LANG_CXX11 + typedef typename IteratorTraits<typename C::const_iterator>::value_type + value_type; +#else + typedef typename IteratorTraits<typename C::iterator>::value_type value_type; +#endif typedef is_same<value_type, C> type; }; // IsRecursiveContainer<Type> is a unary compile-time predicate that -// evaluates whether C is a recursive container type. A recursive container +// evaluates whether C is a recursive container type. A recursive container // type is a container type whose value_type is equal to the container type -// itself. An example for a recursive container type is -// boost::filesystem::path, whose iterator has a value_type that is equal to +// itself. An example for a recursive container type is +// boost::filesystem::path, whose iterator has a value_type that is equal to // boost::filesystem::path. -template<typename C> +template <typename C> struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {}; // EnableIf<condition>::type is void when 'Cond' is true, and @@ -1215,4 +1275,3 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ - diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 4d5aa04..e8cc5ae 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -363,14 +363,14 @@ #if GTEST_STDLIB_CXX11 # define GTEST_HAS_STD_BEGIN_AND_END_ 1 # define GTEST_HAS_STD_FORWARD_LIST_ 1 -# if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824) // works only with VS2015U2 and better +# if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824) +// works only with VS2015U2 and better # define GTEST_HAS_STD_FUNCTION_ 1 # endif # define GTEST_HAS_STD_INITIALIZER_LIST_ 1 # define GTEST_HAS_STD_MOVE_ 1 -# define GTEST_HAS_STD_SHARED_PTR_ 1 -# define GTEST_HAS_STD_TYPE_TRAITS_ 1 # define GTEST_HAS_STD_UNIQUE_PTR_ 1 +# define GTEST_HAS_STD_SHARED_PTR_ 1 # define GTEST_HAS_UNORDERED_MAP_ 1 # define GTEST_HAS_UNORDERED_SET_ 1 #endif @@ -519,7 +519,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; # define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. -# error "Google Test cannot be used where ::std::string isn't available." +# error "::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING @@ -889,6 +889,12 @@ using ::std::tuple_size; # define GTEST_ATTRIBUTE_UNUSED_ #endif +#if GTEST_LANG_CXX11 +# define GTEST_CXX11_EQUALS_DELETE_ = delete +#else // GTEST_LANG_CXX11 +# define GTEST_CXX11_EQUALS_DELETE_ +#endif // GTEST_LANG_CXX11 + // Use this annotation before a function that takes a printf format string. #if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) # if defined(__MINGW_PRINTF_FORMAT) @@ -906,15 +912,16 @@ using ::std::tuple_size; # define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) #endif + // A macro to disallow operator= // This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_ASSIGN_(type)\ - void operator=(type const &) +#define GTEST_DISALLOW_ASSIGN_(type) \ + void operator=(type const &) GTEST_CXX11_EQUALS_DELETE_ // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ - type(type const &);\ +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \ + type(type const &) GTEST_CXX11_EQUALS_DELETE_; \ GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared @@ -975,13 +982,13 @@ using ::std::tuple_size; # endif #elif __GNUC__ >= 4 || defined(__clang__) # define GTEST_API_ __attribute__((visibility ("default"))) -#endif // _MSC_VER +#endif // _MSC_VER -#endif // GTEST_API_ +#endif // GTEST_API_ #ifndef GTEST_API_ # define GTEST_API_ -#endif // GTEST_API_ +#endif // GTEST_API_ #ifndef GTEST_DEFAULT_DEATH_TEST_STYLE # define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" @@ -995,10 +1002,12 @@ using ::std::tuple_size; #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. -#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) -# define GTEST_HAS_CXXABI_H_ 1 -#else -# define GTEST_HAS_CXXABI_H_ 0 +#if !defined(GTEST_HAS_CXXABI_H_) +# if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) +# define GTEST_HAS_CXXABI_H_ 1 +# else +# define GTEST_HAS_CXXABI_H_ 0 +# endif #endif // A function level attribute to disable checking for use of uninitialized @@ -1425,6 +1434,8 @@ template <typename T> const T& move(const T& t) { return t; } +template <typename T> +GTEST_ADD_REFERENCE_(T) forward(GTEST_ADD_REFERENCE_(T) t) { return t; } template <typename T> struct RvalueRef { @@ -1537,14 +1548,18 @@ GTEST_API_ size_t GetFileSize(FILE* file); GTEST_API_ std::string ReadEntireFile(FILE* file); // All command line arguments. -GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs(); +GTEST_API_ std::vector<std::string> GetArgvs(); #if GTEST_HAS_DEATH_TEST -const ::std::vector<testing::internal::string>& GetInjectableArgvs(); -void SetInjectableArgvs(const ::std::vector<testing::internal::string>* - new_argvs); - +std::vector<std::string> GetInjectableArgvs(); +// Deprecated: pass the args vector by value instead. +void SetInjectableArgvs(const std::vector<std::string>* new_argvs); +void SetInjectableArgvs(const std::vector<std::string>& new_argvs); +#if GTEST_HAS_GLOBAL_STRING +void SetInjectableArgvs(const std::vector< ::string>& new_argvs); +#endif // GTEST_HAS_GLOBAL_STRING +void ClearInjectableArgvs(); #endif // GTEST_HAS_DEATH_TEST @@ -2325,6 +2340,7 @@ struct is_same : public false_type {}; template <typename T> struct is_same<T, T> : public true_type {}; + template <typename T> struct is_pointer : public false_type {}; @@ -2336,6 +2352,7 @@ struct IteratorTraits { typedef typename Iterator::value_type value_type; }; + template <typename T> struct IteratorTraits<T*> { typedef T value_type; @@ -2631,15 +2648,15 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. # define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) # define GTEST_DECLARE_int32_(name) \ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) -#define GTEST_DECLARE_string_(name) \ +# define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) // Macros for defining flags. -#define GTEST_DEFINE_bool_(name, default_val, doc) \ +# define GTEST_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GTEST_FLAG(name) = (default_val) -#define GTEST_DEFINE_int32_(name, default_val, doc) \ +# define GTEST_DEFINE_int32_(name, default_val, doc) \ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) -#define GTEST_DEFINE_string_(name, default_val, doc) \ +# define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) #endif // !defined(GTEST_DECLARE_bool_) @@ -2662,10 +2679,10 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value); // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); -std::string StringFromGTestEnv(const char* flag, const char* default_val); +std::string OutputFlagAlsoCheckEnvVar(); +const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal - } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/googletest/scripts/gen_gtest_pred_impl.py b/googletest/scripts/gen_gtest_pred_impl.py index 3e7ab04..b43efdf 100755 --- a/googletest/scripts/gen_gtest_pred_impl.py +++ b/googletest/scripts/gen_gtest_pred_impl.py @@ -115,10 +115,9 @@ def HeaderPreamble(n): #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -// Makes sure this header is not included before gtest.h. -#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ +#include "gtest/gtest.h" + +namespace testing { // This header implements a family of generic predicate assertion // macros: @@ -295,16 +294,17 @@ def HeaderPostamble(): return """ +} // namespace testing + #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ """ def GenerateFile(path, content): - """Given a file path and a content string, overwrites it with the - given content.""" - + """Given a file path and a content string + overwrites it with the given content. + """ print 'Updating file %s . . .' % path - f = file(path, 'w+') print >>f, content, f.close() @@ -314,8 +314,8 @@ def GenerateFile(path, content): def GenerateHeader(n): """Given the maximum arity n, updates the header file that implements - the predicate assertions.""" - + the predicate assertions. + """ GenerateFile(HEADER, HeaderPreamble(n) + ''.join([ImplementationForArity(i) for i in OneTo(n)]) diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index af0d120..d32afb1 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -1081,22 +1081,36 @@ std::string ReadEntireFile(FILE* file) { } #if GTEST_HAS_DEATH_TEST +static const std::vector<std::string>* g_injected_test_argvs = NULL; // Owned. -static const ::std::vector<testing::internal::string>* g_injected_test_argvs = - NULL; // Owned. - -void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) { - if (g_injected_test_argvs != argvs) - delete g_injected_test_argvs; - g_injected_test_argvs = argvs; -} - -const ::std::vector<testing::internal::string>& GetInjectableArgvs() { +std::vector<std::string> GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return GetArgvs(); } + +void SetInjectableArgvs(const std::vector<std::string>* new_argvs) { + if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs; + g_injected_test_argvs = new_argvs; +} + +void SetInjectableArgvs(const std::vector<std::string>& new_argvs) { + SetInjectableArgvs( + new std::vector<std::string>(new_argvs.begin(), new_argvs.end())); +} + +#if GTEST_HAS_GLOBAL_STRING +void SetInjectableArgvs(const std::vector< ::string>& new_argvs) { + SetInjectableArgvs( + new std::vector<std::string>(new_argvs.begin(), new_argvs.end())); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void ClearInjectableArgvs() { + delete g_injected_test_argvs; + g_injected_test_argvs = NULL; +} #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE @@ -1171,11 +1185,12 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) { bool BoolFromGTestEnv(const char* flag, bool default_value) { #if defined(GTEST_GET_BOOL_FROM_ENV_) return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); -#endif // defined(GTEST_GET_BOOL_FROM_ENV_) +#else const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; +#endif // defined(GTEST_GET_BOOL_FROM_ENV_) } // Reads and returns a 32-bit integer stored in the environment @@ -1184,7 +1199,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) { Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { #if defined(GTEST_GET_INT32_FROM_ENV_) return GTEST_GET_INT32_FROM_ENV_(flag, default_value); -#endif // defined(GTEST_GET_INT32_FROM_ENV_) +#else const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { @@ -1202,37 +1217,36 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { } return result; +#endif // defined(GTEST_GET_INT32_FROM_ENV_) +} + +// As a special case for the 'output' flag, if GTEST_OUTPUT is not +// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build +// system. The value of XML_OUTPUT_FILE is a filename without the +// "xml:" prefix of GTEST_OUTPUT. +// Note that this is meant to be called at the call site so it does +// not check that the flag is 'output' +// In essence this checks an env variable called XML_OUTPUT_FILE +// and if it is set we prepend "xml:" to its value, if it not set we return "" +std::string OutputFlagAlsoCheckEnvVar(){ + std::string default_value_for_output_flag = ""; + const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); + if (NULL != xml_output_file_env) { + default_value_for_output_flag = std::string("xml:") + xml_output_file_env; + } + return default_value_for_output_flag; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. -std::string StringFromGTestEnv(const char* flag, const char* default_value) { +const char* StringFromGTestEnv(const char* flag, const char* default_value) { #if defined(GTEST_GET_STRING_FROM_ENV_) return GTEST_GET_STRING_FROM_ENV_(flag, default_value); -#endif // defined(GTEST_GET_STRING_FROM_ENV_) +#else const std::string env_var = FlagToEnvVar(flag); - const char* value = posix::GetEnv(env_var.c_str()); - if (value != NULL) { - return value; - } - - // As a special case for the 'output' flag, if GTEST_OUTPUT is not - // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build - // system. The value of XML_OUTPUT_FILE is a filename without the - // "xml:" prefix of GTEST_OUTPUT. - // - // The net priority order after flag processing is thus: - // --gtest_output command line flag - // GTEST_OUTPUT environment variable - // XML_OUTPUT_FILE environment variable - // 'default_value' - if (strcmp(flag, "output") == 0) { - value = posix::GetEnv("XML_OUTPUT_FILE"); - if (value != NULL) { - return std::string("xml:") + value; - } - } - return default_value; + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +#endif // defined(GTEST_GET_STRING_FROM_ENV_) } } // namespace internal diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 248cfa5..948e4ea 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -230,9 +230,15 @@ GTEST_DEFINE_string_( GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); +// The net priority order after flag processing is thus: +// --gtest_output command line flag +// GTEST_OUTPUT environment variable +// XML_OUTPUT_FILE environment variable +// '' GTEST_DEFINE_string_( output, - internal::StringFromGTestEnv("output", ""), + internal::StringFromGTestEnv("output", + internal::OutputFlagAlsoCheckEnvVar().c_str()), "A format (defaults to \"xml\" but can be specified to be \"json\"), " "optionally followed by a colon and an output file name or directory. " "A directory is indicated by a trailing pathname separator. " @@ -386,12 +392,15 @@ void AssertHelper::operator=(const Message& message) const { GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // A copy of all command line arguments. Set by InitGoogleTest(). -::std::vector<testing::internal::string> g_argvs; +::std::vector<std::string> g_argvs; -const ::std::vector<testing::internal::string>& GetArgvs() { +::std::vector<std::string> GetArgvs() { #if defined(GTEST_CUSTOM_GET_ARGVS_) - return GTEST_CUSTOM_GET_ARGVS_(); -#else // defined(GTEST_CUSTOM_GET_ARGVS_) + // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or + // ::string. This code converts it to the appropriate type. + const auto& custom = GTEST_CUSTOM_GET_ARGVS_(); + return ::std::vector<std::string>(custom.begin(), custom.end()); +#else // defined(GTEST_CUSTOM_GET_ARGVS_) return g_argvs; #endif // defined(GTEST_CUSTOM_GET_ARGVS_) } @@ -2912,16 +2921,20 @@ static int GetBitOffset(WORD color_mask) { static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { // Let's reuse the BG - static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; - static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; + static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | + BACKGROUND_RED | BACKGROUND_INTENSITY; + static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | + FOREGROUND_RED | FOREGROUND_INTENSITY; const WORD existing_bg = old_color_attrs & background_mask; - WORD new_color = GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; + WORD new_color = + GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; static const int bg_bitOffset = GetBitOffset(background_mask); static const int fg_bitOffset = GetBitOffset(foreground_mask); - if (((new_color & background_mask) >> bg_bitOffset) == ((new_color & foreground_mask) >> fg_bitOffset)) { - new_color ^= FOREGROUND_INTENSITY; //invert intensity + if (((new_color & background_mask) >> bg_bitOffset) == + ((new_color & foreground_mask) >> fg_bitOffset)) { + new_color ^= FOREGROUND_INTENSITY; // invert intensity } return new_color; } @@ -2982,7 +2995,6 @@ bool ShouldUseColor(bool stdout_is_tty) { // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. -GTEST_ATTRIBUTE_PRINTF_(2, 3) static void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); @@ -3032,7 +3044,7 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_end(args); } -// Text printed in Google Test's text output and --gunit_list_tests +// Text printed in Google Test's text output and --gtest_list_tests // output to label the type parameter and value parameter for a test. static const char kTypeParamLabel[] = "TypeParam"; static const char kValueParamLabel[] = "GetParam()"; @@ -3442,6 +3454,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { // to delimit this attribute from prior attributes. static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + // Streams an XML representation of the test properties of a TestResult + // object. + static void OutputXmlTestProperties(std::ostream* stream, + const TestResult& result); + // The output file. const std::string output_file_; @@ -3653,6 +3670,10 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const TestResult& result = *test_info.result(); const std::string kTestcase = "testcase"; + if (test_info.is_in_another_shard()) { + return; + } + *stream << " <testcase"; OutputXmlAttribute(stream, kTestcase, "name", test_info.name()); @@ -3669,7 +3690,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, OutputXmlAttribute(stream, kTestcase, "time", FormatTimeInMillisAsSeconds(result.elapsed_time())); OutputXmlAttribute(stream, kTestcase, "classname", test_case_name); - *stream << TestPropertiesAsXmlAttributes(result); int failures = 0; for (int i = 0; i < result.total_part_count(); ++i) { @@ -3691,10 +3711,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, } } - if (failures == 0) + if (failures == 0 && result.test_property_count() == 0) { *stream << " />\n"; - else + } else { + if (failures == 0) { + *stream << ">\n"; + } + OutputXmlTestProperties(stream, result); *stream << " </testcase>\n"; + } } // Prints an XML representation of a TestCase object @@ -3749,7 +3774,6 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, OutputXmlAttribute(stream, kTestsuites, "random_seed", StreamableToString(unit_test.random_seed())); } - *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); @@ -3775,6 +3799,26 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( return attributes.GetString(); } +void XmlUnitTestResultPrinter::OutputXmlTestProperties( + std::ostream* stream, const TestResult& result) { + const std::string kProperties = "properties"; + const std::string kProperty = "property"; + + if (result.test_property_count() <= 0) { + return; + } + + *stream << "<" << kProperties << ">\n"; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + *stream << "<" << kProperty; + *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\""; + *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\""; + *stream << "/>\n"; + } + *stream << "</" << kProperties << ">\n"; +} + // End XmlUnitTestResultPrinter @@ -4210,9 +4254,10 @@ void OsStackTraceGetter::UponLeavingGTest() {} class ScopedPrematureExitFile { public: explicit ScopedPrematureExitFile(const char* premature_exit_filepath) - : premature_exit_filepath_(premature_exit_filepath) { + : premature_exit_filepath_(premature_exit_filepath ? + premature_exit_filepath : "") { // If a path to the premature-exit file is specified... - if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { + if (!premature_exit_filepath_.empty()) { // create the file with a single "0" character in it. I/O // errors are ignored as there's nothing better we can do and we // don't want to fail the test because of this. @@ -4223,13 +4268,18 @@ class ScopedPrematureExitFile { } ~ScopedPrematureExitFile() { - if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { - remove(premature_exit_filepath_); + if (!premature_exit_filepath_.empty()) { + int retval = remove(premature_exit_filepath_.c_str()); + if (retval) { + GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \"" + << premature_exit_filepath_ << "\" with error " + << retval; + } } } private: - const char* const premature_exit_filepath_; + const std::string premature_exit_filepath_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); }; @@ -4897,13 +4947,8 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. bool UnitTestImpl::RunAllTests() { - // Makes sure InitGoogleTest() was called. - if (!GTestIsInitialized()) { - GTEST_LOG_(ERROR) << - "\nThis test program did NOT call ::testing::InitGoogleTest " - "before calling RUN_ALL_TESTS(). Please fix it."; - return false; - } + // True iff Google Test is initialized before RUN_ALL_TESTS() is called. + const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized(); // Do not run any test if the --help flag was specified. if (g_help_flag) @@ -5031,6 +5076,20 @@ bool UnitTestImpl::RunAllTests() { repeater->OnTestProgramEnd(*parent_); + if (!gtest_is_initialized_before_run_all_tests) { + ColoredPrintf( + COLOR_RED, + "\nIMPORTANT NOTICE - DO NOT IGNORE:\n" + "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ + "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ + " will start to enforce the valid usage. " + "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT +#if GTEST_FOR_GOOGLE_ + ColoredPrintf(COLOR_RED, + "For more details, see http://wiki/Main/ValidGUnitMain.\n"); +#endif // GTEST_FOR_GOOGLE_ + } + return !failed; } @@ -5077,7 +5136,7 @@ bool ShouldShard(const char* total_shards_env, << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { @@ -5085,7 +5144,7 @@ bool ShouldShard(const char* total_shards_env, << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { @@ -5094,7 +5153,7 @@ bool ShouldShard(const char* total_shards_env, << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } @@ -5132,8 +5191,8 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { // each TestCase and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see -// https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md . -// Returns the number of tests that should run. +// https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md +// . Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; @@ -5361,8 +5420,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) { // part can be omitted. // // Returns the value of the flag, or NULL if the parsing failed. -static const char* ParseFlagValue(const char* str, - const char* flag, +static const char* ParseFlagValue(const char* str, const char* flag, bool def_optional) { // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; @@ -5433,9 +5491,8 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -static bool ParseStringFlag(const char* str, - const char* flag, - std::string* value) { +template <typename String> +static bool ParseStringFlag(const char* str, const char* flag, String* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); @@ -5535,22 +5592,22 @@ static const char kColorEncodedHelpMessage[] = "Test Output:\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " Enable/disable colored output. The default is @Gauto@D.\n" -" @G--" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " Don't print the elapsed time of each test.\n" " @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" " Generate a JSON or XML report in the given directory or with the given\n" " file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" -#if GTEST_CAN_STREAM_RESULTS_ +# if GTEST_CAN_STREAM_RESULTS_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" -#endif // GTEST_CAN_STREAM_RESULTS_ +# endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" -#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " Set the default death test style.\n" -#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +# endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " Turn assertion failures into debugger break-points.\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index b21cb31..adc4d1b 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -848,6 +848,34 @@ TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); +// Tests that macros in test names are expanded correctly. +class MacroNamingTest : public TestWithParam<int> {}; + +#define PREFIX_WITH_FOO(test_name) Foo##test_name +#define PREFIX_WITH_MACRO(test_name) Macro##test_name + +TEST_P(PREFIX_WITH_MACRO(NamingTest), PREFIX_WITH_FOO(SomeTestName)) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("FortyTwo/MacroNamingTest", test_info->test_case_name()); + EXPECT_STREQ("FooSomeTestName", test_info->name()); +} + +INSTANTIATE_TEST_CASE_P(FortyTwo, MacroNamingTest, Values(42)); + +// Tests the same thing for non-parametrized tests. +class MacroNamingTestNonParametrized : public ::testing::Test {}; + +TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized), + PREFIX_WITH_FOO(SomeTestName)) { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + EXPECT_STREQ("MacroNamingTestNonParametrized", test_info->test_case_name()); + EXPECT_STREQ("FooSomeTestName", test_info->name()); +} + // Tests that user supplied custom parameter names are working correctly. // Runs the test with a builtin helper method which uses PrintToString, // as well as a custom function and custom functor to ensure all possible diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index 60a8d03..4487978 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -50,18 +50,13 @@ #include "gtest/gtest.h" -// hash_map and hash_set are available under Visual C++, or on Linux. #if GTEST_HAS_UNORDERED_MAP_ # include <unordered_map> // NOLINT -#elif GTEST_HAS_HASH_MAP_ -# include <hash_map> // NOLINT -#endif // GTEST_HAS_HASH_MAP_ +#endif // GTEST_HAS_UNORDERED_MAP_ #if GTEST_HAS_UNORDERED_SET_ # include <unordered_set> // NOLINT -#elif GTEST_HAS_HASH_SET_ -# include <hash_set> // NOLINT -#endif // GTEST_HAS_HASH_SET_ +#endif // GTEST_HAS_UNORDERED_SET_ #if GTEST_HAS_STD_FORWARD_LIST_ # include <forward_list> // NOLINT @@ -200,7 +195,6 @@ class PathLike { struct iterator { typedef PathLike value_type; }; - typedef iterator const_iterator; PathLike() {} @@ -239,50 +233,6 @@ using ::testing::internal::UniversalTersePrint; #if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; #endif -using ::testing::internal::string; - -// The hash_* classes are not part of the C++ standard. STLport -// defines them in namespace std. MSVC defines them in ::stdext. GCC -// defines them in ::. -#if GTEST_HAS_UNORDERED_MAP_ - -#define GTEST_HAS_HASH_MAP_ 1 -template <class Key, class T> -using hash_map = ::std::unordered_map<Key, T>; -template <class Key, class T> -using hash_multimap = ::std::unordered_multimap<Key, T>; - -#elif GTEST_HAS_HASH_MAP_ - -#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport. -using ::std::hash_map; -using ::std::hash_multimap; -#elif _MSC_VER -using ::stdext::hash_map; -using ::stdext::hash_multimap; -#endif - -#endif - -#if GTEST_HAS_UNORDERED_SET_ - -#define GTEST_HAS_HASH_SET_ 1 -template <class Key> -using hash_set = ::std::unordered_set<Key>; -template <class Key> -using hash_multiset = ::std::unordered_multiset<Key>; - -#elif GTEST_HAS_HASH_SET_ - -#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport. -using ::std::hash_map; -using ::std::hash_multimap; -#elif _MSC_VER -using ::stdext::hash_map; -using ::stdext::hash_multimap; -#endif - -#endif // Prints a value to a string using the universal value printer. This // is a helper for testing UniversalPrinter<T>::Print() for various types. @@ -868,16 +818,16 @@ TEST(PrintStlContainerTest, NonEmptyDeque) { EXPECT_EQ("{ 1, 3 }", Print(non_empty)); } -#if GTEST_HAS_HASH_MAP_ +#if GTEST_HAS_UNORDERED_MAP_ TEST(PrintStlContainerTest, OneElementHashMap) { - hash_map<int, char> map1; + ::std::unordered_map<int, char> map1; map1[1] = 'a'; EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); } TEST(PrintStlContainerTest, HashMultiMap) { - hash_multimap<int, bool> map1; + ::std::unordered_multimap<int, bool> map1; map1.insert(make_pair(5, true)); map1.insert(make_pair(5, false)); @@ -888,12 +838,12 @@ TEST(PrintStlContainerTest, HashMultiMap) { << " where Print(map1) returns \"" << result << "\"."; } -#endif // GTEST_HAS_HASH_MAP_ +#endif // GTEST_HAS_UNORDERED_MAP_ -#if GTEST_HAS_HASH_SET_ +#if GTEST_HAS_UNORDERED_SET_ TEST(PrintStlContainerTest, HashSet) { - hash_set<int> set1; + ::std::unordered_set<int> set1; set1.insert(1); EXPECT_EQ("{ 1 }", Print(set1)); } @@ -901,7 +851,7 @@ TEST(PrintStlContainerTest, HashSet) { TEST(PrintStlContainerTest, HashMultiSet) { const int kSize = 5; int a[kSize] = { 1, 1, 2, 5, 1 }; - hash_multiset<int> set1(a, a + kSize); + ::std::unordered_multiset<int> set1(a, a + kSize); // Elements of hash_multiset can be printed in any order. const std::string result = Print(set1); @@ -927,7 +877,7 @@ TEST(PrintStlContainerTest, HashMultiSet) { EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); } -#endif // GTEST_HAS_HASH_SET_ +#endif // GTEST_HAS_UNORDERED_SET_ TEST(PrintStlContainerTest, List) { const std::string a[] = {"hello", "world"}; diff --git a/googletest/test/gtest_env_var_test.py b/googletest/test/gtest_env_var_test.py index 7af00ce..beb2a8b 100755 --- a/googletest/test/gtest_env_var_test.py +++ b/googletest/test/gtest_env_var_test.py @@ -81,13 +81,14 @@ def TestFlag(flag, test_val, default_val): class GTestEnvVarTest(gtest_test_utils.TestCase): + def testEnvVarAffectsFlag(self): """Tests that environment variable should affect the corresponding flag.""" TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') TestFlag('filter', 'FooTest.Bar', '*') - SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test + SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') @@ -99,6 +100,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('death_test_use_fork', '1', '0') TestFlag('stack_trace_depth', '0', '100') + def testXmlOutputFile(self): """Tests that $XML_OUTPUT_FILE affects the output flag.""" @@ -107,7 +109,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): AssertEq('xml:tmp/bar.xml', GetFlag('output')) def testXmlOutputFileOverride(self): - """Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT""" + """Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT.""" SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml') SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') diff --git a/googletest/test/gtest_json_outfiles_test.py b/googletest/test/gtest_json_outfiles_test.py index 62ad18e..46010d8 100644 --- a/googletest/test/gtest_json_outfiles_test.py +++ b/googletest/test/gtest_json_outfiles_test.py @@ -32,9 +32,8 @@ import json import os -import gtest_test_utils import gtest_json_test_utils - +import gtest_test_utils GTEST_OUTPUT_SUBDIR = 'json_outfiles' GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_' diff --git a/googletest/test/gtest_json_output_unittest.py b/googletest/test/gtest_json_output_unittest.py index 4d23c3a..12047c4 100644 --- a/googletest/test/gtest_json_output_unittest.py +++ b/googletest/test/gtest_json_output_unittest.py @@ -37,9 +37,8 @@ import os import re import sys -import gtest_test_utils import gtest_json_test_utils - +import gtest_test_utils GTEST_FILTER_FLAG = '--gtest_filter' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' diff --git a/googletest/test/gtest_json_test_utils.py b/googletest/test/gtest_json_test_utils.py index 4ef5f6f..62bbfc2 100644 --- a/googletest/test/gtest_json_test_utils.py +++ b/googletest/test/gtest_json_test_utils.py @@ -44,7 +44,7 @@ def normalize(obj): """ def _normalize(key, value): if key == 'time': - return re.sub(r'^\d+(\.\d+)?s$', u'*', value) + return re.sub(r'^\d+(\.\d+)?s$', '*', value) elif key == 'timestamp': return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value) elif key == 'failure': diff --git a/googletest/test/gtest_test_utils.py b/googletest/test/gtest_test_utils.py index cc4ba64..7c48933 100755 --- a/googletest/test/gtest_test_utils.py +++ b/googletest/test/gtest_test_utils.py @@ -227,7 +227,7 @@ class Subprocess: combined in a string. """ - # The subprocess module is the preferable way of running programs + # The subprocess module is the preferrable way of running programs # since it is available and behaves consistently on all platforms, # including Windows. But it is only available starting in python 2.4. # In earlier python versions, we revert to the popen2 module, which is diff --git a/googletest/test/gtest_uninitialized_test.py b/googletest/test/gtest_uninitialized_test.py index 574db77..ae91f2a 100755 --- a/googletest/test/gtest_uninitialized_test.py +++ b/googletest/test/gtest_uninitialized_test.py @@ -33,7 +33,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' -import os import gtest_test_utils COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 11af9c9..3791592 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -64,6 +64,9 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include <map> #include <vector> #include <ostream> +#if GTEST_LANG_CXX11 +#include <unordered_set> +#endif // GTEST_LANG_CXX11 #include "gtest/gtest-spi.h" #include "src/gtest-internal-inl.h" @@ -258,6 +261,8 @@ using testing::internal::IsContainer; using testing::internal::IsContainerTest; using testing::internal::IsNotContainer; using testing::internal::NativeArray; +using testing::internal::OsStackTraceGetter; +using testing::internal::OsStackTraceGetterInterface; using testing::internal::ParseInt32Flag; using testing::internal::RelationToSourceCopy; using testing::internal::RelationToSourceReference; @@ -274,6 +279,7 @@ using testing::internal::String; using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; +using testing::internal::UnitTestImpl; using testing::internal::WideStringToUtf8; using testing::internal::edit_distance::CalculateOptimalEdits; using testing::internal::edit_distance::CreateUnifiedDiff; @@ -7526,6 +7532,50 @@ TEST(IsContainerTestTest, WorksForContainer) { sizeof(IsContainerTest<std::map<int, double> >(0))); } +#if GTEST_LANG_CXX11 +struct ConstOnlyContainerWithPointerIterator { + using const_iterator = int*; + const_iterator begin() const; + const_iterator end() const; +}; + +struct ConstOnlyContainerWithClassIterator { + struct const_iterator { + const int& operator*() const; + const_iterator& operator++(/* pre-increment */); + }; + const_iterator begin() const; + const_iterator end() const; +}; + +TEST(IsContainerTestTest, ConstOnlyContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest<ConstOnlyContainerWithPointerIterator>(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest<ConstOnlyContainerWithClassIterator>(0))); +} +#endif // GTEST_LANG_CXX11 + +// Tests IsHashTable. +struct AHashTable { + typedef void hasher; +}; +struct NotReallyAHashTable { + typedef void hasher; + typedef void reverse_iterator; +}; +TEST(IsHashTable, Basic) { + EXPECT_TRUE(testing::internal::IsHashTable<AHashTable>::value); + EXPECT_FALSE(testing::internal::IsHashTable<NotReallyAHashTable>::value); +#if GTEST_LANG_CXX11 + EXPECT_FALSE(testing::internal::IsHashTable<std::vector<int>>::value); + EXPECT_TRUE(testing::internal::IsHashTable<std::unordered_set<int>>::value); +#endif // GTEST_LANG_CXX11 +#if GTEST_HAS_HASH_SET_ + EXPECT_TRUE(testing::internal::IsHashTable<hash_set<int>>::value); +#endif // GTEST_HAS_HASH_SET_ +} + // Tests ArrayEq(). TEST(ArrayEqTest, WorksForDegeneratedArrays) { diff --git a/googletest/test/gtest_xml_outfiles_test.py b/googletest/test/gtest_xml_outfiles_test.py index 24c6ee6..c7d3413 100755 --- a/googletest/test/gtest_xml_outfiles_test.py +++ b/googletest/test/gtest_xml_outfiles_test.py @@ -43,7 +43,13 @@ GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*"> - <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" /> + <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne"> + <properties> + <property name="SetUpProp" value="1"/> + <property name="TestSomeProperty" value="1"/> + <property name="TearDownProp" value="1"/> + </properties> + </testcase> </testsuite> </testsuites> """ @@ -51,7 +57,13 @@ EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*"> - <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" /> + <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo"> + <properties> + <property name="SetUpProp" value="2"/> + <property name="TestSomeProperty" value="2"/> + <property name="TearDownProp" value="2"/> + </properties> + </testcase> </testsuite> </testsuites> """ diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py index 325ca13..6ffb6e3 100755 --- a/googletest/test/gtest_xml_output_unittest.py +++ b/googletest/test/gtest_xml_output_unittest.py @@ -104,15 +104,45 @@ Invalid characters in brackets []%(stack)s]]></failure> <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/> </testsuite> <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye"> - <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/> - <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/> - <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/> - <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/> + <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest"> + <properties> + <property name="key_1" value="1"/> + </properties> + </testcase> + <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest"> + <properties> + <property name="key_int" value="1"/> + </properties> + </testcase> + <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest"> + <properties> + <property name="key_1" value="1"/> + <property name="key_2" value="2"/> + <property name="key_3" value="3"/> + </properties> + </testcase> + <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest"> + <properties> + <property name="key_1" value="2"/> + </properties> + </testcase> </testsuite> <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*"> - <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/> - <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/> - <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/> + <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest"> + <properties> + <property name="key" value="1"/> + </properties> + </testcase> + <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest"> + <properties> + <property name="key_for_utility_int" value="1"/> + </properties> + </testcase> + <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest"> + <properties> + <property name="key_for_utility_string" value="1"/> + </properties> + </testcase> </testsuite> <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*"> <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" /> @@ -149,7 +179,11 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/> </testsuite> <testsuite name="NoFixtureTest" tests="1" failures="0" disabled="0" errors="0" time="*"> - <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/> + <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest"> + <properties> + <property name="key" value="1"/> + </properties> + </testcase> </testsuite> <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" /> diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py index d303425..1e03585 100755 --- a/googletest/test/gtest_xml_test_utils.py +++ b/googletest/test/gtest_xml_test_utils.py @@ -101,19 +101,22 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { - 'testsuites': 'name', - 'testsuite': 'name', - 'testcase': 'name', - 'failure': 'message', - } + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', + 'property': 'name', + } def _GetChildren(self, element): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the - children. For <testsuites>, <testsuite> and <testcase> elements, the ID - is the value of their "name" attribute; for <failure> elements, it is - the value of the "message" attribute; CDATA sections and non-whitespace + children. For <testsuites>, <testsuite>, <testcase>, and <property> + elements, the ID is the value of their "name" attribute; for <failure> + elements, it is the value of the "message" attribute; for <properties> + elements, it is the value of their parent's "name" attribute plus the + literal string "properties"; CDATA sections and non-whitespace text nodes are concatenated into a single CDATA section with ID "detail". An exception is raised if any element other than the above four is encountered, if two child elements with the same identifying @@ -123,11 +126,17 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): children = {} for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: - self.assert_(child.tagName in self.identifying_attribute, - 'Encountered unknown element <%s>' % child.tagName) - childID = child.getAttribute(self.identifying_attribute[child.tagName]) - self.assert_(childID not in children) - children[childID] = child + if child.tagName == 'properties': + self.assert_(child.parentNode is not None, + 'Encountered <properties> element without a parent') + child_id = child.parentNode.getAttribute('name') + '-properties' + else: + self.assert_(child.tagName in self.identifying_attribute, + 'Encountered unknown element <%s>' % child.tagName) + child_id = child.getAttribute( + self.identifying_attribute[child.tagName]) + self.assert_(child_id not in children) + children[child_id] = child elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: if 'detail' not in children: if (child.nodeType == Node.CDATA_SECTION_NODE or |