From 6da2cd7c708db8a9c9da33912881dbce27b60804 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Wed, 24 Jan 2018 13:04:36 -0500 Subject: [PATCH 01/59] upstream cl 182543808 --- googletest/docs/AdvancedGuide.md | 11 ++++ googletest/include/gtest/gtest.h | 3 + googletest/src/gtest-internal-inl.h | 4 ++ googletest/src/gtest-printers.cc | 88 ++++++++++++++++++++++++-- googletest/src/gtest.cc | 7 ++ googletest/test/gtest-printers_test.cc | 72 +++++++++++++++++++++ 6 files changed, 181 insertions(+), 4 deletions(-) diff --git a/googletest/docs/AdvancedGuide.md b/googletest/docs/AdvancedGuide.md index ccb087c0..e1df20d5 100644 --- a/googletest/docs/AdvancedGuide.md +++ b/googletest/docs/AdvancedGuide.md @@ -1951,6 +1951,17 @@ variable to `0` has the same effect. _Availability:_ Linux, Windows, Mac. (In Google Test 1.3.0 and lower, the default behavior is that the elapsed time is **not** printed.) +**Availability**: Linux, Windows, Mac. + +#### Suppressing UTF-8 Text Output + +In case of assertion failures, gUnit prints expected and actual values of type +`string` both as hex-encoded strings as well as in readable UTF-8 text if they +contain valid non-ASCII UTF-8 characters. If you want to suppress the UTF-8 text +because, for example, you don't have an UTF-8 compatible output medium, run the +test program with `--gunit_print_utf8=0` or set the `GUNIT_PRINT_UTF8` +environment variable to `0`. + ### Generating an XML Report ### Google Test can emit a detailed XML report to a file in addition to its normal diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 93b755fb..01994e6d 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -115,6 +115,9 @@ GTEST_DECLARE_string_(output); // test. GTEST_DECLARE_bool_(print_time); +// This flags control whether Google Test prints UTF8 characters as text. +GTEST_DECLARE_bool_(print_utf8); + // This flag specifies the random number seed. GTEST_DECLARE_int32_(random_seed); diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index 5ec0af9b..099761ad 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -86,6 +86,7 @@ const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; +const char kPrintUTF8Flag[] = "print_utf8"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; @@ -166,6 +167,7 @@ class GTestFlagSaver { list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); + print_utf8_ = GTEST_FLAG(print_utf8); random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); @@ -187,6 +189,7 @@ class GTestFlagSaver { GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(print_utf8) = print_utf8_; GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; @@ -208,6 +211,7 @@ class GTestFlagSaver { bool list_tests_; std::string output_; bool print_time_; + bool print_utf8_; internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index dd67f645..1bdf243d 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -43,12 +43,13 @@ // defines Foo. #include "gtest/gtest-printers.h" -#include #include +#include #include #include // NOLINT #include #include "gtest/internal/gtest-port.h" +#include "src/gtest-internal-inl.h" namespace testing { @@ -262,11 +263,12 @@ template GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -static void PrintCharsAsStringTo( +static CharFormat PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; *os << kQuoteBegin; bool is_previous_hex = false; + CharFormat print_format = kAsIs; for (size_t index = 0; index < len; ++index) { const CharType cur = begin[index]; if (is_previous_hex && IsXDigit(cur)) { @@ -276,8 +278,13 @@ static void PrintCharsAsStringTo( *os << "\" " << kQuoteBegin; } is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + // Remember if any characters required hex escaping. + if (is_previous_hex) { + print_format = kHexEscape; + } } *os << "\""; + return print_format; } // Prints a (const) char/wchar_t array of 'len' elements, starting at address @@ -347,15 +354,88 @@ void PrintTo(const wchar_t* s, ostream* os) { } #endif // wchar_t is native +namespace { + +bool ContainsUnprintableControlCodes(const char* str, size_t length) { + for (size_t i = 0; i < length; i++) { + char ch = *str++; + if (std::iscntrl(ch)) { + switch (ch) { + case '\t': + case '\n': + case '\r': + break; + default: + return true; + } + } + } + return false; +} + +bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; } + +bool IsValidUTF8(const char* str, size_t length) { + const unsigned char *s = reinterpret_cast(str); + + for (size_t i = 0; i < length;) { + unsigned char lead = s[i++]; + + if (lead <= 0x7f) { + continue; // single-byte character (ASCII) 0..7F + } + if (lead < 0xc2) { + return false; // trail byte or non-shortest form + } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) { + ++i; // 2-byte character + } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length && + IsUTF8TrailByte(s[i]) && + IsUTF8TrailByte(s[i + 1]) && + // check for non-shortest form and surrogate + (lead != 0xe0 || s[i] >= 0xa0) && + (lead != 0xed || s[i] < 0xa0)) { + i += 2; // 3-byte character + } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length && + IsUTF8TrailByte(s[i]) && + IsUTF8TrailByte(s[i + 1]) && + IsUTF8TrailByte(s[i + 2]) && + // check for non-shortest form + (lead != 0xf0 || s[i] >= 0x90) && + (lead != 0xf4 || s[i] < 0x90)) { + i += 3; // 4-byte character + } else { + return false; + } + } + return true; +} + +void ConditionalPrintAsText(const char* str, size_t length, ostream* os) { + if (!ContainsUnprintableControlCodes(str, length) && + IsValidUTF8(str, length)) { + *os << "\n As Text: \"" << str << "\""; + } +} + +} // anonymous namespace + // Prints a ::string object. #if GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); + if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { + if (GTEST_FLAG(print_utf8)) { + ConditionalPrintAsText(s.data(), s.size(), os); + } + } } #endif // GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::std::string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); + if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { + if (GTEST_FLAG(print_utf8)) { + ConditionalPrintAsText(s.data(), s.size(), os); + } + } } // Prints a ::wstring object. diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 3435f9cb..2c25f838 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -246,6 +246,12 @@ GTEST_DEFINE_bool_( "True iff " GTEST_NAME_ " should display elapsed time in text output."); +GTEST_DEFINE_bool_( + print_utf8, + internal::BoolFromGTestEnv("print_utf8", true), + "True iff " GTEST_NAME_ + " prints UTF8 characters as text."); + GTEST_DEFINE_int32_( random_seed, internal::Int32FromGTestEnv("random_seed", 0), @@ -5230,6 +5236,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index aff97a2a..a8c82a8a 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -1552,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); } + TEST(PrintToStringTest, ContainsNonLatin) { + // Sanity test with valid UTF-8. Prints both in hex and as text. + std::string non_ascii_str = ::std::string("오전 4:30"); + EXPECT_PRINT_TO_STRING_(non_ascii_str, + "\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n" + " As Text: \"오전 4:30\""); + non_ascii_str = ::std::string("From ä — ẑ"); + EXPECT_PRINT_TO_STRING_(non_ascii_str, + "\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\"" + "\n As Text: \"From ä — ẑ\""); +} + +TEST(IsValidUTF8Test, IllFormedUTF8) { + // The following test strings are ill-formed UTF-8 and are printed + // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is + // expected to fail, thus output does not contain "As Text:". + + static const char *const kTestdata[][2] = { + // 2-byte lead byte followed by a single-byte character. + {"\xC3\x74", "\"\\xC3t\""}, + // Valid 2-byte character followed by an orphan trail byte. + {"\xC3\x84\xA4", "\"\\xC3\\x84\\xA4\""}, + // Lead byte without trail byte. + {"abc\xC3", "\"abc\\xC3\""}, + // 3-byte lead byte, single-byte character, orphan trail byte. + {"x\xE2\x70\x94", "\"x\\xE2p\\x94\""}, + // Truncated 3-byte character. + {"\xE2\x80", "\"\\xE2\\x80\""}, + // Truncated 3-byte character followed by valid 2-byte char. + {"\xE2\x80\xC3\x84", "\"\\xE2\\x80\\xC3\\x84\""}, + // Truncated 3-byte character followed by a single-byte character. + {"\xE2\x80\x7A", "\"\\xE2\\x80z\""}, + // 3-byte lead byte followed by valid 3-byte character. + {"\xE2\xE2\x80\x94", "\"\\xE2\\xE2\\x80\\x94\""}, + // 4-byte lead byte followed by valid 3-byte character. + {"\xF0\xE2\x80\x94", "\"\\xF0\\xE2\\x80\\x94\""}, + // Truncated 4-byte character. + {"\xF0\xE2\x80", "\"\\xF0\\xE2\\x80\""}, + // Invalid UTF-8 byte sequences embedded in other chars. + {"abc\xE2\x80\x94\xC3\x74xyc", "\"abc\\xE2\\x80\\x94\\xC3txyc\""}, + {"abc\xC3\x84\xE2\x80\xC3\x84xyz", + "\"abc\\xC3\\x84\\xE2\\x80\\xC3\\x84xyz\""}, + // Non-shortest UTF-8 byte sequences are also ill-formed. + // The classics: xC0, xC1 lead byte. + {"\xC0\x80", "\"\\xC0\\x80\""}, + {"\xC1\x81", "\"\\xC1\\x81\""}, + // Non-shortest sequences. + {"\xE0\x80\x80", "\"\\xE0\\x80\\x80\""}, + {"\xf0\x80\x80\x80", "\"\\xF0\\x80\\x80\\x80\""}, + // Last valid code point before surrogate range, should be printed as text, + // too. + {"\xED\x9F\xBF", "\"\\xED\\x9F\\xBF\"\n As Text: \"퟿\""}, + // Start of surrogate lead. Surrogates are not printed as text. + {"\xED\xA0\x80", "\"\\xED\\xA0\\x80\""}, + // Last non-private surrogate lead. + {"\xED\xAD\xBF", "\"\\xED\\xAD\\xBF\""}, + // First private-use surrogate lead. + {"\xED\xAE\x80", "\"\\xED\\xAE\\x80\""}, + // Last private-use surrogate lead. + {"\xED\xAF\xBF", "\"\\xED\\xAF\\xBF\""}, + // Mid-point of surrogate trail. + {"\xED\xB3\xBF", "\"\\xED\\xB3\\xBF\""}, + // First valid code point after surrogate range, should be printed as text, + // too. + {"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""} + }; + + for (int i = 0; i < sizeof(kTestdata)/sizeof(kTestdata[0]); ++i) { + EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]); + } +} + #undef EXPECT_PRINT_TO_STRING_ TEST(UniversalTersePrintTest, WorksForNonReference) { From 52f02b8a994853da2c8a58e92f1199e7d599ee5e Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Wed, 24 Jan 2018 16:06:08 -0500 Subject: [PATCH 02/59] placating gcc and its overzeauls size comparison warnings --- googletest/test/gtest-printers_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index a8c82a8a..e30ce7ef 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -1619,7 +1619,7 @@ TEST(IsValidUTF8Test, IllFormedUTF8) { {"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""} }; - for (int i = 0; i < sizeof(kTestdata)/sizeof(kTestdata[0]); ++i) { + for (int i = 0; i < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) { EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]); } } From 4184660d4ad11a1dbc0c8ef5227eec5565782203 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Thu, 25 Jan 2018 09:58:51 -0500 Subject: [PATCH 03/59] Remove Visual Studio 10,11,12 from build matrix --- appveyor.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f73f413b..6c50fef8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,21 +19,6 @@ environment: - compiler: msvc-14-seh generator: "Visual Studio 14 2015 Win64" - - compiler: msvc-12-seh - generator: "Visual Studio 12 2013" - - - compiler: msvc-12-seh - generator: "Visual Studio 12 2013 Win64" - - - compiler: msvc-11-seh - generator: "Visual Studio 11 2012" - - - compiler: msvc-11-seh - generator: "Visual Studio 11 2012 Win64" - - - compiler: msvc-10-seh - generator: "Visual Studio 10 2010" - - compiler: gcc-5.3.0-posix generator: "MinGW Makefiles" cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' From 442bb38ff8157af16499a80317747483bd672505 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Thu, 25 Jan 2018 10:12:56 -0500 Subject: [PATCH 04/59] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79363002..157316c0 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ package (as described below): ### Windows Requirements ### - * Microsoft Visual C++ 2010 or newer + * Microsoft Visual C++ 2015 or newer ### Cygwin Requirements ### From 69205e815e403ccbe80f932999c25a0cad377546 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 25 Jan 2018 14:14:33 -0800 Subject: [PATCH 05/59] Pass -EHs-c- to disable exceptions with MSVC. --- googletest/cmake/internal_utils.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake index c54bc94f..acffe0c3 100644 --- a/googletest/cmake/internal_utils.cmake +++ b/googletest/cmake/internal_utils.cmake @@ -91,7 +91,7 @@ macro(config_compiler_and_linker) set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") - set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0") + set(cxx_no_exception_flags "-EHs-c- -D_HAS_EXCEPTIONS=0") set(cxx_no_rtti_flags "-GR-") elseif (CMAKE_COMPILER_IS_GNUCXX) set(cxx_base_flags "-Wall -Wshadow -Werror") From bf92c203ea6bf82e7ddaae90d2ccabaf2769b727 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 24 Jan 2018 17:15:18 -0800 Subject: [PATCH 06/59] Use _CPPUNWIND instead of _HAS_EXCEPTIONS with MSVC. _HAS_EXCEPTIONS is specific to the MSVC STL and defining it to 0 causes problems with libc++, so libc++ users may leave it undefined. This can cause GTEST_HAS_EXCEPTIONS to be defined incorrectly if the user has disabled exceptions via the compiler, which can lead to build errors. _CPPUNWIND is a builtin macro provided by the compiler so it should work with both STLs. --- googletest/include/gtest/internal/gtest-port.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 01ad5dac..1a1d9dd0 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -464,8 +464,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. -# if defined(_MSC_VER) || defined(__BORLANDC__) -// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +# if defined(_MSC_VER) && defined(_CPPUNWIND) +// MSVC defines _CPPUNWIND to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__BORLANDC__) +// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. # ifndef _HAS_EXCEPTIONS From c669fb438477260845fcbec8a13f2c9799d07570 Mon Sep 17 00:00:00 2001 From: Stefano Soffia Date: Thu, 25 Jan 2018 21:21:54 +0100 Subject: [PATCH 07/59] Fix test build issue with GCC7.2. --- googletest/cmake/internal_utils.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake index c54bc94f..2c978332 100644 --- a/googletest/cmake/internal_utils.cmake +++ b/googletest/cmake/internal_utils.cmake @@ -95,6 +95,9 @@ macro(config_compiler_and_linker) set(cxx_no_rtti_flags "-GR-") elseif (CMAKE_COMPILER_IS_GNUCXX) set(cxx_base_flags "-Wall -Wshadow -Werror") + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) + set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else") + endif() set(cxx_exception_flags "-fexceptions") set(cxx_no_exception_flags "-fno-exceptions") # Until version 4.3.2, GCC doesn't define a macro to indicate From 38205c4554678869812553cc52e8af08914c2678 Mon Sep 17 00:00:00 2001 From: LI Daobing Date: Fri, 26 Jan 2018 15:36:57 +0800 Subject: [PATCH 08/59] Update Documentation.md --- googletest/docs/Documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/docs/Documentation.md b/googletest/docs/Documentation.md index 3784c8fd..20f25039 100644 --- a/googletest/docs/Documentation.md +++ b/googletest/docs/Documentation.md @@ -12,5 +12,5 @@ the respective git branch/tag).** To contribute code to Google Test, read: - * [CONTRIBUTING](../CONTRIBUTING.md) -- read this _before_ writing your first patch. + * [CONTRIBUTING](../../CONTRIBUTING.md) -- read this _before_ writing your first patch. * [PumpManual](PumpManual.md) -- how we generate some of Google Test's source files. From 05c81235a1eb879b22fff798758552bfc02fe232 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 26 Jan 2018 11:57:58 -0500 Subject: [PATCH 09/59] Code merges --- googlemock/include/gmock/gmock-matchers.h | 3 +- .../include/gmock/gmock-more-matchers.h | 16 ++++++++ .../include/gmock/gmock-spec-builders.h | 9 ++--- googlemock/include/gmock/gmock.h | 2 +- .../internal/gmock-generated-internal-utils.h | 25 +++++++----- .../gmock/internal/gmock-internal-utils.h | 39 +++++++++++++++++-- .../include/gmock/internal/gmock-port.h | 18 ++++----- googlemock/test/gmock_stress_test.cc | 3 +- googlemock/test/gmock_test.cc | 5 ++- 9 files changed, 86 insertions(+), 34 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 3367a0b5..41bf6de3 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -47,10 +47,9 @@ #include #include #include - +#include "gtest/gtest.h" #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" #if GTEST_HAS_STD_INITIALIZER_LIST_ # include // NOLINT -- must be after gtest.h diff --git a/googlemock/include/gmock/gmock-more-matchers.h b/googlemock/include/gmock/gmock-more-matchers.h index 3db899f4..a5a8bfa5 100644 --- a/googlemock/include/gmock/gmock-more-matchers.h +++ b/googlemock/include/gmock/gmock-more-matchers.h @@ -53,6 +53,22 @@ MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { return false; } +// Define a matcher that matches a value that evaluates in boolean +// context to true. Useful for types that define "explicit operator +// bool" operators and so can't be compared for equality with true +// and false. +MATCHER(IsTrue, negation ? "is false" : "is true") { + return static_cast(arg); +} + +// Define a matcher that matches a value that evaluates in boolean +// context to false. Useful for types that define "explicit operator +// bool" operators and so can't be compared for equality with true +// and false. +MATCHER(IsFalse, negation ? "is true" : "is false") { + return !static_cast(arg); +} + } // namespace testing #endif // GMOCK_GMOCK_MORE_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index a8347bd8..c1b63014 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -65,11 +65,6 @@ #include #include #include - -#if GTEST_HAS_EXCEPTIONS -# include // NOLINT -#endif - #include "gmock/gmock-actions.h" #include "gmock/gmock-cardinalities.h" #include "gmock/gmock-matchers.h" @@ -77,6 +72,10 @@ #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" +#if GTEST_HAS_EXCEPTIONS +# include // NOLINT +#endif + namespace testing { // An abstract handle of an expectation. diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h index 5764bc85..6ccb118b 100644 --- a/googlemock/include/gmock/gmock.h +++ b/googlemock/include/gmock/gmock.h @@ -59,8 +59,8 @@ #include "gmock/gmock-cardinalities.h" #include "gmock/gmock-generated-actions.h" #include "gmock/gmock-generated-function-mockers.h" -#include "gmock/gmock-generated-nice-strict.h" #include "gmock/gmock-generated-matchers.h" +#include "gmock/gmock-generated-nice-strict.h" #include "gmock/gmock-matchers.h" #include "gmock/gmock-more-actions.h" #include "gmock/gmock-more-matchers.h" diff --git a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h index 7811e43f..cd94d644 100644 --- a/googlemock/include/gmock/internal/gmock-generated-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-generated-internal-utils.h @@ -90,42 +90,48 @@ struct MatcherTuple< ::testing::tuple > { template struct MatcherTuple< ::testing::tuple > { - typedef ::testing::tuple, Matcher, Matcher, - Matcher > type; + typedef ::testing::tuple, Matcher, Matcher, Matcher > + type; }; template struct MatcherTuple< ::testing::tuple > { typedef ::testing::tuple, Matcher, Matcher, Matcher, - Matcher > type; + Matcher > + type; }; template struct MatcherTuple< ::testing::tuple > { typedef ::testing::tuple, Matcher, Matcher, Matcher, - Matcher, Matcher > type; + Matcher, Matcher > + type; }; template struct MatcherTuple< ::testing::tuple > { typedef ::testing::tuple, Matcher, Matcher, Matcher, - Matcher, Matcher, Matcher > type; + Matcher, Matcher, Matcher > + type; }; template struct MatcherTuple< ::testing::tuple > { typedef ::testing::tuple, Matcher, Matcher, Matcher, - Matcher, Matcher, Matcher, Matcher > type; + Matcher, Matcher, Matcher, Matcher > + type; }; template struct MatcherTuple< ::testing::tuple > { typedef ::testing::tuple, Matcher, Matcher, Matcher, - Matcher, Matcher, Matcher, Matcher, Matcher > type; + Matcher, Matcher, Matcher, Matcher, + Matcher > + type; }; template > { typedef ::testing::tuple, Matcher, Matcher, Matcher, - Matcher, Matcher, Matcher, Matcher, Matcher, - Matcher > type; + Matcher, Matcher, Matcher, Matcher, + Matcher, Matcher > + type; }; // Template struct Function, where F must be a function type, contains diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 7e65cea8..319b389b 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -41,7 +41,6 @@ #include #include // NOLINT #include - #include "gmock/internal/gmock-generated-internal-utils.h" #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" @@ -49,11 +48,15 @@ namespace testing { namespace internal { +// Joins a vector of strings as if they are fields of a tuple; returns +// the joined string. +GTEST_API_ std::string JoinAsTuple(const Strings& fields); + // Converts an identifier name to a space-separated list of lower-case // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // treated as one word. For example, both "FooBar123" and // "foo_bar_123" are converted to "foo bar 123". -GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name); +GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name); // PointeeOf::type is the type of a value pointed to by a // Pointer, which can be either a smart pointer or a raw pointer. The @@ -503,8 +506,38 @@ struct RemoveConstFromKey > { template struct BooleanConstant {}; +// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to +// reduce code size. +void IllegalDoDefault(const char* file, int line); + +#if GTEST_LANG_CXX11 +// Helper types for Apply() below. +template struct int_pack { typedef int_pack type; }; + +template struct append; +template +struct append, I> : int_pack {}; + +template +struct make_int_pack : append::type, C - 1> {}; +template <> struct make_int_pack<0> : int_pack<> {}; + +template +auto ApplyImpl(F&& f, Tuple&& args, int_pack) -> decltype( + std::forward(f)(std::get(std::forward(args))...)) { + return std::forward(f)(std::get(std::forward(args))...); +} + +// Apply the function to a tuple of arguments. +template +auto Apply(F&& f, Tuple&& args) + -> decltype(ApplyImpl(std::forward(f), std::forward(args), + make_int_pack::value>())) { + return ApplyImpl(std::forward(f), std::forward(args), + make_int_pack::value>()); +} +#endif } // namespace internal } // namespace testing #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ - diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index 63f4a680..cb37f260 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -50,15 +50,11 @@ // portability utilities to Google Test's gtest-port.h instead of // here, as Google Mock depends on Google Test. Only add a utility // here if it's truly specific to Google Mock. + #include "gtest/internal/gtest-linked_ptr.h" #include "gtest/internal/gtest-port.h" #include "gmock/internal/custom/gmock-port.h" -// To avoid conditional compilation everywhere, we make it -// gmock-port.h's responsibility to #include the header implementing -// tr1/tuple. gmock-port.h does this via gtest-port.h, which is -// guaranteed to pull in the tuple header. - // For MS Visual C++, check the compiler version. At least VS 2003 is // required to compile Google Mock. #if defined(_MSC_VER) && _MSC_VER < 1310 @@ -72,18 +68,18 @@ #if !defined(GMOCK_DECLARE_bool_) // Macros for declaring flags. -#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) -#define GMOCK_DECLARE_int32_(name) \ +# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) +# define GMOCK_DECLARE_int32_(name) \ extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) -#define GMOCK_DECLARE_string_(name) \ +# define GMOCK_DECLARE_string_(name) \ extern GTEST_API_ ::std::string GMOCK_FLAG(name) // Macros for defining flags. -#define GMOCK_DEFINE_bool_(name, default_val, doc) \ +# define GMOCK_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GMOCK_FLAG(name) = (default_val) -#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) -#define GMOCK_DEFINE_string_(name, default_val, doc) \ +# define GMOCK_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) #endif // !defined(GMOCK_DECLARE_bool_) diff --git a/googlemock/test/gmock_stress_test.cc b/googlemock/test/gmock_stress_test.cc index c16badda..b9fdc45c 100644 --- a/googlemock/test/gmock_stress_test.cc +++ b/googlemock/test/gmock_stress_test.cc @@ -33,12 +33,13 @@ // threads concurrently. #include "gmock/gmock.h" + #include "gtest/gtest.h" namespace testing { namespace { -// From . +// From "gtest/internal/gtest-port.h". using ::testing::internal::ThreadWithParam; // The maximum number of test threads (not including helper threads) diff --git a/googlemock/test/gmock_test.cc b/googlemock/test/gmock_test.cc index 28995345..70075679 100644 --- a/googlemock/test/gmock_test.cc +++ b/googlemock/test/gmock_test.cc @@ -37,6 +37,7 @@ #include #include "gtest/gtest.h" +#include "gtest/internal/custom/gtest.h" #if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) @@ -51,9 +52,9 @@ void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N], const ::std::string& expected_gmock_verbose) { const ::std::string old_verbose = GMOCK_FLAG(verbose); - int argc = M; + int argc = M - 1; InitGoogleMock(&argc, const_cast(argv)); - ASSERT_EQ(N, argc) << "The new argv has wrong number of elements."; + ASSERT_EQ(N - 1, argc) << "The new argv has wrong number of elements."; for (int i = 0; i < N; i++) { EXPECT_STREQ(new_argv[i], argv[i]); From 8a3cd4124ef6d970f95eabbdcfbad84913f5c39c Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 26 Jan 2018 16:30:57 -0500 Subject: [PATCH 10/59] Adding tests to googlemock bazel --- googlemock/test/BUILD.bazel | 72 ++++++++++++++++++++++++++++- googlemock/test/gmock_test_utils.py | 6 +-- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/googlemock/test/BUILD.bazel b/googlemock/test/BUILD.bazel index 4c2df9e2..0fe72a67 100644 --- a/googlemock/test/BUILD.bazel +++ b/googlemock/test/BUILD.bazel @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# Copyright 2017 Google Inc. # All Rights Reserved. # # @@ -29,7 +29,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Author: misterg@google.com (Gennadiy Civil) -# +# # Bazel Build for Google C++ Testing Framework(Google Test)-googlemock licenses(["notice"]) @@ -53,3 +53,71 @@ cc_test( }), deps = ["//:gtest"], ) + +# Py tests + +py_library( + name = "gmock_test_utils", + testonly = 1, + srcs = ["gmock_test_utils.py"], +) + +cc_binary( + name = "gmock_leak_test_", + testonly = 1, + srcs = ["gmock_leak_test_.cc"], + deps = [ + "//:gtest_main", + ], +) + +py_test( + name = "gmock_leak_test", + size = "medium", + srcs = ["gmock_leak_test.py"], + data = [ + ":gmock_leak_test_", + ":gmock_test_utils", + ], +) + +cc_test( + name = "gmock_link_test", + size = "small", + srcs = [ + "gmock_link2_test.cc", + "gmock_link_test.cc", + "gmock_link_test.h", + ], + deps = [ + "//:gtest_main", + ], +) + +cc_binary( + name = "gmock_output_test_", + srcs = ["gmock_output_test_.cc"], + deps = [ + "//:gtest", + ], +) + +py_test( + name = "gmock_output_test", + size = "medium", + srcs = ["gmock_output_test.py"], + data = [ + ":gmock_output_test_", + ":gmock_output_test_golden.txt", + ], + deps = [":gmock_test_utils"], +) + +cc_test( + name = "gmock_test", + size = "small", + srcs = ["gmock_test.cc"], + deps = [ + "//:gtest_main", + ], +) diff --git a/googlemock/test/gmock_test_utils.py b/googlemock/test/gmock_test_utils.py index 20e3d3d4..1983c53b 100755 --- a/googlemock/test/gmock_test_utils.py +++ b/googlemock/test/gmock_test_utils.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Copyright 2006, Google Inc. # All rights reserved. # @@ -41,11 +39,11 @@ import sys SCRIPT_DIR = os.path.dirname(__file__) or '.' # isdir resolves symbolic links. -gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../gtest/test') +gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../googletest/test') if os.path.isdir(gtest_tests_util_dir): GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir else: - GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../gtest/test') + GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../googletest/test') sys.path.append(GTEST_TESTS_UTIL_DIR) import gtest_test_utils # pylint: disable-msg=C6204 From 735ae77a8ff74b8ec7adc79e1499befe3de649cf Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 30 Jan 2018 11:42:03 -0500 Subject: [PATCH 11/59] Ability to optionally depend on Abseil plus upstream of 183716547 --- BUILD.bazel | 20 ++++++++++++++++ WORKSPACE | 7 ++++++ googletest/include/gtest/gtest-printers.h | 28 +++++++++++++++++++++++ googletest/test/gtest-printers_test.cc | 12 ++++++++++ 4 files changed, 67 insertions(+) diff --git a/BUILD.bazel b/BUILD.bazel index 7d2e9d2b..91dd3b74 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -46,6 +46,12 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "has_absl", + values = {"define": "absl=1"}, +) + + # Google Test including Google Mock cc_library( name = "gtest", @@ -88,6 +94,20 @@ cc_library( "-pthread", ], }), + defines = select ({ + ":has_absl": [ + "GTEST_HAS_ABSL=1", + ], + "//conditions:default": [], + } + ), + deps = select ({ + ":has_absl": [ + "@com_google_absl//absl/types:optional", + ], + "//conditions:default": [], + } + ) ) cc_library( diff --git a/WORKSPACE b/WORKSPACE index 106b824e..1d5d3886 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1 +1,8 @@ workspace(name = "com_google_googletest") + +# Abseil +http_archive( + name = "com_google_absl", + urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"], + strip_prefix = "abseil-cpp-master", +) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 38c63d25..8dcb256a 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -46,6 +46,10 @@ // 2. operator<<(ostream&, const T&) defined in either foo or the // global namespace. // +// However if T is an STL-style container then it is printed element-wise +// unless foo::PrintTo(const T&, ostream*) is defined. Note that +// operator<<() is ignored for container types. +// // If none of the above is defined, it will print the debug string of // the value if it is a protocol buffer, or print the raw bytes in the // value otherwise. @@ -107,6 +111,10 @@ # include #endif +#if GTEST_HAS_ABSL +#include "absl/types/optional.h" +#endif // GTEST_HAS_ABSL + namespace testing { // Definitions in the 'internal' and 'internal2' name spaces are @@ -722,6 +730,26 @@ class UniversalPrinter { GTEST_DISABLE_MSC_WARNINGS_POP_() }; +#if GTEST_HAS_ABSL + +// Printer for absl::optional + +template +class UniversalPrinter<::absl::optional> { + public: + static void Print(const ::absl::optional& value, ::std::ostream* os) { + *os << '('; + if (!value) { + *os << "nullopt"; + } else { + UniversalPrint(*value, os); + } + *os << ')'; + } +}; + +#endif // GTEST_HAS_ABSL + // UniversalPrintArray(begin, len, os) prints an array of 'len' // elements, starting at address 'begin'. template diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index e30ce7ef..42e19656 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -1765,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { #endif // GTEST_HAS_STD_TUPLE_ +#if GTEST_HAS_ABSL + +TEST(PrintOptionalTest, Basic) { + absl::optional value; + EXPECT_EQ("(nullopt)", PrintToString(value)); + value = {7}; + EXPECT_EQ("(7)", PrintToString(value)); + EXPECT_EQ("(1.1)", PrintToString(absl::optional{1.1})); + EXPECT_EQ("(\"A\")", PrintToString(absl::optional{"A"})); +} +#endif // GTEST_HAS_ABSL + } // namespace gtest_printers_test } // namespace testing From 9f2c3d4cacb1b7785c5e50e414b5183316269edd Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 30 Jan 2018 17:34:22 -0500 Subject: [PATCH 12/59] Code merges --- googletest/include/gtest/gtest-printers.h | 72 ++++++++++++++++++----- googletest/test/gtest-printers_test.cc | 14 ++--- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 8dcb256a..fa7da7ee 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -133,7 +133,11 @@ enum TypeKind { kProtobuf, // a protobuf type kConvertibleToInteger, // a type implicitly convertible to BiggestInt // (e.g. a named or unnamed enum type) - kOtherType // anything else +#if GTEST_HAS_ABSL + kConvertibleToStringView, // a type implicitly convertible to + // absl::string_view +#endif + kOtherType // anything else }; // TypeWithoutFormatter::PrintValue(value, os) is called @@ -146,7 +150,7 @@ class TypeWithoutFormatter { // This default version is called when kTypeKind is kOtherType. static void PrintValue(const T& value, ::std::ostream* os) { PrintBytesInObjectTo(static_cast( - reinterpret_cast(&value)), + reinterpret_cast(&value)), sizeof(value), os); } }; @@ -184,6 +188,19 @@ class TypeWithoutFormatter { } }; +#if GTEST_HAS_ABSL +template +class TypeWithoutFormatter { + public: + // Since T has neither operator<< nor PrintTo() but can be implicitly + // converted to absl::string_view, we print it as a absl::string_view. + // + // Note: the implementation is further below, as it depends on + // internal::PrintTo symbol which is defined later in the file. + static void PrintValue(const T& value, ::std::ostream* os); +}; +#endif + // Prints the given value to the given ostream. If the value is a // protocol message, its debug string is printed; if it's an enum or // of a type implicitly convertible to BiggestInt, it's printed as an @@ -211,10 +228,19 @@ class TypeWithoutFormatter { template ::std::basic_ostream& operator<<( ::std::basic_ostream& os, const T& x) { - TypeWithoutFormatter::value ? kProtobuf : - internal::ImplicitlyConvertible::value ? - kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + TypeWithoutFormatter::value + ? kProtobuf + : internal::ImplicitlyConvertible< + const T&, internal::BiggestInt>::value + ? kConvertibleToInteger + : +#if GTEST_HAS_ABSL + internal::ImplicitlyConvertible< + const T&, absl::string_view>::value + ? kConvertibleToStringView + : +#endif + kOtherType)>::PrintValue(x, &os); return os; } @@ -435,7 +461,8 @@ void DefaultPrintTo(WrapPrinterType /* dummy */, *os << "NULL"; } else { // T is a function type, so '*os << p' doesn't do what we want - // (it just prints p as bool). Cast p to const void* to print it. + // (it just prints p as bool). We want to print p as a const + // void*. *os << reinterpret_cast(p); } } @@ -464,17 +491,15 @@ void PrintTo(const T& value, ::std::ostream* os) { // DefaultPrintTo() is overloaded. The type of its first argument // determines which version will be picked. // - // Note that we check for recursive and other container types here, prior - // to we check for protocol message types in our operator<<. The rationale is: + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: // // For protocol messages, we want to give people a chance to // override Google Mock's format by defining a PrintTo() or // operator<<. For STL containers, other formats can be // incompatible with Google Mock's format for the container // elements; therefore we check for container types here to ensure - // that our format is used. To prevent an infinite runtime recursion - // during the output of recursive container types, we check first for - // those. + // that our format is used. // // Note that MSVC and clang-cl do allow an implicit conversion from // pointer-to-function to pointer-to-object, but clang-cl warns on it. @@ -492,8 +517,8 @@ void PrintTo(const T& value, ::std::ostream* os) { #else : !internal::ImplicitlyConvertible::value #endif - ? kPrintFunctionPointer - : kPrintPointer>(), + ? kPrintFunctionPointer + : kPrintPointer>(), value, os); } @@ -601,6 +626,13 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { } #endif // GTEST_HAS_STD_WSTRING +#if GTEST_HAS_ABSL +// Overload for absl::string_view. +inline void PrintTo(absl::string_view sp, ::std::ostream* os) { + PrintTo(string(sp), os); +} +#endif // GTEST_HAS_ABSL + #if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ // Helper function for printing a tuple. T must be instantiated with // a tuple type. @@ -896,7 +928,7 @@ void UniversalPrint(const T& value, ::std::ostream* os) { UniversalPrinter::Print(value, os); } -typedef ::std::vector Strings; +typedef ::std::vector< ::std::string> Strings; // TuplePolicy must provide: // - tuple_size @@ -1016,6 +1048,16 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { } // namespace internal +#if GTEST_HAS_ABSL +namespace internal2 { +template +void TypeWithoutFormatter::PrintValue( + const T& value, ::std::ostream* os) { + internal::PrintTo(absl::string_view(value), os); +} +} // namespace internal2 +#endif + template ::std::string PrintToString(const T& value) { ::std::stringstream ss; diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index 42e19656..0860abf5 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -837,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); } -#if GTEST_HAS_STRING_PIECE_ +#if GTEST_HAS_ABSL -// Tests printing StringPiece. +// Tests printing ::absl::string_view. -TEST(PrintStringPieceTest, SimpleStringPiece) { - const StringPiece sp = "Hello"; +TEST(PrintStringViewTest, SimpleStringView) { + const ::absl::string_view sp = "Hello"; EXPECT_EQ("\"Hello\"", Print(sp)); } -TEST(PrintStringPieceTest, UnprintableCharacters) { +TEST(PrintStringViewTest, UnprintableCharacters) { const char str[] = "NUL (\0) and \r\t"; - const StringPiece sp(str, sizeof(str) - 1); + const ::absl::string_view sp(str, sizeof(str) - 1); EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); } -#endif // GTEST_HAS_STRING_PIECE_ +#endif // GTEST_HAS_ABSL // Tests printing STL containers. From d9df92287e98ea5eb60a4b5eb61c535a37b16e0b Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Wed, 31 Jan 2018 12:05:18 -0500 Subject: [PATCH 13/59] Merges and also adding new bazel build mode --- BUILD.bazel | 1 + ci/build-linux-bazel.sh | 1 + googletest/include/gtest/gtest-printers.h | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/BUILD.bazel b/BUILD.bazel index 91dd3b74..6d828294 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -104,6 +104,7 @@ cc_library( deps = select ({ ":has_absl": [ "@com_google_absl//absl/types:optional", + "@com_google_absl//absl/strings" ], "//conditions:default": [], } diff --git a/ci/build-linux-bazel.sh b/ci/build-linux-bazel.sh index 2f63896a..3f1c7849 100755 --- a/ci/build-linux-bazel.sh +++ b/ci/build-linux-bazel.sh @@ -33,3 +33,4 @@ set -e bazel build --curses=no //...:all bazel test --curses=no //...:all +bazel test --curses=no //...:all --define absl=1 diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index fa7da7ee..4deaad05 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -113,6 +113,7 @@ #if GTEST_HAS_ABSL #include "absl/types/optional.h" +#include "absl/strings/string_view.h" #endif // GTEST_HAS_ABSL namespace testing { @@ -629,7 +630,7 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { #if GTEST_HAS_ABSL // Overload for absl::string_view. inline void PrintTo(absl::string_view sp, ::std::ostream* os) { - PrintTo(string(sp), os); + PrintTo(::std::string(sp), os); } #endif // GTEST_HAS_ABSL From 8170693de667b183bf8ebef2b1cb392f77f4883d Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 6 Feb 2018 11:06:11 -0500 Subject: [PATCH 14/59] Include MSVC14 on PRs as well --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 6c50fef8..8d9cc64f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,6 +15,7 @@ environment: - compiler: msvc-14-seh generator: "Visual Studio 14 2015" + enabled_on_pr: yes - compiler: msvc-14-seh generator: "Visual Studio 14 2015 Win64" From d20708cf0baf5c435069bfb63a3ce91db6c21992 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 3 Feb 2018 23:36:19 +0000 Subject: [PATCH 15/59] Add ability to throw from ASSERT while not losing benefits of EXPECT, and not killing the whole test, as with --gtest_throw_on_failure. 183822976 --- googletest/docs/AdvancedGuide.md | 30 ++++- googletest/include/gtest/gtest.h | 16 ++- googletest/src/gtest.cc | 7 +- googletest/test/BUILD.bazel | 7 ++ .../test/gtest_assert_by_exception_test.cc | 119 ++++++++++++++++++ 5 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 googletest/test/gtest_assert_by_exception_test.cc diff --git a/googletest/docs/AdvancedGuide.md b/googletest/docs/AdvancedGuide.md index e1df20d5..6605f448 100644 --- a/googletest/docs/AdvancedGuide.md +++ b/googletest/docs/AdvancedGuide.md @@ -872,13 +872,33 @@ TEST(FooTest, Bar) { } ``` -Since we don't use exceptions, it is technically impossible to -implement the intended behavior here. To alleviate this, Google Test -provides two solutions. You could use either the -`(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the -`HasFatalFailure()` function. They are described in the following two +To alleviate this, gUnit provides three different solutions. You could use +either exceptions, the `(ASSERT|EXPECT)_NO_FATAL_FAILURE` assertions or the +`HasFatalFailure()` function. They are described in the following two subsections. +#### Asserting on Subroutines with an exception + +The following code can turn ASSERT-failure into an exception: + +```c++ +class ThrowListener : public testing::EmptyTestEventListener { + void OnTestPartResult(const testing::TestPartResult& result) override { + if (result.type() == testing::TestPartResult::kFatalFailure) { + throw testing::AssertionException(result); + } + } +}; +int main(int argc, char** argv) { + ... + testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener); + return RUN_ALL_TESTS(); +} +``` + +This listener should be added after other listeners if you have any, otherwise +they won't see failed `OnTestPartResult`. + ### Asserting on Subroutines ### As shown above, if your test calls a subroutine that has an `ASSERT_*` diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 01994e6d..26e787d9 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -138,7 +138,7 @@ GTEST_DECLARE_int32_(stack_trace_depth); // When this flag is specified, a failed assertion will throw an // exception if exceptions are enabled, or exit the program with a -// non-zero code otherwise. +// non-zero code otherwise. For use with an external test framework. GTEST_DECLARE_bool_(throw_on_failure); // When this flag is set with a "host:port" string, on supported @@ -1004,6 +1004,18 @@ class Environment { virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; +#if GTEST_HAS_EXCEPTIONS + +// Exception which can be thrown from TestEventListener::OnTestPartResult. +class GTEST_API_ AssertionException + : public internal::GoogleTestFailureException { + public: + explicit AssertionException(const TestPartResult& result) + : GoogleTestFailureException(result) {} +}; + +#endif // GTEST_HAS_EXCEPTIONS + // The interface for tracing execution of tests. The methods are organized in // the order the corresponding events are fired. class TestEventListener { @@ -1032,6 +1044,8 @@ class TestEventListener { virtual void OnTestStart(const TestInfo& test_info) = 0; // Fired after a failed assertion or a SUCCEED() invocation. + // If you want to throw an exception from this function to skip to the next + // TEST, it must be AssertionException defined above, or inherited from it. virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; // Fired after the test ends. diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 2c25f838..54e25b2d 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -293,7 +293,7 @@ GTEST_DEFINE_bool_( internal::BoolFromGTestEnv("throw_on_failure", false), "When this flag is specified, a failed assertion will throw an exception " "if exceptions are enabled or exit the program with a non-zero code " - "otherwise."); + "otherwise. For use with an external test framework."); #if GTEST_USE_OWN_FLAGFILE_FLAG_ GTEST_DEFINE_string_( @@ -2435,6 +2435,8 @@ Result HandleExceptionsInMethodIfSupported( #if GTEST_HAS_EXCEPTIONS try { return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const AssertionException&) { // NOLINT + // This failure was reported already. } catch (const internal::GoogleTestFailureException&) { // NOLINT // This exception type can only be thrown by a failed Google // Test assertion with the intention of letting another testing @@ -5201,7 +5203,8 @@ static const char kColorEncodedHelpMessage[] = " @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" -" Turn assertion failures into C++ exceptions.\n" +" Turn assertion failures into C++ exceptions for use by an external\n" +" test framework.\n" " @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" " Do not report exceptions as test failures. Instead, allow them\n" " to crash the program or throw a pop-up (on Windows).\n" diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index 3c700b15..1b81133c 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -219,6 +219,13 @@ py_test( deps = [":gtest_test_utils"], ) +cc_test( + name = "gtest_assert_by_exception_test", + size = "small", + srcs = ["gtest_assert_by_exception_test.cc"], + deps = ["//:gtest"], +) + cc_binary( name = "gtest_throw_on_failure_test_", testonly = 1, diff --git a/googletest/test/gtest_assert_by_exception_test.cc b/googletest/test/gtest_assert_by_exception_test.cc new file mode 100644 index 00000000..2f0e34af --- /dev/null +++ b/googletest/test/gtest_assert_by_exception_test.cc @@ -0,0 +1,119 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Test's assert-by-exception mode with exceptions enabled. + +#include "gtest/gtest.h" + +#include +#include +#include +#include + +class ThrowListener : public testing::EmptyTestEventListener { + void OnTestPartResult(const testing::TestPartResult& result) override { + if (result.type() == testing::TestPartResult::kFatalFailure) { + throw testing::AssertionException(result); + } + } +}; + +// Prints the given failure message and exits the program with +// non-zero. We use this instead of a Google Test assertion to +// indicate a failure, as the latter is been tested and cannot be +// relied on. +void Fail(const char* msg) { + printf("FAILURE: %s\n", msg); + fflush(stdout); + exit(1); +} + +static void AssertFalse() { + ASSERT_EQ(2, 3) << "Expected failure"; +} + +// Tests that an assertion failure throws a subclass of +// std::runtime_error. +TEST(Test, Test) { + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 3); + } catch(...) { + Fail("A successful assertion wrongfully threw."); + } + + // A successful assertion shouldn't throw. + try { + EXPECT_EQ(3, 4); + } catch(...) { + Fail("A failed non-fatal assertion wrongfully threw."); + } + + // A failed assertion should throw. + try { + AssertFalse(); + } catch(const testing::AssertionException& e) { + if (strstr(e.what(), "Expected failure") != NULL) + throw; + + printf("%s", + "A failed assertion did throw an exception of the right type, " + "but the message is incorrect. Instead of containing \"Expected " + "failure\", it is:\n"); + Fail(e.what()); + } catch(...) { + Fail("A failed assertion threw the wrong type of exception."); + } + Fail("A failed assertion should've thrown but didn't."); +} + +int kTestForContinuingTest = 0; + +TEST(Test, Test2) { + // FIXME(sokolov): how to force Test2 to be after Test? + kTestForContinuingTest = 1; +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener); + + int result = RUN_ALL_TESTS(); + if (result == 0) { + printf("RUN_ALL_TESTS returned %d\n", result); + Fail("Expected failure instead."); + } + + if (kTestForContinuingTest == 0) { + Fail("Should have continued with other tests, but did not."); + } + return 0; +} From a2866dfdf595d8ee906fc301b698c8ff90af92d2 Mon Sep 17 00:00:00 2001 From: Troy Holsapple Date: Wed, 7 Feb 2018 22:06:00 -0800 Subject: [PATCH 16/59] Fixed typos --- googlemock/docs/CookBook.md | 6 +++--- googlemock/include/gmock/gmock-matchers.h | 4 ++-- googlemock/scripts/generator/cpp/ast.py | 6 +++--- googlemock/test/gmock-actions_test.cc | 2 +- googlemock/test/gmock-matchers_test.cc | 8 ++++---- googletest/docs/FAQ.md | 2 +- googletest/include/gtest/internal/gtest-filepath.h | 2 +- googletest/src/gtest-filepath.cc | 2 +- googletest/src/gtest-printers.cc | 4 ++-- googletest/src/gtest.cc | 2 +- googletest/test/gtest-printers_test.cc | 2 +- googletest/test/gtest_test_utils.py | 2 +- googletest/test/gtest_unittest.cc | 10 +++++----- googletest/xcode/Scripts/versiongenerate.py | 2 +- 14 files changed, 27 insertions(+), 27 deletions(-) diff --git a/googlemock/docs/CookBook.md b/googlemock/docs/CookBook.md index 3d07e68b..c2565f1e 100644 --- a/googlemock/docs/CookBook.md +++ b/googlemock/docs/CookBook.md @@ -1231,7 +1231,7 @@ that references the implementation object dies, the implementation object will be deleted. Therefore, if you have some complex matcher that you want to use again -and again, there is no need to build it everytime. Just assign it to a +and again, there is no need to build it every time. Just assign it to a matcher variable and use that variable repeatedly! For example, ``` @@ -1403,7 +1403,7 @@ edge from node A to node B wherever A must occur before B, we can get a DAG. We use the term "sequence" to mean a directed path in this DAG. Now, if we decompose the DAG into sequences, we just need to know which sequences each `EXPECT_CALL()` belongs to in order to be able to -reconstruct the orginal DAG. +reconstruct the original DAG. So, to specify the partial order on the expectations we need to do two things: first to define some `Sequence` objects, and then for each @@ -2182,7 +2182,7 @@ the implementation object dies, the implementation object will be deleted. If you have some complex action that you want to use again and again, -you may not have to build it from scratch everytime. If the action +you may not have to build it from scratch every time. If the action doesn't have an internal state (i.e. if it always does the same thing no matter how many times it has been called), you can assign it to an action variable and use that variable repeatedly. For example: diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 41bf6de3..94c23d38 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -1550,7 +1550,7 @@ class BothOfMatcherImpl : public MatcherInterface { // MatcherList provides mechanisms for storing a variable number of matchers in // a list structure (ListType) and creating a combining matcher from such a // list. -// The template is defined recursively using the following template paramters: +// The template is defined recursively using the following template parameters: // * kSize is the length of the MatcherList. // * Head is the type of the first matcher of the list. // * Tail denotes the types of the remaining matchers of the list. @@ -2379,7 +2379,7 @@ class ResultOfMatcher { private: // Functors often define operator() as non-const method even though - // they are actualy stateless. But we need to use them even when + // they are actually stateless. But we need to use them even when // 'this' is a const pointer. It's the user's responsibility not to // use stateful callables with ResultOf(), which does't guarantee // how many times the callable will be invoked. diff --git a/googlemock/scripts/generator/cpp/ast.py b/googlemock/scripts/generator/cpp/ast.py index 11cbe912..cce32724 100755 --- a/googlemock/scripts/generator/cpp/ast.py +++ b/googlemock/scripts/generator/cpp/ast.py @@ -338,7 +338,7 @@ class Class(_GenericDeclaration): # TODO(nnorwitz): handle namespaces, etc. if self.bases: for token_list in self.bases: - # TODO(nnorwitz): bases are tokens, do name comparision. + # TODO(nnorwitz): bases are tokens, do name comparison. for token in token_list: if token.name == node.name: return True @@ -381,7 +381,7 @@ class Function(_GenericDeclaration): def Requires(self, node): if self.parameters: - # TODO(nnorwitz): parameters are tokens, do name comparision. + # TODO(nnorwitz): parameters are tokens, do name comparison. for p in self.parameters: if p.name == node.name: return True @@ -858,7 +858,7 @@ class AstBuilder(object): last_token = self._GetNextToken() return tokens, last_token - # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. + # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary. def _IgnoreUpTo(self, token_type, token): unused_tokens = self._GetTokensUpTo(token_type, token) diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index f470de4c..f7218391 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -751,7 +751,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { } // Tests that DoDefault() returns the default value set by -// DefaultValue::Set() when it's not overriden by an ON_CALL(). +// DefaultValue::Set() when it's not overridden by an ON_CALL(). TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { DefaultValue::Set(1); MockClass mock; diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 5c764eb4..07e5fa63 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -915,7 +915,7 @@ TEST(TypedEqTest, CanDescribeSelf) { // Type::IsTypeOf(v) compiles iff the type of value v is T, where T // is a "bare" type (i.e. not in the form of const U or U&). If v's // type is not T, the compiler will generate a message about -// "undefined referece". +// "undefined reference". template struct Type { static bool IsTypeOf(const T& /* v */) { return true; } @@ -1424,7 +1424,7 @@ TEST(PairTest, MatchesCorrectly) { EXPECT_THAT(p, Pair(25, "foo")); EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); - // 'first' doesnt' match, but 'second' matches. + // 'first' does not match, but 'second' matches. EXPECT_THAT(p, Not(Pair(42, "foo"))); EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); @@ -4263,7 +4263,7 @@ TYPED_TEST(ContainerEqTest, DuplicateDifference) { #endif // GTEST_HAS_TYPED_TEST // Tests that mutliple missing values are reported. -// Using just vector here, so order is predicatble. +// Using just vector here, so order is predictable. TEST(ContainerEqExtraTest, MultipleValuesMissing) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {2, 1, 5}; @@ -4276,7 +4276,7 @@ TEST(ContainerEqExtraTest, MultipleValuesMissing) { } // Tests that added values are reported. -// Using just vector here, so order is predicatble. +// Using just vector here, so order is predictable. TEST(ContainerEqExtraTest, MultipleValuesAdded) { static const int vals[] = {1, 1, 2, 3, 5, 8}; static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46}; diff --git a/googletest/docs/FAQ.md b/googletest/docs/FAQ.md index 1a216a1a..bd9526de 100644 --- a/googletest/docs/FAQ.md +++ b/googletest/docs/FAQ.md @@ -460,7 +460,7 @@ following benefits: You may still want to use `SetUp()/TearDown()` in the following rare cases: * If the tear-down operation could throw an exception, you must use `TearDown()` as opposed to the destructor, as throwing in a destructor leads to undefined behavior and usually will kill your program right away. Note that many standard libraries (like STL) may throw when exceptions are enabled in the compiler. Therefore you should prefer `TearDown()` if you want to write portable tests that work with or without exceptions. * The assertion macros throw an exception when flag `--gtest_throw_on_failure` is specified. Therefore, you shouldn't use Google Test assertions in a destructor if you plan to run your tests with this flag. - * In a constructor or destructor, you cannot make a virtual function call on this object. (You can call a method declared as virtual, but it will be statically bound.) Therefore, if you need to call a method that will be overriden in a derived class, you have to use `SetUp()/TearDown()`. + * In a constructor or destructor, you cannot make a virtual function call on this object. (You can call a method declared as virtual, but it will be statically bound.) Therefore, if you need to call a method that will be overridden in a derived class, you have to use `SetUp()/TearDown()`. ## The compiler complains "no matching function to call" when I use ASSERT\_PREDn. How do I fix it? ## diff --git a/googletest/include/gtest/internal/gtest-filepath.h b/googletest/include/gtest/internal/gtest-filepath.h index 406597a4..bce50dc6 100644 --- a/googletest/include/gtest/internal/gtest-filepath.h +++ b/googletest/include/gtest/internal/gtest-filepath.h @@ -191,7 +191,7 @@ class GTEST_API_ FilePath { void Normalize(); - // Returns a pointer to the last occurence of a valid path separator in + // Returns a pointer to the last ioccurrence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; diff --git a/googletest/src/gtest-filepath.cc b/googletest/src/gtest-filepath.cc index a1fc0e37..6b76ea0f 100644 --- a/googletest/src/gtest-filepath.cc +++ b/googletest/src/gtest-filepath.cc @@ -128,7 +128,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const { return *this; } -// Returns a pointer to the last occurence of a valid path separator in +// Returns a pointer to the last occurrence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FilePath::FindLastPathSeparator() const { diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index 1bdf243d..fe70edcf 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -124,7 +124,7 @@ namespace internal { // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), -// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a hexadecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). enum CharFormat { kAsIs, @@ -231,7 +231,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) { return; *os << " (" << static_cast(c); - // For more convenience, we print c's code again in hexidecimal, + // For more convenience, we print c's code again in hexadecimal, // unless c was already printed in the form '\x##' or the code is in // [1, 9]. if (format == kHexEscape || (1 <= c && c <= 9)) { diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 2c25f838..ee555bc9 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -1718,7 +1718,7 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT // Utility functions for encoding Unicode text (wide strings) in // UTF-8. -// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8 // like this: // // Code-point length Encoding diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index 0860abf5..60a8d037 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -1327,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { } // Tests formatting a char pointer when it's compared with another pointer. -// In this case we want to print it as a raw pointer, as the comparision is by +// In this case we want to print it as a raw pointer, as the comparison is by // pointer. // char pointer vs pointer diff --git a/googletest/test/gtest_test_utils.py b/googletest/test/gtest_test_utils.py index 7c489336..cc4ba649 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 preferrable way of running programs + # The subprocess module is the preferable 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_unittest.cc b/googletest/test/gtest_unittest.cc index a45927d0..2ea3ca4a 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -538,7 +538,7 @@ TEST(CodePointToUtf8Test, CanEncode8To11Bits) { // 101 0111 0110 => 110-10101 10-110110 // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints - // in wide strings and wide chars. In order to accomodate them, we have to + // in wide strings and wide chars. In order to accommodate them, we have to // introduce such character constants as integers. EXPECT_EQ("\xD5\xB6", CodePointToUtf8(static_cast(0x576))); @@ -1779,7 +1779,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { } // Tests that Int32FromEnvOrDie() aborts with an error message -// if the variable cannot be represnted by an Int32. +// if the variable cannot be represented by an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); EXPECT_DEATH_IF_SUPPORTED( @@ -3658,7 +3658,7 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) { } #ifdef __BORLANDC__ -// Restores warnings after previous "#pragma option push" supressed them +// Restores warnings after previous "#pragma option push" suppressed them # pragma option pop #endif @@ -4384,7 +4384,7 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) { } #ifdef __BORLANDC__ -// Restores warnings after previous "#pragma option push" supressed them +// Restores warnings after previous "#pragma option push" suppressed them # pragma option pop #endif @@ -6642,7 +6642,7 @@ TEST(StreamingAssertionsTest, Truth2) { } #ifdef __BORLANDC__ -// Restores warnings after previous "#pragma option push" supressed them +// Restores warnings after previous "#pragma option push" suppressed them # pragma option pop #endif diff --git a/googletest/xcode/Scripts/versiongenerate.py b/googletest/xcode/Scripts/versiongenerate.py index 16791d25..bdd7541a 100755 --- a/googletest/xcode/Scripts/versiongenerate.py +++ b/googletest/xcode/Scripts/versiongenerate.py @@ -29,7 +29,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""A script to prepare version informtion for use the gtest Info.plist file. +"""A script to prepare version information for use the gtest Info.plist file. This script extracts the version information from the configure.ac file and uses it to generate a header file containing the same information. The From 1fb2e10cfe82f3b65712fc68e65381c580ef3f88 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 9 Feb 2018 10:41:09 -0500 Subject: [PATCH 17/59] merges --- googlemock/test/gmock_output_test.py | 13 +++++---- googlemock/test/gmock_test_utils.py | 6 ++--- .../include/gtest/internal/gtest-port.h | 27 ++++++++++--------- googletest/src/gtest-death-test.cc | 8 +++++- googletest/test/gtest_env_var_test.py | 2 +- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/googlemock/test/gmock_output_test.py b/googlemock/test/gmock_output_test.py index eced8a81..9d73d570 100755 --- a/googlemock/test/gmock_output_test.py +++ b/googlemock/test/gmock_output_test.py @@ -31,11 +31,11 @@ """Tests the text output of Google C++ Mocking Framework. -SYNOPSIS - gmock_output_test.py --build_dir=BUILD/DIR --gengolden - # where BUILD/DIR contains the built gmock_output_test_ file. - gmock_output_test.py --gengolden - gmock_output_test.py +To update the golden file: +gmock_output_test.py --build_dir=BUILD/DIR --gengolden +# where BUILD/DIR contains the built gmock_output_test_ file. +gmock_output_test.py --gengolden +gmock_output_test.py """ __author__ = 'wan@google.com (Zhanyong Wan)' @@ -176,5 +176,8 @@ if __name__ == '__main__': golden_file = open(GOLDEN_PATH, 'wb') golden_file.write(output) golden_file.close() + # Suppress the error "googletest was imported but a call to its main() + # was never detected." + os._exit(0) else: gmock_test_utils.Main() diff --git a/googlemock/test/gmock_test_utils.py b/googlemock/test/gmock_test_utils.py index 1983c53b..b5130001 100755 --- a/googlemock/test/gmock_test_utils.py +++ b/googlemock/test/gmock_test_utils.py @@ -34,7 +34,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)' import os import sys - # Determines path to gtest_test_utils and imports it. SCRIPT_DIR = os.path.dirname(__file__) or '.' @@ -44,9 +43,10 @@ if os.path.isdir(gtest_tests_util_dir): GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir else: GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../googletest/test') - sys.path.append(GTEST_TESTS_UTIL_DIR) -import gtest_test_utils # pylint: disable-msg=C6204 + +# pylint: disable=C6204 +import gtest_test_utils def GetSourceDir(): diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 01ad5dac..3775f069 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -73,11 +73,9 @@ // GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions // are enabled. // GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string -// is/isn't available (some systems define -// ::string, which is different to std::string). -// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string -// is/isn't available (some systems define -// ::wstring, which is different to std::wstring). +// is/isn't available +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::wstring +// is/isn't available // GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular // expressions are/aren't available. // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that @@ -178,7 +176,7 @@ // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; -// the above two are mutually exclusive. +// the above _RE(s) are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // Misc public macros @@ -272,10 +270,12 @@ # include #endif +// Brings in the definition of HAS_GLOBAL_STRING. This must be done +// BEFORE we test HAS_GLOBAL_STRING. +#include // NOLINT #include // NOLINT #include // NOLINT #include // NOLINT -#include // NOLINT #include #include // NOLINT @@ -806,9 +806,9 @@ using ::std::tuple_size; // Google Test does not support death tests for VC 7.1 and earlier as // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. -#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - (GTEST_OS_MAC && !GTEST_OS_IOS) || \ - (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD) # define GTEST_HAS_DEATH_TEST 1 @@ -824,9 +824,10 @@ using ::std::tuple_size; # define GTEST_HAS_TYPED_TEST_P 1 #endif -// Determines whether to support Combine(). -// The implementation doesn't work on Sun Studio since it doesn't -// understand templated conversion operators. +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. #if (GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_) && !defined(__SUNPRO_CC) # define GTEST_HAS_COMBINE 1 #endif diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index 2bbb1bc9..00e231b8 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -73,7 +73,7 @@ namespace testing { // Constants. // The default death test style. -static const char kDefaultDeathTestStyle[] = "fast"; +static const char kDefaultDeathTestStyle[] = "threadsafe"; GTEST_DEFINE_string_( death_test_style, @@ -555,7 +555,13 @@ bool DeathTestImpl::Passed(bool status_ok) { break; case DIED: if (status_ok) { +# if GTEST_USES_PCRE + // PCRE regexes support embedded NULs. + // GTEST_USES_PCRE is defined only in google3 mode + const bool matched = RE::PartialMatch(error_message, *regex()); +# else const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); +# endif // GTEST_USES_PCRE if (matched) { success = true; } else { diff --git a/googletest/test/gtest_env_var_test.py b/googletest/test/gtest_env_var_test.py index 7af00cee..2fe9cd5f 100755 --- a/googletest/test/gtest_env_var_test.py +++ b/googletest/test/gtest_env_var_test.py @@ -92,7 +92,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') TestFlag('throw_on_failure', '1', '0') - TestFlag('death_test_style', 'threadsafe', 'fast') + TestFlag('death_test_style', 'fast', 'threadsafe') TestFlag('catch_exceptions', '0', '1') if IS_LINUX: From 2848f99c65576c4ec64108c44ea2069fca89c277 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 9 Feb 2018 16:02:17 -0500 Subject: [PATCH 18/59] merges --- .../include/gtest/internal/gtest-port.h | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 3775f069..2b78186d 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -176,7 +176,7 @@ // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; -// the above _RE(s) are mutually exclusive. +// the above RE\b(s) are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // Misc public macros @@ -205,6 +205,7 @@ // // C++11 feature wrappers: // +// testing::internal::forward - portability wrapper for std::forward. // testing::internal::move - portability wrapper for std::move. // // Synchronization: @@ -611,8 +612,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. -#define GTEST_HAS_PTHREAD \ - (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \ +#define GTEST_HAS_PTHREAD \ + (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \ GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA) #endif // GTEST_HAS_PTHREAD @@ -1127,6 +1128,16 @@ struct StaticAssertTypeEqHelper { enum { value = true }; }; +// Same as std::is_same<>. +template +struct IsSame { + enum { value = false }; +}; +template +struct IsSame { + enum { value = true }; +}; + // Evaluates to the number of elements in 'array'. #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) @@ -1190,6 +1201,10 @@ class scoped_ptr { // Defines RE. +#if GTEST_USES_PCRE +using ::RE; +#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE + // A simple C++ wrapper for . It uses the POSIX Extended // Regular Expression syntax. class GTEST_API_ RE { @@ -1201,11 +1216,11 @@ class GTEST_API_ RE { // Constructs an RE from a string. RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT -#if GTEST_HAS_GLOBAL_STRING +# if GTEST_HAS_GLOBAL_STRING RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING +# endif // GTEST_HAS_GLOBAL_STRING RE(const char* regex) { Init(regex); } // NOLINT ~RE(); @@ -1227,7 +1242,7 @@ class GTEST_API_ RE { return PartialMatch(str.c_str(), re); } -#if GTEST_HAS_GLOBAL_STRING +# if GTEST_HAS_GLOBAL_STRING static bool FullMatch(const ::string& str, const RE& re) { return FullMatch(str.c_str(), re); @@ -1236,7 +1251,7 @@ class GTEST_API_ RE { return PartialMatch(str.c_str(), re); } -#endif // GTEST_HAS_GLOBAL_STRING +# endif // GTEST_HAS_GLOBAL_STRING static bool FullMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re); @@ -1250,20 +1265,22 @@ class GTEST_API_ RE { const char* pattern_; bool is_valid_; -#if GTEST_USES_POSIX_RE +# if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). -#else // GTEST_USES_SIMPLE_RE +# else // GTEST_USES_SIMPLE_RE const char* full_pattern_; // For FullMatch(); -#endif +# endif GTEST_DISALLOW_ASSIGN_(RE); }; +#endif // GTEST_USES_PCRE + // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); @@ -1350,12 +1367,25 @@ inline void FlushInfoLog() { fflush(NULL); } << gtest_error #if GTEST_HAS_STD_MOVE_ +using std::forward; using std::move; + +template +struct RvalueRef { + typedef T&& type; +}; #else // GTEST_HAS_STD_MOVE_ template const T& move(const T& t) { return t; } +template +GTEST_ADD_REFERENCE_(T) forward(GTEST_ADD_REFERENCE_(T) t) { return t; } + +template +struct RvalueRef { + typedef const T& type; +}; #endif // GTEST_HAS_STD_MOVE_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -1456,7 +1486,6 @@ GTEST_API_ void CaptureStderr(); GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION - // Returns the size (in bytes) of a file. GTEST_API_ size_t GetFileSize(FILE* file); From 2c7e37af6fa979a5e7380a69b3c6082df0b3c538 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 9 Feb 2018 17:45:10 -0500 Subject: [PATCH 19/59] merging --- googletest/include/gtest/internal/gtest-port.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 2b78186d..c5416935 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -1379,8 +1379,6 @@ template const T& move(const T& t) { return t; } -template -GTEST_ADD_REFERENCE_(T) forward(GTEST_ADD_REFERENCE_(T) t) { return t; } template struct RvalueRef { From a8a2f4ab0563e3fb05d655d424c0699c82c43522 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 12 Feb 2018 14:07:45 -0500 Subject: [PATCH 20/59] Merging, coniniue --- googletest/src/gtest-death-test.cc | 10 ++++------ googletest/test/gtest-death-test_test.cc | 6 +++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index 00e231b8..92a29806 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -983,7 +983,6 @@ static int ExecDeathTestChildMain(void* child_arg) { } # endif // !GTEST_OS_QNX -# if GTEST_HAS_CLONE // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive @@ -1008,7 +1007,6 @@ static bool StackGrowsDown() { StackLowerThanAddress(&dummy, &result); return result; } -# endif // GTEST_HAS_CLONE // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The @@ -1225,11 +1223,11 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. static int GetStatusFileDescriptor(unsigned int parent_process_id, - size_t write_handle_as_size_t, - size_t event_handle_as_size_t) { + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, - FALSE, // Non-inheritable. - parent_process_id)); + FALSE, // Non-inheritable. + parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); diff --git a/googletest/test/gtest-death-test_test.cc b/googletest/test/gtest-death-test_test.cc index b7846b2c..21573c77 100644 --- a/googletest/test/gtest-death-test_test.cc +++ b/googletest/test/gtest-death-test_test.cc @@ -617,7 +617,11 @@ TEST_F(TestForDeathTest, ReturnIsFailure) { TEST_F(TestForDeathTest, TestExpectDebugDeath) { int sideeffect = 0; - EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") + // Put the regex in a local variable to make sure we don't get an "unused" + // warning in opt mode. + const char* regex = "death.*DieInDebugElse12"; + + EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), regex) << "Must accept a streamed message"; # ifdef NDEBUG From 04f97d9c86060c40910d3dc430b816d526ead31d Mon Sep 17 00:00:00 2001 From: Victor Costan Date: Fri, 9 Feb 2018 22:42:32 -0800 Subject: [PATCH 21/59] Fix std::iscntrl use in gtest-printers.cc ContainsUnprintableControlCodes() in gtest-printers.cc passes a char argument to std::iscntrl. Although its argument is an int, std::iscntrl produces undefined behavior if its argument is not representable as an unsigned char. The standard library on Windows asserts that the argument is an unsigned char, resulting in an assertion crash on debug builds. --- googletest/src/gtest-printers.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index fe70edcf..d55a5e9b 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -357,8 +357,10 @@ void PrintTo(const wchar_t* s, ostream* os) { namespace { bool ContainsUnprintableControlCodes(const char* str, size_t length) { + const unsigned char *s = reinterpret_cast(str); + for (size_t i = 0; i < length; i++) { - char ch = *str++; + unsigned char ch = *s++; if (std::iscntrl(ch)) { switch (ch) { case '\t': From d40efb1166e79b216ad98716f7e282f0f8984066 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 12 Feb 2018 16:42:12 -0500 Subject: [PATCH 22/59] moving JoinAsTuple to internal --- googlemock/include/gmock/gmock-matchers.h | 4 ---- googlemock/src/gmock-internal-utils.cc | 19 +++++++++++++++ googlemock/src/gmock-matchers.cc | 19 --------------- googlemock/test/gmock-matchers_test.cc | 29 +++-------------------- 4 files changed, 22 insertions(+), 49 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 94c23d38..fc3fe3aa 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -3614,10 +3614,6 @@ BoundSecondMatcher MatcherBindSecond( return BoundSecondMatcher(tm, second); } -// Joins a vector of strings as if they are fields of a tuple; returns -// the joined string. This function is exported for testing. -GTEST_API_ string JoinAsTuple(const Strings& fields); - // Returns the description for a matcher defined using the MATCHER*() // macro where the user-supplied description string is "", if // 'negation' is false; otherwise returns the description of the diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 91bf3fd9..658fa62d 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -47,6 +47,25 @@ namespace testing { namespace internal { +// Joins a vector of strings as if they are fields of a tuple; returns +// the joined string. +GTEST_API_ std::string JoinAsTuple(const Strings& fields) { + switch (fields.size()) { + case 0: + return ""; + case 1: + return fields[0]; + default: + std::string result = "(" + fields[0]; + for (size_t i = 1; i < fields.size(); i++) { + result += ", "; + result += fields[i]; + } + result += ")"; + return result; + } +} + // Converts an identifier name to a space-separated list of lower-case // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // treated as one word. For example, both "FooBar123" and diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc index 6e40e5e8..f37d5c2d 100644 --- a/googlemock/src/gmock-matchers.cc +++ b/googlemock/src/gmock-matchers.cc @@ -100,25 +100,6 @@ Matcher::Matcher(StringPiece s) { namespace internal { -// Joins a vector of strings as if they are fields of a tuple; returns -// the joined string. -GTEST_API_ string JoinAsTuple(const Strings& fields) { - switch (fields.size()) { - case 0: - return ""; - case 1: - return fields[0]; - default: - string result = "(" + fields[0]; - for (size_t i = 1; i < fields.size(); i++) { - result += ", "; - result += fields[i]; - } - result += ")"; - return result; - } -} - // Returns the description for a matcher defined using the MATCHER*() // macro where the user-supplied description string is "", if // 'negation' is false; otherwise returns the description of the diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 07e5fa63..761c0c22 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -146,7 +146,6 @@ using testing::internal::ExplainMatchFailureTupleTo; using testing::internal::FloatingEqMatcher; using testing::internal::FormatMatcherDescription; using testing::internal::IsReadableTypeName; -using testing::internal::JoinAsTuple; using testing::internal::linked_ptr; using testing::internal::MatchMatrix; using testing::internal::RE; @@ -872,9 +871,9 @@ class Unprintable { char c_; }; -inline bool operator==(const Unprintable& /* lhs */, - const Unprintable& /* rhs */) { - return true; +inline bool operator==(const Unprintable& /* lhs */, + const Unprintable& /* rhs */) { + return true; } TEST(EqTest, CanDescribeSelf) { @@ -5268,28 +5267,6 @@ TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) { EXPECT_FALSE(IsReadableTypeName("void (&)(int, bool, char, float)")); } -// Tests JoinAsTuple(). - -TEST(JoinAsTupleTest, JoinsEmptyTuple) { - EXPECT_EQ("", JoinAsTuple(Strings())); -} - -TEST(JoinAsTupleTest, JoinsOneTuple) { - const char* fields[] = {"1"}; - EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); -} - -TEST(JoinAsTupleTest, JoinsTwoTuple) { - const char* fields[] = {"1", "a"}; - EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); -} - -TEST(JoinAsTupleTest, JoinsTenTuple) { - const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; - EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", - JoinAsTuple(Strings(fields, fields + 10))); -} - // Tests FormatMatcherDescription(). TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) { From ee0e251fe3364f8e7daa398acb5a327e0d689a1f Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 09:45:12 -0500 Subject: [PATCH 23/59] merges --- googletest/test/gtest-param-test_test.cc | 49 ++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index b0aa4f9b..60bdfea0 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -41,8 +41,8 @@ # include # include # include -# include "src/gtest-internal-inl.h" // for UnitTestOptions +# include "src/gtest-internal-inl.h" // for UnitTestOptions # include "test/gtest-param-test_test.h" using ::std::vector; @@ -536,6 +536,48 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) { VerifyGenerator(gen, expected_values); } +class NonDefaultConstructAssignString { + public: + NonDefaultConstructAssignString(const std::string& str) : str_(str) {} + + const std::string& str() const { return str_; } + + private: + std::string str_; + + // Not default constructible + NonDefaultConstructAssignString(); + // Not assignable + void operator=(const NonDefaultConstructAssignString&); +}; + +TEST(CombineTest, NonDefaultConstructAssign) { + const ParamGenerator> gen = + Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"), + NonDefaultConstructAssignString("B"))); + + ParamGenerator>::iterator it = + gen.begin(); + + EXPECT_EQ(0, std::get<0>(*it)); + EXPECT_EQ("A", std::get<1>(*it).str()); + ++it; + + EXPECT_EQ(0, std::get<0>(*it)); + EXPECT_EQ("B", std::get<1>(*it).str()); + ++it; + + EXPECT_EQ(1, std::get<0>(*it)); + EXPECT_EQ("A", std::get<1>(*it).str()); + ++it; + + EXPECT_EQ(1, std::get<0>(*it)); + EXPECT_EQ("B", std::get<1>(*it).str()); + ++it; + + EXPECT_TRUE(it == gen.end()); +} + # endif // GTEST_HAS_COMBINE // Tests that an generator produces correct sequence after being @@ -851,8 +893,8 @@ TEST_P(CustomLambdaNamingTest, CustomTestNames) {} INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest, Values(std::string("LambdaName")), - [](const ::testing::TestParamInfo& tpinfo) { - return tpinfo.param; + [](const ::testing::TestParamInfo& info) { + return info.param; }); #endif // GTEST_LANG_CXX11 @@ -1019,6 +1061,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); + int main(int argc, char **argv) { // Used in TestGenerationTest test case. AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); From 7164a54bd46c29fc667b1791def860e171d8b145 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 10:05:43 -0500 Subject: [PATCH 24/59] clang warning https://travis-ci.org/google/googletest/jobs/340978022 --- googletest/test/gtest-param-test_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index 60bdfea0..11ad853c 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -538,7 +538,7 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) { class NonDefaultConstructAssignString { public: - NonDefaultConstructAssignString(const std::string& str) : str_(str) {} + NonDefaultConstructAssignString(const std::string& s) : str_(s) {} const std::string& str() const { return str_; } From 95cd910e81555364ca2faa9e753a72f366f0b3ca Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 10:23:42 -0500 Subject: [PATCH 25/59] clang warning 'https://travis-ci.org/google/googletest/jobs/340987201' --- googletest/test/gtest-param-test_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index 11ad853c..6e62dfa2 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -853,8 +853,8 @@ class CustomFunctorNamingTest : public TestWithParam {}; TEST_P(CustomFunctorNamingTest, CustomTestNames) {} struct CustomParamNameFunctor { - std::string operator()(const ::testing::TestParamInfo& info) { - return info.param; + std::string operator()(const ::testing::TestParamInfo& inf) { + return inf.param; } }; @@ -893,8 +893,8 @@ TEST_P(CustomLambdaNamingTest, CustomTestNames) {} INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest, Values(std::string("LambdaName")), - [](const ::testing::TestParamInfo& info) { - return info.param; + [](const ::testing::TestParamInfo& inf) { + return inf.param; }); #endif // GTEST_LANG_CXX11 From f9ab8f86bba54c8926a7a2a98e5b46b57e9a6bd7 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 11:05:01 -0500 Subject: [PATCH 26/59] https://travis-ci.org/google/googletest/jobs/340995238 --- googletest/test/gtest-param-test_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index 6e62dfa2..9d970d2e 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -556,7 +556,7 @@ TEST(CombineTest, NonDefaultConstructAssign) { Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"), NonDefaultConstructAssignString("B"))); - ParamGenerator>::iterator it = + ParamGenerator >::iterator it = gen.begin(); EXPECT_EQ(0, std::get<0>(*it)); @@ -871,8 +871,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters, CustomParamNameFunctor()); inline std::string CustomParamNameFunction( - const ::testing::TestParamInfo& info) { - return info.param; + const ::testing::TestParamInfo& inf) { + return inf.param; } class CustomFunctionNamingTest : public TestWithParam {}; @@ -893,8 +893,8 @@ TEST_P(CustomLambdaNamingTest, CustomTestNames) {} INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest, Values(std::string("LambdaName")), - [](const ::testing::TestParamInfo& inf) { - return inf.param; + [](const ::testing::TestParamInfo& info) { + return info.param; }); #endif // GTEST_LANG_CXX11 From 95ecbcbb86a8fb2d853ce449df378fae98ee255f Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 11:15:03 -0500 Subject: [PATCH 27/59] clang warnings --- googletest/test/gtest-param-test_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index 9d970d2e..5f6d946b 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -893,8 +893,8 @@ TEST_P(CustomLambdaNamingTest, CustomTestNames) {} INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest, Values(std::string("LambdaName")), - [](const ::testing::TestParamInfo& info) { - return info.param; + [](const ::testing::TestParamInfo& inf) { + return inf.param; }); #endif // GTEST_LANG_CXX11 From 70e74eb482b102f786b718bc2ca23ac9c3ad3a21 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 11:24:09 -0500 Subject: [PATCH 28/59] clang warnings --- googletest/test/gtest-param-test_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index 5f6d946b..0236e878 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -552,7 +552,7 @@ class NonDefaultConstructAssignString { }; TEST(CombineTest, NonDefaultConstructAssign) { - const ParamGenerator> gen = + const ParamGenerator > gen = Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"), NonDefaultConstructAssignString("B"))); From ccc4035c99ec8569c3f8516fa19ef053b11488dd Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 11:48:32 -0500 Subject: [PATCH 29/59] cxxx11 --- googletest/test/gtest-param-test_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index 0236e878..fb2e44b0 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -536,6 +536,8 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) { VerifyGenerator(gen, expected_values); } +#if GTEST_LANG_CXX11 + class NonDefaultConstructAssignString { public: NonDefaultConstructAssignString(const std::string& s) : str_(s) {} @@ -578,6 +580,7 @@ TEST(CombineTest, NonDefaultConstructAssign) { EXPECT_TRUE(it == gen.end()); } +#endif // GTEST_LANG_CXX11 # endif // GTEST_HAS_COMBINE // Tests that an generator produces correct sequence after being From 516a39cda744bb3418a64c1f778ecfe77590f966 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 13:49:57 -0500 Subject: [PATCH 30/59] merges --- googletest/test/gtest-param-test_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/googletest/test/gtest-param-test_test.cc b/googletest/test/gtest-param-test_test.cc index fb2e44b0..b21cb31f 100644 --- a/googletest/test/gtest-param-test_test.cc +++ b/googletest/test/gtest-param-test_test.cc @@ -893,8 +893,7 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction, class CustomLambdaNamingTest : public TestWithParam {}; TEST_P(CustomLambdaNamingTest, CustomTestNames) {} -INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, - CustomLambdaNamingTest, +INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest, Values(std::string("LambdaName")), [](const ::testing::TestParamInfo& inf) { return inf.param; From 729d6dc865490ee30c47dd3a864211195ac19528 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 14:13:52 -0500 Subject: [PATCH 31/59] merging, cleaning up --- googletest/test/gtest_all_test.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/googletest/test/gtest_all_test.cc b/googletest/test/gtest_all_test.cc index 955aa628..e16ef539 100644 --- a/googletest/test/gtest_all_test.cc +++ b/googletest/test/gtest_all_test.cc @@ -33,15 +33,15 @@ // // Sometimes it's desirable to build most of Google Test's own tests // by compiling a single file. This file serves this purpose. -#include "test/gtest-filepath_test.cc" -#include "test/gtest-linked_ptr_test.cc" -#include "test/gtest-message_test.cc" -#include "test/gtest-options_test.cc" -#include "test/gtest-port_test.cc" -#include "test/gtest_pred_impl_unittest.cc" -#include "test/gtest_prod_test.cc" -#include "test/gtest-test-part_test.cc" -#include "test/gtest-typed-test_test.cc" -#include "test/gtest-typed-test2_test.cc" -#include "test/gtest_unittest.cc" -#include "test/production.cc" +#include "gtest-filepath_test.cc" +#include "gtest-linked_ptr_test.cc" +#include "gtest-message_test.cc" +#include "gtest-options_test.cc" +#include "gtest-port_test.cc" +#include "gtest_pred_impl_unittest.cc" +#include "gtest_prod_test.cc" +#include "gtest-test-part_test.cc" +#include "gtest-typed-test_test.cc" +#include "gtest-typed-test2_test.cc" +#include "gtest_unittest.cc" +#include "production.cc" From 551f80ffcb0269b2d2091a4036a3b539691492ec Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 14:56:05 -0500 Subject: [PATCH 32/59] cleanup/merges --- googletest/include/gtest/gtest-printers.h | 2 +- googletest/include/gtest/gtest_prod.h | 11 +++++--- googletest/src/gtest-internal-inl.h | 4 +-- googletest/src/gtest-port.cc | 8 ++++-- googletest/src/gtest-typed-test.cc | 1 + googletest/src/gtest.cc | 28 +++++++++----------- googletest/test/gtest_env_var_test_.cc | 1 + googletest/test/gtest_main_unittest.cc | 4 +-- googletest/test/gtest_uninitialized_test_.cc | 2 +- 9 files changed, 33 insertions(+), 28 deletions(-) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 4deaad05..2c83c3ff 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -112,8 +112,8 @@ #endif #if GTEST_HAS_ABSL -#include "absl/types/optional.h" #include "absl/strings/string_view.h" +#include "absl/types/optional.h" #endif // GTEST_HAS_ABSL namespace testing { diff --git a/googletest/include/gtest/gtest_prod.h b/googletest/include/gtest/gtest_prod.h index da80ddc6..d9ea685f 100644 --- a/googletest/include/gtest/gtest_prod.h +++ b/googletest/include/gtest/gtest_prod.h @@ -40,17 +40,20 @@ // // class MyClass { // private: -// void MyMethod(); -// FRIEND_TEST(MyClassTest, MyMethod); +// void PrivateMethod(); +// FRIEND_TEST(MyClassTest, PrivateMethodWorks); // }; // // class MyClassTest : public testing::Test { // // ... // }; // -// TEST_F(MyClassTest, MyMethod) { -// // Can call MyClass::MyMethod() here. +// TEST_F(MyClassTest, PrivateMethodWorks) { +// // Can call MyClass::PrivateMethod() here. // } +// +// Note: The test class must be in the same namespace as the class being tested. +// For example, putting MyClassTest in an anonymous namespace will not work. #define FRIEND_TEST(test_case_name, test_name)\ friend class test_case_name##_##test_name##_Test diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index 099761ad..e77c8b6c 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -59,7 +59,7 @@ # include // NOLINT #endif // GTEST_OS_WINDOWS -#include "gtest/gtest.h" // NOLINT +#include "gtest/gtest.h" #include "gtest/gtest-spi.h" namespace testing { @@ -1024,7 +1024,7 @@ class TestResultAccessor { #if GTEST_CAN_STREAM_RESULTS_ // Streams test results to the given port on the given host machine. -class GTEST_API_ StreamingListener : public EmptyTestEventListener { +class StreamingListener : public EmptyTestEventListener { public: // Abstract base class for writing strings to a socket. class AbstractSocketWriter { diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index 01711fda..af0d120a 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -915,6 +915,7 @@ GTestLog::~GTestLog() { posix::Abort(); } } + // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) @@ -1007,8 +1008,7 @@ static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). -static void CaptureStream(int fd, - const char* stream_name, +static void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { if (*stream != NULL) { GTEST_LOG_(FATAL) << "Only one " << stream_name @@ -1049,6 +1049,10 @@ std::string GetCapturedStderr() { #endif // GTEST_HAS_STREAM_REDIRECTION + + + + size_t GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(ftell(file)); diff --git a/googletest/src/gtest-typed-test.cc b/googletest/src/gtest-typed-test.cc index df1eef47..b3582434 100644 --- a/googletest/src/gtest-typed-test.cc +++ b/googletest/src/gtest-typed-test.cc @@ -30,6 +30,7 @@ // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest-typed-test.h" + #include "gtest/gtest.h" namespace testing { diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index ada5849a..7afa5a95 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -2571,12 +2571,10 @@ void ReportInvalidTestCaseType(const char* test_case_name, << "probably rename one of the classes to put the tests into different\n" << "test cases."; - GTEST_LOG_(ERROR) - << FormatFileLocation(code_location.file.c_str(), - code_location.line) - << " " << errors.GetString(); + GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(), + code_location.line) + << " " << errors.GetString(); } - } // namespace internal namespace { @@ -2898,7 +2896,7 @@ static int GetBitOffset(WORD color_mask) { if (color_mask == 0) return 0; int bitOffset = 0; - while((color_mask & 1) == 0) { + while ((color_mask & 1) == 0) { color_mask >>= 1; ++bitOffset; } @@ -3106,7 +3104,6 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } - ColoredPrintf(COLOR_GREEN, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), @@ -3473,8 +3470,8 @@ void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, // 3. To interpret the meaning of errno in a thread-safe way, // we need the strerror_r() function, which is not available on // Windows. - GTEST_LOG_(FATAL) << "Unable to open file \"" - << output_file_ << "\""; + + GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file_ << "\""; } std::stringstream stream; PrintXmlUnitTest(&stream, unit_test); @@ -3773,6 +3770,7 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( // End XmlUnitTestResultPrinter + #if GTEST_CAN_STREAM_RESULTS_ // Checks if str contains '=', '&', '%' or '\n' characters. If yes, @@ -4401,8 +4399,7 @@ void UnitTestImpl::ConfigureXmlOutput() { UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" - << output_format - << "\" ignored."; + << output_format << "\" ignored."; } } @@ -4417,8 +4414,7 @@ void UnitTestImpl::ConfigureStreamingOutput() { listeners()->Append(new StreamingListener(target.substr(0, pos), target.substr(pos+1))); } else { - GTEST_LOG_(WARNING) << "unrecognized streaming target \"" - << target + GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target << "\" ignored."; } } @@ -5255,8 +5251,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { static void LoadFlagsFromFile(const std::string& path) { FILE* flagfile = posix::FOpen(path.c_str(), "r"); if (!flagfile) { - GTEST_LOG_(FATAL) << "Unable to open file \"" - << GTEST_FLAG(flagfile) + GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile) << "\""; } std::string contents(ReadEntireFile(flagfile)); @@ -5387,8 +5382,9 @@ void InitGoogleTest(int* argc, wchar_t** argv) { std::string TempDir() { #if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) - return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); + return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); #endif + #if GTEST_OS_WINDOWS_MOBILE return "\\temp\\"; #elif GTEST_OS_WINDOWS diff --git a/googletest/test/gtest_env_var_test_.cc b/googletest/test/gtest_env_var_test_.cc index ed623722..9b668dc0 100644 --- a/googletest/test/gtest_env_var_test_.cc +++ b/googletest/test/gtest_env_var_test_.cc @@ -35,6 +35,7 @@ #include "gtest/gtest.h" #include + #include "src/gtest-internal-inl.h" using ::std::cout; diff --git a/googletest/test/gtest_main_unittest.cc b/googletest/test/gtest_main_unittest.cc index ecd9bb87..c979fce6 100644 --- a/googletest/test/gtest_main_unittest.cc +++ b/googletest/test/gtest_main_unittest.cc @@ -41,5 +41,5 @@ TEST(GTestMainTest, ShouldSucceed) { } // namespace -// We are using the main() function defined in src/gtest_main.cc, so -// we don't define it here. +// We are using the main() function defined in gtest_main.cc, so we +// don't define it here. diff --git a/googletest/test/gtest_uninitialized_test_.cc b/googletest/test/gtest_uninitialized_test_.cc index 502b0add..2ba0e8b8 100644 --- a/googletest/test/gtest_uninitialized_test_.cc +++ b/googletest/test/gtest_uninitialized_test_.cc @@ -34,7 +34,7 @@ TEST(DummyTest, Dummy) { // This test doesn't verify anything. We just need it to create a // realistic stage for testing the behavior of Google Test when - // RUN_ALL_TESTS() is called without + // RUN_ALL_TESTS() is called without // testing::InitGoogleTest() being called first. } From 47607b5a5e8227bc34648195e2aff26caa475757 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 13 Feb 2018 15:25:57 -0500 Subject: [PATCH 33/59] cleanup, merges --- .../include/gtest/internal/gtest-filepath.h | 2 +- .../include/gtest/internal/gtest-internal.h | 25 -------------- .../include/gtest/internal/gtest-port.h | 33 +++++++++++++++++++ 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-filepath.h b/googletest/include/gtest/internal/gtest-filepath.h index bce50dc6..406597a4 100644 --- a/googletest/include/gtest/internal/gtest-filepath.h +++ b/googletest/include/gtest/internal/gtest-filepath.h @@ -191,7 +191,7 @@ class GTEST_API_ FilePath { void Normalize(); - // Returns a pointer to the last ioccurrence of a valid path separator in + // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 843058f3..a8a9a8c1 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -803,31 +803,6 @@ struct RemoveConst { #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) -// Adds reference to a type if it is not a reference type, -// otherwise leaves it unchanged. This is the same as -// tr1::add_reference, which is not widely available yet. -template -struct AddReference { typedef T& type; }; // NOLINT -template -struct AddReference { typedef T& type; }; // NOLINT - -// A handy wrapper around AddReference that works when the argument T -// depends on template parameters. -#define GTEST_ADD_REFERENCE_(T) \ - typename ::testing::internal::AddReference::type - -// Adds a reference to const on top of T as necessary. For example, -// it transforms -// -// char ==> const char& -// const char ==> const char& -// char& ==> const char& -// const char& ==> const char& -// -// The argument T must depend on some template parameters. -#define GTEST_REFERENCE_TO_CONST_(T) \ - GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) - // ImplicitlyConvertible::value is a compile-time bool // constant that's true iff type From can be implicitly converted to // type To. diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index c5416935..81f047bf 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -1366,6 +1366,39 @@ inline void FlushInfoLog() { fflush(NULL); } GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template +struct AddReference { typedef T& type; }; // NOLINT +template +struct AddReference { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference::type + +// Transforms "T" into "const T&" according to standard reference collapsing +// rules (this is only needed as a backport for C++98 compilers that do not +// support reference collapsing). Specifically, it transforms: +// +// char ==> const char& +// const char ==> const char& +// char& ==> char& +// const char& ==> const char& +// +// Note that the non-const reference will not have "const" added. This is +// standard, and necessary so that "T" can always bind to "const T&". +template +struct ConstRef { typedef const T& type; }; +template +struct ConstRef { typedef T& type; }; + +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + typename ::testing::internal::ConstRef::type + #if GTEST_HAS_STD_MOVE_ using std::forward; using std::move; From d22c9736047ce9a435a3381204549e9647f9289f Mon Sep 17 00:00:00 2001 From: Victor Costan Date: Mon, 19 Feb 2018 01:56:53 -0800 Subject: [PATCH 34/59] Fix unused function warning on Mac OS. As of recently, Google Test fails to compile with the warning below when used in projects with strict warning settings. googletest/src/gtest-death-test.cc:1004:13: error: unused function 'StackGrowsDown' [-Werror,-Wunused-function] --- googletest/src/gtest-death-test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index 92a29806..852912b5 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -983,6 +983,7 @@ static int ExecDeathTestChildMain(void* child_arg) { } # endif // !GTEST_OS_QNX +# if GTEST_HAS_CLONE // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive @@ -1007,6 +1008,7 @@ static bool StackGrowsDown() { StackLowerThanAddress(&dummy, &result); return result; } +# endif // GTEST_HAS_CLONE // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The From 964e433c37f63994cad1d1d0552f761d4e89cf11 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Thu, 22 Feb 2018 15:53:14 -0500 Subject: [PATCH 35/59] merges --- googletest/test/BUILD.bazel | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index 1b81133c..6ea18ec6 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -119,6 +119,16 @@ cc_test( "//:gtest", ], ) + +cc_test( + name = "gtest_unittest", + size = "small", + srcs = ["gtest_unittest.cc"], + args = ["--heap_check=strict"], + shard_count = 2, + deps = ["//:gtest_main"], +) + # Py tests py_library( From 3357dad60daa3ce83d7523ba39887e7675ef0edc Mon Sep 17 00:00:00 2001 From: Aleksey Kozin Date: Fri, 23 Feb 2018 01:34:26 +0300 Subject: [PATCH 36/59] TEST() arguments are invalid in an example Both names must be valid C++ identifiers, and they should not contain underscore (`_`) --- googletest/docs/Primer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/docs/Primer.md b/googletest/docs/Primer.md index 384d4d6e..5e8ee0c6 100644 --- a/googletest/docs/Primer.md +++ b/googletest/docs/Primer.md @@ -239,7 +239,7 @@ To create a test: 1. The test's result is determined by the assertions; if any assertion in the test fails (either fatally or non-fatally), or if the test crashes, the entire test fails. Otherwise, it succeeds. ``` -TEST(test_case_name, test_name) { +TEST(testCaseName, testName) { ... test body ... } ``` From 8d0e9cade8045661a52e3ed9dfc7087a745904fb Mon Sep 17 00:00:00 2001 From: "Anders Sundman (asum)" Date: Fri, 23 Feb 2018 14:55:24 +0100 Subject: [PATCH 37/59] Removed trailing comma in enum --- googletest/include/gtest/internal/gtest-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index a8a9a8c1..db5a4eff 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -1050,7 +1050,7 @@ class NativeArray { private: enum { kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper< - Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value, + Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value }; // Initializes this object with a copy of the input. From 227b3455660eeb905939ce209bce27daa39c2198 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 23 Feb 2018 10:47:11 -0500 Subject: [PATCH 38/59] merging unitests --- googletest/test/gtest_unittest.cc | 125 +++++++++++++++--------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 2ea3ca4a..a5743fc5 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -5454,7 +5454,8 @@ TEST_F(SetUpTestCaseTest, Test2) { EXPECT_STREQ("123", shared_resource_); } -// The InitGoogleTestTest test case tests testing::InitGoogleTest(). + +// The ParseFlagsTest test case tests ParseGoogleTestFlagsOnly. // The Flags struct stores a copy of all Google Test flags. struct Flags { @@ -5540,8 +5541,8 @@ struct Flags { return flags; } - // Creates a Flags struct where the gtest_random_seed flag has - // the given value. + // Creates a Flags struct where the gtest_random_seed flag has the given + // value. static Flags RandomSeed(Int32 random_seed) { Flags flags; flags.random_seed = random_seed; @@ -5556,8 +5557,8 @@ struct Flags { return flags; } - // Creates a Flags struct where the gtest_shuffle flag has - // the given value. + // Creates a Flags struct where the gtest_shuffle flag has the given + // value. static Flags Shuffle(bool shuffle) { Flags flags; flags.shuffle = shuffle; @@ -5605,8 +5606,8 @@ struct Flags { bool throw_on_failure; }; -// Fixture for testing InitGoogleTest(). -class InitGoogleTestTest : public Test { +// Fixture for testing ParseGoogleTestFlagsOnly(). +class ParseFlagsTest : public Test { protected: // Clears the flags before each test. virtual void SetUp() { @@ -5667,16 +5668,16 @@ class InitGoogleTestTest : public Test { const bool saved_help_flag = ::testing::internal::g_help_flag; ::testing::internal::g_help_flag = false; -#if GTEST_HAS_STREAM_REDIRECTION +# if GTEST_HAS_STREAM_REDIRECTION CaptureStdout(); -#endif +# endif // Parses the command line. internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); -#if GTEST_HAS_STREAM_REDIRECTION +# if GTEST_HAS_STREAM_REDIRECTION const std::string captured_stdout = GetCapturedStdout(); -#endif +# endif // Verifies the flag values. CheckFlags(expected); @@ -5689,7 +5690,7 @@ class InitGoogleTestTest : public Test { // help message for the flags it recognizes. EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); -#if GTEST_HAS_STREAM_REDIRECTION +# if GTEST_HAS_STREAM_REDIRECTION const char* const expected_help_fragment = "This program contains tests written using"; if (should_print_help) { @@ -5698,7 +5699,7 @@ class InitGoogleTestTest : public Test { EXPECT_PRED_FORMAT2(IsNotSubstring, expected_help_fragment, captured_stdout); } -#endif // GTEST_HAS_STREAM_REDIRECTION +# endif // GTEST_HAS_STREAM_REDIRECTION ::testing::internal::g_help_flag = saved_help_flag; } @@ -5706,14 +5707,14 @@ class InitGoogleTestTest : public Test { // This macro wraps TestParsingFlags s.t. the user doesn't need // to specify the array sizes. -#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ +# define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ expected, should_print_help) }; // Tests parsing an empty command line. -TEST_F(InitGoogleTestTest, Empty) { +TEST_F(ParseFlagsTest, Empty) { const char* argv[] = { NULL }; @@ -5726,7 +5727,7 @@ TEST_F(InitGoogleTestTest, Empty) { } // Tests parsing a command line that has no flag. -TEST_F(InitGoogleTestTest, NoFlag) { +TEST_F(ParseFlagsTest, NoFlag) { const char* argv[] = { "foo.exe", NULL @@ -5741,7 +5742,7 @@ TEST_F(InitGoogleTestTest, NoFlag) { } // Tests parsing a bad --gtest_filter flag. -TEST_F(InitGoogleTestTest, FilterBad) { +TEST_F(ParseFlagsTest, FilterBad) { const char* argv[] = { "foo.exe", "--gtest_filter", @@ -5758,7 +5759,7 @@ TEST_F(InitGoogleTestTest, FilterBad) { } // Tests parsing an empty --gtest_filter flag. -TEST_F(InitGoogleTestTest, FilterEmpty) { +TEST_F(ParseFlagsTest, FilterEmpty) { const char* argv[] = { "foo.exe", "--gtest_filter=", @@ -5774,7 +5775,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) { } // Tests parsing a non-empty --gtest_filter flag. -TEST_F(InitGoogleTestTest, FilterNonEmpty) { +TEST_F(ParseFlagsTest, FilterNonEmpty) { const char* argv[] = { "foo.exe", "--gtest_filter=abc", @@ -5790,7 +5791,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) { } // Tests parsing --gtest_break_on_failure. -TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { +TEST_F(ParseFlagsTest, BreakOnFailureWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure", @@ -5806,7 +5807,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { } // Tests parsing --gtest_break_on_failure=0. -TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { +TEST_F(ParseFlagsTest, BreakOnFailureFalse_0) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=0", @@ -5822,7 +5823,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { } // Tests parsing --gtest_break_on_failure=f. -TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { +TEST_F(ParseFlagsTest, BreakOnFailureFalse_f) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=f", @@ -5838,7 +5839,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { } // Tests parsing --gtest_break_on_failure=F. -TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { +TEST_F(ParseFlagsTest, BreakOnFailureFalse_F) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=F", @@ -5855,7 +5856,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { // Tests parsing a --gtest_break_on_failure flag that has a "true" // definition. -TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { +TEST_F(ParseFlagsTest, BreakOnFailureTrue) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=1", @@ -5871,7 +5872,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { } // Tests parsing --gtest_catch_exceptions. -TEST_F(InitGoogleTestTest, CatchExceptions) { +TEST_F(ParseFlagsTest, CatchExceptions) { const char* argv[] = { "foo.exe", "--gtest_catch_exceptions", @@ -5887,7 +5888,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) { } // Tests parsing --gtest_death_test_use_fork. -TEST_F(InitGoogleTestTest, DeathTestUseFork) { +TEST_F(ParseFlagsTest, DeathTestUseFork) { const char* argv[] = { "foo.exe", "--gtest_death_test_use_fork", @@ -5904,7 +5905,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) { // Tests having the same flag twice with different values. The // expected behavior is that the one coming last takes precedence. -TEST_F(InitGoogleTestTest, DuplicatedFlags) { +TEST_F(ParseFlagsTest, DuplicatedFlags) { const char* argv[] = { "foo.exe", "--gtest_filter=a", @@ -5921,7 +5922,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) { } // Tests having an unrecognized flag on the command line. -TEST_F(InitGoogleTestTest, UnrecognizedFlag) { +TEST_F(ParseFlagsTest, UnrecognizedFlag) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure", @@ -5943,7 +5944,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) { } // Tests having a --gtest_list_tests flag -TEST_F(InitGoogleTestTest, ListTestsFlag) { +TEST_F(ParseFlagsTest, ListTestsFlag) { const char* argv[] = { "foo.exe", "--gtest_list_tests", @@ -5959,7 +5960,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) { } // Tests having a --gtest_list_tests flag with a "true" value -TEST_F(InitGoogleTestTest, ListTestsTrue) { +TEST_F(ParseFlagsTest, ListTestsTrue) { const char* argv[] = { "foo.exe", "--gtest_list_tests=1", @@ -5975,7 +5976,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) { } // Tests having a --gtest_list_tests flag with a "false" value -TEST_F(InitGoogleTestTest, ListTestsFalse) { +TEST_F(ParseFlagsTest, ListTestsFalse) { const char* argv[] = { "foo.exe", "--gtest_list_tests=0", @@ -5991,7 +5992,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) { } // Tests parsing --gtest_list_tests=f. -TEST_F(InitGoogleTestTest, ListTestsFalse_f) { +TEST_F(ParseFlagsTest, ListTestsFalse_f) { const char* argv[] = { "foo.exe", "--gtest_list_tests=f", @@ -6007,7 +6008,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) { } // Tests parsing --gtest_list_tests=F. -TEST_F(InitGoogleTestTest, ListTestsFalse_F) { +TEST_F(ParseFlagsTest, ListTestsFalse_F) { const char* argv[] = { "foo.exe", "--gtest_list_tests=F", @@ -6023,7 +6024,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) { } // Tests parsing --gtest_output (invalid). -TEST_F(InitGoogleTestTest, OutputEmpty) { +TEST_F(ParseFlagsTest, OutputEmpty) { const char* argv[] = { "foo.exe", "--gtest_output", @@ -6040,7 +6041,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) { } // Tests parsing --gtest_output=xml -TEST_F(InitGoogleTestTest, OutputXml) { +TEST_F(ParseFlagsTest, OutputXml) { const char* argv[] = { "foo.exe", "--gtest_output=xml", @@ -6056,7 +6057,7 @@ TEST_F(InitGoogleTestTest, OutputXml) { } // Tests parsing --gtest_output=xml:file -TEST_F(InitGoogleTestTest, OutputXmlFile) { +TEST_F(ParseFlagsTest, OutputXmlFile) { const char* argv[] = { "foo.exe", "--gtest_output=xml:file", @@ -6072,7 +6073,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) { } // Tests parsing --gtest_output=xml:directory/path/ -TEST_F(InitGoogleTestTest, OutputXmlDirectory) { +TEST_F(ParseFlagsTest, OutputXmlDirectory) { const char* argv[] = { "foo.exe", "--gtest_output=xml:directory/path/", @@ -6089,7 +6090,7 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) { } // Tests having a --gtest_print_time flag -TEST_F(InitGoogleTestTest, PrintTimeFlag) { +TEST_F(ParseFlagsTest, PrintTimeFlag) { const char* argv[] = { "foo.exe", "--gtest_print_time", @@ -6105,7 +6106,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) { } // Tests having a --gtest_print_time flag with a "true" value -TEST_F(InitGoogleTestTest, PrintTimeTrue) { +TEST_F(ParseFlagsTest, PrintTimeTrue) { const char* argv[] = { "foo.exe", "--gtest_print_time=1", @@ -6121,7 +6122,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) { } // Tests having a --gtest_print_time flag with a "false" value -TEST_F(InitGoogleTestTest, PrintTimeFalse) { +TEST_F(ParseFlagsTest, PrintTimeFalse) { const char* argv[] = { "foo.exe", "--gtest_print_time=0", @@ -6137,7 +6138,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) { } // Tests parsing --gtest_print_time=f. -TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { +TEST_F(ParseFlagsTest, PrintTimeFalse_f) { const char* argv[] = { "foo.exe", "--gtest_print_time=f", @@ -6153,7 +6154,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { } // Tests parsing --gtest_print_time=F. -TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { +TEST_F(ParseFlagsTest, PrintTimeFalse_F) { const char* argv[] = { "foo.exe", "--gtest_print_time=F", @@ -6169,7 +6170,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { } // Tests parsing --gtest_random_seed=number -TEST_F(InitGoogleTestTest, RandomSeed) { +TEST_F(ParseFlagsTest, RandomSeed) { const char* argv[] = { "foo.exe", "--gtest_random_seed=1000", @@ -6185,7 +6186,7 @@ TEST_F(InitGoogleTestTest, RandomSeed) { } // Tests parsing --gtest_repeat=number -TEST_F(InitGoogleTestTest, Repeat) { +TEST_F(ParseFlagsTest, Repeat) { const char* argv[] = { "foo.exe", "--gtest_repeat=1000", @@ -6201,7 +6202,7 @@ TEST_F(InitGoogleTestTest, Repeat) { } // Tests having a --gtest_also_run_disabled_tests flag -TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { +TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFlag) { const char* argv[] = { "foo.exe", "--gtest_also_run_disabled_tests", @@ -6218,7 +6219,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { } // Tests having a --gtest_also_run_disabled_tests flag with a "true" value -TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { +TEST_F(ParseFlagsTest, AlsoRunDisabledTestsTrue) { const char* argv[] = { "foo.exe", "--gtest_also_run_disabled_tests=1", @@ -6235,7 +6236,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { } // Tests having a --gtest_also_run_disabled_tests flag with a "false" value -TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { +TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFalse) { const char* argv[] = { "foo.exe", "--gtest_also_run_disabled_tests=0", @@ -6252,7 +6253,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { } // Tests parsing --gtest_shuffle. -TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { +TEST_F(ParseFlagsTest, ShuffleWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_shuffle", @@ -6268,7 +6269,7 @@ TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { } // Tests parsing --gtest_shuffle=0. -TEST_F(InitGoogleTestTest, ShuffleFalse_0) { +TEST_F(ParseFlagsTest, ShuffleFalse_0) { const char* argv[] = { "foo.exe", "--gtest_shuffle=0", @@ -6283,9 +6284,8 @@ TEST_F(InitGoogleTestTest, ShuffleFalse_0) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); } -// Tests parsing a --gtest_shuffle flag that has a "true" -// definition. -TEST_F(InitGoogleTestTest, ShuffleTrue) { +// Tests parsing a --gtest_shuffle flag that has a "true" definition. +TEST_F(ParseFlagsTest, ShuffleTrue) { const char* argv[] = { "foo.exe", "--gtest_shuffle=1", @@ -6301,7 +6301,7 @@ TEST_F(InitGoogleTestTest, ShuffleTrue) { } // Tests parsing --gtest_stack_trace_depth=number. -TEST_F(InitGoogleTestTest, StackTraceDepth) { +TEST_F(ParseFlagsTest, StackTraceDepth) { const char* argv[] = { "foo.exe", "--gtest_stack_trace_depth=5", @@ -6316,7 +6316,7 @@ TEST_F(InitGoogleTestTest, StackTraceDepth) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); } -TEST_F(InitGoogleTestTest, StreamResultTo) { +TEST_F(ParseFlagsTest, StreamResultTo) { const char* argv[] = { "foo.exe", "--gtest_stream_result_to=localhost:1234", @@ -6333,7 +6333,7 @@ TEST_F(InitGoogleTestTest, StreamResultTo) { } // Tests parsing --gtest_throw_on_failure. -TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { +TEST_F(ParseFlagsTest, ThrowOnFailureWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure", @@ -6349,7 +6349,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { } // Tests parsing --gtest_throw_on_failure=0. -TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { +TEST_F(ParseFlagsTest, ThrowOnFailureFalse_0) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure=0", @@ -6366,7 +6366,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { // Tests parsing a --gtest_throw_on_failure flag that has a "true" // definition. -TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { +TEST_F(ParseFlagsTest, ThrowOnFailureTrue) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure=1", @@ -6381,9 +6381,9 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS // Tests parsing wide strings. -TEST_F(InitGoogleTestTest, WideStrings) { +TEST_F(ParseFlagsTest, WideStrings) { const wchar_t* argv[] = { L"foo.exe", L"--gtest_filter=Foo*", @@ -6409,10 +6409,10 @@ TEST_F(InitGoogleTestTest, WideStrings) { # endif // GTEST_OS_WINDOWS #if GTEST_USE_OWN_FLAGFILE_FLAG_ -class FlagfileTest : public InitGoogleTestTest { +class FlagfileTest : public ParseFlagsTest { public: virtual void SetUp() { - InitGoogleTestTest::SetUp(); + ParseFlagsTest::SetUp(); testdata_path_.Set(internal::FilePath( testing::TempDir() + internal::GetCurrentExecutableName().string() + @@ -6423,7 +6423,7 @@ class FlagfileTest : public InitGoogleTestTest { virtual void TearDown() { testing::internal::posix::RmDir(testdata_path_.c_str()); - InitGoogleTestTest::TearDown(); + ParseFlagsTest::TearDown(); } internal::FilePath CreateFlagfile(const char* contents) { @@ -6562,6 +6562,7 @@ TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { } // namespace testing + // These two lines test that we can define tests in a namespace that // has the name "testing" and is nested in another namespace. namespace my_namespace { From 05e1ffc0310bd52ab6bfebc177ae056703afa1a6 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 23 Feb 2018 11:07:18 -0500 Subject: [PATCH 39/59] merging unittests - 2 --- googletest/test/gtest_unittest.cc | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index a5743fc5..bf7621ef 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -2088,7 +2088,7 @@ class UnitTestRecordPropertyTestEnvironment : public Environment { }; // This will test property recording outside of any test or test case. -Environment* record_property_env GTEST_ATTRIBUTE_UNUSED_ = +static Environment* record_property_env = AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); // This group of tests is for predicate assertions (ASSERT_PRED*, etc) @@ -3361,7 +3361,7 @@ class NoFatalFailureTest : public Test { void DoAssertNoFatalFailureOnFails() { ASSERT_NO_FATAL_FAILURE(Fails()); - ADD_FAILURE() << "shold not reach here."; + ADD_FAILURE() << "should not reach here."; } void DoExpectNoFatalFailureOnFails() { @@ -6893,14 +6893,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { StaticAssertTypeEq(); } -TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { - testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); - - // We don't have a stack walker in Google Test yet. - EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); - EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); -} - TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { EXPECT_FALSE(HasNonfatalFailure()); } @@ -7660,7 +7652,7 @@ TEST(NativeArrayTest, MethodsWork) { EXPECT_EQ(0, *it); ++it; EXPECT_EQ(1, *it); - ++it; + it++; EXPECT_EQ(2, *it); ++it; EXPECT_EQ(na.end(), it); From 026c7e4c8f19937eabb1c839aa77019529104669 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 23 Feb 2018 11:29:35 -0500 Subject: [PATCH 40/59] merging unitests, check --- googletest/test/gtest_unittest.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index bf7621ef..f62e5b4b 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -2421,9 +2421,8 @@ TEST(StringAssertionTest, ASSERT_STREQ) { const char p2[] = "good"; ASSERT_STREQ(p1, p2); - EXPECT_FATAL_FAILURE( - ASSERT_STREQ("bad", "good"), - "Expected equality of these values:\n \"bad\"\n \"good\""); + EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), + " \"bad\"\n \"good\""); } // Tests ASSERT_STREQ with NULL arguments. @@ -3698,7 +3697,7 @@ TEST(AssertionTest, ASSERT_EQ_NULL) { // A failure. static int n = 0; EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), - " &n\n Which is:"); + " &n\n Which is: 0x"); } #endif // GTEST_CAN_COMPARE_NULL From aac61e939eaa6c2cc47b1bd582966ca8aa6e075e Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 23 Feb 2018 15:27:11 -0500 Subject: [PATCH 41/59] merging unitests - check 4 --- googletest/test/gtest_unittest.cc | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index f62e5b4b..38ff19ee 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -3697,7 +3697,7 @@ TEST(AssertionTest, ASSERT_EQ_NULL) { // A failure. static int n = 0; EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), - " &n\n Which is: 0x"); + " &n\n Which is:"); } #endif // GTEST_CAN_COMPARE_NULL @@ -3812,7 +3812,7 @@ void TestEq1(int x) { // Tests calling a test subroutine that's not part of a fixture. TEST(AssertionTest, NonFixtureSubroutine) { EXPECT_FATAL_FAILURE(TestEq1(2), - "Which is: 2"); + " x\n Which is: 2"); } // An uncopyable class. @@ -3951,13 +3951,13 @@ TEST(AssertionTest, AnonymousEnum) { // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), - "kCaseB"); + " kCaseB\n Which is: "); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), - "Which is: 42"); + "\n Which is: 42"); # endif EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), - "Which is: -1"); + "\n Which is: -1"); } #endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) @@ -4441,7 +4441,7 @@ TEST(ExpectTest, EXPECT_EQ_0) { // A failure. EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), - "Expected equality of these values:\n 0\n 5.6"); + " 0\n 5.6"); } // Tests EXPECT_NE. @@ -4541,7 +4541,7 @@ TEST(ExpectTest, EXPECT_ANY_THROW) { TEST(ExpectTest, ExpectPrecedence) { EXPECT_EQ(1 < 2, true); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), - "true && false"); + " true && false\n Which is: false"); } @@ -4688,14 +4688,14 @@ TEST(EqAssertionTest, Bool) { EXPECT_FATAL_FAILURE({ bool false_value = false; ASSERT_EQ(false_value, true); - }, "Which is: false"); + }, " false_value\n Which is: false\n true"); } // Tests using int values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, Int) { ASSERT_EQ(32, 32); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), - "33"); + " 32\n 33"); } // Tests using time_t values in {EXPECT|ASSERT}_EQ. @@ -4712,9 +4712,9 @@ TEST(EqAssertionTest, Char) { ASSERT_EQ('z', 'z'); const char ch = 'b'; EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), - "ch"); + " ch\n Which is: 'b'"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), - "ch"); + " ch\n Which is: 'b'"); } // Tests using wchar_t values in {EXPECT|ASSERT}_EQ. @@ -4734,7 +4734,7 @@ TEST(EqAssertionTest, WideChar) { "wchar"); wchar = 0x8119; EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), - "wchar"); + " wchar\n Which is: L'"); } // Tests using ::std::string values in {EXPECT|ASSERT}_EQ. @@ -4763,8 +4763,7 @@ TEST(EqAssertionTest, StdString) { static ::std::string str3(str1); str3.at(2) = '\0'; EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), - " str3\n" - " Which is: \"A \\0 in the middle\""); + " str3\n Which is: \"A \\0 in the middle\""); } #if GTEST_HAS_STD_WSTRING From 7c60f81b22b983c9d73d4940c16a7c10afeb96db Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Fri, 23 Feb 2018 12:28:09 -0800 Subject: [PATCH 42/59] Try to handle unsigned wchar_t (arm) a bit better --- googlemock/include/gmock/internal/gmock-internal-utils.h | 2 ++ googlemock/test/gmock-actions_test.cc | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 319b389b..37ceb549 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -117,9 +117,11 @@ struct LinkedPtrLessThan { // To gcc, // wchar_t == signed wchar_t != unsigned wchar_t == unsigned int #ifdef __GNUC__ +#if !defined(__WCHAR_UNSIGNED__) // signed/unsigned wchar_t are valid types. # define GMOCK_HAS_SIGNED_WCHAR_T_ 1 #endif +#endif // In what follows, we use the term "kind" to indicate whether a type // is bool, an integer type (excluding bool), a floating-point type, diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index f7218391..9447c22b 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -107,7 +107,11 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { EXPECT_EQ(0, BuiltInDefaultValue::Get()); #endif #if GMOCK_WCHAR_T_IS_NATIVE_ +#if !defined(__WCHAR_UNSIGNED__) EXPECT_EQ(0, BuiltInDefaultValue::Get()); +#else + EXPECT_EQ(0U, BuiltInDefaultValue::Get()); +#endif #endif EXPECT_EQ(0U, BuiltInDefaultValue::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue::Get()); // NOLINT From 5fd9cb3a67cb68421385f2beb9ee3759a1664782 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 26 Feb 2018 09:51:27 -0500 Subject: [PATCH 43/59] merging unittests - 5 --- googletest/test/gtest_unittest.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 38ff19ee..11af9c9b 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -4425,7 +4425,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) { // A failure. int n = 0; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), - "&n\n"); + " &n\n Which is:"); } #endif // GTEST_CAN_COMPARE_NULL @@ -4883,9 +4883,9 @@ TEST(EqAssertionTest, CharPointer) { ASSERT_EQ(p1, p1); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), - "p2"); + " p2\n Which is:"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), - "p2"); + " p2\n Which is:"); EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), reinterpret_cast(0xABC0)), "ABC0"); @@ -4905,9 +4905,9 @@ TEST(EqAssertionTest, WideCharPointer) { EXPECT_EQ(p0, p0); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), - "p2"); + " p2\n Which is:"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), - "p2"); + " p2\n Which is:"); void* pv3 = (void*)0x1234; // NOLINT void* pv4 = (void*)0xABC0; // NOLINT const wchar_t* p3 = reinterpret_cast(pv3); From 12243d083a278593a08b7dca32be09e902bbedf6 Mon Sep 17 00:00:00 2001 From: David Neto Date: Mon, 26 Feb 2018 14:54:16 -0500 Subject: [PATCH 44/59] Use DEBUG_POSTFIX instead of CMAKE_DEBUG_POSTFIX CMAKE_DEBUG_POSTFIX is a global configuration parameter, and changing it pollutes the configuration space for other projects that enclose this project. DEBUG_POSTFIX is better to use since it is a target-specific poperty. Fixes #1334 Fixes #1268 --- googletest/CMakeLists.txt | 2 -- googletest/cmake/internal_utils.cmake | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt index 77b55cae..5c392e2c 100644 --- a/googletest/CMakeLists.txt +++ b/googletest/CMakeLists.txt @@ -27,8 +27,6 @@ option( "Build gtest with internal symbols hidden in shared libraries." OFF) -set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Generate debug library name with a postfix.") - # Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). include(cmake/hermetic_build.cmake OPTIONAL) diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake index 2c978332..01f9fe50 100644 --- a/googletest/cmake/internal_utils.cmake +++ b/googletest/cmake/internal_utils.cmake @@ -158,6 +158,10 @@ function(cxx_library_with_type name type cxx_flags) set_target_properties(${name} PROPERTIES COMPILE_FLAGS "${cxx_flags}") + # Generate debug library name with a postfix. + set_target_properties(${name} + PROPERTIES + DEBUG_POSTFIX "d") if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") set_target_properties(${name} PROPERTIES From 8921d82a1c66d7169c1249cf78beebe6a8eb99ae Mon Sep 17 00:00:00 2001 From: Victor Costan Date: Fri, 23 Feb 2018 14:55:25 -0800 Subject: [PATCH 45/59] Switch default death test style back to "fast". Google Test has recently (02/09/2018) switched the default death test style from "fast" to "threadsafe" in https://github.com/google/googletest/commit/ec7faa943d7817c81ce7bdf71a21ebc9244dc8de Threadsafe death tests have been used internally for a while, and are proven to be a better default. However, adopting this better default can be challenging for large projects with a significant investment in custom infrastructure built on top of Google Test. The same custom infrastructure can make it difficult for large projects to switch back to the old default by passing in --gtest_death_test_style=fast. For the reasons above, the default switch is considered too disruptive, and this CL reverts it. This CL also introduces the GTEST_DEFAULT_DEATH_TEST_STYLE preprocesor macro, which replaces the hard-coded default. The macro can be defined in gtest/internal/custom/gtest-port.h by projects that are ready to migrate to thread-safe death tests. --- googletest/include/gtest/internal/gtest-port.h | 10 ++++++++++ googletest/src/gtest-death-test.cc | 6 +++++- googletest/test/gtest_env_var_test.py | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 81f047bf..2c819c9f 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -107,6 +107,12 @@ // GTEST_CREATE_SHARED_LIBRARY // - Define to 1 when compiling Google Test itself // as a shared library. +// GTEST_DEFAULT_DEATH_TEST_STYLE +// - The default value of --gtest_death_test_style. +// The legacy default has been "fast" in the open +// source version since 2008. The recommended value +// is "threadsafe", and can be set in +// custom/gtest-port.h. // Platform-indicating macros // -------------------------- @@ -974,6 +980,10 @@ using ::std::tuple_size; # define GTEST_API_ #endif // GTEST_API_ +#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE +# define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" +#endif // GTEST_DEFAULT_DEATH_TEST_STYLE + #ifdef __GNUC__ // Ask the compiler to never inline a given function. # define GTEST_NO_INLINE_ __attribute__((noinline)) diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index 852912b5..9ecab8f9 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -73,7 +73,11 @@ namespace testing { // Constants. // The default death test style. -static const char kDefaultDeathTestStyle[] = "threadsafe"; +// +// This is defined in internal/gtest-port.h as "fast", but can be overridden by +// a definition in internal/custom/gtest-port.h. The recommended value, which is +// used internally at Google, is "threadsafe". +static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; GTEST_DEFINE_string_( death_test_style, diff --git a/googletest/test/gtest_env_var_test.py b/googletest/test/gtest_env_var_test.py index 2fe9cd5f..7af00cee 100755 --- a/googletest/test/gtest_env_var_test.py +++ b/googletest/test/gtest_env_var_test.py @@ -92,7 +92,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') TestFlag('throw_on_failure', '1', '0') - TestFlag('death_test_style', 'fast', 'threadsafe') + TestFlag('death_test_style', 'threadsafe', 'fast') TestFlag('catch_exceptions', '0', '1') if IS_LINUX: From fe8a4bec1b797cfba2d5dbc435d4ca9dc28ec709 Mon Sep 17 00:00:00 2001 From: Xiaoyi Zhang Date: Tue, 27 Feb 2018 11:36:21 -0500 Subject: [PATCH 46/59] Add matcher for std::variant. --- googlemock/include/gmock/gmock-matchers.h | 71 +++++++++++++++++++++++ googlemock/test/gmock-matchers_test.cc | 64 ++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index fc3fe3aa..85b5b13b 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -3623,6 +3623,66 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation, const char* matcher_name, const Strings& param_values); +namespace variant_matcher { +// Overloads to allow VariantMatcher to do proper ADL lookup. +template +void holds_alternative() {} +template +void get() {} + +// Implements a matcher that checks the value of a variant<> type variable. +template +class VariantMatcher { + public: + explicit VariantMatcher(::testing::Matcher matcher) + : matcher_(internal::move(matcher)) {} + + template + bool MatchAndExplain(const Variant& value, + ::testing::MatchResultListener* listener) const { + if (!listener->IsInterested()) { + return holds_alternative(value) && matcher_.Matches(get(value)); + } + + if (!holds_alternative(value)) { + *listener << "whose value is not of type '" << GetTypeName() << "'"; + return false; + } + + const T& elem = get(value); + StringMatchResultListener elem_listener; + const bool match = matcher_.MatchAndExplain(elem, &elem_listener); + *listener << "whose value " << PrintToString(elem) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(elem_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(std::ostream* os) const { + *os << "is a variant<> with value of type '" << GetTypeName() + << "' and the value "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "is a variant<> with value of type other than '" << GetTypeName() + << "' or the value "; + matcher_.DescribeNegationTo(os); + } + + private: + static string GetTypeName() { +#if GTEST_HAS_RTTI + return internal::GetTypeName(); +#endif + return "the element type"; + } + + const ::testing::Matcher matcher_; +}; + +} // namespace variant_matcher + } // namespace internal // ElementsAreArray(first, last) @@ -4397,6 +4457,17 @@ inline internal::AnyOfMatcher AnyOf(const Args&... matchers) { template inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } +// Returns a matcher that matches the value of a variant<> type variable. +// The matcher implementation uses ADL to find the holds_alternative and get +// functions. +// It is compatible with std::variant. +template +PolymorphicMatcher > VariantWith( + const Matcher& matcher) { + return MakePolymorphicMatcher( + internal::variant_matcher::VariantMatcher(matcher)); +} + // These macros allow using matchers to check values in Google Test // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // succeed iff the value matches the matcher. If the assertion fails, diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 761c0c22..829935ef 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -5655,5 +5655,69 @@ TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) { EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs)); } +class SampleVariantIntString { + public: + SampleVariantIntString(int i) : i_(i), has_int_(true) {} + SampleVariantIntString(const std::string& s) : s_(s), has_int_(false) {} + + template + friend bool holds_alternative(const SampleVariantIntString& value) { + return value.has_int_ == internal::IsSame::value; + } + + template + friend const T& get(const SampleVariantIntString& value) { + return value.get_impl(static_cast(NULL)); + } + + private: + const int& get_impl(int*) const { return i_; } + const std::string& get_impl(std::string*) const { return s_; } + + int i_; + std::string s_; + bool has_int_; +}; + +TEST(VariantTest, DescribesSelf) { + const Matcher m = VariantWith(Eq(1)); + EXPECT_THAT(Describe(m), ContainsRegex("is a variant<> with value of type " + "'.*' and the value is equal to 1")); +} + +TEST(VariantTest, ExplainsSelf) { + const Matcher m = VariantWith(Eq(1)); + EXPECT_THAT(Explain(m, SampleVariantIntString(1)), + ContainsRegex("whose value 1")); + EXPECT_THAT(Explain(m, SampleVariantIntString("A")), + HasSubstr("whose value is not of type '")); + EXPECT_THAT(Explain(m, SampleVariantIntString(2)), + "whose value 2 doesn't match"); +} + +TEST(VariantTest, FullMatch) { + Matcher m = VariantWith(Eq(1)); + EXPECT_TRUE(m.Matches(SampleVariantIntString(1))); + + m = VariantWith(Eq("1")); + EXPECT_TRUE(m.Matches(SampleVariantIntString("1"))); +} + +TEST(VariantTest, TypeDoesNotMatch) { + Matcher m = VariantWith(Eq(1)); + EXPECT_FALSE(m.Matches(SampleVariantIntString("1"))); + + m = VariantWith(Eq("1")); + EXPECT_FALSE(m.Matches(SampleVariantIntString(1))); +} + +TEST(VariantTest, InnerDoesNotMatch) { + Matcher m = VariantWith(Eq(1)); + EXPECT_FALSE(m.Matches(SampleVariantIntString(2))); + + m = VariantWith(Eq("1")); + EXPECT_FALSE(m.Matches(SampleVariantIntString("2"))); +} + } // namespace gmock_matchers_test } // namespace testing From bcc0a1afa10aa4bd51f22180b477fc997938f4db Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Tue, 27 Feb 2018 13:51:09 -0500 Subject: [PATCH 47/59] gmock merging -2 --- googlemock/include/gmock/gmock-matchers.h | 231 +++++++++++++++++----- googlemock/src/gmock-matchers.cc | 196 ++++++++++-------- googlemock/test/gmock_link_test.h | 24 ++- 3 files changed, 328 insertions(+), 123 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index fc3fe3aa..3d2d6177 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -514,7 +514,7 @@ template class MatcherCastImpl { public: static Matcher Cast(const M& polymorphic_matcher_or_value) { - // M can be a polymorhic matcher, in which case we want to use + // M can be a polymorphic matcher, in which case we want to use // its conversion operator to create Matcher. Or it can be a value // that should be passed to the Matcher's constructor. // @@ -3303,14 +3303,23 @@ typedef ::std::vector ElementMatcherPairs; GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g); -GTEST_API_ bool FindPairing(const MatchMatrix& matrix, - MatchResultListener* listener); +struct UnorderedMatcherRequire { + enum Flags { + Superset = 1 << 0, + Subset = 1 << 1, + ExactMatch = Superset | Subset, + }; +}; // Untyped base class for implementing UnorderedElementsAre. By // putting logic that's not specific to the element type here, we // reduce binary bloat and increase compilation speed. class GTEST_API_ UnorderedElementsAreMatcherImplBase { protected: + explicit UnorderedElementsAreMatcherImplBase( + UnorderedMatcherRequire::Flags matcher_flags) + : match_flags_(matcher_flags) {} + // A vector of matcher describers, one for each element matcher. // Does not own the describers (and thus can be used only when the // element matchers are alive). @@ -3322,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { // Describes the negation of this UnorderedElementsAre matcher. void DescribeNegationToImpl(::std::ostream* os) const; - bool VerifyAllElementsAndMatchersAreMatched( - const ::std::vector& element_printouts, - const MatchMatrix& matrix, MatchResultListener* listener) const; + bool VerifyMatchMatrix(const ::std::vector& element_printouts, + const MatchMatrix& matrix, + MatchResultListener* listener) const; + + bool FindPairing(const MatchMatrix& matrix, + MatchResultListener* listener) const; MatcherDescriberVec& matcher_describers() { return matcher_describers_; @@ -3334,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { return Message() << n << " element" << (n == 1 ? "" : "s"); } + UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; } + private: + UnorderedMatcherRequire::Flags match_flags_; MatcherDescriberVec matcher_describers_; GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase); }; -// Implements unordered ElementsAre and unordered ElementsAreArray. +// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and +// IsSupersetOf. template class UnorderedElementsAreMatcherImpl : public MatcherInterface, @@ -3353,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl typedef typename StlContainer::const_iterator StlContainerConstIterator; typedef typename StlContainer::value_type Element; - // Constructs the matcher from a sequence of element values or - // element matchers. template - UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) { + UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, + InputIter first, InputIter last) + : UnorderedElementsAreMatcherImplBase(matcher_flags) { for (; first != last; ++first) { matchers_.push_back(MatcherCast(*first)); matcher_describers().push_back(matchers_.back().GetDescriber()); @@ -3377,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl MatchResultListener* listener) const { StlContainerReference stl_container = View::ConstReference(container); ::std::vector element_printouts; - MatchMatrix matrix = AnalyzeElements(stl_container.begin(), - stl_container.end(), - &element_printouts, - listener); + MatchMatrix matrix = + AnalyzeElements(stl_container.begin(), stl_container.end(), + &element_printouts, listener); - const size_t actual_count = matrix.LhsSize(); - if (actual_count == 0 && matchers_.empty()) { + if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) { return true; } - if (actual_count != matchers_.size()) { - // The element count doesn't match. If the container is empty, - // there's no need to explain anything as Google Mock already - // prints the empty container. Otherwise we just need to show - // how many elements there actually are. - if (actual_count != 0 && listener->IsInterested()) { - *listener << "which has " << Elements(actual_count); + + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + if (matrix.LhsSize() != matrix.RhsSize()) { + // The element count doesn't match. If the container is empty, + // there's no need to explain anything as Google Mock already + // prints the empty container. Otherwise we just need to show + // how many elements there actually are. + if (matrix.LhsSize() != 0 && listener->IsInterested()) { + *listener << "which has " << Elements(matrix.LhsSize()); + } + return false; } - return false; } - return VerifyAllElementsAndMatchersAreMatched(element_printouts, - matrix, listener) && + return VerifyMatchMatrix(element_printouts, matrix, listener) && FindPairing(matrix, listener); } private: - typedef ::std::vector > MatcherVec; - template MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, ::std::vector* element_printouts, @@ -3431,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl return matrix; } - MatcherVec matchers_; + ::std::vector > matchers_; GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl); }; @@ -3464,7 +3478,7 @@ class UnorderedElementsAreMatcher { TransformTupleValues(CastAndAppendTransform(), matchers_, ::std::back_inserter(matchers)); return MakeMatcher(new UnorderedElementsAreMatcherImpl( - matchers.begin(), matchers.end())); + UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end())); } private: @@ -3497,24 +3511,23 @@ class ElementsAreMatcher { GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher); }; -// Implements UnorderedElementsAreArray(). +// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). template class UnorderedElementsAreArrayMatcher { public: - UnorderedElementsAreArrayMatcher() {} - template - UnorderedElementsAreArrayMatcher(Iter first, Iter last) - : matchers_(first, last) {} + UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags, + Iter first, Iter last) + : match_flags_(match_flags), matchers_(first, last) {} template operator Matcher() const { - return MakeMatcher( - new UnorderedElementsAreMatcherImpl(matchers_.begin(), - matchers_.end())); + return MakeMatcher(new UnorderedElementsAreMatcherImpl( + match_flags_, matchers_.begin(), matchers_.end())); } private: + UnorderedMatcherRequire::Flags match_flags_; ::std::vector matchers_; GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher); @@ -3625,7 +3638,7 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation, } // namespace internal -// ElementsAreArray(first, last) +// ElementsAreArray(iterator_first, iterator_last) // ElementsAreArray(pointer, count) // ElementsAreArray(array) // ElementsAreArray(container) @@ -3674,20 +3687,26 @@ ElementsAreArray(::std::initializer_list xs) { } #endif -// UnorderedElementsAreArray(first, last) +// UnorderedElementsAreArray(iterator_first, iterator_last) // UnorderedElementsAreArray(pointer, count) // UnorderedElementsAreArray(array) // UnorderedElementsAreArray(container) // UnorderedElementsAreArray({ e1, e2, ..., en }) // -// The UnorderedElementsAreArray() functions are like -// ElementsAreArray(...), but allow matching the elements in any order. +// UnorderedElementsAreArray() verifies that a bijective mapping onto a +// collection of matchers exists. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + template inline internal::UnorderedElementsAreArrayMatcher< typename ::std::iterator_traits::value_type> UnorderedElementsAreArray(Iter first, Iter last) { typedef typename ::std::iterator_traits::value_type T; - return internal::UnorderedElementsAreArrayMatcher(first, last); + return internal::UnorderedElementsAreArrayMatcher( + internal::UnorderedMatcherRequire::ExactMatch, first, last); } template @@ -3729,7 +3748,9 @@ UnorderedElementsAreArray(::std::initializer_list xs) { const internal::AnythingMatcher _ = {}; // Creates a matcher that matches any value of the given type T. template -inline Matcher A() { return MakeMatcher(new internal::AnyMatcherImpl()); } +inline Matcher A() { + return Matcher(new internal::AnyMatcherImpl()); +} // Creates a matcher that matches any value of the given type T. template @@ -4299,6 +4320,128 @@ inline internal::ContainsMatcher Contains(M matcher) { return internal::ContainsMatcher(matcher); } +// IsSupersetOf(iterator_first, iterator_last) +// IsSupersetOf(pointer, count) +// IsSupersetOf(array) +// IsSupersetOf(container) +// IsSupersetOf({e1, e2, ..., en}) +// +// IsSupersetOf() verifies that a surjective partial mapping onto a collection +// of matchers exists. In other words, a container matches +// IsSupersetOf({e1, ..., en}) if and only if there is a permutation +// {y1, ..., yn} of some of the container's elements where y1 matches e1, +// ..., and yn matches en. Obviously, the size of the container must be >= n +// in order to have a match. Examples: +// +// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and +// 1 matches Ne(0). +// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches +// both Eq(1) and Lt(2). The reason is that different matchers must be used +// for elements in different slots of the container. +// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches +// Eq(1) and (the second) 1 matches Lt(2). +// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first) +// Gt(1) and 3 matches (the second) Gt(1). +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits::value_type> +IsSupersetOf(Iter first, Iter last) { + typedef typename ::std::iterator_traits::value_type T; + return internal::UnorderedElementsAreArrayMatcher( + internal::UnorderedMatcherRequire::Superset, first, last); +} + +template +inline internal::UnorderedElementsAreArrayMatcher IsSupersetOf( + const T* pointer, size_t count) { + return IsSupersetOf(pointer, pointer + count); +} + +template +inline internal::UnorderedElementsAreArrayMatcher IsSupersetOf( + const T (&array)[N]) { + return IsSupersetOf(array, N); +} + +template +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +IsSupersetOf(const Container& container) { + return IsSupersetOf(container.begin(), container.end()); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +template +inline internal::UnorderedElementsAreArrayMatcher IsSupersetOf( + ::std::initializer_list xs) { + return IsSupersetOf(xs.begin(), xs.end()); +} +#endif + +// IsSubsetOf(iterator_first, iterator_last) +// IsSubsetOf(pointer, count) +// IsSubsetOf(array) +// IsSubsetOf(container) +// IsSubsetOf({e1, e2, ..., en}) +// +// IsSubsetOf() verifies that an injective mapping onto a collection of matchers +// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and +// only if there is a subset of matchers {m1, ..., mk} which would match the +// container using UnorderedElementsAre. Obviously, the size of the container +// must be <= n in order to have a match. Examples: +// +// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0). +// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1 +// matches Lt(0). +// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both +// match Gt(0). The reason is that different matchers must be used for +// elements in different slots of the container. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits::value_type> +IsSubsetOf(Iter first, Iter last) { + typedef typename ::std::iterator_traits::value_type T; + return internal::UnorderedElementsAreArrayMatcher( + internal::UnorderedMatcherRequire::Subset, first, last); +} + +template +inline internal::UnorderedElementsAreArrayMatcher IsSubsetOf( + const T* pointer, size_t count) { + return IsSubsetOf(pointer, pointer + count); +} + +template +inline internal::UnorderedElementsAreArrayMatcher IsSubsetOf( + const T (&array)[N]) { + return IsSubsetOf(array, N); +} + +template +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +IsSubsetOf(const Container& container) { + return IsSubsetOf(container.begin(), container.end()); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +template +inline internal::UnorderedElementsAreArrayMatcher IsSubsetOf( + ::std::initializer_list xs) { + return IsSubsetOf(xs.begin(), xs.end()); +} +#endif + // Matches an STL-style container or a native array that contains only // elements matching the given value or matcher. // diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc index f37d5c2d..88e40088 100644 --- a/googlemock/src/gmock-matchers.cc +++ b/googlemock/src/gmock-matchers.cc @@ -38,6 +38,7 @@ #include "gmock/gmock-generated-matchers.h" #include +#include #include #include @@ -181,8 +182,7 @@ class MaxBipartiteMatchState { explicit MaxBipartiteMatchState(const MatchMatrix& graph) : graph_(&graph), left_(graph_->LhsSize(), kUnused), - right_(graph_->RhsSize(), kUnused) { - } + right_(graph_->RhsSize(), kUnused) {} // Returns the edges of a maximal match, each in the form {left, right}. ElementMatcherPairs Compute() { @@ -239,10 +239,8 @@ class MaxBipartiteMatchState { // bool TryAugment(size_t ilhs, ::std::vector* seen) { for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) { - if ((*seen)[irhs]) - continue; - if (!graph_->HasEdge(ilhs, irhs)) - continue; + if ((*seen)[irhs]) continue; + if (!graph_->HasEdge(ilhs, irhs)) continue; // There's an available edge from ilhs to irhs. (*seen)[irhs] = 1; // Next a search is performed to determine whether @@ -285,8 +283,7 @@ class MaxBipartiteMatchState { const size_t MaxBipartiteMatchState::kUnused; -GTEST_API_ ElementMatcherPairs -FindMaxBipartiteMatching(const MatchMatrix& g) { +GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) { return MaxBipartiteMatchState(g).Compute(); } @@ -295,7 +292,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, typedef ElementMatcherPairs::const_iterator Iter; ::std::ostream& os = *stream; os << "{"; - const char *sep = ""; + const char* sep = ""; for (Iter it = pairs.begin(); it != pairs.end(); ++it) { os << sep << "\n (" << "element #" << it->first << ", " @@ -305,38 +302,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, os << "\n}"; } -// Tries to find a pairing, and explains the result. -GTEST_API_ bool FindPairing(const MatchMatrix& matrix, - MatchResultListener* listener) { - ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); - - size_t max_flow = matches.size(); - bool result = (max_flow == matrix.RhsSize()); - - if (!result) { - if (listener->IsInterested()) { - *listener << "where no permutation of the elements can " - "satisfy all matchers, and the closest match is " - << max_flow << " of " << matrix.RhsSize() - << " matchers with the pairings:\n"; - LogElementMatcherPairVec(matches, listener->stream()); - } - return false; - } - - if (matches.size() > 1) { - if (listener->IsInterested()) { - const char *sep = "where:\n"; - for (size_t mi = 0; mi < matches.size(); ++mi) { - *listener << sep << " - element #" << matches[mi].first - << " is matched by matcher #" << matches[mi].second; - sep = ",\n"; - } - } - } - return true; -} - bool MatchMatrix::NextGraph() { for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { @@ -362,7 +327,7 @@ void MatchMatrix::Randomize() { std::string MatchMatrix::DebugString() const { ::std::stringstream ss; - const char *sep = ""; + const char* sep = ""; for (size_t i = 0; i < LhsSize(); ++i) { ss << sep; for (size_t j = 0; j < RhsSize(); ++j) { @@ -375,44 +340,83 @@ std::string MatchMatrix::DebugString() const { void UnorderedElementsAreMatcherImplBase::DescribeToImpl( ::std::ostream* os) const { - if (matcher_describers_.empty()) { - *os << "is empty"; - return; + switch (match_flags()) { + case UnorderedMatcherRequire::ExactMatch: + if (matcher_describers_.empty()) { + *os << "is empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "has " << Elements(1) << " and that element "; + matcher_describers_[0]->DescribeTo(os); + return; + } + *os << "has " << Elements(matcher_describers_.size()) + << " and there exists some permutation of elements such that:\n"; + break; + case UnorderedMatcherRequire::Superset: + *os << "a surjection from elements to requirements exists such that:\n"; + break; + case UnorderedMatcherRequire::Subset: + *os << "an injection from elements to requirements exists such that:\n"; + break; } - if (matcher_describers_.size() == 1) { - *os << "has " << Elements(1) << " and that element "; - matcher_describers_[0]->DescribeTo(os); - return; - } - *os << "has " << Elements(matcher_describers_.size()) - << " and there exists some permutation of elements such that:\n"; + const char* sep = ""; for (size_t i = 0; i != matcher_describers_.size(); ++i) { - *os << sep << " - element #" << i << " "; + *os << sep; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + *os << " - element #" << i << " "; + } else { + *os << " - an element "; + } matcher_describers_[i]->DescribeTo(os); - sep = ", and\n"; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + sep = ", and\n"; + } else { + sep = "\n"; + } } } void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( ::std::ostream* os) const { - if (matcher_describers_.empty()) { - *os << "isn't empty"; - return; + switch (match_flags()) { + case UnorderedMatcherRequire::ExactMatch: + if (matcher_describers_.empty()) { + *os << "isn't empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "doesn't have " << Elements(1) << ", or has " << Elements(1) + << " that "; + matcher_describers_[0]->DescribeNegationTo(os); + return; + } + *os << "doesn't have " << Elements(matcher_describers_.size()) + << ", or there exists no permutation of elements such that:\n"; + break; + case UnorderedMatcherRequire::Superset: + *os << "no surjection from elements to requirements exists such that:\n"; + break; + case UnorderedMatcherRequire::Subset: + *os << "no injection from elements to requirements exists such that:\n"; + break; } - if (matcher_describers_.size() == 1) { - *os << "doesn't have " << Elements(1) - << ", or has " << Elements(1) << " that "; - matcher_describers_[0]->DescribeNegationTo(os); - return; - } - *os << "doesn't have " << Elements(matcher_describers_.size()) - << ", or there exists no permutation of elements such that:\n"; const char* sep = ""; for (size_t i = 0; i != matcher_describers_.size(); ++i) { - *os << sep << " - element #" << i << " "; + *os << sep; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + *os << " - element #" << i << " "; + } else { + *os << " - an element "; + } matcher_describers_[i]->DescribeTo(os); - sep = ", and\n"; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + sep = ", and\n"; + } else { + sep = "\n"; + } } } @@ -421,10 +425,9 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( // and better error reporting. // Returns false, writing an explanation to 'listener', if and only // if the success criteria are not met. -bool UnorderedElementsAreMatcherImplBase:: - VerifyAllElementsAndMatchersAreMatched( - const ::std::vector& element_printouts, - const MatchMatrix& matrix, MatchResultListener* listener) const { +bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix( + const ::std::vector& element_printouts, + const MatchMatrix& matrix, MatchResultListener* listener) const { bool result = true; ::std::vector element_matched(matrix.LhsSize(), 0); ::std::vector matcher_matched(matrix.RhsSize(), 0); @@ -437,12 +440,11 @@ bool UnorderedElementsAreMatcherImplBase:: } } - { + if (match_flags() & UnorderedMatcherRequire::Superset) { const char* sep = "where the following matchers don't match any elements:\n"; for (size_t mi = 0; mi < matcher_matched.size(); ++mi) { - if (matcher_matched[mi]) - continue; + if (matcher_matched[mi]) continue; result = false; if (listener->IsInterested()) { *listener << sep << "matcher #" << mi << ": "; @@ -452,7 +454,7 @@ bool UnorderedElementsAreMatcherImplBase:: } } - { + if (match_flags() & UnorderedMatcherRequire::Subset) { const char* sep = "where the following elements don't match any matchers:\n"; const char* outer_sep = ""; @@ -460,8 +462,7 @@ bool UnorderedElementsAreMatcherImplBase:: outer_sep = "\nand "; } for (size_t ei = 0; ei < element_matched.size(); ++ei) { - if (element_matched[ei]) - continue; + if (element_matched[ei]) continue; result = false; if (listener->IsInterested()) { *listener << outer_sep << sep << "element #" << ei << ": " @@ -474,5 +475,46 @@ bool UnorderedElementsAreMatcherImplBase:: return result; } +bool UnorderedElementsAreMatcherImplBase::FindPairing( + const MatchMatrix& matrix, MatchResultListener* listener) const { + ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); + + size_t max_flow = matches.size(); + if ((match_flags() & UnorderedMatcherRequire::Superset) && + max_flow < matrix.RhsSize()) { + if (listener->IsInterested()) { + *listener << "where no permutation of the elements can satisfy all " + "matchers, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + if ((match_flags() & UnorderedMatcherRequire::Subset) && + max_flow < matrix.LhsSize()) { + if (listener->IsInterested()) { + *listener + << "where not all elements can be matched, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + + if (matches.size() > 1) { + if (listener->IsInterested()) { + const char* sep = "where:\n"; + for (size_t mi = 0; mi < matches.size(); ++mi) { + *listener << sep << " - element #" << matches[mi].first + << " is matched by matcher #" << matches[mi].second; + sep = ",\n"; + } + } + } + return true; +} + } // namespace internal } // namespace testing diff --git a/googlemock/test/gmock_link_test.h b/googlemock/test/gmock_link_test.h index 1f55f5bd..5f855d19 100644 --- a/googlemock/test/gmock_link_test.h +++ b/googlemock/test/gmock_link_test.h @@ -120,13 +120,15 @@ # include #endif -#include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" #include #include +#include "gtest/gtest.h" +#include "gtest/internal/gtest-port.h" + using testing::_; using testing::A; +using testing::Action; using testing::AllOf; using testing::AnyOf; using testing::Assign; @@ -148,6 +150,8 @@ using testing::Invoke; using testing::InvokeArgument; using testing::InvokeWithoutArgs; using testing::IsNull; +using testing::IsSubsetOf; +using testing::IsSupersetOf; using testing::Le; using testing::Lt; using testing::Matcher; @@ -592,6 +596,22 @@ TEST(LinkTest, TestMatcherElementsAreArray) { ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return()); } +// Tests the linkage of the IsSubsetOf matcher. +TEST(LinkTest, TestMatcherIsSubsetOf) { + Mock mock; + char arr[] = {'a', 'b'}; + + ON_CALL(mock, VoidFromVector(IsSubsetOf(arr))).WillByDefault(Return()); +} + +// Tests the linkage of the IsSupersetOf matcher. +TEST(LinkTest, TestMatcherIsSupersetOf) { + Mock mock; + char arr[] = {'a', 'b'}; + + ON_CALL(mock, VoidFromVector(IsSupersetOf(arr))).WillByDefault(Return()); +} + // Tests the linkage of the ContainerEq matcher. TEST(LinkTest, TestMatcherContainerEq) { Mock mock; From 250d4e8066609018efd2ad8f7e54d3ed8d331d9d Mon Sep 17 00:00:00 2001 From: Xiaoyi Zhang Date: Tue, 27 Feb 2018 16:00:42 -0500 Subject: [PATCH 48/59] Add documentation for VariantWith. --- googlemock/docs/CheatSheet.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/googlemock/docs/CheatSheet.md b/googlemock/docs/CheatSheet.md index c6367fdd..f8bbbfe6 100644 --- a/googlemock/docs/CheatSheet.md +++ b/googlemock/docs/CheatSheet.md @@ -178,6 +178,8 @@ divided into several categories: |`Ne(value)` |`argument != value`| |`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| |`NotNull()` |`argument` is a non-null pointer (raw or smart).| +|`VariantWith(m)` |`argument` is `variant<>` that holds the alternative of +type T with a value matching `m`.| |`Ref(variable)` |`argument` is a reference to `variable`.| |`TypedEq(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.| From e95050f496b68aeeaa6169deadcd03b6cdaa9269 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Mon, 26 Feb 2018 01:15:50 -0800 Subject: [PATCH 49/59] Support JSON output format in addition to XML This change allows emitting output in JSON format in addition to the already supported XML format. The implementation as well as the file structure is intentionally modelled after the XML one. --- googletest/CMakeLists.txt | 2 + googletest/docs/AdvancedGuide.md | 201 ++++++ googletest/src/gtest.cc | 375 ++++++++++- googletest/test/gtest_json_outfiles_test.py | 163 +++++ googletest/test/gtest_json_output_unittest.py | 612 ++++++++++++++++++ googletest/test/gtest_json_test_utils.py | 60 ++ 6 files changed, 1403 insertions(+), 10 deletions(-) create mode 100644 googletest/test/gtest_json_outfiles_test.py create mode 100644 googletest/test/gtest_json_output_unittest.py create mode 100644 googletest/test/gtest_json_test_utils.py diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt index 77b55cae..575353f4 100644 --- a/googletest/CMakeLists.txt +++ b/googletest/CMakeLists.txt @@ -306,7 +306,9 @@ if (gtest_build_tests) cxx_executable(gtest_xml_outfile1_test_ test gtest_main) cxx_executable(gtest_xml_outfile2_test_ test gtest_main) py_test(gtest_xml_outfiles_test) + py_test(gtest_json_outfiles_test) cxx_executable(gtest_xml_output_unittest_ test gtest) py_test(gtest_xml_output_unittest) + py_test(gtest_json_output_unittest) endif() diff --git a/googletest/docs/AdvancedGuide.md b/googletest/docs/AdvancedGuide.md index 6605f448..c1a1a4ab 100644 --- a/googletest/docs/AdvancedGuide.md +++ b/googletest/docs/AdvancedGuide.md @@ -2060,6 +2060,207 @@ Things to note: _Availability:_ Linux, Windows, Mac. +#### Generating an JSON Report {#JsonReport} + +gUnit can also emit a JSON report as an alternative format to XML. To generate +the JSON report, set the `GUNIT_OUTPUT` environment variable or the +`--gunit_output` flag to the string `"json:path_to_output_file"`, which will +create the file at the given location. You can also just use the string +`"json"`, in which case the output can be found in the `test_detail.json` file +in the current directory. + +The report format conforms to the following JSON Schema: + +```json +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "definitions": { + "TestCase": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "tests": { "type": "integer" }, + "failures": { "type": "integer" }, + "disabled": { "type": "integer" }, + "time": { "type": "string" }, + "testsuite": { + "type": "array", + "items": { + "$ref": "#/definitions/TestInfo" + } + } + } + }, + "TestInfo": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "status": { + "type": "string", + "enum": ["RUN", "NOTRUN"] + }, + "time": { "type": "string" }, + "classname": { "type": "string" }, + "failures": { + "type": "array", + "items": { + "$ref": "#/definitions/Failure" + } + } + } + }, + "Failure": { + "type": "object", + "properties": { + "failures": { "type": "string" }, + "type": { "type": "string" } + } + } + }, + "properties": { + "tests": { "type": "integer" }, + "failures": { "type": "integer" }, + "disabled": { "type": "integer" }, + "errors": { "type": "integer" }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "time": { "type": "string" }, + "name": { "type": "string" }, + "testsuites": { + "type": "array", + "items": { + "$ref": "#/definitions/TestCase" + } + } + } +} +``` + +The report uses the format that conforms to the following Proto3 using the +[JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json): + +```proto +syntax = "proto3"; + +package googletest; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; + +message UnitTest { + int32 tests = 1; + int32 failures = 2; + int32 disabled = 3; + int32 errors = 4; + google.protobuf.Timestamp timestamp = 5; + google.protobuf.Duration time = 6; + string name = 7; + repeated TestCase testsuites = 8; +} + +message TestCase { + string name = 1; + int32 tests = 2; + int32 failures = 3; + int32 disabled = 4; + int32 errors = 5; + google.protobuf.Duration time = 6; + repeated TestInfo testsuite = 7; +} + +message TestInfo { + string name = 1; + enum Status { + RUN = 0; + NOTRUN = 1; + } + Status status = 2; + google.protobuf.Duration time = 3; + string classname = 4; + message Failure { + string failures = 1; + string type = 2; + } + repeated Failure failures = 5; +} +``` + +For instance, the following program + +```c++ +TEST(MathTest, Addition) { ... } +TEST(MathTest, Subtraction) { ... } +TEST(LogicTest, NonContradiction) { ... } +``` + +could generate this report: + +```json +{ + "tests": 3, + "failures": 1, + "errors": 0, + "time": "0.035s", + "timestamp": "2011-10-31T18:52:42Z" + "name": "AllTests", + "testsuites": [ + { + "name": "MathTest", + "tests": 2, + "failures": 1, + "errors": 0, + "time": "0.015s", + "testsuite": [ + { + "name": "Addition", + "status": "RUN", + "time": "0.007s", + "classname": "", + "failures": [ + { + "message": "Value of: add(1, 1)\x0A Actual: 3\x0AExpected: 2", + "type": "" + }, + { + "message": "Value of: add(1, -1)\x0A Actual: 1\x0AExpected: 0", + "type": "" + } + ] + }, + { + "name": "Subtraction", + "status": "RUN", + "time": "0.005s", + "classname": "" + } + ] + } + { + "name": "LogicTest", + "tests": 1, + "failures": 0, + "errors": 0, + "time": "0.005s", + "testsuite": [ + { + "name": "NonContradiction", + "status": "RUN", + "time": "0.005s", + "classname": "" + } + ] + } + ] +} +``` + +IMPORTANT: The exact format of the JSON document is subject to change. + +**Availability**: Linux, Windows, Mac. + ## Controlling How Failures Are Reported ## ### Turning Assertion Failures into Break-Points ### diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 7afa5a95..15cc9073 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -160,8 +160,10 @@ static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; // A test filter that matches everything. static const char kUniversalFilter[] = "*"; -// The default output file for XML output. -static const char kDefaultOutputFile[] = "test_detail.xml"; +// The default output format. +static const char kDefaultOutputFormat[] = "xml"; +// The default output file. +static const char kDefaultOutputFile[] = "test_detail"; // The environment variable name for the test shard index. static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; @@ -231,9 +233,9 @@ GTEST_DEFINE_bool_(list_tests, false, GTEST_DEFINE_string_( output, internal::StringFromGTestEnv("output", ""), - "A format (currently must be \"xml\"), optionally followed " - "by a colon and an output file name or directory. A directory " - "is indicated by a trailing pathname separator. " + "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. " "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " "If a directory is specified, output files will be created " "within that directory, with file-names based on the test " @@ -428,12 +430,17 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() { if (gtest_output_flag == NULL) return ""; + std::string format = GetOutputFormat(); + if (format.empty()) + format = std::string(kDefaultOutputFormat); + const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) - return internal::FilePath::ConcatPaths( + return internal::FilePath::MakeFileName( internal::FilePath( UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(kDefaultOutputFile)).string(); + internal::FilePath(kDefaultOutputFile), 0, + format.c_str()).string(); internal::FilePath output_name(colon + 1); if (!output_name.IsAbsolutePath()) @@ -3771,6 +3778,351 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( // End XmlUnitTestResultPrinter +// This class generates an JSON output file. +class JsonUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit JsonUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Returns an JSON-escaped copy of the input string str. + static std::string EscapeJson(const std::string& str); + + //// Verifies that the given attribute belongs to the given element and + //// streams the attribute as JSON. + static void OutputJsonKey(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value, + const std::string& indent, + bool comma = true); + static void OutputJsonKey(std::ostream* stream, + const std::string& element_name, + const std::string& name, + int value, + const std::string& indent, + bool comma = true); + + // Streams a JSON representation of a TestInfo object. + static void OutputJsonTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints a JSON representation of a TestCase object + static void PrintJsonTestCase(::std::ostream* stream, + const TestCase& test_case); + + // Prints a JSON summary of unit_test to output stream out. + static void PrintJsonUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as + // a JSON dictionary. + static std::string TestPropertiesAsJson(const TestResult& result, + const std::string& indent); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter); +}; + +// Creates a new JsonUnitTestResultPrinter. +JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.empty()) { + GTEST_LOG_(FATAL) << "JSON output file may not be null"; + } +} + +void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* jsonout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + jsonout = posix::FOpen(output_file_.c_str(), "w"); + } + if (jsonout == NULL) { + // TODO(phosek): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + GTEST_LOG_(FATAL) << "Unable to open file \"" + << output_file_ << "\""; + } + std::stringstream stream; + PrintJsonUnitTest(&stream, unit_test); + fprintf(jsonout, "%s", StringStreamToString(&stream).c_str()); + fclose(jsonout); +} + +// Returns an JSON-escaped copy of the input string str. +std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '\\': + case '"': + case '/': + m << '\\' << ch; + break; + case '\b': + m << "\\b"; + break; + case '\t': + m << "\\t"; + break; + case '\n': + m << "\\n"; + break; + case '\f': + m << "\\f"; + break; + case '\r': + m << "\\r"; + break; + default: + if (ch < ' ') { + m << "\\u00" << String::FormatByte(static_cast(ch)); + } else { + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// The following routines generate an JSON representation of a UnitTest +// object. + +// Formats the given time in milliseconds as seconds. +static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) { + ::std::stringstream ss; + ss << (static_cast(ms) * 1e-3) << "s"; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the +// RFC3339 format, without the timezone information. +static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) { + struct tm time_struct; + if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) + return ""; + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec) + "Z"; +} + +static inline std::string Indent(int width) { + return std::string(width, ' '); +} + +void JsonUnitTestResultPrinter::OutputJsonKey( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value, + const std::string& indent, + bool comma) { + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Key \"" << name << "\" is not allowed for value \"" << element_name + << "\"."; + + *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\""; + if (comma) + *stream << ",\n"; +} + +void JsonUnitTestResultPrinter::OutputJsonKey( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + int value, + const std::string& indent, + bool comma) { + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Key \"" << name << "\" is not allowed for value \"" << element_name + << "\"."; + + *stream << indent << "\"" << name << "\": " << StreamableToString(value); + if (comma) + *stream << ",\n"; +} + +// Prints a JSON representation of a TestInfo object. +void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestcase = "testcase"; + const std::string kIndent = Indent(10); + + *stream << Indent(8) << "{\n"; + OutputJsonKey(stream, kTestcase, "name", test_info.name(), kIndent); + + if (test_info.value_param() != NULL) { + OutputJsonKey(stream, kTestcase, "value_param", + test_info.value_param(), kIndent); + } + if (test_info.type_param() != NULL) { + OutputJsonKey(stream, kTestcase, "type_param", test_info.type_param(), + kIndent); + } + + OutputJsonKey(stream, kTestcase, "status", + test_info.should_run() ? "RUN" : "NOTRUN", kIndent); + OutputJsonKey(stream, kTestcase, "time", + FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent); + OutputJsonKey(stream, kTestcase, "classname", test_case_name, kIndent, false); + *stream << TestPropertiesAsJson(result, kIndent); + + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) { + *stream << ",\n"; + if (++failures == 1) { + *stream << kIndent << "\"" << "failures" << "\": [\n"; + } + const std::string location = + internal::FormatCompilerIndependentFileLocation(part.file_name(), + part.line_number()); + const std::string summary = EscapeJson(location + "\n" + part.summary()); + *stream << kIndent << " {\n" + << kIndent << " \"failure\": \"" << summary << "\",\n" + << kIndent << " \"type\": \"\"\n" + << kIndent << " }"; + } + } + + if (failures > 0) + *stream << "\n" << kIndent << "]"; + *stream << "\n" << Indent(8) << "}"; +} + +// Prints an JSON representation of a TestCase object +void JsonUnitTestResultPrinter::PrintJsonTestCase(std::ostream* stream, + const TestCase& test_case) { + const std::string kTestsuite = "testsuite"; + const std::string kIndent = Indent(6); + + *stream << Indent(4) << "{\n"; + OutputJsonKey(stream, kTestsuite, "name", test_case.name(), kIndent); + OutputJsonKey(stream, kTestsuite, "tests", test_case.reportable_test_count(), + kIndent); + OutputJsonKey(stream, kTestsuite, "failures", test_case.failed_test_count(), + kIndent); + OutputJsonKey(stream, kTestsuite, "disabled", + test_case.reportable_disabled_test_count(), kIndent); + OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent); + OutputJsonKey(stream, kTestsuite, "time", + FormatTimeInMillisAsDuration(test_case.elapsed_time()), kIndent, + false); + *stream << TestPropertiesAsJson(test_case.ad_hoc_test_result(), kIndent) + << ",\n"; + + *stream << kIndent << "\"" << kTestsuite << "\": [\n"; + + bool comma = false; + for (int i = 0; i < test_case.total_test_count(); ++i) { + if (test_case.GetTestInfo(i)->is_reportable()) { + if (comma) { + *stream << ",\n"; + } else { + comma = true; + } + OutputJsonTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); + } + } + *stream << "\n" << kIndent << "]\n" << Indent(4) << "}"; +} + +// Prints a JSON summary of unit_test to output stream out. +void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + const std::string kIndent = Indent(2); + *stream << "{\n"; + + OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(), + kIndent); + OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(), + kIndent); + OutputJsonKey(stream, kTestsuites, "disabled", + unit_test.reportable_disabled_test_count(), kIndent); + OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent); + if (GTEST_FLAG(shuffle)) { + OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(), + kIndent); + } + OutputJsonKey(stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()), + kIndent); + OutputJsonKey(stream, kTestsuites, "time", + FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent, + false); + + *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent) + << ",\n"; + + OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); + *stream << kIndent << "\"" << kTestsuites << "\": [\n"; + + bool comma = false; + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + if (unit_test.GetTestCase(i)->reportable_test_count() > 0) { + if (comma) { + *stream << ",\n"; + } else { + comma = true; + } + PrintJsonTestCase(stream, *unit_test.GetTestCase(i)); + } + } + + *stream << "\n" << kIndent << "]\n" << "}\n"; +} + +// Produces a string representing the test properties in a result as +// a JSON dictionary. +std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( + const TestResult& result, const std::string& indent) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << ",\n" << indent << "\"" << property.key() << "\": " + << "\"" << EscapeJson(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End JsonUnitTestResultPrinter + #if GTEST_CAN_STREAM_RESULTS_ // Checks if str contains '=', '&', '%' or '\n' characters. If yes, @@ -4397,6 +4749,9 @@ void UnitTestImpl::ConfigureXmlOutput() { if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format == "json") { + listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" << output_format << "\" ignored."; @@ -5182,10 +5537,10 @@ static const char kColorEncodedHelpMessage[] = " Enable/disable colored output. The default is @Gauto@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=xml@Y[@G:@YDIRECTORY_PATH@G" +" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" -" Generate an XML report in the given directory or with the given file\n" -" name. @YFILE_PATH@D defaults to @Gtest_detail.xml@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_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" diff --git a/googletest/test/gtest_json_outfiles_test.py b/googletest/test/gtest_json_outfiles_test.py new file mode 100644 index 00000000..62ad18e7 --- /dev/null +++ b/googletest/test/gtest_json_outfiles_test.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python +# Copyright 2018, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for the gtest_json_output module.""" + +import json +import os +import gtest_test_utils +import gtest_json_test_utils + + +GTEST_OUTPUT_SUBDIR = 'json_outfiles' +GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_' +GTEST_OUTPUT_2_TEST = 'gtest_xml_outfile2_test_' + +EXPECTED_1 = { + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'timestamp': u'*', + u'name': u'AllTests', + u'testsuites': [{ + u'name': u'PropertyOne', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [{ + u'name': u'TestSomeProperties', + u'status': u'RUN', + u'time': u'*', + u'classname': u'PropertyOne', + u'SetUpProp': u'1', + u'TestSomeProperty': u'1', + u'TearDownProp': u'1', + }], + }], +} + +EXPECTED_2 = { + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'timestamp': u'*', + u'name': u'AllTests', + u'testsuites': [{ + u'name': u'PropertyTwo', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [{ + u'name': u'TestSomeProperties', + u'status': u'RUN', + u'time': u'*', + u'classname': u'PropertyTwo', + u'SetUpProp': u'2', + u'TestSomeProperty': u'2', + u'TearDownProp': u'2', + }], + }], +} + + +class GTestJsonOutFilesTest(gtest_test_utils.TestCase): + """Unit test for Google Test's JSON output functionality.""" + + def setUp(self): + # We want the trailing '/' that the last "" provides in os.path.join, for + # telling Google Test to create an output directory instead of a single file + # for xml output. + self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_OUTPUT_SUBDIR, '') + self.DeleteFilesAndDir() + + def tearDown(self): + self.DeleteFilesAndDir() + + def DeleteFilesAndDir(self): + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + '.json')) + except os.error: + pass + try: + os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + '.json')) + except os.error: + pass + try: + os.rmdir(self.output_dir_) + except os.error: + pass + + def testOutfile1(self): + self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_1) + + def testOutfile2(self): + self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_2) + + def _TestOutFile(self, test_name, expected): + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) + command = [gtest_prog_path, '--gtest_output=json:%s' % self.output_dir_] + p = gtest_test_utils.Subprocess(command, + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + + # TODO(wan@google.com): libtool causes the built test binary to be + # named lt-gtest_xml_outfiles_test_ instead of + # gtest_xml_outfiles_test_. To account for this possibility, we + # allow both names in the following code. We should remove this + # hack when Chandler Carruth's libtool replacement tool is ready. + output_file_name1 = test_name + '.json' + output_file1 = os.path.join(self.output_dir_, output_file_name1) + output_file_name2 = 'lt-' + output_file_name1 + output_file2 = os.path.join(self.output_dir_, output_file_name2) + self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), + output_file1) + + if os.path.isfile(output_file1): + with open(output_file1) as f: + actual = json.load(f) + else: + with open(output_file2) as f: + actual = json.load(f) + self.assertEqual(expected, gtest_json_test_utils.normalize(actual)) + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '0' + gtest_test_utils.Main() diff --git a/googletest/test/gtest_json_output_unittest.py b/googletest/test/gtest_json_output_unittest.py new file mode 100644 index 00000000..4d23c3ab --- /dev/null +++ b/googletest/test/gtest_json_output_unittest.py @@ -0,0 +1,612 @@ +#!/usr/bin/env python +# Copyright 2018, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test for the gtest_json_output module.""" + +import datetime +import errno +import json +import os +import re +import sys + +import gtest_test_utils +import gtest_json_test_utils + + +GTEST_FILTER_FLAG = '--gtest_filter' +GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json' +GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_' + +SUPPORTS_STACK_TRACES = False + +if SUPPORTS_STACK_TRACES: + STACK_TRACE_TEMPLATE = '\nStack trace:\n*' +else: + STACK_TRACE_TEMPLATE = '' + +EXPECTED_NON_EMPTY = { + u'tests': 23, + u'failures': 4, + u'disabled': 2, + u'errors': 0, + u'timestamp': u'*', + u'time': u'*', + u'ad_hoc_property': u'42', + u'name': u'AllTests', + u'testsuites': [ + { + u'name': u'SuccessfulTest', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'Succeeds', + u'status': u'RUN', + u'time': u'*', + u'classname': u'SuccessfulTest' + } + ] + }, + { + u'name': u'FailedTest', + u'tests': 1, + u'failures': 1, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'Fails', + u'status': u'RUN', + u'time': u'*', + u'classname': u'FailedTest', + u'failures': [ + { + u'failure': + u'gtest_xml_output_unittest_.cc:*\n' + u'Expected equality of these values:\n' + u' 1\n 2' + STACK_TRACE_TEMPLATE, + u'type': u'' + } + ] + } + ] + }, + { + u'name': u'DisabledTest', + u'tests': 1, + u'failures': 0, + u'disabled': 1, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'DISABLED_test_not_run', + u'status': u'NOTRUN', + u'time': u'*', + u'classname': u'DisabledTest' + } + ] + }, + { + u'name': u'MixedResultTest', + u'tests': 3, + u'failures': 1, + u'disabled': 1, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'Succeeds', + u'status': u'RUN', + u'time': u'*', + u'classname': u'MixedResultTest' + }, + { + u'name': u'Fails', + u'status': u'RUN', + u'time': u'*', + u'classname': u'MixedResultTest', + u'failures': [ + { + u'failure': + u'gtest_xml_output_unittest_.cc:*\n' + u'Expected equality of these values:\n' + u' 1\n 2' + STACK_TRACE_TEMPLATE, + u'type': u'' + }, + { + u'failure': + u'gtest_xml_output_unittest_.cc:*\n' + u'Expected equality of these values:\n' + u' 2\n 3' + STACK_TRACE_TEMPLATE, + u'type': u'' + } + ] + }, + { + u'name': u'DISABLED_test', + u'status': u'NOTRUN', + u'time': u'*', + u'classname': u'MixedResultTest' + } + ] + }, + { + u'name': u'XmlQuotingTest', + u'tests': 1, + u'failures': 1, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'OutputsCData', + u'status': u'RUN', + u'time': u'*', + u'classname': u'XmlQuotingTest', + u'failures': [ + { + u'failure': + u'gtest_xml_output_unittest_.cc:*\n' + u'Failed\nXML output: ' + u'' + + STACK_TRACE_TEMPLATE, + u'type': u'' + } + ] + } + ] + }, + { + u'name': u'InvalidCharactersTest', + u'tests': 1, + u'failures': 1, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'InvalidCharactersInMessage', + u'status': u'RUN', + u'time': u'*', + u'classname': u'InvalidCharactersTest', + u'failures': [ + { + u'failure': + u'gtest_xml_output_unittest_.cc:*\n' + u'Failed\nInvalid characters in brackets' + u' [\x01\x02]' + STACK_TRACE_TEMPLATE, + u'type': u'' + } + ] + } + ] + }, + { + u'name': u'PropertyRecordingTest', + u'tests': 4, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'SetUpTestCase': u'yes', + u'TearDownTestCase': u'aye', + u'testsuite': [ + { + u'name': u'OneProperty', + u'status': u'RUN', + u'time': u'*', + u'classname': u'PropertyRecordingTest', + u'key_1': u'1' + }, + { + u'name': u'IntValuedProperty', + u'status': u'RUN', + u'time': u'*', + u'classname': u'PropertyRecordingTest', + u'key_int': u'1' + }, + { + u'name': u'ThreeProperties', + u'status': u'RUN', + u'time': u'*', + u'classname': u'PropertyRecordingTest', + u'key_1': u'1', + u'key_2': u'2', + u'key_3': u'3' + }, + { + u'name': u'TwoValuesForOneKeyUsesLastValue', + u'status': u'RUN', + u'time': u'*', + u'classname': u'PropertyRecordingTest', + u'key_1': u'2' + } + ] + }, + { + u'name': u'NoFixtureTest', + u'tests': 3, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'RecordProperty', + u'status': u'RUN', + u'time': u'*', + u'classname': u'NoFixtureTest', + u'key': u'1' + }, + { + u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty', + u'status': u'RUN', + u'time': u'*', + u'classname': u'NoFixtureTest', + u'key_for_utility_int': u'1' + }, + { + u'name': + u'ExternalUtilityThatCallsRecordStringValuedProperty', + u'status': u'RUN', + u'time': u'*', + u'classname': u'NoFixtureTest', + u'key_for_utility_string': u'1' + } + ] + }, + { + u'name': u'TypedTest/0', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'HasTypeParamAttribute', + u'type_param': u'int', + u'status': u'RUN', + u'time': u'*', + u'classname': u'TypedTest/0' + } + ] + }, + { + u'name': u'TypedTest/1', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'HasTypeParamAttribute', + u'type_param': u'long', + u'status': u'RUN', + u'time': u'*', + u'classname': u'TypedTest/1' + } + ] + }, + { + u'name': u'Single/TypeParameterizedTestCase/0', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'HasTypeParamAttribute', + u'type_param': u'int', + u'status': u'RUN', + u'time': u'*', + u'classname': u'Single/TypeParameterizedTestCase/0' + } + ] + }, + { + u'name': u'Single/TypeParameterizedTestCase/1', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'HasTypeParamAttribute', + u'type_param': u'long', + u'status': u'RUN', + u'time': u'*', + u'classname': u'Single/TypeParameterizedTestCase/1' + } + ] + }, + { + u'name': u'Single/ValueParamTest', + u'tests': 4, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [ + { + u'name': u'HasValueParamAttribute/0', + u'value_param': u'33', + u'status': u'RUN', + u'time': u'*', + u'classname': u'Single/ValueParamTest' + }, + { + u'name': u'HasValueParamAttribute/1', + u'value_param': u'42', + u'status': u'RUN', + u'time': u'*', + u'classname': u'Single/ValueParamTest' + }, + { + u'name': u'AnotherTestThatHasValueParamAttribute/0', + u'value_param': u'33', + u'status': u'RUN', + u'time': u'*', + u'classname': u'Single/ValueParamTest' + }, + { + u'name': u'AnotherTestThatHasValueParamAttribute/1', + u'value_param': u'42', + u'status': u'RUN', + u'time': u'*', + u'classname': u'Single/ValueParamTest' + } + ] + } + ] +} + +EXPECTED_FILTERED = { + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'timestamp': u'*', + u'name': u'AllTests', + u'ad_hoc_property': u'42', + u'testsuites': [{ + u'name': u'SuccessfulTest', + u'tests': 1, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'testsuite': [{ + u'name': u'Succeeds', + u'status': u'RUN', + u'time': u'*', + u'classname': u'SuccessfulTest', + }] + }], +} + +EXPECTED_EMPTY = { + u'tests': 0, + u'failures': 0, + u'disabled': 0, + u'errors': 0, + u'time': u'*', + u'timestamp': u'*', + u'name': u'AllTests', + u'testsuites': [], +} + +GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + +SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( + [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output + + +class GTestJsonOutputUnitTest(gtest_test_utils.TestCase): + """Unit test for Google Test's JSON output functionality. + """ + + # This test currently breaks on platforms that do not support typed and + # type-parameterized tests, so we don't run it under them. + if SUPPORTS_TYPED_TESTS: + + def testNonEmptyJsonOutput(self): + """Verifies JSON output for a Google Test binary with non-empty output. + + Runs a test program that generates a non-empty JSON output, and + tests that the JSON output is expected. + """ + self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1) + + def testEmptyJsonOutput(self): + """Verifies JSON output for a Google Test binary without actual tests. + + Runs a test program that generates an empty JSON output, and + tests that the JSON output is expected. + """ + + self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0) + + def testTimestampValue(self): + """Checks whether the timestamp attribute in the JSON output is valid. + + Runs a test program that generates an empty JSON output, and checks if + the timestamp attribute in the testsuites tag is valid. + """ + actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0) + date_time_str = actual['timestamp'] + # datetime.strptime() is only available in Python 2.5+ so we have to + # parse the expected datetime manually. + match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) + self.assertTrue( + re.match, + 'JSON datettime string %s has incorrect format' % date_time_str) + date_time_from_json = datetime.datetime( + year=int(match.group(1)), month=int(match.group(2)), + day=int(match.group(3)), hour=int(match.group(4)), + minute=int(match.group(5)), second=int(match.group(6))) + + time_delta = abs(datetime.datetime.now() - date_time_from_json) + # timestamp value should be near the current local time + self.assertTrue(time_delta < datetime.timedelta(seconds=600), + 'time_delta is %s' % time_delta) + + def testDefaultOutputFile(self): + """Verifies the default output file name. + + Confirms that Google Test produces an JSON output file with the expected + default name if no name is explicitly specified. + """ + output_file = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_DEFAULT_OUTPUT_FILE) + gtest_prog_path = gtest_test_utils.GetTestExecutablePath( + 'gtest_no_test_unittest') + try: + os.remove(output_file) + except OSError: + e = sys.exc_info()[1] + if e.errno != errno.ENOENT: + raise + + p = gtest_test_utils.Subprocess( + [gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG], + working_dir=gtest_test_utils.GetTempDir()) + self.assert_(p.exited) + self.assertEquals(0, p.exit_code) + self.assert_(os.path.isfile(output_file)) + + def testSuppressedJsonOutput(self): + """Verifies that no JSON output is generated. + + Tests that no JSON file is generated if the default JSON listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + json_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + 'out.json') + if os.path.isfile(json_path): + os.remove(json_path) + + command = [GTEST_PROGRAM_PATH, + '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path), + '--shut_down_xml'] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + # p.signal is available only if p.terminated_by_signal is True. + self.assertFalse( + p.terminated_by_signal, + '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(json_path)) + + def testFilteredTestJsonOutput(self): + """Verifies JSON output when a filter is applied. + + Runs a test program that executes only some tests and verifies that + non-selected tests do not show up in the JSON output. + """ + + self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED, 0, + extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) + + def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code): + """Returns the JSON output generated by running the program gtest_prog_name. + + Furthermore, the program's exit code must be expected_exit_code. + + Args: + gtest_prog_name: Google Test binary name. + extra_args: extra arguments to binary invocation. + expected_exit_code: program's exit code. + """ + json_path = os.path.join(gtest_test_utils.GetTempDir(), + gtest_prog_name + 'out.json') + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) + + command = ( + [gtest_prog_path, '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path)] + + extra_args + ) + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + '%s was killed by signal %d' % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(expected_exit_code, p.exit_code, + "'%s' exited with code %s, which doesn't match " + 'the expected exit code %s.' + % (command, p.exit_code, expected_exit_code)) + with open(json_path) as f: + actual = json.load(f) + return actual + + def _TestJsonOutput(self, gtest_prog_name, expected, + expected_exit_code, extra_args=None): + """Checks the JSON output generated by the Google Test binary. + + Asserts that the JSON document generated by running the program + gtest_prog_name matches expected_json, a string containing another + JSON document. Furthermore, the program's exit code must be + expected_exit_code. + + Args: + gtest_prog_name: Google Test binary name. + expected: expected output. + expected_exit_code: program's exit code. + extra_args: extra arguments to binary invocation. + """ + + actual = self._GetJsonOutput(gtest_prog_name, extra_args or [], + expected_exit_code) + self.assertEqual(expected, gtest_json_test_utils.normalize(actual)) + + +if __name__ == '__main__': + os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' + gtest_test_utils.Main() diff --git a/googletest/test/gtest_json_test_utils.py b/googletest/test/gtest_json_test_utils.py new file mode 100644 index 00000000..4ef5f6fc --- /dev/null +++ b/googletest/test/gtest_json_test_utils.py @@ -0,0 +1,60 @@ +# Copyright 2018, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test utilities for gtest_json_output.""" + +import re + + +def normalize(obj): + """Normalize output object. + + Args: + obj: Google Test's JSON output object to normalize. + + Returns: + Normalized output without any references to transient information that may + change from run to run. + """ + def _normalize(key, value): + if key == 'time': + return re.sub(r'^\d+(\.\d+)?s$', u'*', value) + elif key == 'timestamp': + return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value) + elif key == 'failure': + value = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', value) + return re.sub(r'Stack trace:\n(.|\n)*', 'Stack trace:\n*', value) + else: + return normalize(value) + if isinstance(obj, dict): + return {k: _normalize(k, v) for k, v in obj.items()} + if isinstance(obj, list): + return [normalize(x) for x in obj] + else: + return obj From ed90bec3114d266f7aeee1156c0d8d73b680b8d0 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Wed, 28 Feb 2018 11:28:57 -0500 Subject: [PATCH 50/59] Add options to parallelize builds. AppVeyor build servers have two cores, so why not use them? --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 8d9cc64f..84d9fbce 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -72,7 +72,8 @@ build_script: if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } - & cmake --build . --config $env:configuration + $cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"} + & cmake --build . --config $env:configuration -- $cmake_parallel if ($LastExitCode -ne 0) { throw "Exec: $ErrorMessage" } From 1c8ca09f0117bfefe88ac9db593f3fe18290afc5 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Thu, 1 Mar 2018 13:19:34 -0800 Subject: [PATCH 51/59] Use a full message in the JSON output for failures The full message unlike summary also includes stack trace. --- googletest/src/gtest.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 15cc9073..74c43a41 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -4012,9 +4012,9 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, const std::string location = internal::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number()); - const std::string summary = EscapeJson(location + "\n" + part.summary()); + const std::string message = EscapeJson(location + "\n" + part.message()); *stream << kIndent << " {\n" - << kIndent << " \"failure\": \"" << summary << "\",\n" + << kIndent << " \"failure\": \"" << message << "\",\n" << kIndent << " \"type\": \"\"\n" << kIndent << " }"; } From 78797f38efb39d67db35da19262f43d9a2a3351b Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 5 Mar 2018 12:26:15 -0500 Subject: [PATCH 52/59] Merges-1 --- .../gmock/internal/custom/gmock-matchers.h | 7 +++---- googlemock/test/gmock_link_test.h | 2 ++ .../internal/gtest-death-test-internal.h | 20 +++++++++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/googlemock/include/gmock/internal/custom/gmock-matchers.h b/googlemock/include/gmock/internal/custom/gmock-matchers.h index f2efef91..fe0d9e84 100644 --- a/googlemock/include/gmock/internal/custom/gmock-matchers.h +++ b/googlemock/include/gmock/internal/custom/gmock-matchers.h @@ -33,7 +33,6 @@ // // Adds google3 callback support to CallableTraits. // -#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ - -#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ diff --git a/googlemock/test/gmock_link_test.h b/googlemock/test/gmock_link_test.h index 5f855d19..06a1cf89 100644 --- a/googlemock/test/gmock_link_test.h +++ b/googlemock/test/gmock_link_test.h @@ -90,8 +90,10 @@ // Field // Property // ResultOf(function) +// ResultOf(callback) // Pointee // Truly(predicate) +// AddressSatisfies // AllOf // AnyOf // Not diff --git a/googletest/include/gtest/internal/gtest-death-test-internal.h b/googletest/include/gtest/internal/gtest-death-test-internal.h index a9e66106..88e7799c 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(gtest_regex); \ + } else \ ::testing::Message() // A class representing the parsed contents of the From ffd5d36f593c21f5f896bd841eac151a033b0806 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 5 Mar 2018 13:28:13 -0500 Subject: [PATCH 53/59] merges-2 --- googlemock/src/gmock-internal-utils.cc | 14 ++++++++++++-- googlemock/src/gmock.cc | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 658fa62d..20c5a8db 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -70,8 +70,8 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields) { // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // treated as one word. For example, both "FooBar123" and // "foo_bar_123" are converted to "foo bar 123". -GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { - string result; +GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { + std::string result; char prev_char = '\0'; for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { // We don't care about the current locale as the input is @@ -188,5 +188,15 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message, std::cout << ::std::flush; } +void IllegalDoDefault(const char* file, int line) { + internal::Assert( + false, file, line, + "You are using DoDefault() inside a composite action like " + "DoAll() or WithArgs(). This is not supported for technical " + "reasons. Please instead spell out the default action, or " + "assign the default action to an Action variable and use " + "the variable in various places."); +} + } // namespace internal } // namespace testing diff --git a/googlemock/src/gmock.cc b/googlemock/src/gmock.cc index 3c370510..2308168b 100644 --- a/googlemock/src/gmock.cc +++ b/googlemock/src/gmock.cc @@ -136,8 +136,8 @@ static bool ParseGoogleMockIntFlag(const char* str, const char* flag, if (value_str == NULL) return false; // Sets *value to the value of the flag. - *value = atoi(value_str); - return true; + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); } // The internal implementation of InitGoogleMock(). From 193af9ad369d9914b1d422238f3726a3d43b64a6 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 5 Mar 2018 13:51:39 -0500 Subject: [PATCH 54/59] merges-3 --- googletest/test/gtest-printers_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index 60a8d037..cd7c5d34 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -239,7 +239,7 @@ 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 From b39f4ff8d0f08c5d2de5cba58591bffbe6a54ab0 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 5 Mar 2018 14:21:41 -0500 Subject: [PATCH 55/59] merges-6 --- googletest/test/gtest_json_outfiles_test.py | 3 +-- googletest/test/gtest_json_output_unittest.py | 3 +-- googletest/test/gtest_json_test_utils.py | 2 +- googletest/test/gtest_test_utils.py | 2 +- googletest/test/gtest_uninitialized_test.py | 1 - 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/googletest/test/gtest_json_outfiles_test.py b/googletest/test/gtest_json_outfiles_test.py index 62ad18e7..46010d89 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 4d23c3ab..12047c4f 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 4ef5f6fc..62bbfc28 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 cc4ba649..7c489336 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 574db77a..ae91f2aa 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_') From 23d6041c404eeaec7c12c1e7ed0beb4c824b713b Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 5 Mar 2018 15:21:48 -0500 Subject: [PATCH 56/59] merges-7 --- googletest/src/gtest.cc | 66 +++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 74c43a41..473a666e 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -2912,16 +2912,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 +2986,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); @@ -3749,7 +3752,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"); @@ -4210,9 +4212,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 +4226,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 +4905,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 +5034,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 +5094,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 +5102,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 +5111,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); } @@ -5361,8 +5378,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; @@ -5535,7 +5551,7 @@ 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" From 7ee36bdbeaaf9a625eadaac7a2ea579c315cb33c Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 5 Mar 2018 15:53:36 -0500 Subject: [PATCH 57/59] merges-8 --- .../include/gtest/internal/gtest-port.h | 14 +++++--- googletest/src/gtest-port.cc | 34 +++++++++++++------ googletest/src/gtest.cc | 26 +++++++------- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 4d5aa043..97206bea 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -1537,14 +1537,18 @@ GTEST_API_ size_t GetFileSize(FILE* file); GTEST_API_ std::string ReadEntireFile(FILE* file); // All command line arguments. -GTEST_API_ const ::std::vector& GetArgvs(); +GTEST_API_ std::vector GetArgvs(); #if GTEST_HAS_DEATH_TEST -const ::std::vector& GetInjectableArgvs(); -void SetInjectableArgvs(const ::std::vector* - new_argvs); - +std::vector GetInjectableArgvs(); +// Deprecated: pass the args vector by value instead. +void SetInjectableArgvs(const std::vector* new_argvs); +void SetInjectableArgvs(const std::vector& 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 diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index af0d120a..99791f9c 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* g_injected_test_argvs = NULL; // Owned. -static const ::std::vector* g_injected_test_argvs = - NULL; // Owned. - -void SetInjectableArgvs(const ::std::vector* argvs) { - if (g_injected_test_argvs != argvs) - delete g_injected_test_argvs; - g_injected_test_argvs = argvs; -} - -const ::std::vector& GetInjectableArgvs() { +std::vector GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return GetArgvs(); } + +void SetInjectableArgvs(const std::vector* 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& new_argvs) { + SetInjectableArgvs( + new std::vector(new_argvs.begin(), new_argvs.end())); +} + +#if GTEST_HAS_GLOBAL_STRING +void SetInjectableArgvs(const std::vector< ::string>& new_argvs) { + SetInjectableArgvs( + new std::vector(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 diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 473a666e..3384c024 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -386,12 +386,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 g_argvs; +::std::vector g_argvs; -const ::std::vector& GetArgvs() { +::std::vector 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(custom.begin(), custom.end()); +#else // defined(GTEST_CUSTOM_GET_ARGVS_) return g_argvs; #endif // defined(GTEST_CUSTOM_GET_ARGVS_) } @@ -3035,7 +3038,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()"; @@ -5449,9 +5452,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 +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); @@ -5557,16 +5559,16 @@ static const char kColorEncodedHelpMessage[] = 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" From 744688e8bc1edb3c36b1861105f4680028565904 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Wed, 7 Mar 2018 15:57:55 -0500 Subject: [PATCH 58/59] Merging, XML tests --- googletest/src/gtest.cc | 39 +++++++++++++-- googletest/test/gtest_xml_outfiles_test.py | 16 ++++++- googletest/test/gtest_xml_output_unittest.py | 50 ++++++++++++++++---- googletest/test/gtest_xml_test_utils.py | 35 +++++++++----- 4 files changed, 114 insertions(+), 26 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 3384c024..74df5492 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -3448,6 +3448,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_; @@ -3659,6 +3664,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 << " \n"; - else + } else { + if (failures == 0) { + *stream << ">\n"; + } + OutputXmlTestProperties(stream, result); *stream << " \n"; + } } // Prints an XML representation of a TestCase object @@ -3780,6 +3793,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 << "\n"; +} + // End XmlUnitTestResultPrinter diff --git a/googletest/test/gtest_xml_outfiles_test.py b/googletest/test/gtest_xml_outfiles_test.py index 24c6ee6b..c7d34134 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 = """ - + + + + + + + """ @@ -51,7 +57,13 @@ EXPECTED_XML_1 = """ EXPECTED_XML_2 = """ - + + + + + + + """ diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py index 325ca131..6ffb6e3f 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]]> - - - - + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + @@ -149,7 +179,11 @@ EXPECTED_SHARDED_TEST_XML = """ - + + + + + diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py index d303425c..1e035859 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 , and elements, the ID - is the value of their "name" attribute; for elements, it is - the value of the "message" attribute; CDATA sections and non-whitespace + children. For , , , and + elements, the ID is the value of their "name" attribute; for + elements, it is the value of the "message" attribute; for + 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 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 From 2cb5677ab7b93a9419efefd46e17336699f04aed Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Mon, 12 Mar 2018 11:51:44 -0400 Subject: [PATCH 59/59] merges-port(1) --- .../include/gtest/internal/gtest-port.h | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 97206bea..7a10d903 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -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 @@ -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 @@ -2635,15 +2644,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_) @@ -2669,7 +2678,6 @@ GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); std::string StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal - } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_