Commit 6d089311 authored by Tanzinul Islam's avatar Tanzinul Islam
Browse files

Merge branch 'fix_death_test_child_mingw_wer_issue1116' of...

Merge branch 'fix_death_test_child_mingw_wer_issue1116' of https://github.com/tanzislam/googletest into fix_death_test_child_mingw_wer_issue1116
parents 555e6e79 a7a7f51d
...@@ -42,11 +42,7 @@ ...@@ -42,11 +42,7 @@
# include <string> # include <string>
# include <vector> # include <vector>
// To include gtest-internal-inl.h.
# define GTEST_IMPLEMENTATION_ 1
# include "src/gtest-internal-inl.h" // for UnitTestOptions # include "src/gtest-internal-inl.h" // for UnitTestOptions
# undef GTEST_IMPLEMENTATION_
# include "test/gtest-param-test_test.h" # include "test/gtest-param-test_test.h"
using ::std::vector; using ::std::vector;
...@@ -540,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) { ...@@ -540,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
VerifyGenerator(gen, expected_values); VerifyGenerator(gen, expected_values);
} }
#if GTEST_LANG_CXX11
class NonDefaultConstructAssignString {
public:
NonDefaultConstructAssignString(const std::string& s) : str_(s) {}
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<tuple<int, NonDefaultConstructAssignString> > gen =
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
NonDefaultConstructAssignString("B")));
ParamGenerator<tuple<int, NonDefaultConstructAssignString> >::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_LANG_CXX11
# endif // GTEST_HAS_COMBINE # endif // GTEST_HAS_COMBINE
// Tests that an generator produces correct sequence after being // Tests that an generator produces correct sequence after being
...@@ -815,8 +856,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {}; ...@@ -815,8 +856,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {};
TEST_P(CustomFunctorNamingTest, CustomTestNames) {} TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
struct CustomParamNameFunctor { struct CustomParamNameFunctor {
std::string operator()(const ::testing::TestParamInfo<std::string>& info) { std::string operator()(const ::testing::TestParamInfo<std::string>& inf) {
return info.param; return inf.param;
} }
}; };
...@@ -833,8 +874,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters, ...@@ -833,8 +874,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters,
CustomParamNameFunctor()); CustomParamNameFunctor());
inline std::string CustomParamNameFunction( inline std::string CustomParamNameFunction(
const ::testing::TestParamInfo<std::string>& info) { const ::testing::TestParamInfo<std::string>& inf) {
return info.param; return inf.param;
} }
class CustomFunctionNamingTest : public TestWithParam<std::string> {}; class CustomFunctionNamingTest : public TestWithParam<std::string> {};
...@@ -852,11 +893,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction, ...@@ -852,11 +893,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction,
class CustomLambdaNamingTest : public TestWithParam<std::string> {}; class CustomLambdaNamingTest : public TestWithParam<std::string> {};
TEST_P(CustomLambdaNamingTest, CustomTestNames) {} TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest,
CustomLambdaNamingTest,
Values(std::string("LambdaName")), Values(std::string("LambdaName")),
[](const ::testing::TestParamInfo<std::string>& tpinfo) { [](const ::testing::TestParamInfo<std::string>& inf) {
return tpinfo.param; return inf.param;
}); });
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
...@@ -1023,6 +1063,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { ...@@ -1023,6 +1063,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
int main(int argc, char **argv) { int main(int argc, char **argv) {
// Used in TestGenerationTest test case. // Used in TestGenerationTest test case.
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
......
...@@ -45,15 +45,7 @@ ...@@ -45,15 +45,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// their code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
using std::make_pair; using std::make_pair;
using std::pair; using std::pair;
...@@ -75,8 +67,8 @@ TEST(IsXDigitTest, WorksForNarrowAscii) { ...@@ -75,8 +67,8 @@ TEST(IsXDigitTest, WorksForNarrowAscii) {
} }
TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
EXPECT_FALSE(IsXDigit('\x80')); EXPECT_FALSE(IsXDigit(static_cast<char>(0x80)));
EXPECT_FALSE(IsXDigit(static_cast<char>('0' | '\x80'))); EXPECT_FALSE(IsXDigit(static_cast<char>('0' | 0x80)));
} }
TEST(IsXDigitTest, WorksForWideAscii) { TEST(IsXDigitTest, WorksForWideAscii) {
......
...@@ -52,13 +52,13 @@ ...@@ -52,13 +52,13 @@
// hash_map and hash_set are available under Visual C++, or on Linux. // hash_map and hash_set are available under Visual C++, or on Linux.
#if GTEST_HAS_UNORDERED_MAP_ #if GTEST_HAS_UNORDERED_MAP_
# include <unordered_map> // NOLINT # include <unordered_map> // NOLINT
#elif GTEST_HAS_HASH_MAP_ #elif GTEST_HAS_HASH_MAP_
# include <hash_map> // NOLINT # include <hash_map> // NOLINT
#endif // GTEST_HAS_HASH_MAP_ #endif // GTEST_HAS_HASH_MAP_
#if GTEST_HAS_UNORDERED_SET_ #if GTEST_HAS_UNORDERED_SET_
# include <unordered_set> // NOLINT # include <unordered_set> // NOLINT
#elif GTEST_HAS_HASH_SET_ #elif GTEST_HAS_HASH_SET_
# include <hash_set> // NOLINT # include <hash_set> // NOLINT
#endif // GTEST_HAS_HASH_SET_ #endif // GTEST_HAS_HASH_SET_
...@@ -192,13 +192,12 @@ inline ::std::ostream& operator<<(::std::ostream& os, ...@@ -192,13 +192,12 @@ inline ::std::ostream& operator<<(::std::ostream& os,
return os << "StreamableTemplateInFoo: " << x.value(); return os << "StreamableTemplateInFoo: " << x.value();
} }
// A user-defined streamable but recursivly-defined container type in // A user-defined streamable but recursivly-defined container type in
// a user namespace, it mimics therefore std::filesystem::path or // a user namespace, it mimics therefore std::filesystem::path or
// boost::filesystem::path. // boost::filesystem::path.
class PathLike { class PathLike {
public: public:
struct iterator struct iterator {
{
typedef PathLike value_type; typedef PathLike value_type;
}; };
typedef iterator const_iterator; typedef iterator const_iterator;
...@@ -208,9 +207,7 @@ class PathLike { ...@@ -208,9 +207,7 @@ class PathLike {
iterator begin() const { return iterator(); } iterator begin() const { return iterator(); }
iterator end() const { return iterator(); } iterator end() const { return iterator(); }
friend friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) {
::std::ostream& operator<<(::std::ostream& os, const PathLike&)
{
return os << "Streamable-PathLike"; return os << "Streamable-PathLike";
} }
}; };
...@@ -250,9 +247,9 @@ using ::testing::internal::string; ...@@ -250,9 +247,9 @@ using ::testing::internal::string;
#if GTEST_HAS_UNORDERED_MAP_ #if GTEST_HAS_UNORDERED_MAP_
#define GTEST_HAS_HASH_MAP_ 1 #define GTEST_HAS_HASH_MAP_ 1
template<class Key, class T> template <class Key, class T>
using hash_map = ::std::unordered_map<Key, T>; using hash_map = ::std::unordered_map<Key, T>;
template<class Key, class T> template <class Key, class T>
using hash_multimap = ::std::unordered_multimap<Key, T>; using hash_multimap = ::std::unordered_multimap<Key, T>;
#elif GTEST_HAS_HASH_MAP_ #elif GTEST_HAS_HASH_MAP_
...@@ -270,19 +267,19 @@ using ::stdext::hash_multimap; ...@@ -270,19 +267,19 @@ using ::stdext::hash_multimap;
#if GTEST_HAS_UNORDERED_SET_ #if GTEST_HAS_UNORDERED_SET_
#define GTEST_HAS_HASH_SET_ 1 #define GTEST_HAS_HASH_SET_ 1
template<class Key> template <class Key>
using hash_set = ::std::unordered_set<Key>; using hash_set = ::std::unordered_set<Key>;
template<class Key> template <class Key>
using hash_multiset = ::std::unordered_multiset<Key>; using hash_multiset = ::std::unordered_multiset<Key>;
#elif GTEST_HAS_HASH_SET_ #elif GTEST_HAS_HASH_SET_
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport. #ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
using ::std::hash_set; using ::std::hash_map;
using ::std::hash_multiset; using ::std::hash_multimap;
#elif _MSC_VER #elif _MSC_VER
using ::stdext::hash_set; using ::stdext::hash_map;
using ::stdext::hash_multiset; using ::stdext::hash_multimap;
#endif #endif
#endif #endif
...@@ -840,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { ...@@ -840,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) {
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); 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) { TEST(PrintStringViewTest, SimpleStringView) {
const StringPiece sp = "Hello"; const ::absl::string_view sp = "Hello";
EXPECT_EQ("\"Hello\"", Print(sp)); EXPECT_EQ("\"Hello\"", Print(sp));
} }
TEST(PrintStringPieceTest, UnprintableCharacters) { TEST(PrintStringViewTest, UnprintableCharacters) {
const char str[] = "NUL (\0) and \r\t"; 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)); EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp));
} }
#endif // GTEST_HAS_STRING_PIECE_ #endif // GTEST_HAS_ABSL
// Tests printing STL containers. // Tests printing STL containers.
...@@ -1092,7 +1089,7 @@ TEST(PrintTr1TupleTest, VariousSizes) { ...@@ -1092,7 +1089,7 @@ TEST(PrintTr1TupleTest, VariousSizes) {
::std::tr1::tuple<bool, char, short, testing::internal::Int32, // NOLINT ::std::tr1::tuple<bool, char, short, testing::internal::Int32, // NOLINT
testing::internal::Int64, float, double, const char*, void*, testing::internal::Int64, float, double, const char*, void*,
std::string> std::string>
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT
ImplicitCast_<void*>(NULL), "10"); ImplicitCast_<void*>(NULL), "10");
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
" pointing to \"8\", NULL, \"10\")", " pointing to \"8\", NULL, \"10\")",
...@@ -1152,7 +1149,7 @@ TEST(PrintStdTupleTest, VariousSizes) { ...@@ -1152,7 +1149,7 @@ TEST(PrintStdTupleTest, VariousSizes) {
::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT ::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT
testing::internal::Int64, float, double, const char*, void*, testing::internal::Int64, float, double, const char*, void*,
std::string> std::string>
t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT
ImplicitCast_<void*>(NULL), "10"); ImplicitCast_<void*>(NULL), "10");
EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
" pointing to \"8\", NULL, \"10\")", " pointing to \"8\", NULL, \"10\")",
...@@ -1330,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { ...@@ -1330,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
} }
// Tests formatting a char pointer when it's compared with another pointer. // 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. // pointer.
// char pointer vs pointer // char pointer vs pointer
...@@ -1555,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { ...@@ -1555,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); 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 < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) {
EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]);
}
}
#undef EXPECT_PRINT_TO_STRING_ #undef EXPECT_PRINT_TO_STRING_
TEST(UniversalTersePrintTest, WorksForNonReference) { TEST(UniversalTersePrintTest, WorksForNonReference) {
...@@ -1696,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { ...@@ -1696,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
#endif // GTEST_HAS_STD_TUPLE_ #endif // GTEST_HAS_STD_TUPLE_
#if GTEST_HAS_ABSL
TEST(PrintOptionalTest, Basic) {
absl::optional<int> value;
EXPECT_EQ("(nullopt)", PrintToString(value));
value = {7};
EXPECT_EQ("(7)", PrintToString(value));
EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1}));
EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"}));
}
#endif // GTEST_HAS_ABSL
} // namespace gtest_printers_test } // namespace gtest_printers_test
} // namespace testing } // namespace testing
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <vector> #include <vector>
#include "test/gtest-typed-test_test.h" #include "gtest-typed-test_test.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#if GTEST_HAS_TYPED_TEST_P #if GTEST_HAS_TYPED_TEST_P
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
// //
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
#include "test/gtest-typed-test_test.h" #include "gtest-typed-test_test.h"
#include <set> #include <set>
#include <vector> #include <vector>
......
...@@ -33,15 +33,15 @@ ...@@ -33,15 +33,15 @@
// //
// Sometimes it's desirable to build most of Google Test's own tests // Sometimes it's desirable to build most of Google Test's own tests
// by compiling a single file. This file serves this purpose. // by compiling a single file. This file serves this purpose.
#include "test/gtest-filepath_test.cc" #include "gtest-filepath_test.cc"
#include "test/gtest-linked_ptr_test.cc" #include "gtest-linked_ptr_test.cc"
#include "test/gtest-message_test.cc" #include "gtest-message_test.cc"
#include "test/gtest-options_test.cc" #include "gtest-options_test.cc"
#include "test/gtest-port_test.cc" #include "gtest-port_test.cc"
#include "test/gtest_pred_impl_unittest.cc" #include "gtest_pred_impl_unittest.cc"
#include "test/gtest_prod_test.cc" #include "gtest_prod_test.cc"
#include "test/gtest-test-part_test.cc" #include "gtest-test-part_test.cc"
#include "test/gtest-typed-test_test.cc" #include "gtest-typed-test_test.cc"
#include "test/gtest-typed-test2_test.cc" #include "gtest-typed-test2_test.cc"
#include "test/gtest_unittest.cc" #include "gtest_unittest.cc"
#include "test/production.cc" #include "production.cc"
// 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdexcept>
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;
}
...@@ -40,10 +40,8 @@ Google Test) with different environments and command line flags. ...@@ -40,10 +40,8 @@ Google Test) with different environments and command line flags.
__author__ = 'wan@google.com (Zhanyong Wan)' __author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os import os
import sys import gtest_test_utils
# Constants. # Constants.
......
...@@ -80,8 +80,7 @@ int main(int argc, char **argv) { ...@@ -80,8 +80,7 @@ int main(int argc, char **argv) {
SetUnhandledExceptionFilter(ExitWithExceptionCode); SetUnhandledExceptionFilter(ExitWithExceptionCode);
# endif # endif
#endif #endif // GTEST_OS_WINDOWS
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
......
...@@ -37,8 +37,6 @@ Google Test) and verifies their output. ...@@ -37,8 +37,6 @@ Google Test) and verifies their output.
__author__ = 'vladl@google.com (Vlad Losev)' __author__ = 'vladl@google.com (Vlad Losev)'
import os
import gtest_test_utils import gtest_test_utils
# Constants. # Constants.
......
...@@ -36,8 +36,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)' ...@@ -36,8 +36,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os import os
import gtest_test_utils import gtest_test_utils
IS_WINDOWS = os.name == 'nt'
IS_WINDOWS = os.name = 'nt'
COLOR_ENV_VAR = 'GTEST_COLOR' COLOR_ENV_VAR = 'GTEST_COLOR'
COLOR_FLAG = 'gtest_color' COLOR_FLAG = 'gtest_color'
......
...@@ -36,15 +36,7 @@ ...@@ -36,15 +36,7 @@
#include <stdio.h> #include <stdio.h>
#include "gtest/gtest.h" #include "gtest/gtest.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// their code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
using testing::internal::ShouldUseColor; using testing::internal::ShouldUseColor;
......
...@@ -47,8 +47,8 @@ environ = os.environ.copy() ...@@ -47,8 +47,8 @@ environ = os.environ.copy()
def AssertEq(expected, actual): def AssertEq(expected, actual):
if expected != actual: if expected != actual:
print('Expected: %s' % (expected,)) print 'Expected: %s' % (expected,)
print(' Actual: %s' % (actual,)) print ' Actual: %s' % (actual,)
raise AssertionError raise AssertionError
......
...@@ -36,9 +36,7 @@ ...@@ -36,9 +36,7 @@
#include <iostream> #include <iostream>
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
using ::std::cout; using ::std::cout;
......
...@@ -34,10 +34,7 @@ ...@@ -34,10 +34,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#define GTEST_IMPLEMENTATION_ 1 // Required for the next #include.
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
namespace testing { namespace testing {
GTEST_DECLARE_string_(filter); GTEST_DECLARE_string_(filter);
......
...@@ -44,12 +44,8 @@ __author__ = 'wan@google.com (Zhanyong Wan)' ...@@ -44,12 +44,8 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os import os
import re import re
try: import sets
from sets import Set as set # For Python 2.3 compatibility
except ImportError:
pass
import sys import sys
import gtest_test_utils import gtest_test_utils
# Constants. # Constants.
...@@ -59,10 +55,12 @@ import gtest_test_utils ...@@ -59,10 +55,12 @@ import gtest_test_utils
# script in a subprocess to print whether the variable is STILL in # script in a subprocess to print whether the variable is STILL in
# os.environ. We then use 'eval' to parse the child's output so that an # os.environ. We then use 'eval' to parse the child's output so that an
# exception is thrown if the input is anything other than 'True' nor 'False'. # exception is thrown if the input is anything other than 'True' nor 'False'.
os.environ['EMPTY_VAR'] = '' CAN_PASS_EMPTY_ENV = False
child = gtest_test_utils.Subprocess( if sys.executable:
[sys.executable, '-c', 'import os; print(\'EMPTY_VAR\' in os.environ)']) os.environ['EMPTY_VAR'] = ''
CAN_PASS_EMPTY_ENV = eval(child.output) child = gtest_test_utils.Subprocess(
[sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ'])
CAN_PASS_EMPTY_ENV = eval(child.output)
# Check if this platform can unset environment variables in child processes. # Check if this platform can unset environment variables in child processes.
...@@ -71,11 +69,14 @@ CAN_PASS_EMPTY_ENV = eval(child.output) ...@@ -71,11 +69,14 @@ CAN_PASS_EMPTY_ENV = eval(child.output)
# is NO LONGER in os.environ. # is NO LONGER in os.environ.
# We use 'eval' to parse the child's output so that an exception # We use 'eval' to parse the child's output so that an exception
# is thrown if the input is neither 'True' nor 'False'. # is thrown if the input is neither 'True' nor 'False'.
os.environ['UNSET_VAR'] = 'X' CAN_UNSET_ENV = False
del os.environ['UNSET_VAR'] if sys.executable:
child = gtest_test_utils.Subprocess( os.environ['UNSET_VAR'] = 'X'
[sys.executable, '-c', 'import os; print(\'UNSET_VAR\' not in os.environ)']) del os.environ['UNSET_VAR']
CAN_UNSET_ENV = eval(child.output) child = gtest_test_utils.Subprocess(
[sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ'
])
CAN_UNSET_ENV = eval(child.output)
# Checks if we should test with an empty filter. This doesn't # Checks if we should test with an empty filter. This doesn't
...@@ -97,7 +98,7 @@ SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' ...@@ -97,7 +98,7 @@ SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
FILTER_FLAG = 'gtest_filter' FILTER_FLAG = 'gtest_filter'
# The command line flag for including disabled tests. # The command line flag for including disabled tests.
ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' ALSO_RUN_DISABLED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
# Command to run the gtest_filter_unittest_ program. # Command to run the gtest_filter_unittest_ program.
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_') COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
...@@ -246,14 +247,14 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): ...@@ -246,14 +247,14 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
for slice_var in list_of_sets: for slice_var in list_of_sets:
full_partition.extend(slice_var) full_partition.extend(slice_var)
self.assertEqual(len(set_var), len(full_partition)) self.assertEqual(len(set_var), len(full_partition))
self.assertEqual(set(set_var), set(full_partition)) self.assertEqual(sets.Set(set_var), sets.Set(full_partition))
def AdjustForParameterizedTests(self, tests_to_run): def AdjustForParameterizedTests(self, tests_to_run):
"""Adjust tests_to_run in case value parameterized tests are disabled.""" """Adjust tests_to_run in case value parameterized tests are disabled."""
global param_tests_present global param_tests_present
if not param_tests_present: if not param_tests_present:
return list(set(tests_to_run) - set(PARAM_TESTS)) return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
else: else:
return tests_to_run return tests_to_run
...@@ -294,6 +295,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): ...@@ -294,6 +295,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
Runs all shards of gtest_filter_unittest_ with the given filter, and Runs all shards of gtest_filter_unittest_ with the given filter, and
verifies that the right set of tests were run. The union of tests run verifies that the right set of tests were run. The union of tests run
on each shard should be identical to tests_to_run, without duplicates. on each shard should be identical to tests_to_run, without duplicates.
If check_exit_0, .
Args: Args:
gtest_filter: A filter to apply to the tests. gtest_filter: A filter to apply to the tests.
...@@ -339,7 +341,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): ...@@ -339,7 +341,7 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase):
tests_to_run = self.AdjustForParameterizedTests(tests_to_run) tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Construct the command line. # Construct the command line.
args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] args = ['--%s' % ALSO_RUN_DISABLED_TESTS_FLAG]
if gtest_filter is not None: if gtest_filter is not None:
args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) args.append('--%s=%s' % (FILTER_FLAG, gtest_filter))
......
#!/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()
#!/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: <?xml encoding="utf-8">'
u'<top><![CDATA[cdata text]]></top>' +
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()
# 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
...@@ -39,9 +39,8 @@ Google Test) the command line flags. ...@@ -39,9 +39,8 @@ Google Test) the command line flags.
__author__ = 'phanna@google.com (Patrick Hanna)' __author__ = 'phanna@google.com (Patrick Hanna)'
import gtest_test_utils
import re import re
import gtest_test_utils
# Constants. # Constants.
...@@ -123,6 +122,7 @@ def Run(args): ...@@ -123,6 +122,7 @@ def Run(args):
# The unit test. # The unit test.
class GTestListTestsUnitTest(gtest_test_utils.TestCase): class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests.""" """Tests using the --gtest_list_tests flag to list all tests."""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment