Import Cobalt 8.21796
diff --git a/src/testing/gtest/test/gtest-death-test_test.cc b/src/testing/gtest/test/gtest-death-test_test.cc
index e42c013..bb4a3d1 100644
--- a/src/testing/gtest/test/gtest-death-test_test.cc
+++ b/src/testing/gtest/test/gtest-death-test_test.cc
@@ -45,7 +45,6 @@
# else
# include <unistd.h>
# include <sys/wait.h> // For waitpid.
-# include <limits> // For std::numeric_limits.
# endif // GTEST_OS_WINDOWS
# include <limits.h>
@@ -327,12 +326,9 @@
// Tests that death test macros expand to code which interacts well with switch
// statements.
TEST_F(TestForDeathTest, SwitchStatement) {
-// Microsoft compiler usually complains about switch statements without
-// case labels. We suppress that warning for this test.
-# ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable: 4065)
-# endif // _MSC_VER
+ // Microsoft compiler usually complains about switch statements without
+ // case labels. We suppress that warning for this test.
+ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065)
switch (0)
default:
@@ -342,9 +338,7 @@
case 0:
EXPECT_DEATH(_exit(1), "") << "exit in switch case";
-# ifdef _MSC_VER
-# pragma warning(pop)
-# endif // _MSC_VER
+ GTEST_DISABLE_MSC_WARNINGS_POP_()
}
// Tests that a static member function can be used in a "fast" style
@@ -465,6 +459,8 @@
EXPECT_DEATH(_exit(1), "");
}
+# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
+
namespace {
bool pthread_flag;
@@ -475,8 +471,6 @@
} // namespace
-# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
-
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
if (!testing::GTEST_FLAG(death_test_use_fork)) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
@@ -516,8 +510,12 @@
# endif // GTEST_HAS_GLOBAL_STRING
+# if !GTEST_USES_PCRE
+
const ::std::string regex_std_str(regex_c_str);
EXPECT_DEATH(GlobalFunction(), regex_std_str);
+
+# endif // !GTEST_USES_PCRE
}
// Tests that a non-void function can be used in a death test.
@@ -700,7 +698,10 @@
void AssertDebugDeathHelper(bool* aborted) {
*aborted = true;
- ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail.";
+ GTEST_LOG_(INFO) << "Before ASSERT_DEBUG_DEATH";
+ ASSERT_DEBUG_DEATH(GTEST_LOG_(INFO) << "In ASSERT_DEBUG_DEATH"; return, "")
+ << "This is expected to fail.";
+ GTEST_LOG_(INFO) << "After ASSERT_DEBUG_DEATH";
*aborted = false;
}
@@ -713,6 +714,69 @@
EXPECT_TRUE(aborted);
}
+TEST_F(TestForDeathTest, AssertDebugDeathAborts2) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts3) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts4) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts5) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts6) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts7) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts8) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts9) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
+TEST_F(TestForDeathTest, AssertDebugDeathAborts10) {
+ static bool aborted;
+ aborted = false;
+ EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+ EXPECT_TRUE(aborted);
+}
+
# endif // _NDEBUG
// Tests the *_EXIT family of macros, using a variety of predicates.
@@ -827,9 +891,9 @@
// Accessors.
int AssumeRoleCalls() const { return assume_role_calls_; }
int WaitCalls() const { return wait_calls_; }
- int PassedCalls() const { return passed_args_.size(); }
+ size_t PassedCalls() const { return passed_args_.size(); }
bool PassedArgument(int n) const { return passed_args_[n]; }
- int AbortCalls() const { return abort_args_.size(); }
+ size_t AbortCalls() const { return abort_args_.size(); }
DeathTest::AbortReason AbortArgument(int n) const {
return abort_args_[n];
}
@@ -990,8 +1054,8 @@
EXPECT_FALSE(flag);
EXPECT_EQ(0, factory_->AssumeRoleCalls());
EXPECT_EQ(0, factory_->WaitCalls());
- EXPECT_EQ(0, factory_->PassedCalls());
- EXPECT_EQ(0, factory_->AbortCalls());
+ EXPECT_EQ(0U, factory_->PassedCalls());
+ EXPECT_EQ(0U, factory_->AbortCalls());
EXPECT_FALSE(factory_->TestDeleted());
}
@@ -1005,9 +1069,9 @@
EXPECT_FALSE(flag);
EXPECT_EQ(1, factory_->AssumeRoleCalls());
EXPECT_EQ(1, factory_->WaitCalls());
- ASSERT_EQ(1, factory_->PassedCalls());
+ ASSERT_EQ(1U, factory_->PassedCalls());
EXPECT_FALSE(factory_->PassedArgument(0));
- EXPECT_EQ(0, factory_->AbortCalls());
+ EXPECT_EQ(0U, factory_->AbortCalls());
EXPECT_TRUE(factory_->TestDeleted());
}
@@ -1020,9 +1084,9 @@
EXPECT_FALSE(flag);
EXPECT_EQ(1, factory_->AssumeRoleCalls());
EXPECT_EQ(1, factory_->WaitCalls());
- ASSERT_EQ(1, factory_->PassedCalls());
+ ASSERT_EQ(1U, factory_->PassedCalls());
EXPECT_TRUE(factory_->PassedArgument(0));
- EXPECT_EQ(0, factory_->AbortCalls());
+ EXPECT_EQ(0U, factory_->AbortCalls());
EXPECT_TRUE(factory_->TestDeleted());
}
@@ -1036,8 +1100,8 @@
EXPECT_TRUE(flag);
EXPECT_EQ(1, factory_->AssumeRoleCalls());
EXPECT_EQ(0, factory_->WaitCalls());
- EXPECT_EQ(0, factory_->PassedCalls());
- EXPECT_EQ(1, factory_->AbortCalls());
+ EXPECT_EQ(0U, factory_->PassedCalls());
+ EXPECT_EQ(1U, factory_->AbortCalls());
EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT,
factory_->AbortArgument(0));
EXPECT_TRUE(factory_->TestDeleted());
@@ -1052,13 +1116,13 @@
EXPECT_TRUE(flag);
EXPECT_EQ(1, factory_->AssumeRoleCalls());
EXPECT_EQ(0, factory_->WaitCalls());
- EXPECT_EQ(0, factory_->PassedCalls());
+ EXPECT_EQ(0U, factory_->PassedCalls());
// This time there are two calls to Abort: one since the test didn't
// die, and another from the ReturnSentinel when it's destroyed. The
// sentinel normally isn't destroyed if a test doesn't die, since
// _exit(2) is called in that case by ForkingDeathTest, but not by
// our MockDeathTest.
- ASSERT_EQ(2, factory_->AbortCalls());
+ ASSERT_EQ(2U, factory_->AbortCalls());
EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE,
factory_->AbortArgument(0));
EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT,
@@ -1123,17 +1187,16 @@
# if GTEST_OS_WINDOWS
typedef unsigned __int64 BiggestParsable;
typedef signed __int64 BiggestSignedParsable;
-const BiggestParsable kBiggestParsableMax = ULLONG_MAX;
-const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX;
# else
typedef unsigned long long BiggestParsable;
typedef signed long long BiggestSignedParsable;
-const BiggestParsable kBiggestParsableMax =
- ::std::numeric_limits<BiggestParsable>::max();
-const BiggestSignedParsable kBiggestSignedParsableMax =
- ::std::numeric_limits<BiggestSignedParsable>::max();
# endif // GTEST_OS_WINDOWS
+// We cannot use std::numeric_limits<T>::max() as it clashes with the
+// max() macro defined by <windows.h>.
+const BiggestParsable kBiggestParsableMax = ULLONG_MAX;
+const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX;
+
TEST(ParseNaturalNumberTest, RejectsInvalidFormat) {
BiggestParsable result = 0;
@@ -1240,7 +1303,27 @@
EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), "");
}
-#else
+TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ EXPECT_FALSE(InDeathTestChild());
+ EXPECT_DEATH({
+ fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
+ fflush(stderr);
+ _exit(1);
+ }, "Inside");
+}
+
+TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
+ testing::GTEST_FLAG(death_test_style) = "threadsafe";
+ EXPECT_FALSE(InDeathTestChild());
+ EXPECT_DEATH({
+ fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
+ fflush(stderr);
+ _exit(1);
+ }, "Inside");
+}
+
+#else // !GTEST_HAS_DEATH_TEST follows
using testing::internal::CaptureStderr;
using testing::internal::GetCapturedStderr;
@@ -1289,7 +1372,8 @@
FuncWithAssert(&n);
EXPECT_EQ(1, n);
}
-#endif // GTEST_HAS_DEATH_TEST
+
+#endif // !GTEST_HAS_DEATH_TEST
// Tests that the death test macros expand to code which may or may not
// be followed by operator<<, and that in either case the complete text
@@ -1320,12 +1404,9 @@
// Tests that conditional death test macros expand to code which interacts
// well with switch statements.
TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) {
-// Microsoft compiler usually complains about switch statements without
-// case labels. We suppress that warning for this test.
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable: 4065)
-#endif // _MSC_VER
+ // Microsoft compiler usually complains about switch statements without
+ // case labels. We suppress that warning for this test.
+ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065)
switch (0)
default:
@@ -1336,29 +1417,7 @@
case 0:
EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case";
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif // _MSC_VER
-}
-
-TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) {
- testing::GTEST_FLAG(death_test_style) = "fast";
- EXPECT_FALSE(InDeathTestChild());
- EXPECT_DEATH({
- fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
- fflush(stderr);
- _exit(1);
- }, "Inside");
-}
-
-TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- EXPECT_FALSE(InDeathTestChild());
- EXPECT_DEATH({
- fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside");
- fflush(stderr);
- _exit(1);
- }, "Inside");
+ GTEST_DISABLE_MSC_WARNINGS_POP_()
}
// Tests that a test case whose name ends with "DeathTest" works fine
diff --git a/src/testing/gtest/test/gtest-filepath_test.cc b/src/testing/gtest/test/gtest-filepath_test.cc
index ae9f55a..da72986 100644
--- a/src/testing/gtest/test/gtest-filepath_test.cc
+++ b/src/testing/gtest/test/gtest-filepath_test.cc
@@ -514,24 +514,6 @@
posix::RmDir(testdata_path_.c_str());
}
- std::string TempDir() const {
-#if GTEST_OS_WINDOWS_MOBILE
- return "\\temp\\";
-#elif GTEST_OS_WINDOWS
- const char* temp_dir = posix::GetEnv("TEMP");
- if (temp_dir == NULL || temp_dir[0] == '\0')
- return "\\temp\\";
- else if (temp_dir[strlen(temp_dir) - 1] == '\\')
- return temp_dir;
- else
- return std::string(temp_dir) + "\\";
-#elif GTEST_OS_LINUX_ANDROID
- return "/sdcard/";
-#else
- return "/tmp/";
-#endif // GTEST_OS_WINDOWS_MOBILE
- }
-
void CreateTextFile(const char* filename) {
FILE* f = posix::FOpen(filename, "w");
fprintf(f, "text\n");
diff --git a/src/testing/gtest/test/gtest-listener_test.cc b/src/testing/gtest/test/gtest-listener_test.cc
index 99662cf..9074768 100644
--- a/src/testing/gtest/test/gtest-listener_test.cc
+++ b/src/testing/gtest/test/gtest-listener_test.cc
@@ -176,16 +176,16 @@
void VerifyResults(const std::vector<std::string>& data,
const char* const* expected_data,
- int expected_data_size) {
- const int actual_size = data.size();
+ size_t expected_data_size) {
+ const size_t actual_size = data.size();
// If the following assertion fails, a new entry will be appended to
// data. Hence we save data.size() first.
EXPECT_EQ(expected_data_size, actual_size);
// Compares the common prefix.
- const int shorter_size = expected_data_size <= actual_size ?
+ const size_t shorter_size = expected_data_size <= actual_size ?
expected_data_size : actual_size;
- int i = 0;
+ size_t i = 0;
for (; i < shorter_size; ++i) {
ASSERT_STREQ(expected_data[i], data[i].c_str())
<< "at position " << i;
@@ -193,7 +193,8 @@
// Prints extra elements in the actual data.
for (; i < actual_size; ++i) {
- printf(" Actual event #%d: %s\n", i, data[i].c_str());
+ printf(" Actual event #%lu: %s\n",
+ static_cast<unsigned long>(i), data[i].c_str());
}
}
diff --git a/src/testing/gtest/test/gtest-param-test_test.cc b/src/testing/gtest/test/gtest-param-test_test.cc
index 7b6f7e2..8b278bb 100644
--- a/src/testing/gtest/test/gtest-param-test_test.cc
+++ b/src/testing/gtest/test/gtest-param-test_test.cc
@@ -64,9 +64,9 @@
# if GTEST_HAS_COMBINE
using ::testing::Combine;
-using ::std::tr1::get;
-using ::std::tr1::make_tuple;
-using ::std::tr1::tuple;
+using ::testing::get;
+using ::testing::make_tuple;
+using ::testing::tuple;
# endif // GTEST_HAS_COMBINE
using ::testing::internal::ParamGenerator;
@@ -809,6 +809,157 @@
INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
+// Tests that user supplied custom parameter names are working correctly.
+// Runs the test with a builtin helper method which uses PrintToString,
+// as well as a custom function and custom functor to ensure all possible
+// uses work correctly.
+class CustomFunctorNamingTest : public TestWithParam<std::string> {};
+TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
+
+struct CustomParamNameFunctor {
+ std::string operator()(const ::testing::TestParamInfo<std::string>& info) {
+ return info.param;
+ }
+};
+
+INSTANTIATE_TEST_CASE_P(CustomParamNameFunctor,
+ CustomFunctorNamingTest,
+ Values(std::string("FunctorName")),
+ CustomParamNameFunctor());
+
+INSTANTIATE_TEST_CASE_P(AllAllowedCharacters,
+ CustomFunctorNamingTest,
+ Values("abcdefghijklmnopqrstuvwxyz",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "01234567890_"),
+ CustomParamNameFunctor());
+
+inline std::string CustomParamNameFunction(
+ const ::testing::TestParamInfo<std::string>& info) {
+ return info.param;
+}
+
+class CustomFunctionNamingTest : public TestWithParam<std::string> {};
+TEST_P(CustomFunctionNamingTest, CustomTestNames) {}
+
+INSTANTIATE_TEST_CASE_P(CustomParamNameFunction,
+ CustomFunctionNamingTest,
+ Values(std::string("FunctionName")),
+ CustomParamNameFunction);
+
+#if GTEST_LANG_CXX11
+
+// Test custom naming with a lambda
+
+class CustomLambdaNamingTest : public TestWithParam<std::string> {};
+TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
+
+INSTANTIATE_TEST_CASE_P(CustomParamNameLambda,
+ CustomLambdaNamingTest,
+ Values(std::string("LambdaName")),
+ [](const ::testing::TestParamInfo<std::string>& info) {
+ return info.param;
+ });
+
+#endif // GTEST_LANG_CXX11
+
+TEST(CustomNamingTest, CheckNameRegistry) {
+ ::testing::UnitTest* unit_test = ::testing::UnitTest::GetInstance();
+ std::set<std::string> test_names;
+ for (int case_num = 0;
+ case_num < unit_test->total_test_case_count();
+ ++case_num) {
+ const ::testing::TestCase* test_case = unit_test->GetTestCase(case_num);
+ for (int test_num = 0;
+ test_num < test_case->total_test_count();
+ ++test_num) {
+ const ::testing::TestInfo* test_info = test_case->GetTestInfo(test_num);
+ test_names.insert(std::string(test_info->name()));
+ }
+ }
+ EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctorName"));
+ EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctionName"));
+#if GTEST_LANG_CXX11
+ EXPECT_EQ(1u, test_names.count("CustomTestNames/LambdaName"));
+#endif // GTEST_LANG_CXX11
+}
+
+// Test a numeric name to ensure PrintToStringParamName works correctly.
+
+class CustomIntegerNamingTest : public TestWithParam<int> {};
+
+TEST_P(CustomIntegerNamingTest, TestsReportCorrectNames) {
+ const ::testing::TestInfo* const test_info =
+ ::testing::UnitTest::GetInstance()->current_test_info();
+ Message test_name_stream;
+ test_name_stream << "TestsReportCorrectNames/" << GetParam();
+ EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name());
+}
+
+INSTANTIATE_TEST_CASE_P(PrintToString,
+ CustomIntegerNamingTest,
+ Range(0, 5),
+ ::testing::PrintToStringParamName());
+
+// Test a custom struct with PrintToString.
+
+struct CustomStruct {
+ explicit CustomStruct(int value) : x(value) {}
+ int x;
+};
+
+std::ostream& operator<<(std::ostream& stream, const CustomStruct& val) {
+ stream << val.x;
+ return stream;
+}
+
+class CustomStructNamingTest : public TestWithParam<CustomStruct> {};
+
+TEST_P(CustomStructNamingTest, TestsReportCorrectNames) {
+ const ::testing::TestInfo* const test_info =
+ ::testing::UnitTest::GetInstance()->current_test_info();
+ Message test_name_stream;
+ test_name_stream << "TestsReportCorrectNames/" << GetParam();
+ EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name());
+}
+
+INSTANTIATE_TEST_CASE_P(PrintToString,
+ CustomStructNamingTest,
+ Values(CustomStruct(0), CustomStruct(1)),
+ ::testing::PrintToStringParamName());
+
+// Test that using a stateful parameter naming function works as expected.
+
+struct StatefulNamingFunctor {
+ StatefulNamingFunctor() : sum(0) {}
+ std::string operator()(const ::testing::TestParamInfo<int>& info) {
+ int value = info.param + sum;
+ sum += info.param;
+ return ::testing::PrintToString(value);
+ }
+ int sum;
+};
+
+class StatefulNamingTest : public ::testing::TestWithParam<int> {
+ protected:
+ StatefulNamingTest() : sum_(0) {}
+ int sum_;
+};
+
+TEST_P(StatefulNamingTest, TestsReportCorrectNames) {
+ const ::testing::TestInfo* const test_info =
+ ::testing::UnitTest::GetInstance()->current_test_info();
+ sum_ += GetParam();
+ Message test_name_stream;
+ test_name_stream << "TestsReportCorrectNames/" << sum_;
+ EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name());
+}
+
+INSTANTIATE_TEST_CASE_P(StatefulNamingFunctor,
+ StatefulNamingTest,
+ Range(0, 5),
+ StatefulNamingFunctor());
+
// Class that cannot be streamed into an ostream. It needs to be copyable
// (and, in case of MSVC, also assignable) in order to be a test parameter
// type. Its default copy constructor and assignment operator do exactly
@@ -865,6 +1016,13 @@
EXPECT_EQ(GetParam(), global_count_++);
}
+class ParameterizedDeathTest : public ::testing::TestWithParam<int> { };
+
+TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
+ EXPECT_DEATH_IF_SUPPORTED(GetParam(),
+ ".* value-parameterized test .*");
+}
+
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
#endif // GTEST_HAS_PARAM_TEST
diff --git a/src/testing/gtest/test/gtest-port_test.cc b/src/testing/gtest/test/gtest-port_test.cc
index 43f1f20..d17bad0 100644
--- a/src/testing/gtest/test/gtest-port_test.cc
+++ b/src/testing/gtest/test/gtest-port_test.cc
@@ -304,58 +304,51 @@
EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1));
}
-#if GTEST_OS_MAC || GTEST_OS_QNX
+#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
void* ThreadFunc(void* data) {
- pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
- pthread_mutex_lock(mutex);
- pthread_mutex_unlock(mutex);
+ internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
+ mutex->Lock();
+ mutex->Unlock();
return NULL;
}
TEST(GetThreadCountTest, ReturnsCorrectValue) {
- EXPECT_EQ(1U, GetThreadCount());
- pthread_mutex_t mutex;
- pthread_attr_t attr;
+ const size_t starting_count = GetThreadCount();
pthread_t thread_id;
- // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic
- // destruction.
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
- ASSERT_EQ(0, pthread_attr_init(&attr));
- ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
+ internal::Mutex mutex;
+ {
+ internal::MutexLock lock(&mutex);
+ pthread_attr_t attr;
+ ASSERT_EQ(0, pthread_attr_init(&attr));
+ ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
- const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
- ASSERT_EQ(0, pthread_attr_destroy(&attr));
- ASSERT_EQ(0, status);
- EXPECT_EQ(2U, GetThreadCount());
- pthread_mutex_unlock(&mutex);
+ const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
+ ASSERT_EQ(0, pthread_attr_destroy(&attr));
+ ASSERT_EQ(0, status);
+ EXPECT_EQ(starting_count + 1, GetThreadCount());
+ }
void* dummy;
ASSERT_EQ(0, pthread_join(thread_id, &dummy));
-# if GTEST_OS_MAC
-
- // MacOS X may not immediately report the updated thread count after
+ // The OS may not immediately report the updated thread count after
// joining a thread, causing flakiness in this test. To counter that, we
// wait for up to .5 seconds for the OS to report the correct value.
for (int i = 0; i < 5; ++i) {
- if (GetThreadCount() == 1)
+ if (GetThreadCount() == starting_count)
break;
SleepMilliseconds(100);
}
-# endif // GTEST_OS_MAC
-
- EXPECT_EQ(1U, GetThreadCount());
- pthread_mutex_destroy(&mutex);
+ EXPECT_EQ(starting_count, GetThreadCount());
}
#else
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
EXPECT_EQ(0U, GetThreadCount());
}
-#endif // GTEST_OS_MAC || GTEST_OS_QNX
+#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
const bool a_false_condition = false;
@@ -389,15 +382,17 @@
// the platform. The test will produce compiler errors in case of failure.
// For simplicity, we only cover the most important platforms here.
TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
-#if GTEST_HAS_POSIX_RE
+#if !GTEST_USES_PCRE
+# if GTEST_HAS_POSIX_RE
EXPECT_TRUE(GTEST_USES_POSIX_RE);
-#else
+# else
EXPECT_TRUE(GTEST_USES_SIMPLE_RE);
-#endif
+# endif
+#endif // !GTEST_USES_PCRE
}
#if GTEST_USES_POSIX_RE
@@ -1062,11 +1057,13 @@
MutexLock lock(mutex_);
int temp = value_;
{
- // Locking a mutex puts up a memory barrier, preventing reads and
- // writes to value_ rearranged when observed from other threads.
- //
- // We cannot use Mutex and MutexLock here or rely on their memory
- // barrier functionality as we are testing them here.
+ // We need to put up a memory barrier to prevent reads and writes to
+ // value_ rearranged with the call to SleepMilliseconds when observed
+ // from other threads.
+#if GTEST_HAS_PTHREAD
+ // On POSIX, locking a mutex puts up a memory barrier. We cannot use
+ // Mutex and MutexLock here or rely on their memory barrier
+ // functionality as we are testing them here.
pthread_mutex_t memory_barrier_mutex;
GTEST_CHECK_POSIX_SUCCESS_(
pthread_mutex_init(&memory_barrier_mutex, NULL));
@@ -1076,6 +1073,15 @@
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex));
+#elif GTEST_OS_WINDOWS
+ // On Windows, performing an interlocked access puts up a memory barrier.
+ volatile LONG dummy = 0;
+ ::InterlockedIncrement(&dummy);
+ SleepMilliseconds(random_.Generate(30));
+ ::InterlockedIncrement(&dummy);
+#else
+# error "Memory barrier not implemented on this platform."
+#endif // GTEST_HAS_PTHREAD
}
value_ = temp + 1;
}
@@ -1145,27 +1151,76 @@
EXPECT_STREQ("foo", result.c_str());
}
+// Keeps track of whether of destructors being called on instances of
+// DestructorTracker. On Windows, waits for the destructor call reports.
+class DestructorCall {
+ public:
+ DestructorCall() {
+ invoked_ = false;
+#if GTEST_OS_WINDOWS
+ wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL));
+ GTEST_CHECK_(wait_event_.Get() != NULL);
+#endif
+ }
+
+ bool CheckDestroyed() const {
+#if GTEST_OS_WINDOWS
+ if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0)
+ return false;
+#endif
+ return invoked_;
+ }
+
+ void ReportDestroyed() {
+ invoked_ = true;
+#if GTEST_OS_WINDOWS
+ ::SetEvent(wait_event_.Get());
+#endif
+ }
+
+ static std::vector<DestructorCall*>& List() { return *list_; }
+
+ static void ResetList() {
+ for (size_t i = 0; i < list_->size(); ++i) {
+ delete list_->at(i);
+ }
+ list_->clear();
+ }
+
+ private:
+ bool invoked_;
+#if GTEST_OS_WINDOWS
+ AutoHandle wait_event_;
+#endif
+ static std::vector<DestructorCall*>* const list_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall);
+};
+
+std::vector<DestructorCall*>* const DestructorCall::list_ =
+ new std::vector<DestructorCall*>;
+
// DestructorTracker keeps track of whether its instances have been
// destroyed.
-static std::vector<bool> g_destroyed;
-
class DestructorTracker {
public:
DestructorTracker() : index_(GetNewIndex()) {}
DestructorTracker(const DestructorTracker& /* rhs */)
: index_(GetNewIndex()) {}
~DestructorTracker() {
- // We never access g_destroyed concurrently, so we don't need to
- // protect the write operation under a mutex.
- g_destroyed[index_] = true;
+ // We never access DestructorCall::List() concurrently, so we don't need
+ // to protect this acccess with a mutex.
+ DestructorCall::List()[index_]->ReportDestroyed();
}
private:
- static int GetNewIndex() {
- g_destroyed.push_back(false);
- return g_destroyed.size() - 1;
+ static size_t GetNewIndex() {
+ DestructorCall::List().push_back(new DestructorCall);
+ return DestructorCall::List().size() - 1;
}
- const int index_;
+ const size_t index_;
+
+ GTEST_DISALLOW_ASSIGN_(DestructorTracker);
};
typedef ThreadLocal<DestructorTracker>* ThreadParam;
@@ -1177,63 +1232,49 @@
// Tests that when a ThreadLocal object dies in a thread, it destroys
// the managed object for that thread.
TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) {
- g_destroyed.clear();
+ DestructorCall::ResetList();
{
- // The next line default constructs a DestructorTracker object as
- // the default value of objects managed by thread_local_tracker.
ThreadLocal<DestructorTracker> thread_local_tracker;
- ASSERT_EQ(1U, g_destroyed.size());
- ASSERT_FALSE(g_destroyed[0]);
+ ASSERT_EQ(0U, DestructorCall::List().size());
// This creates another DestructorTracker object for the main thread.
thread_local_tracker.get();
- ASSERT_EQ(2U, g_destroyed.size());
- ASSERT_FALSE(g_destroyed[0]);
- ASSERT_FALSE(g_destroyed[1]);
+ ASSERT_EQ(1U, DestructorCall::List().size());
+ ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed());
}
- // Now thread_local_tracker has died. It should have destroyed both the
- // default value shared by all threads and the value for the main
- // thread.
- ASSERT_EQ(2U, g_destroyed.size());
- EXPECT_TRUE(g_destroyed[0]);
- EXPECT_TRUE(g_destroyed[1]);
+ // Now thread_local_tracker has died.
+ ASSERT_EQ(1U, DestructorCall::List().size());
+ EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed());
- g_destroyed.clear();
+ DestructorCall::ResetList();
}
// Tests that when a thread exits, the thread-local object for that
// thread is destroyed.
TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
- g_destroyed.clear();
+ DestructorCall::ResetList();
{
- // The next line default constructs a DestructorTracker object as
- // the default value of objects managed by thread_local_tracker.
ThreadLocal<DestructorTracker> thread_local_tracker;
- ASSERT_EQ(1U, g_destroyed.size());
- ASSERT_FALSE(g_destroyed[0]);
+ ASSERT_EQ(0U, DestructorCall::List().size());
// This creates another DestructorTracker object in the new thread.
ThreadWithParam<ThreadParam> thread(
&CallThreadLocalGet, &thread_local_tracker, NULL);
thread.Join();
- // Now the new thread has exited. The per-thread object for it
- // should have been destroyed.
- ASSERT_EQ(2U, g_destroyed.size());
- ASSERT_FALSE(g_destroyed[0]);
- ASSERT_TRUE(g_destroyed[1]);
+ // The thread has exited, and we should have a DestroyedTracker
+ // instance created for it. But it may not have been destroyed yet.
+ ASSERT_EQ(1U, DestructorCall::List().size());
}
- // Now thread_local_tracker has died. The default value should have been
- // destroyed too.
- ASSERT_EQ(2U, g_destroyed.size());
- EXPECT_TRUE(g_destroyed[0]);
- EXPECT_TRUE(g_destroyed[1]);
+ // The thread has exited and thread_local_tracker has died.
+ ASSERT_EQ(1U, DestructorCall::List().size());
+ EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed());
- g_destroyed.clear();
+ DestructorCall::ResetList();
}
TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
@@ -1249,5 +1290,15 @@
#endif // GTEST_IS_THREADSAFE
+#if GTEST_OS_WINDOWS
+TEST(WindowsTypesTest, HANDLEIsVoidStar) {
+ StaticAssertTypeEq<HANDLE, void*>();
+}
+
+TEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) {
+ StaticAssertTypeEq<CRITICAL_SECTION, _RTL_CRITICAL_SECTION>();
+}
+#endif // GTEST_OS_WINDOWS
+
} // namespace internal
} // namespace testing
diff --git a/src/testing/gtest/test/gtest-printers_test.cc b/src/testing/gtest/test/gtest-printers_test.cc
index 45610f8..3e97cc2 100644
--- a/src/testing/gtest/test/gtest-printers_test.cc
+++ b/src/testing/gtest/test/gtest-printers_test.cc
@@ -50,13 +50,17 @@
#include "gtest/gtest.h"
-// hash_map and hash_set are available under Visual C++.
-#if _MSC_VER
-# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available.
+// hash_map and hash_set are available under Visual C++, or on Linux.
+#if GTEST_HAS_HASH_MAP_
# include <hash_map> // NOLINT
-# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available.
+#endif // GTEST_HAS_HASH_MAP_
+#if GTEST_HAS_HASH_SET_
# include <hash_set> // NOLINT
-#endif // GTEST_OS_WINDOWS
+#endif // GTEST_HAS_HASH_SET_
+
+#if GTEST_HAS_STD_FORWARD_LIST_
+# include <forward_list> // NOLINT
+#endif // GTEST_HAS_STD_FORWARD_LIST_
// Some user-defined types for testing the universal value printer.
@@ -125,6 +129,7 @@
class UnprintableInFoo {
public:
UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); }
+ double z() const { return z_; }
private:
char xy_[8];
double z_;
@@ -201,23 +206,23 @@
using ::testing::internal::ImplicitCast_;
using ::testing::internal::NativeArray;
using ::testing::internal::RE;
+using ::testing::internal::RelationToSourceReference;
using ::testing::internal::Strings;
using ::testing::internal::UniversalPrint;
using ::testing::internal::UniversalPrinter;
using ::testing::internal::UniversalTersePrint;
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
-using ::testing::internal::kReference;
using ::testing::internal::string;
-#if GTEST_HAS_TR1_TUPLE
-using ::std::tr1::make_tuple;
-using ::std::tr1::tuple;
-#endif
-
-#if _MSC_VER
-// MSVC defines the following classes in the ::stdext namespace while
-// gcc defines them in the :: namespace. Note that they are not part
-// of the C++ standard.
+// The hash_* classes are not part of the C++ standard. STLport
+// defines them in namespace std. MSVC defines them in ::stdext. GCC
+// defines them in ::.
+#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
+using ::std::hash_map;
+using ::std::hash_set;
+using ::std::hash_multimap;
+using ::std::hash_multiset;
+#elif _MSC_VER
using ::stdext::hash_map;
using ::stdext::hash_set;
using ::stdext::hash_multimap;
@@ -409,8 +414,6 @@
Print(p));
}
-
-
// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
@@ -914,6 +917,17 @@
EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1));
}
+#if GTEST_HAS_STD_FORWARD_LIST_
+// <slist> is available on Linux in the google3 mode, but not on
+// Windows or Mac OS X.
+
+TEST(PrintStlContainerTest, SinglyLinkedList) {
+ int a[] = { 9, 2, 8 };
+ const std::forward_list<int> ints(a, a + 3);
+ EXPECT_EQ("{ 9, 2, 8 }", Print(ints));
+}
+#endif // GTEST_HAS_STD_FORWARD_LIST_
+
TEST(PrintStlContainerTest, Pair) {
pair<const bool, int> p(true, 5);
EXPECT_EQ("(true, 5)", Print(p));
@@ -947,13 +961,13 @@
TEST(PrintStlContainerTest, OneDimensionalNativeArray) {
const int a[3] = { 1, 2, 3 };
- NativeArray<int> b(a, 3, kReference);
+ NativeArray<int> b(a, 3, RelationToSourceReference());
EXPECT_EQ("{ 1, 2, 3 }", Print(b));
}
TEST(PrintStlContainerTest, TwoDimensionalNativeArray) {
const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
- NativeArray<int[3]> b(a, 2, kReference);
+ NativeArray<int[3]> b(a, 2, RelationToSourceReference());
EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b));
}
@@ -980,46 +994,47 @@
}
#if GTEST_HAS_TR1_TUPLE
-// Tests printing tuples.
+// Tests printing ::std::tr1::tuples.
// Tuples of various arities.
-TEST(PrintTupleTest, VariousSizes) {
- tuple<> t0;
+TEST(PrintTr1TupleTest, VariousSizes) {
+ ::std::tr1::tuple<> t0;
EXPECT_EQ("()", Print(t0));
- tuple<int> t1(5);
+ ::std::tr1::tuple<int> t1(5);
EXPECT_EQ("(5)", Print(t1));
- tuple<char, bool> t2('a', true);
+ ::std::tr1::tuple<char, bool> t2('a', true);
EXPECT_EQ("('a' (97, 0x61), true)", Print(t2));
- tuple<bool, int, int> t3(false, 2, 3);
+ ::std::tr1::tuple<bool, int, int> t3(false, 2, 3);
EXPECT_EQ("(false, 2, 3)", Print(t3));
- tuple<bool, int, int, int> t4(false, 2, 3, 4);
+ ::std::tr1::tuple<bool, int, int, int> t4(false, 2, 3, 4);
EXPECT_EQ("(false, 2, 3, 4)", Print(t4));
- tuple<bool, int, int, int, bool> t5(false, 2, 3, 4, true);
+ ::std::tr1::tuple<bool, int, int, int, bool> t5(false, 2, 3, 4, true);
EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5));
- tuple<bool, int, int, int, bool, int> t6(false, 2, 3, 4, true, 6);
+ ::std::tr1::tuple<bool, int, int, int, bool, int> t6(false, 2, 3, 4, true, 6);
EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6));
- tuple<bool, int, int, int, bool, int, int> t7(false, 2, 3, 4, true, 6, 7);
+ ::std::tr1::tuple<bool, int, int, int, bool, int, int> t7(
+ false, 2, 3, 4, true, 6, 7);
EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7));
- tuple<bool, int, int, int, bool, int, int, bool> t8(
+ ::std::tr1::tuple<bool, int, int, int, bool, int, int, bool> t8(
false, 2, 3, 4, true, 6, 7, true);
EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8));
- tuple<bool, int, int, int, bool, int, int, bool, int> t9(
+ ::std::tr1::tuple<bool, int, int, int, bool, int, int, bool, int> t9(
false, 2, 3, 4, true, 6, 7, true, 9);
EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9));
const char* const str = "8";
// VC++ 2010's implementation of tuple of C++0x is deficient, requiring
// an explicit type cast of NULL to be used.
- 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*, string>
t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str,
ImplicitCast_<void*>(NULL), "10");
@@ -1029,13 +1044,73 @@
}
// Nested tuples.
-TEST(PrintTupleTest, NestedTuple) {
- tuple<tuple<int, bool>, char> nested(make_tuple(5, true), 'a');
+TEST(PrintTr1TupleTest, NestedTuple) {
+ ::std::tr1::tuple< ::std::tr1::tuple<int, bool>, char> nested(
+ ::std::tr1::make_tuple(5, true), 'a');
EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested));
}
#endif // GTEST_HAS_TR1_TUPLE
+#if GTEST_HAS_STD_TUPLE_
+// Tests printing ::std::tuples.
+
+// Tuples of various arities.
+TEST(PrintStdTupleTest, VariousSizes) {
+ ::std::tuple<> t0;
+ EXPECT_EQ("()", Print(t0));
+
+ ::std::tuple<int> t1(5);
+ EXPECT_EQ("(5)", Print(t1));
+
+ ::std::tuple<char, bool> t2('a', true);
+ EXPECT_EQ("('a' (97, 0x61), true)", Print(t2));
+
+ ::std::tuple<bool, int, int> t3(false, 2, 3);
+ EXPECT_EQ("(false, 2, 3)", Print(t3));
+
+ ::std::tuple<bool, int, int, int> t4(false, 2, 3, 4);
+ EXPECT_EQ("(false, 2, 3, 4)", Print(t4));
+
+ ::std::tuple<bool, int, int, int, bool> t5(false, 2, 3, 4, true);
+ EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5));
+
+ ::std::tuple<bool, int, int, int, bool, int> t6(false, 2, 3, 4, true, 6);
+ EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6));
+
+ ::std::tuple<bool, int, int, int, bool, int, int> t7(
+ false, 2, 3, 4, true, 6, 7);
+ EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7));
+
+ ::std::tuple<bool, int, int, int, bool, int, int, bool> t8(
+ false, 2, 3, 4, true, 6, 7, true);
+ EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8));
+
+ ::std::tuple<bool, int, int, int, bool, int, int, bool, int> t9(
+ false, 2, 3, 4, true, 6, 7, true, 9);
+ EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9));
+
+ const char* const str = "8";
+ // VC++ 2010's implementation of tuple of C++0x is deficient, requiring
+ // an explicit type cast of NULL to be used.
+ ::std::tuple<bool, char, short, testing::internal::Int32, // NOLINT
+ testing::internal::Int64, float, double, const char*, void*, string>
+ t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str,
+ ImplicitCast_<void*>(NULL), "10");
+ EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) +
+ " pointing to \"8\", NULL, \"10\")",
+ Print(t10));
+}
+
+// Nested tuples.
+TEST(PrintStdTupleTest, NestedTuple) {
+ ::std::tuple< ::std::tuple<int, bool>, char> nested(
+ ::std::make_tuple(5, true), 'a');
+ EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested));
+}
+
+#endif // GTEST_LANG_CXX11
+
// Tests printing user-defined unprintable types.
// Unprintable types in the global namespace.
@@ -1102,44 +1177,6 @@
Print(::foo::PrintableViaPrintToTemplate<int>(5)));
}
-#if GTEST_HAS_PROTOBUF_
-
-// Tests printing a protocol message.
-TEST(PrintProtocolMessageTest, PrintsShortDebugString) {
- testing::internal::TestMessage msg;
- msg.set_member("yes");
- EXPECT_EQ("<member:\"yes\">", Print(msg));
-}
-
-// Tests printing a short proto2 message.
-TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) {
- testing::internal::FooMessage msg;
- msg.set_int_field(2);
- msg.set_string_field("hello");
- EXPECT_PRED2(RE::FullMatch, Print(msg),
- "<int_field:\\s*2\\s+string_field:\\s*\"hello\">");
-}
-
-// Tests printing a long proto2 message.
-TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) {
- testing::internal::FooMessage msg;
- msg.set_int_field(2);
- msg.set_string_field("hello");
- msg.add_names("peter");
- msg.add_names("paul");
- msg.add_names("mary");
- EXPECT_PRED2(RE::FullMatch, Print(msg),
- "<\n"
- "int_field:\\s*2\n"
- "string_field:\\s*\"hello\"\n"
- "names:\\s*\"peter\"\n"
- "names:\\s*\"paul\"\n"
- "names:\\s*\"mary\"\n"
- ">");
-}
-
-#endif // GTEST_HAS_PROTOBUF_
-
// Tests that the universal printer prints both the address and the
// value of a reference.
TEST(PrintReferenceTest, PrintsAddressAndValue) {
@@ -1528,28 +1565,31 @@
#if GTEST_HAS_TR1_TUPLE
-TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) {
- Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple());
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsEmptyTuple) {
+ Strings result = UniversalTersePrintTupleFieldsToStrings(
+ ::std::tr1::make_tuple());
EXPECT_EQ(0u, result.size());
}
-TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) {
- Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1));
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsOneTuple) {
+ Strings result = UniversalTersePrintTupleFieldsToStrings(
+ ::std::tr1::make_tuple(1));
ASSERT_EQ(1u, result.size());
EXPECT_EQ("1", result[0]);
}
-TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) {
- Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a'));
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsTwoTuple) {
+ Strings result = UniversalTersePrintTupleFieldsToStrings(
+ ::std::tr1::make_tuple(1, 'a'));
ASSERT_EQ(2u, result.size());
EXPECT_EQ("1", result[0]);
EXPECT_EQ("'a' (97, 0x61)", result[1]);
}
-TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) {
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithTr1, PrintsTersely) {
const int n = 1;
Strings result = UniversalTersePrintTupleFieldsToStrings(
- tuple<const int&, const char*>(n, "a"));
+ ::std::tr1::tuple<const int&, const char*>(n, "a"));
ASSERT_EQ(2u, result.size());
EXPECT_EQ("1", result[0]);
EXPECT_EQ("\"a\"", result[1]);
@@ -1557,5 +1597,39 @@
#endif // GTEST_HAS_TR1_TUPLE
+#if GTEST_HAS_STD_TUPLE_
+
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) {
+ Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple());
+ EXPECT_EQ(0u, result.size());
+}
+
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) {
+ Strings result = UniversalTersePrintTupleFieldsToStrings(
+ ::std::make_tuple(1));
+ ASSERT_EQ(1u, result.size());
+ EXPECT_EQ("1", result[0]);
+}
+
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTwoTuple) {
+ Strings result = UniversalTersePrintTupleFieldsToStrings(
+ ::std::make_tuple(1, 'a'));
+ ASSERT_EQ(2u, result.size());
+ EXPECT_EQ("1", result[0]);
+ EXPECT_EQ("'a' (97, 0x61)", result[1]);
+}
+
+TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
+ const int n = 1;
+ Strings result = UniversalTersePrintTupleFieldsToStrings(
+ ::std::tuple<const int&, const char*>(n, "a"));
+ ASSERT_EQ(2u, result.size());
+ EXPECT_EQ("1", result[0]);
+ EXPECT_EQ("\"a\"", result[1]);
+}
+
+#endif // GTEST_HAS_STD_TUPLE_
+
} // namespace gtest_printers_test
} // namespace testing
+
diff --git a/src/testing/gtest/test/gtest-typed-test_test.cc b/src/testing/gtest/test/gtest-typed-test_test.cc
index dd4ba43..93628ba 100644
--- a/src/testing/gtest/test/gtest-typed-test_test.cc
+++ b/src/testing/gtest/test/gtest-typed-test_test.cc
@@ -29,10 +29,11 @@
//
// Author: wan@google.com (Zhanyong Wan)
+#include "test/gtest-typed-test_test.h"
+
#include <set>
#include <vector>
-#include "test/gtest-typed-test_test.h"
#include "gtest/gtest.h"
using testing::Test;
@@ -343,6 +344,25 @@
typedef Types<int, double> NumericTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes);
+static const char* GetTestName() {
+ return testing::UnitTest::GetInstance()->current_test_info()->name();
+}
+// Test the stripping of space from test names
+template <typename T> class TrimmedTest : public Test { };
+TYPED_TEST_CASE_P(TrimmedTest);
+TYPED_TEST_P(TrimmedTest, Test1) { EXPECT_STREQ("Test1", GetTestName()); }
+TYPED_TEST_P(TrimmedTest, Test2) { EXPECT_STREQ("Test2", GetTestName()); }
+TYPED_TEST_P(TrimmedTest, Test3) { EXPECT_STREQ("Test3", GetTestName()); }
+TYPED_TEST_P(TrimmedTest, Test4) { EXPECT_STREQ("Test4", GetTestName()); }
+TYPED_TEST_P(TrimmedTest, Test5) { EXPECT_STREQ("Test5", GetTestName()); }
+REGISTER_TYPED_TEST_CASE_P(
+ TrimmedTest,
+ Test1, Test2,Test3 , Test4 ,Test5 ); // NOLINT
+template <typename T1, typename T2> struct MyPair {};
+// Be sure to try a type with a comma in its name just in case it matters.
+typedef Types<int, double, MyPair<int, int> > TrimTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, TrimmedTest, TrimTypes);
+
} // namespace library2
#endif // GTEST_HAS_TYPED_TEST_P
diff --git a/src/testing/gtest/test/gtest-unittest-api_test.cc b/src/testing/gtest/test/gtest-unittest-api_test.cc
index 07083e5..b1f5168 100644
--- a/src/testing/gtest/test/gtest-unittest-api_test.cc
+++ b/src/testing/gtest/test/gtest-unittest-api_test.cc
@@ -54,7 +54,7 @@
public:
// Returns the array of pointers to all test cases sorted by the test case
// name. The caller is responsible for deleting the array.
- static TestCase const** const GetSortedTestCases() {
+ static TestCase const** GetSortedTestCases() {
UnitTest& unit_test = *UnitTest::GetInstance();
TestCase const** const test_cases =
new const TestCase*[unit_test.total_test_case_count()];
@@ -83,7 +83,7 @@
// Returns the array of pointers to all tests in a particular test case
// sorted by the test name. The caller is responsible for deleting the
// array.
- static TestInfo const** const GetSortedTests(const TestCase* test_case) {
+ static TestInfo const** GetSortedTests(const TestCase* test_case) {
TestInfo const** const tests =
new const TestInfo*[test_case->total_test_count()];
diff --git a/src/testing/gtest/test/gtest_break_on_failure_unittest.py b/src/testing/gtest/test/gtest_break_on_failure_unittest.py
index c819183..78f3e0f 100755
--- a/src/testing/gtest/test/gtest_break_on_failure_unittest.py
+++ b/src/testing/gtest/test/gtest_break_on_failure_unittest.py
@@ -66,21 +66,15 @@
'gtest_break_on_failure_unittest_')
-# Utilities.
+environ = gtest_test_utils.environ
+SetEnvVar = gtest_test_utils.SetEnvVar
-
-environ = os.environ.copy()
-
-
-def SetEnvVar(env_var, value):
- """Sets an environment variable to a given value; unsets it when the
- given value is None.
- """
-
- if value is not None:
- environ[env_var] = value
- elif env_var in environ:
- del environ[env_var]
+# Tests in this file run a Google-Test-based test program and expect it
+# to terminate prematurely. Therefore they are incompatible with
+# the premature-exit-file protocol by design. Unset the
+# premature-exit filepath to prevent Google Test from creating
+# the file.
+SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None)
def Run(command):
diff --git a/src/testing/gtest/test/gtest_catch_exceptions_test.py b/src/testing/gtest/test/gtest_catch_exceptions_test.py
index d7ef10e..e6fc22f 100755
--- a/src/testing/gtest/test/gtest_catch_exceptions_test.py
+++ b/src/testing/gtest/test/gtest_catch_exceptions_test.py
@@ -57,14 +57,27 @@
EXE_PATH = gtest_test_utils.GetTestExecutablePath(
'gtest_catch_exceptions_no_ex_test_')
-TEST_LIST = gtest_test_utils.Subprocess([EXE_PATH, LIST_TESTS_FLAG]).output
+environ = gtest_test_utils.environ
+SetEnvVar = gtest_test_utils.SetEnvVar
+
+# Tests in this file run a Google-Test-based test program and expect it
+# to terminate prematurely. Therefore they are incompatible with
+# the premature-exit-file protocol by design. Unset the
+# premature-exit filepath to prevent Google Test from creating
+# the file.
+SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None)
+
+TEST_LIST = gtest_test_utils.Subprocess(
+ [EXE_PATH, LIST_TESTS_FLAG], env=environ).output
SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST
if SUPPORTS_SEH_EXCEPTIONS:
- BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH]).output
+ BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output
-EX_BINARY_OUTPUT = gtest_test_utils.Subprocess([EX_EXE_PATH]).output
+EX_BINARY_OUTPUT = gtest_test_utils.Subprocess(
+ [EX_EXE_PATH], env=environ).output
+
# The tests.
if SUPPORTS_SEH_EXCEPTIONS:
@@ -212,7 +225,8 @@
uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess(
[EX_EXE_PATH,
NO_CATCH_EXCEPTIONS_FLAG,
- FITLER_OUT_SEH_TESTS_FLAG]).output
+ FITLER_OUT_SEH_TESTS_FLAG],
+ env=environ).output
self.assert_('Unhandled C++ exception terminating the program'
in uncaught_exceptions_ex_binary_output)
diff --git a/src/testing/gtest/test/gtest_list_tests_unittest.py b/src/testing/gtest/test/gtest_list_tests_unittest.py
index ce8c3ef..925b09d 100755
--- a/src/testing/gtest/test/gtest_list_tests_unittest.py
+++ b/src/testing/gtest/test/gtest_list_tests_unittest.py
@@ -40,6 +40,7 @@
__author__ = 'phanna@google.com (Patrick Hanna)'
import gtest_test_utils
+import re
# Constants.
@@ -52,38 +53,63 @@
# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests
-EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest.
+EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\.
Test1
-Foo.
+Foo\.
Bar1
Bar2
DISABLED_Bar3
-Abc.
+Abc\.
Xyz
Def
-FooBar.
+FooBar\.
Baz
-FooTest.
+FooTest\.
Test1
DISABLED_Test2
Test3
-"""
+TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
+ TestA
+ TestB
+TypedTest/1\. # TypeParam = int\s*\*
+ TestA
+ TestB
+TypedTest/2\. # TypeParam = .*MyArray<bool,\s*42>
+ TestA
+ TestB
+My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
+ TestA
+ TestB
+My/TypeParamTest/1\. # TypeParam = int\s*\*
+ TestA
+ TestB
+My/TypeParamTest/2\. # TypeParam = .*MyArray<bool,\s*42>
+ TestA
+ TestB
+MyInstantiation/ValueParamTest\.
+ TestA/0 # GetParam\(\) = one line
+ TestA/1 # GetParam\(\) = two\\nlines
+ TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
+ TestB/0 # GetParam\(\) = one line
+ TestB/1 # GetParam\(\) = two\\nlines
+ TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
+""")
# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests and --gtest_filter=Foo*.
-EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest.
+EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\.
Test1
-Foo.
+Foo\.
Bar1
Bar2
DISABLED_Bar3
-FooBar.
+FooBar\.
Baz
-FooTest.
+FooTest\.
Test1
DISABLED_Test2
Test3
-"""
+""")
# Utilities.
@@ -100,19 +126,18 @@
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests."""
- def RunAndVerify(self, flag_value, expected_output, other_flag):
+ def RunAndVerify(self, flag_value, expected_output_re, other_flag):
"""Runs gtest_list_tests_unittest_ and verifies that it prints
the correct tests.
Args:
- flag_value: value of the --gtest_list_tests flag;
- None if the flag should not be present.
-
- expected_output: the expected output after running command;
-
- other_flag: a different flag to be passed to command
- along with gtest_list_tests;
- None if the flag should not be present.
+ flag_value: value of the --gtest_list_tests flag;
+ None if the flag should not be present.
+ expected_output_re: regular expression that matches the expected
+ output after running command;
+ other_flag: a different flag to be passed to command
+ along with gtest_list_tests;
+ None if the flag should not be present.
"""
if flag_value is None:
@@ -132,36 +157,41 @@
output = Run(args)
- msg = ('when %s is %s, the output of "%s" is "%s".' %
- (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))
-
- if expected_output is not None:
- self.assert_(output == expected_output, msg)
+ if expected_output_re:
+ self.assert_(
+ expected_output_re.match(output),
+ ('when %s is %s, the output of "%s" is "%s",\n'
+ 'which does not match regex "%s"' %
+ (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output,
+ expected_output_re.pattern)))
else:
- self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg)
+ self.assert_(
+ not EXPECTED_OUTPUT_NO_FILTER_RE.match(output),
+ ('when %s is %s, the output of "%s" is "%s"'%
+ (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)))
def testDefaultBehavior(self):
"""Tests the behavior of the default mode."""
self.RunAndVerify(flag_value=None,
- expected_output=None,
+ expected_output_re=None,
other_flag=None)
def testFlag(self):
"""Tests using the --gtest_list_tests flag."""
self.RunAndVerify(flag_value='0',
- expected_output=None,
+ expected_output_re=None,
other_flag=None)
self.RunAndVerify(flag_value='1',
- expected_output=EXPECTED_OUTPUT_NO_FILTER,
+ expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag=None)
def testOverrideNonFilterFlags(self):
"""Tests that --gtest_list_tests overrides the non-filter flags."""
self.RunAndVerify(flag_value='1',
- expected_output=EXPECTED_OUTPUT_NO_FILTER,
+ expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag='--gtest_break_on_failure')
def testWithFilterFlags(self):
@@ -169,7 +199,7 @@
--gtest_filter flag."""
self.RunAndVerify(flag_value='1',
- expected_output=EXPECTED_OUTPUT_FILTER_FOO,
+ expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE,
other_flag='--gtest_filter=Foo*')
diff --git a/src/testing/gtest/test/gtest_list_tests_unittest_.cc b/src/testing/gtest/test/gtest_list_tests_unittest_.cc
index 2b1d078..907c176 100644
--- a/src/testing/gtest/test/gtest_list_tests_unittest_.cc
+++ b/src/testing/gtest/test/gtest_list_tests_unittest_.cc
@@ -40,8 +40,6 @@
#include "gtest/gtest.h"
-namespace {
-
// Several different test cases and tests that will be listed.
TEST(Foo, Bar1) {
}
@@ -76,7 +74,81 @@
TEST(FooDeathTest, Test1) {
}
-} // namespace
+// A group of value-parameterized tests.
+
+class MyType {
+ public:
+ explicit MyType(const std::string& a_value) : value_(a_value) {}
+
+ const std::string& value() const { return value_; }
+
+ private:
+ std::string value_;
+};
+
+// Teaches Google Test how to print a MyType.
+void PrintTo(const MyType& x, std::ostream* os) {
+ *os << x.value();
+}
+
+class ValueParamTest : public testing::TestWithParam<MyType> {
+};
+
+TEST_P(ValueParamTest, TestA) {
+}
+
+TEST_P(ValueParamTest, TestB) {
+}
+
+INSTANTIATE_TEST_CASE_P(
+ MyInstantiation, ValueParamTest,
+ testing::Values(MyType("one line"),
+ MyType("two\nlines"),
+ MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT
+
+// A group of typed tests.
+
+// A deliberately long type name for testing the line-truncating
+// behavior when printing a type parameter.
+class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT
+};
+
+template <typename T>
+class TypedTest : public testing::Test {
+};
+
+template <typename T, int kSize>
+class MyArray {
+};
+
+typedef testing::Types<VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName, // NOLINT
+ int*, MyArray<bool, 42> > MyTypes;
+
+TYPED_TEST_CASE(TypedTest, MyTypes);
+
+TYPED_TEST(TypedTest, TestA) {
+}
+
+TYPED_TEST(TypedTest, TestB) {
+}
+
+// A group of type-parameterized tests.
+
+template <typename T>
+class TypeParamTest : public testing::Test {
+};
+
+TYPED_TEST_CASE_P(TypeParamTest);
+
+TYPED_TEST_P(TypeParamTest, TestA) {
+}
+
+TYPED_TEST_P(TypeParamTest, TestB) {
+}
+
+REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB);
+
+INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes);
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/src/testing/gtest/test/gtest_output_test.py b/src/testing/gtest/test/gtest_output_test.py
index f409e2a..d5c637b 100755
--- a/src/testing/gtest/test/gtest_output_test.py
+++ b/src/testing/gtest/test/gtest_output_test.py
@@ -40,6 +40,7 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
+import difflib
import os
import re
import sys
@@ -58,22 +59,22 @@
PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_')
# At least one command we exercise must not have the
-# --gtest_internal_skip_environment_and_ad_hoc_tests flag.
+# 'internal_skip_environment_and_ad_hoc_tests' argument.
COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests'])
COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes'])
COMMAND_WITH_TIME = ({}, [PROGRAM_PATH,
'--gtest_print_time',
- '--gtest_internal_skip_environment_and_ad_hoc_tests',
+ 'internal_skip_environment_and_ad_hoc_tests',
'--gtest_filter=FatalFailureTest.*:LoggingTest.*'])
COMMAND_WITH_DISABLED = (
{}, [PROGRAM_PATH,
'--gtest_also_run_disabled_tests',
- '--gtest_internal_skip_environment_and_ad_hoc_tests',
+ 'internal_skip_environment_and_ad_hoc_tests',
'--gtest_filter=*DISABLED_*'])
COMMAND_WITH_SHARDING = (
{'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'},
[PROGRAM_PATH,
- '--gtest_internal_skip_environment_and_ad_hoc_tests',
+ 'internal_skip_environment_and_ad_hoc_tests',
'--gtest_filter=PassingTest.*'])
GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME)
@@ -252,8 +253,8 @@
CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and
SUPPORTS_TYPED_TESTS and
- SUPPORTS_THREADS)
-
+ SUPPORTS_THREADS and
+ not IS_WINDOWS)
class GTestOutputTest(gtest_test_utils.TestCase):
def RemoveUnsupportedTests(self, test_output):
@@ -294,7 +295,11 @@
normalized_golden = RemoveTypeInfoDetails(golden)
if CAN_GENERATE_GOLDEN_FILE:
- self.assertEqual(normalized_golden, normalized_actual)
+ self.assertEqual(normalized_golden, normalized_actual,
+ '\n'.join(difflib.unified_diff(
+ normalized_golden.split('\n'),
+ normalized_actual.split('\n'),
+ 'golden', 'actual')))
else:
normalized_actual = NormalizeToCurrentPlatform(
RemoveTestCounts(normalized_actual))
diff --git a/src/testing/gtest/test/gtest_output_test_.cc b/src/testing/gtest/test/gtest_output_test_.cc
index 07ab633..1070a9f 100644
--- a/src/testing/gtest/test/gtest_output_test_.cc
+++ b/src/testing/gtest/test/gtest_output_test_.cc
@@ -58,7 +58,6 @@
#endif
namespace posix = ::testing::internal::posix;
-using testing::internal::scoped_ptr;
// Tests catching fatal failures.
@@ -113,6 +112,11 @@
EXPECT_EQ(golden, actual);
}
+TEST(NonfatalFailureTest, DiffForLongStrings) {
+ std::string golden_str(kGoldenString, sizeof(kGoldenString) - 1);
+ EXPECT_EQ(golden_str, "Line 2");
+}
+
// Tests catching a fatal failure in a subroutine.
TEST(FatalFailureTest, FatalFailureInSubroutine) {
printf("(expecting a failure that x should be 1)\n");
@@ -510,7 +514,8 @@
private:
SpawnThreadNotifications notifications_;
- scoped_ptr<ThreadWithParam<SpawnThreadNotifications*> > thread_;
+ testing::internal::scoped_ptr<ThreadWithParam<SpawnThreadNotifications*> >
+ thread_;
};
#endif // GTEST_IS_THREADSAFE
@@ -750,6 +755,32 @@
#endif // GTEST_HAS_EXCEPTIONS
+// This #ifdef block tests the output of value-parameterized tests.
+
+#if GTEST_HAS_PARAM_TEST
+
+std::string ParamNameFunc(const testing::TestParamInfo<std::string>& info) {
+ return info.param;
+}
+
+class ParamTest : public testing::TestWithParam<std::string> {
+};
+
+TEST_P(ParamTest, Success) {
+ EXPECT_EQ("a", GetParam());
+}
+
+TEST_P(ParamTest, Failure) {
+ EXPECT_EQ("b", GetParam()) << "Expected failure";
+}
+
+INSTANTIATE_TEST_CASE_P(PrintingStrings,
+ ParamTest,
+ testing::Values(std::string("a")),
+ ParamNameFunc);
+
+#endif // GTEST_HAS_PARAM_TEST
+
// This #ifdef block tests the output of typed tests.
#if GTEST_HAS_TYPED_TEST
@@ -985,8 +1016,6 @@
}
};
-bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false;
-
// The main function.
//
// The idea is to use Google Test to run all the tests we have defined (some
@@ -1003,10 +1032,9 @@
// global side effects. The following line serves as a sanity test
// for it.
testing::InitGoogleTest(&argc, argv);
- if (argc >= 2 &&
- (std::string(argv[1]) ==
- "--gtest_internal_skip_environment_and_ad_hoc_tests"))
- GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true;
+ bool internal_skip_environment_and_ad_hoc_tests =
+ std::count(argv, argv + argc,
+ std::string("internal_skip_environment_and_ad_hoc_tests")) > 0;
#if GTEST_HAS_DEATH_TEST
if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") {
@@ -1021,7 +1049,7 @@
}
#endif // GTEST_HAS_DEATH_TEST
- if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests))
+ if (internal_skip_environment_and_ad_hoc_tests)
return RUN_ALL_TESTS();
// Registers two global test environments.
diff --git a/src/testing/gtest/test/gtest_output_test_golden_lin.txt b/src/testing/gtest/test/gtest_output_test_golden_lin.txt
index 0e26d63..7fff853 100644
--- a/src/testing/gtest/test/gtest_output_test_golden_lin.txt
+++ b/src/testing/gtest/test/gtest_output_test_golden_lin.txt
@@ -7,7 +7,7 @@
gtest_output_test_.cc:#: Failure
Value of: 3
Expected: 2
-[0;32m[==========] [mRunning 63 tests from 28 test cases.
+[0;32m[==========] [mRunning 66 tests from 29 test cases.
[0;32m[----------] [mGlobal test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
@@ -31,7 +31,7 @@
[0;32m[ OK ] [mPassingTest.PassingTest1
[0;32m[ RUN ] [mPassingTest.PassingTest2
[0;32m[ OK ] [mPassingTest.PassingTest2
-[0;32m[----------] [m1 test from NonfatalFailureTest
+[0;32m[----------] [m2 tests from NonfatalFailureTest
[0;32m[ RUN ] [mNonfatalFailureTest.EscapesStringOperands
gtest_output_test_.cc:#: Failure
Value of: actual
@@ -44,6 +44,17 @@
Expected: golden
Which is: "\"Line"
[0;31m[ FAILED ] [mNonfatalFailureTest.EscapesStringOperands
+[0;32m[ RUN ] [mNonfatalFailureTest.DiffForLongStrings
+gtest_output_test_.cc:#: Failure
+Value of: "Line 2"
+Expected: golden_str
+Which is: "\"Line\0 1\"\nLine 2"
+With diff:
+@@ -1,2 @@
+-\"Line\0 1\"
+ Line 2
+
+[0;31m[ FAILED ] [mNonfatalFailureTest.DiffForLongStrings
[0;32m[----------] [m3 tests from FatalFailureTest
[0;32m[ RUN ] [mFatalFailureTest.FatalFailureInSubroutine
(expecting a failure that x should be 1)
@@ -590,6 +601,16 @@
Actual: 2
Expected: 1
[0;31m[ FAILED ] [mPrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
+[0;32m[----------] [m2 tests from PrintingStrings/ParamTest
+[0;32m[ RUN ] [mPrintingStrings/ParamTest.Success/a
+[0;32m[ OK ] [mPrintingStrings/ParamTest.Success/a
+[0;32m[ RUN ] [mPrintingStrings/ParamTest.Failure/a
+gtest_output_test_.cc:#: Failure
+Value of: GetParam()
+ Actual: "a"
+Expected: "b"
+Expected failure
+[0;31m[ FAILED ] [mPrintingStrings/ParamTest.Failure/a, where GetParam() = "a"
[0;32m[----------] [mGlobal test environment tear-down
BarEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
@@ -599,10 +620,11 @@
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
-[0;32m[==========] [m63 tests from 28 test cases ran.
-[0;32m[ PASSED ] [m21 tests.
-[0;31m[ FAILED ] [m42 tests, listed below:
+[0;32m[==========] [m66 tests from 29 test cases ran.
+[0;32m[ PASSED ] [m22 tests.
+[0;31m[ FAILED ] [m44 tests, listed below:
[0;31m[ FAILED ] [mNonfatalFailureTest.EscapesStringOperands
+[0;31m[ FAILED ] [mNonfatalFailureTest.DiffForLongStrings
[0;31m[ FAILED ] [mFatalFailureTest.FatalFailureInSubroutine
[0;31m[ FAILED ] [mFatalFailureTest.FatalFailureInNestedSubroutine
[0;31m[ FAILED ] [mFatalFailureTest.NonfatalFailureInSubroutine
@@ -644,8 +666,9 @@
[0;31m[ FAILED ] [mExpectFailureWithThreadsTest.ExpectNonFatalFailure
[0;31m[ FAILED ] [mScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
[0;31m[ FAILED ] [mPrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
+[0;31m[ FAILED ] [mPrintingStrings/ParamTest.Failure/a, where GetParam() = "a"
-42 FAILED TESTS
+44 FAILED TESTS
[0;33m YOU HAVE 1 DISABLED TEST
[mNote: Google Test filter = FatalFailureTest.*:LoggingTest.*
@@ -699,8 +722,6 @@
[ FAILED ] LoggingTest.InterleavingLoggingAndAssertions
4 FAILED TESTS
- YOU HAVE 1 DISABLED TEST
-
Note: Google Test filter = *DISABLED_*
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
@@ -720,6 +741,3 @@
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran.
[ PASSED ] 1 test.
-
- YOU HAVE 1 DISABLED TEST
-
diff --git a/src/testing/gtest/test/gtest_premature_exit_test.cc b/src/testing/gtest/test/gtest_premature_exit_test.cc
new file mode 100644
index 0000000..3b4dc7d
--- /dev/null
+++ b/src/testing/gtest/test/gtest_premature_exit_test.cc
@@ -0,0 +1,127 @@
+// Copyright 2013, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Tests that Google Test manipulates the premature-exit-detection
+// file correctly.
+
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+
+using ::testing::InitGoogleTest;
+using ::testing::Test;
+using ::testing::internal::posix::GetEnv;
+using ::testing::internal::posix::Stat;
+using ::testing::internal::posix::StatStruct;
+
+namespace {
+
+class PrematureExitTest : public Test {
+ public:
+ // Returns true iff the given file exists.
+ static bool FileExists(const char* filepath) {
+ StatStruct stat;
+ return Stat(filepath, &stat) == 0;
+ }
+
+ protected:
+ PrematureExitTest() {
+ premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE");
+
+ // Normalize NULL to "" for ease of handling.
+ if (premature_exit_file_path_ == NULL) {
+ premature_exit_file_path_ = "";
+ }
+ }
+
+ // Returns true iff the premature-exit file exists.
+ bool PrematureExitFileExists() const {
+ return FileExists(premature_exit_file_path_);
+ }
+
+ const char* premature_exit_file_path_;
+};
+
+typedef PrematureExitTest PrematureExitDeathTest;
+
+// Tests that:
+// - the premature-exit file exists during the execution of a
+// death test (EXPECT_DEATH*), and
+// - a death test doesn't interfere with the main test process's
+// handling of the premature-exit file.
+TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) {
+ if (*premature_exit_file_path_ == '\0') {
+ return;
+ }
+
+ EXPECT_DEATH_IF_SUPPORTED({
+ // If the file exists, crash the process such that the main test
+ // process will catch the (expected) crash and report a success;
+ // otherwise don't crash, which will cause the main test process
+ // to report that the death test has failed.
+ if (PrematureExitFileExists()) {
+ exit(1);
+ }
+ }, "");
+}
+
+// Tests that the premature-exit file exists during the execution of a
+// normal (non-death) test.
+TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) {
+ if (*premature_exit_file_path_ == '\0') {
+ return;
+ }
+
+ EXPECT_TRUE(PrematureExitFileExists())
+ << " file " << premature_exit_file_path_
+ << " should exist during test execution, but doesn't.";
+}
+
+} // namespace
+
+int main(int argc, char **argv) {
+ InitGoogleTest(&argc, argv);
+ const int exit_code = RUN_ALL_TESTS();
+
+ // Test that the premature-exit file is deleted upon return from
+ // RUN_ALL_TESTS().
+ const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE");
+ if (filepath != NULL && *filepath != '\0') {
+ if (PrematureExitTest::FileExists(filepath)) {
+ printf(
+ "File %s shouldn't exist after the test program finishes, but does.",
+ filepath);
+ return 1;
+ }
+ }
+
+ return exit_code;
+}
diff --git a/src/testing/gtest/test/gtest_test_utils.py b/src/testing/gtest/test/gtest_test_utils.py
index 6dd8db4..7e3cbca 100755
--- a/src/testing/gtest/test/gtest_test_utils.py
+++ b/src/testing/gtest/test/gtest_test_utils.py
@@ -56,6 +56,21 @@
IS_WINDOWS = os.name == 'nt'
IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
+# The environment variable for specifying the path to the premature-exit file.
+PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE'
+
+environ = os.environ.copy()
+
+
+def SetEnvVar(env_var, value):
+ """Sets/unsets an environment variable to a given value."""
+
+ if value is not None:
+ environ[env_var] = value
+ elif env_var in environ:
+ del environ[env_var]
+
+
# Here we expose a class from a particular module, depending on the
# environment. The comment suppresses the 'Invalid variable name' lint
# complaint.
@@ -160,9 +175,9 @@
if not os.path.exists(path):
message = (
- 'Unable to find the test binary. Please make sure to provide path\n'
- 'to the binary via the --build_dir flag or the BUILD_DIR\n'
- 'environment variable.')
+ 'Unable to find the test binary "%s". Please make sure to provide\n'
+ 'a path to the binary via the --build_dir flag or the BUILD_DIR\n'
+ 'environment variable.' % path)
print >> sys.stderr, message
sys.exit(1)
diff --git a/src/testing/gtest/test/gtest_unittest.cc b/src/testing/gtest/test/gtest_unittest.cc
index f4f3043..60aed35 100644
--- a/src/testing/gtest/test/gtest_unittest.cc
+++ b/src/testing/gtest/test/gtest_unittest.cc
@@ -79,6 +79,82 @@
namespace testing {
namespace internal {
+#if GTEST_CAN_STREAM_RESULTS_
+
+class StreamingListenerTest : public Test {
+ public:
+ class FakeSocketWriter : public StreamingListener::AbstractSocketWriter {
+ public:
+ // Sends a string to the socket.
+ virtual void Send(const string& message) { output_ += message; }
+
+ string output_;
+ };
+
+ StreamingListenerTest()
+ : fake_sock_writer_(new FakeSocketWriter),
+ streamer_(fake_sock_writer_),
+ test_info_obj_("FooTest", "Bar", NULL, NULL,
+ CodeLocation(__FILE__, __LINE__), 0, NULL) {}
+
+ protected:
+ string* output() { return &(fake_sock_writer_->output_); }
+
+ FakeSocketWriter* const fake_sock_writer_;
+ StreamingListener streamer_;
+ UnitTest unit_test_;
+ TestInfo test_info_obj_; // The name test_info_ was taken by testing::Test.
+};
+
+TEST_F(StreamingListenerTest, OnTestProgramEnd) {
+ *output() = "";
+ streamer_.OnTestProgramEnd(unit_test_);
+ EXPECT_EQ("event=TestProgramEnd&passed=1\n", *output());
+}
+
+TEST_F(StreamingListenerTest, OnTestIterationEnd) {
+ *output() = "";
+ streamer_.OnTestIterationEnd(unit_test_, 42);
+ EXPECT_EQ("event=TestIterationEnd&passed=1&elapsed_time=0ms\n", *output());
+}
+
+TEST_F(StreamingListenerTest, OnTestCaseStart) {
+ *output() = "";
+ streamer_.OnTestCaseStart(TestCase("FooTest", "Bar", NULL, NULL));
+ EXPECT_EQ("event=TestCaseStart&name=FooTest\n", *output());
+}
+
+TEST_F(StreamingListenerTest, OnTestCaseEnd) {
+ *output() = "";
+ streamer_.OnTestCaseEnd(TestCase("FooTest", "Bar", NULL, NULL));
+ EXPECT_EQ("event=TestCaseEnd&passed=1&elapsed_time=0ms\n", *output());
+}
+
+TEST_F(StreamingListenerTest, OnTestStart) {
+ *output() = "";
+ streamer_.OnTestStart(test_info_obj_);
+ EXPECT_EQ("event=TestStart&name=Bar\n", *output());
+}
+
+TEST_F(StreamingListenerTest, OnTestEnd) {
+ *output() = "";
+ streamer_.OnTestEnd(test_info_obj_);
+ EXPECT_EQ("event=TestEnd&passed=1&elapsed_time=0ms\n", *output());
+}
+
+TEST_F(StreamingListenerTest, OnTestPartResult) {
+ *output() = "";
+ streamer_.OnTestPartResult(TestPartResult(
+ TestPartResult::kFatalFailure, "foo.cc", 42, "failed=\n&%"));
+
+ // Meta characters in the failure message should be properly escaped.
+ EXPECT_EQ(
+ "event=TestPartResult&file=foo.cc&line=42&message=failed%3D%0A%26%25\n",
+ *output());
+}
+
+#endif // GTEST_CAN_STREAM_RESULTS_
+
// Provides access to otherwise private parts of the TestEventListeners class
// that are needed to test it.
class TestEventListenersAccessor {
@@ -105,6 +181,18 @@
}
};
+class UnitTestRecordPropertyTestHelper : public Test {
+ protected:
+ UnitTestRecordPropertyTestHelper() {}
+
+ // Forwards to UnitTest::RecordProperty() to bypass access controls.
+ void UnitTestRecordProperty(const char* key, const std::string& value) {
+ unit_test_.RecordProperty(key, value);
+ }
+
+ UnitTest unit_test_;
+};
+
} // namespace internal
} // namespace testing
@@ -113,6 +201,7 @@
using testing::AssertionSuccess;
using testing::DoubleLE;
using testing::EmptyTestEventListener;
+using testing::Environment;
using testing::FloatLE;
using testing::GTEST_FLAG(also_run_disabled_tests);
using testing::GTEST_FLAG(break_on_failure);
@@ -138,13 +227,13 @@
using testing::Test;
using testing::TestCase;
using testing::TestEventListeners;
+using testing::TestInfo;
using testing::TestPartResult;
using testing::TestPartResultArray;
using testing::TestProperty;
using testing::TestResult;
using testing::TimeInMillis;
using testing::UnitTest;
-using testing::kMaxStackTraceDepth;
using testing::internal::AddReference;
using testing::internal::AlwaysFalse;
using testing::internal::AlwaysTrue;
@@ -178,6 +267,8 @@
using testing::internal::IsNotContainer;
using testing::internal::NativeArray;
using testing::internal::ParseInt32Flag;
+using testing::internal::RelationToSourceCopy;
+using testing::internal::RelationToSourceReference;
using testing::internal::RemoveConst;
using testing::internal::RemoveReference;
using testing::internal::ShouldRunTestOnShard;
@@ -192,11 +283,12 @@
using testing::internal::TestResultAccessor;
using testing::internal::UInt32;
using testing::internal::WideStringToUtf8;
-using testing::internal::kCopy;
+using testing::internal::edit_distance::CalculateOptimalEdits;
+using testing::internal::edit_distance::CreateUnifiedDiff;
+using testing::internal::edit_distance::EditType;
using testing::internal::kMaxRandomSeed;
-using testing::internal::kReference;
using testing::internal::kTestTypeIdInGoogleTest;
-using testing::internal::scoped_ptr;
+using testing::kMaxStackTraceDepth;
#if GTEST_HAS_STREAM_REDIRECTION
using testing::internal::CaptureStdout;
@@ -328,19 +420,11 @@
private:
virtual void SetUp() {
saved_tz_ = NULL;
-#if _MSC_VER
-# pragma warning(push) // Saves the current warning state.
-# pragma warning(disable:4996) // Temporarily disables warning 4996
- // (function or variable may be unsafe
- // for getenv, function is deprecated for
- // strdup).
+
+ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* getenv, strdup: deprecated */)
if (getenv("TZ"))
saved_tz_ = strdup(getenv("TZ"));
-# pragma warning(pop) // Restores the warning state again.
-#else
- if (getenv("TZ"))
- saved_tz_ = strdup(getenv("TZ"));
-#endif
+ GTEST_DISABLE_MSC_WARNINGS_POP_()
// Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We
// cannot use the local time zone because the function's output depends
@@ -364,11 +448,9 @@
const std::string env_var =
std::string("TZ=") + (time_zone ? time_zone : "");
_putenv(env_var.c_str());
-# pragma warning(push) // Saves the current warning state.
-# pragma warning(disable:4996) // Temporarily disables warning 4996
- // (function is deprecated).
+ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */)
tzset();
-# pragma warning(pop) // Restores the warning state again.
+ GTEST_DISABLE_MSC_WARNINGS_POP_()
#else
if (time_zone) {
setenv(("TZ"), time_zone, 1);
@@ -423,15 +505,6 @@
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0));
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U));
EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L));
-
-# ifndef __BORLANDC__
-
- // Some compilers may fail to detect some null pointer literals;
- // as long as users of the framework don't use such literals, this
- // is harmless.
- EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1));
-
-# endif
}
// Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null
@@ -454,45 +527,41 @@
// Tests that the NUL character L'\0' is encoded correctly.
TEST(CodePointToUtf8Test, CanEncodeNul) {
- char buffer[32];
- EXPECT_STREQ("", CodePointToUtf8(L'\0', buffer));
+ EXPECT_EQ("", CodePointToUtf8(L'\0'));
}
// Tests that ASCII characters are encoded correctly.
TEST(CodePointToUtf8Test, CanEncodeAscii) {
- char buffer[32];
- EXPECT_STREQ("a", CodePointToUtf8(L'a', buffer));
- EXPECT_STREQ("Z", CodePointToUtf8(L'Z', buffer));
- EXPECT_STREQ("&", CodePointToUtf8(L'&', buffer));
- EXPECT_STREQ("\x7F", CodePointToUtf8(L'\x7F', buffer));
+ EXPECT_EQ("a", CodePointToUtf8(L'a'));
+ EXPECT_EQ("Z", CodePointToUtf8(L'Z'));
+ EXPECT_EQ("&", CodePointToUtf8(L'&'));
+ EXPECT_EQ("\x7F", CodePointToUtf8(L'\x7F'));
}
// Tests that Unicode code-points that have 8 to 11 bits are encoded
// as 110xxxxx 10xxxxxx.
TEST(CodePointToUtf8Test, CanEncode8To11Bits) {
- char buffer[32];
// 000 1101 0011 => 110-00011 10-010011
- EXPECT_STREQ("\xC3\x93", CodePointToUtf8(L'\xD3', buffer));
+ EXPECT_EQ("\xC3\x93", CodePointToUtf8(L'\xD3'));
// 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
// introduce such character constants as integers.
- EXPECT_STREQ("\xD5\xB6",
- CodePointToUtf8(static_cast<wchar_t>(0x576), buffer));
+ EXPECT_EQ("\xD5\xB6",
+ CodePointToUtf8(static_cast<wchar_t>(0x576)));
}
// Tests that Unicode code-points that have 12 to 16 bits are encoded
// as 1110xxxx 10xxxxxx 10xxxxxx.
TEST(CodePointToUtf8Test, CanEncode12To16Bits) {
- char buffer[32];
// 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011
- EXPECT_STREQ("\xE0\xA3\x93",
- CodePointToUtf8(static_cast<wchar_t>(0x8D3), buffer));
+ EXPECT_EQ("\xE0\xA3\x93",
+ CodePointToUtf8(static_cast<wchar_t>(0x8D3)));
// 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101
- EXPECT_STREQ("\xEC\x9D\x8D",
- CodePointToUtf8(static_cast<wchar_t>(0xC74D), buffer));
+ EXPECT_EQ("\xEC\x9D\x8D",
+ CodePointToUtf8(static_cast<wchar_t>(0xC74D)));
}
#if !GTEST_WIDE_STRING_USES_UTF16_
@@ -503,22 +572,19 @@
// Tests that Unicode code-points that have 17 to 21 bits are encoded
// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx.
TEST(CodePointToUtf8Test, CanEncode17To21Bits) {
- char buffer[32];
// 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011
- EXPECT_STREQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3', buffer));
+ EXPECT_EQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3'));
// 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000
- EXPECT_STREQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400', buffer));
+ EXPECT_EQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400'));
// 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100
- EXPECT_STREQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634', buffer));
+ EXPECT_EQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634'));
}
// Tests that encoding an invalid code-point generates the expected result.
TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) {
- char buffer[32];
- EXPECT_STREQ("(Invalid Unicode 0x1234ABCD)",
- CodePointToUtf8(L'\x1234ABCD', buffer));
+ EXPECT_EQ("(Invalid Unicode 0x1234ABCD)", CodePointToUtf8(L'\x1234ABCD'));
}
#endif // !GTEST_WIDE_STRING_USES_UTF16_
@@ -960,33 +1026,6 @@
EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar"));
}
-// Tests that String::Format() works.
-TEST(StringTest, FormatWorks) {
- // Normal case: the format spec is valid, the arguments match the
- // spec, and the result is < 4095 characters.
- EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str());
-
- // Edge case: the result is 4095 characters.
- char buffer[4096];
- const size_t kSize = sizeof(buffer);
- memset(buffer, 'a', kSize - 1);
- buffer[kSize - 1] = '\0';
- EXPECT_EQ(buffer, String::Format("%s", buffer));
-
- // The result needs to be 4096 characters, exceeding Format()'s limit.
- EXPECT_EQ("<formatting error or buffer exceeded>",
- String::Format("x%s", buffer));
-
-#if GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID
- // On Linux, invalid format spec should lead to an error message.
- // In other environment (e.g. MSVC on Windows), String::Format() may
- // simply ignore a bad format spec, so this assertion is run on
- // Linux only.
- EXPECT_EQ("<formatting error or buffer exceeded>",
- String::Format("%"));
-#endif
-}
-
#if GTEST_OS_WINDOWS
// Tests String::ShowWideCString().
@@ -1406,7 +1445,7 @@
TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) {
TestResult test_result;
TestProperty property("key_1", "1");
- TestResultAccessor::RecordProperty(&test_result, property);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property);
ASSERT_EQ(1, test_result.test_property_count());
const TestProperty& actual_property = test_result.GetTestProperty(0);
EXPECT_STREQ("key_1", actual_property.key());
@@ -1418,8 +1457,8 @@
TestResult test_result;
TestProperty property_1("key_1", "1");
TestProperty property_2("key_2", "2");
- TestResultAccessor::RecordProperty(&test_result, property_1);
- TestResultAccessor::RecordProperty(&test_result, property_2);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_1);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_2);
ASSERT_EQ(2, test_result.test_property_count());
const TestProperty& actual_property_1 = test_result.GetTestProperty(0);
EXPECT_STREQ("key_1", actual_property_1.key());
@@ -1437,10 +1476,10 @@
TestProperty property_2_1("key_2", "2");
TestProperty property_1_2("key_1", "12");
TestProperty property_2_2("key_2", "22");
- TestResultAccessor::RecordProperty(&test_result, property_1_1);
- TestResultAccessor::RecordProperty(&test_result, property_2_1);
- TestResultAccessor::RecordProperty(&test_result, property_1_2);
- TestResultAccessor::RecordProperty(&test_result, property_2_2);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_1);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_1);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_2);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_2);
ASSERT_EQ(2, test_result.test_property_count());
const TestProperty& actual_property_1 = test_result.GetTestProperty(0);
@@ -1453,14 +1492,14 @@
}
// Tests TestResult::GetTestProperty().
-TEST(TestResultPropertyDeathTest, GetTestProperty) {
+TEST(TestResultPropertyTest, GetTestProperty) {
TestResult test_result;
TestProperty property_1("key_1", "1");
TestProperty property_2("key_2", "2");
TestProperty property_3("key_3", "3");
- TestResultAccessor::RecordProperty(&test_result, property_1);
- TestResultAccessor::RecordProperty(&test_result, property_2);
- TestResultAccessor::RecordProperty(&test_result, property_3);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_1);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_2);
+ TestResultAccessor::RecordProperty(&test_result, "testcase", property_3);
const TestProperty& fetched_property_1 = test_result.GetTestProperty(0);
const TestProperty& fetched_property_2 = test_result.GetTestProperty(1);
@@ -1479,41 +1518,15 @@
EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), "");
}
-// When a property using a reserved key is supplied to this function, it tests
-// that a non-fatal failure is added, a fatal failure is not added, and that the
-// property is not recorded.
-void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) {
- TestResult test_result;
- TestProperty property(key, "1");
- EXPECT_NONFATAL_FAILURE(
- TestResultAccessor::RecordProperty(&test_result, property),
- "Reserved key");
- ASSERT_EQ(0, test_result.test_property_count()) << "Not recorded";
-}
-
-// Attempting to recording a property with the Reserved literal "name"
-// should add a non-fatal failure and the property should not be recorded.
-TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledName) {
- ExpectNonFatalFailureRecordingPropertyWithReservedKey("name");
-}
-
-// Attempting to recording a property with the Reserved literal "status"
-// should add a non-fatal failure and the property should not be recorded.
-TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledStatus) {
- ExpectNonFatalFailureRecordingPropertyWithReservedKey("status");
-}
-
-// Attempting to recording a property with the Reserved literal "time"
-// should add a non-fatal failure and the property should not be recorded.
-TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledTime) {
- ExpectNonFatalFailureRecordingPropertyWithReservedKey("time");
-}
-
-// Attempting to recording a property with the Reserved literal "classname"
-// should add a non-fatal failure and the property should not be recorded.
-TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledClassname) {
- ExpectNonFatalFailureRecordingPropertyWithReservedKey("classname");
-}
+// Tests the Test class.
+//
+// It's difficult to test every public method of this class (we are
+// already stretching the limit of Google Test by using it to test itself!).
+// Fortunately, we don't have to do that, as we are already testing
+// the functionalities of the Test class extensively by using Google Test
+// alone.
+//
+// Therefore, this section only contains one test.
// Tests that GTestFlagSaver works on Windows and Mac.
@@ -1658,6 +1671,8 @@
EXPECT_EQ(10, Int32FromGTestEnv("temp", 10));
}
+# if !defined(GTEST_GET_INT32_FROM_ENV_)
+
// Tests that Int32FromGTestEnv() returns the default value when the
// environment variable overflows as an Int32.
TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) {
@@ -1682,6 +1697,8 @@
EXPECT_EQ(50, Int32FromGTestEnv("temp", 50));
}
+# endif // !defined(GTEST_GET_INT32_FROM_ENV_)
+
// Tests that Int32FromGTestEnv() parses and returns the value of the
// environment variable when it represents a valid decimal integer in
// the range of an Int32.
@@ -1920,6 +1937,168 @@
EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis());
}
+// When a property using a reserved key is supplied to this function, it
+// tests that a non-fatal failure is added, a fatal failure is not added,
+// and that the property is not recorded.
+void ExpectNonFatalFailureRecordingPropertyWithReservedKey(
+ const TestResult& test_result, const char* key) {
+ EXPECT_NONFATAL_FAILURE(Test::RecordProperty(key, "1"), "Reserved key");
+ ASSERT_EQ(0, test_result.test_property_count()) << "Property for key '" << key
+ << "' recorded unexpectedly.";
+}
+
+void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ const char* key) {
+ const TestInfo* test_info = UnitTest::GetInstance()->current_test_info();
+ ASSERT_TRUE(test_info != NULL);
+ ExpectNonFatalFailureRecordingPropertyWithReservedKey(*test_info->result(),
+ key);
+}
+
+void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ const char* key) {
+ const TestCase* test_case = UnitTest::GetInstance()->current_test_case();
+ ASSERT_TRUE(test_case != NULL);
+ ExpectNonFatalFailureRecordingPropertyWithReservedKey(
+ test_case->ad_hoc_test_result(), key);
+}
+
+void ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ const char* key) {
+ ExpectNonFatalFailureRecordingPropertyWithReservedKey(
+ UnitTest::GetInstance()->ad_hoc_test_result(), key);
+}
+
+// Tests that property recording functions in UnitTest outside of tests
+// functions correcly. Creating a separate instance of UnitTest ensures it
+// is in a state similar to the UnitTest's singleton's between tests.
+class UnitTestRecordPropertyTest :
+ public testing::internal::UnitTestRecordPropertyTestHelper {
+ public:
+ static void SetUpTestCase() {
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ "disabled");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ "errors");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ "failures");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ "name");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ "tests");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase(
+ "time");
+
+ Test::RecordProperty("test_case_key_1", "1");
+ const TestCase* test_case = UnitTest::GetInstance()->current_test_case();
+ ASSERT_TRUE(test_case != NULL);
+
+ ASSERT_EQ(1, test_case->ad_hoc_test_result().test_property_count());
+ EXPECT_STREQ("test_case_key_1",
+ test_case->ad_hoc_test_result().GetTestProperty(0).key());
+ EXPECT_STREQ("1",
+ test_case->ad_hoc_test_result().GetTestProperty(0).value());
+ }
+};
+
+// Tests TestResult has the expected property when added.
+TEST_F(UnitTestRecordPropertyTest, OnePropertyFoundWhenAdded) {
+ UnitTestRecordProperty("key_1", "1");
+
+ ASSERT_EQ(1, unit_test_.ad_hoc_test_result().test_property_count());
+
+ EXPECT_STREQ("key_1",
+ unit_test_.ad_hoc_test_result().GetTestProperty(0).key());
+ EXPECT_STREQ("1",
+ unit_test_.ad_hoc_test_result().GetTestProperty(0).value());
+}
+
+// Tests TestResult has multiple properties when added.
+TEST_F(UnitTestRecordPropertyTest, MultiplePropertiesFoundWhenAdded) {
+ UnitTestRecordProperty("key_1", "1");
+ UnitTestRecordProperty("key_2", "2");
+
+ ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count());
+
+ EXPECT_STREQ("key_1",
+ unit_test_.ad_hoc_test_result().GetTestProperty(0).key());
+ EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value());
+
+ EXPECT_STREQ("key_2",
+ unit_test_.ad_hoc_test_result().GetTestProperty(1).key());
+ EXPECT_STREQ("2", unit_test_.ad_hoc_test_result().GetTestProperty(1).value());
+}
+
+// Tests TestResult::RecordProperty() overrides values for duplicate keys.
+TEST_F(UnitTestRecordPropertyTest, OverridesValuesForDuplicateKeys) {
+ UnitTestRecordProperty("key_1", "1");
+ UnitTestRecordProperty("key_2", "2");
+ UnitTestRecordProperty("key_1", "12");
+ UnitTestRecordProperty("key_2", "22");
+
+ ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count());
+
+ EXPECT_STREQ("key_1",
+ unit_test_.ad_hoc_test_result().GetTestProperty(0).key());
+ EXPECT_STREQ("12",
+ unit_test_.ad_hoc_test_result().GetTestProperty(0).value());
+
+ EXPECT_STREQ("key_2",
+ unit_test_.ad_hoc_test_result().GetTestProperty(1).key());
+ EXPECT_STREQ("22",
+ unit_test_.ad_hoc_test_result().GetTestProperty(1).value());
+}
+
+TEST_F(UnitTestRecordPropertyTest,
+ AddFailureInsideTestsWhenUsingTestCaseReservedKeys) {
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ "name");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ "value_param");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ "type_param");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ "status");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ "time");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest(
+ "classname");
+}
+
+TEST_F(UnitTestRecordPropertyTest,
+ AddRecordWithReservedKeysGeneratesCorrectPropertyList) {
+ EXPECT_NONFATAL_FAILURE(
+ Test::RecordProperty("name", "1"),
+ "'classname', 'name', 'status', 'time', 'type_param', and 'value_param'"
+ " are reserved");
+}
+
+class UnitTestRecordPropertyTestEnvironment : public Environment {
+ public:
+ virtual void TearDown() {
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "tests");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "failures");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "disabled");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "errors");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "name");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "timestamp");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "time");
+ ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase(
+ "random_seed");
+ }
+};
+
+// This will test property recording outside of any test or test case.
+static Environment* record_property_env =
+ AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment);
+
// This group of tests is for predicate assertions (ASSERT_PRED*, etc)
// of various arities. They do not attempt to be exhaustive. Rather,
// view them as smoke tests that can be easily reviewed and verified.
@@ -3269,6 +3448,79 @@
// Tests non-string assertions.
+std::string EditsToString(const std::vector<EditType>& edits) {
+ std::string out;
+ for (size_t i = 0; i < edits.size(); ++i) {
+ static const char kEdits[] = " +-/";
+ out.append(1, kEdits[edits[i]]);
+ }
+ return out;
+}
+
+std::vector<size_t> CharsToIndices(const std::string& str) {
+ std::vector<size_t> out;
+ for (size_t i = 0; i < str.size(); ++i) {
+ out.push_back(str[i]);
+ }
+ return out;
+}
+
+std::vector<std::string> CharsToLines(const std::string& str) {
+ std::vector<std::string> out;
+ for (size_t i = 0; i < str.size(); ++i) {
+ out.push_back(str.substr(i, 1));
+ }
+ return out;
+}
+
+TEST(EditDistance, TestCases) {
+ struct Case {
+ int line;
+ const char* left;
+ const char* right;
+ const char* expected_edits;
+ const char* expected_diff;
+ };
+ static const Case kCases[] = {
+ // No change.
+ {__LINE__, "A", "A", " ", ""},
+ {__LINE__, "ABCDE", "ABCDE", " ", ""},
+ // Simple adds.
+ {__LINE__, "X", "XA", " +", "@@ +1,2 @@\n X\n+A\n"},
+ {__LINE__, "X", "XABCD", " ++++", "@@ +1,5 @@\n X\n+A\n+B\n+C\n+D\n"},
+ // Simple removes.
+ {__LINE__, "XA", "X", " -", "@@ -1,2 @@\n X\n-A\n"},
+ {__LINE__, "XABCD", "X", " ----", "@@ -1,5 @@\n X\n-A\n-B\n-C\n-D\n"},
+ // Simple replaces.
+ {__LINE__, "A", "a", "/", "@@ -1,1 +1,1 @@\n-A\n+a\n"},
+ {__LINE__, "ABCD", "abcd", "////",
+ "@@ -1,4 +1,4 @@\n-A\n-B\n-C\n-D\n+a\n+b\n+c\n+d\n"},
+ // Path finding.
+ {__LINE__, "ABCDEFGH", "ABXEGH1", " -/ - +",
+ "@@ -1,8 +1,7 @@\n A\n B\n-C\n-D\n+X\n E\n-F\n G\n H\n+1\n"},
+ {__LINE__, "AAAABCCCC", "ABABCDCDC", "- / + / ",
+ "@@ -1,9 +1,9 @@\n-A\n A\n-A\n+B\n A\n B\n C\n+D\n C\n-C\n+D\n C\n"},
+ {__LINE__, "ABCDE", "BCDCD", "- +/",
+ "@@ -1,5 +1,5 @@\n-A\n B\n C\n D\n-E\n+C\n+D\n"},
+ {__LINE__, "ABCDEFGHIJKL", "BCDCDEFGJKLJK", "- ++ -- ++",
+ "@@ -1,4 +1,5 @@\n-A\n B\n+C\n+D\n C\n D\n"
+ "@@ -6,7 +7,7 @@\n F\n G\n-H\n-I\n J\n K\n L\n+J\n+K\n"},
+ {}};
+ for (const Case* c = kCases; c->left; ++c) {
+ EXPECT_TRUE(c->expected_edits ==
+ EditsToString(CalculateOptimalEdits(CharsToIndices(c->left),
+ CharsToIndices(c->right))))
+ << "Left <" << c->left << "> Right <" << c->right << "> Edits <"
+ << EditsToString(CalculateOptimalEdits(
+ CharsToIndices(c->left), CharsToIndices(c->right))) << ">";
+ EXPECT_TRUE(c->expected_diff == CreateUnifiedDiff(CharsToLines(c->left),
+ CharsToLines(c->right)))
+ << "Left <" << c->left << "> Right <" << c->right << "> Diff <"
+ << CreateUnifiedDiff(CharsToLines(c->left), CharsToLines(c->right))
+ << ">";
+ }
+}
+
// Tests EqFailure(), used for implementing *EQ* assertions.
TEST(AssertionTest, EqFailure) {
const std::string foo_val("5"), bar_val("6");
@@ -3319,6 +3571,24 @@
msg5.c_str());
}
+TEST(AssertionTest, EqFailureWithDiff) {
+ const std::string left(
+ "1\\n2XXX\\n3\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12XXX\\n13\\n14\\n15");
+ const std::string right(
+ "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n11\\n12\\n13\\n14");
+ const std::string msg1(
+ EqFailure("left", "right", left, right, false).failure_message());
+ EXPECT_STREQ(
+ "Value of: right\n"
+ " Actual: 1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n11\\n12\\n13\\n14\n"
+ "Expected: left\n"
+ "Which is: "
+ "1\\n2XXX\\n3\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12XXX\\n13\\n14\\n15\n"
+ "With diff:\n@@ -1,5 +1,6 @@\n 1\n-2XXX\n+2\n 3\n+4\n 5\n 6\n"
+ "@@ -7,8 +8,6 @@\n 8\n 9\n-10\n 11\n-12XXX\n+12\n 13\n 14\n-15\n",
+ msg1.c_str());
+}
+
// Tests AppendUserMessage(), used for implementing the *EQ* macros.
TEST(AssertionTest, AppendUserMessage) {
const std::string foo("foo");
@@ -3731,10 +4001,10 @@
EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()),
"Expected: (OkHRESULTSuccess()) fails.\n"
- " Actual: 0x00000000");
+ " Actual: 0x0");
EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()),
"Expected: (FalseHRESULTSuccess()) fails.\n"
- " Actual: 0x00000001");
+ " Actual: 0x1");
}
TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) {
@@ -3745,12 +4015,12 @@
// ICE's in C++Builder 2007 and 2009.
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()),
"Expected: (OkHRESULTSuccess()) fails.\n"
- " Actual: 0x00000000");
+ " Actual: 0x0");
# endif
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()),
"Expected: (FalseHRESULTSuccess()) fails.\n"
- " Actual: 0x00000001");
+ " Actual: 0x1");
}
// Tests that streaming to the HRESULT macros works.
@@ -4477,7 +4747,7 @@
// Compares a const char* to an std::string that has different
// content
EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")),
- "::std::string(\"test\")");
+ "\"test\"");
// Compares an std::string to a char* that has different content.
char* const p1 = const_cast<char*>("foo");
@@ -4854,6 +5124,31 @@
EXPECT_STREQ("Data\n\\0Will be visible", r.message());
}
+// The next test uses explicit conversion operators -- a C++11 feature.
+#if GTEST_LANG_CXX11
+
+TEST(AssertionResultTest, ConstructibleFromContextuallyConvertibleToBool) {
+ struct ExplicitlyConvertibleToBool {
+ explicit operator bool() const { return value; }
+ bool value;
+ };
+ ExplicitlyConvertibleToBool v1 = {false};
+ ExplicitlyConvertibleToBool v2 = {true};
+ EXPECT_FALSE(v1);
+ EXPECT_TRUE(v2);
+}
+
+#endif // GTEST_LANG_CXX11
+
+struct ConvertibleToAssertionResult {
+ operator AssertionResult() const { return AssertionResult(true); }
+};
+
+TEST(AssertionResultTest, ConstructibleFromImplicitlyConvertible) {
+ ConvertibleToAssertionResult obj;
+ EXPECT_TRUE(obj);
+}
+
// Tests streaming a user type whose definition and operator << are
// both in the global namespace.
class Base {
@@ -5038,6 +5333,59 @@
ASSERT_EQ(0, GetTestResult(test_info)->total_part_count());
}
+#define VERIFY_CODE_LOCATION \
+ const int expected_line = __LINE__ - 1; \
+ const TestInfo* const test_info = GetUnitTestImpl()->current_test_info(); \
+ ASSERT_TRUE(test_info); \
+ EXPECT_STREQ(__FILE__, test_info->file()); \
+ EXPECT_EQ(expected_line, test_info->line())
+
+TEST(CodeLocationForTEST, Verify) {
+ VERIFY_CODE_LOCATION;
+}
+
+class CodeLocationForTESTF : public Test {
+};
+
+TEST_F(CodeLocationForTESTF, Verify) {
+ VERIFY_CODE_LOCATION;
+}
+
+class CodeLocationForTESTP : public TestWithParam<int> {
+};
+
+TEST_P(CodeLocationForTESTP, Verify) {
+ VERIFY_CODE_LOCATION;
+}
+
+INSTANTIATE_TEST_CASE_P(, CodeLocationForTESTP, Values(0));
+
+template <typename T>
+class CodeLocationForTYPEDTEST : public Test {
+};
+
+TYPED_TEST_CASE(CodeLocationForTYPEDTEST, int);
+
+TYPED_TEST(CodeLocationForTYPEDTEST, Verify) {
+ VERIFY_CODE_LOCATION;
+}
+
+template <typename T>
+class CodeLocationForTYPEDTESTP : public Test {
+};
+
+TYPED_TEST_CASE_P(CodeLocationForTYPEDTESTP);
+
+TYPED_TEST_P(CodeLocationForTYPEDTESTP, Verify) {
+ VERIFY_CODE_LOCATION;
+}
+
+REGISTER_TYPED_TEST_CASE_P(CodeLocationForTYPEDTESTP, Verify);
+
+INSTANTIATE_TYPED_TEST_CASE_P(My, CodeLocationForTYPEDTESTP, int);
+
+#undef VERIFY_CODE_LOCATION
+
// Tests setting up and tearing down a test case.
class SetUpTestCaseTest : public Test {
@@ -6053,7 +6401,108 @@
GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false);
}
-#endif // GTEST_OS_WINDOWS
+# endif // GTEST_OS_WINDOWS
+
+#if GTEST_USE_OWN_FLAGFILE_FLAG_
+class FlagfileTest : public InitGoogleTestTest {
+ public:
+ virtual void SetUp() {
+ InitGoogleTestTest::SetUp();
+
+ testdata_path_.Set(internal::FilePath(
+ internal::TempDir() + internal::GetCurrentExecutableName().string() +
+ "_flagfile_test"));
+ testing::internal::posix::RmDir(testdata_path_.c_str());
+ EXPECT_TRUE(testdata_path_.CreateFolder());
+ }
+
+ virtual void TearDown() {
+ testing::internal::posix::RmDir(testdata_path_.c_str());
+ InitGoogleTestTest::TearDown();
+ }
+
+ internal::FilePath CreateFlagfile(const char* contents) {
+ internal::FilePath file_path(internal::FilePath::GenerateUniqueFileName(
+ testdata_path_, internal::FilePath("unique"), "txt"));
+ FILE* f = testing::internal::posix::FOpen(file_path.c_str(), "w");
+ fprintf(f, "%s", contents);
+ fclose(f);
+ return file_path;
+ }
+
+ private:
+ internal::FilePath testdata_path_;
+};
+
+// Tests an empty flagfile.
+TEST_F(FlagfileTest, Empty) {
+ internal::FilePath flagfile_path(CreateFlagfile(""));
+ std::string flagfile_flag =
+ std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str();
+
+ const char* argv[] = {
+ "foo.exe",
+ flagfile_flag.c_str(),
+ NULL
+ };
+
+ const char* argv2[] = {
+ "foo.exe",
+ NULL
+ };
+
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false);
+}
+
+// Tests passing a non-empty --gtest_filter flag via --gtest_flagfile.
+TEST_F(FlagfileTest, FilterNonEmpty) {
+ internal::FilePath flagfile_path(CreateFlagfile(
+ "--" GTEST_FLAG_PREFIX_ "filter=abc"));
+ std::string flagfile_flag =
+ std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str();
+
+ const char* argv[] = {
+ "foo.exe",
+ flagfile_flag.c_str(),
+ NULL
+ };
+
+ const char* argv2[] = {
+ "foo.exe",
+ NULL
+ };
+
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false);
+}
+
+// Tests passing several flags via --gtest_flagfile.
+TEST_F(FlagfileTest, SeveralFlags) {
+ internal::FilePath flagfile_path(CreateFlagfile(
+ "--" GTEST_FLAG_PREFIX_ "filter=abc\n"
+ "--" GTEST_FLAG_PREFIX_ "break_on_failure\n"
+ "--" GTEST_FLAG_PREFIX_ "list_tests"));
+ std::string flagfile_flag =
+ std::string("--" GTEST_FLAG_PREFIX_ "flagfile=") + flagfile_path.c_str();
+
+ const char* argv[] = {
+ "foo.exe",
+ flagfile_flag.c_str(),
+ NULL
+ };
+
+ const char* argv2[] = {
+ "foo.exe",
+ NULL
+ };
+
+ Flags expected_flags;
+ expected_flags.break_on_failure = true;
+ expected_flags.filter = "abc";
+ expected_flags.list_tests = true;
+
+ GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false);
+}
+#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
// Tests current_test_info() in UnitTest.
class CurrentTestInfoTest : public Test {
@@ -6388,6 +6837,15 @@
SetEnv("TERM", "screen"); // TERM supports colors.
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
+ SetEnv("TERM", "screen-256color"); // TERM supports colors.
+ EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
+
+ SetEnv("TERM", "rxvt-unicode"); // TERM supports colors.
+ EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
+
+ SetEnv("TERM", "rxvt-unicode-256color"); // TERM supports colors.
+ EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
+
SetEnv("TERM", "linux"); // TERM supports colors.
EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY.
@@ -7152,7 +7610,7 @@
TEST(NativeArrayTest, ConstructorFromArrayWorks) {
const int a[3] = { 0, 1, 2 };
- NativeArray<int> na(a, 3, kReference);
+ NativeArray<int> na(a, 3, RelationToSourceReference());
EXPECT_EQ(3U, na.size());
EXPECT_EQ(a, na.begin());
}
@@ -7162,7 +7620,7 @@
Array* a = new Array[1];
(*a)[0] = 0;
(*a)[1] = 1;
- NativeArray<int> na(*a, 2, kCopy);
+ NativeArray<int> na(*a, 2, RelationToSourceCopy());
EXPECT_NE(*a, na.begin());
delete[] a;
EXPECT_EQ(0, na.begin()[0]);
@@ -7182,7 +7640,7 @@
TEST(NativeArrayTest, MethodsWork) {
const int a[3] = { 0, 1, 2 };
- NativeArray<int> na(a, 3, kCopy);
+ NativeArray<int> na(a, 3, RelationToSourceCopy());
ASSERT_EQ(3U, na.size());
EXPECT_EQ(3, na.end() - na.begin());
@@ -7197,18 +7655,18 @@
EXPECT_TRUE(na == na);
- NativeArray<int> na2(a, 3, kReference);
+ NativeArray<int> na2(a, 3, RelationToSourceReference());
EXPECT_TRUE(na == na2);
const int b1[3] = { 0, 1, 1 };
const int b2[4] = { 0, 1, 2, 3 };
- EXPECT_FALSE(na == NativeArray<int>(b1, 3, kReference));
- EXPECT_FALSE(na == NativeArray<int>(b2, 4, kCopy));
+ EXPECT_FALSE(na == NativeArray<int>(b1, 3, RelationToSourceReference()));
+ EXPECT_FALSE(na == NativeArray<int>(b2, 4, RelationToSourceCopy()));
}
TEST(NativeArrayTest, WorksForTwoDimensionalArray) {
const char a[2][3] = { "hi", "lo" };
- NativeArray<char[3]> na(a, 2, kReference);
+ NativeArray<char[3]> na(a, 2, RelationToSourceReference());
ASSERT_EQ(2U, na.size());
EXPECT_EQ(a, na.begin());
}
@@ -7238,3 +7696,4 @@
EXPECT_FALSE(SkipPrefix("world!", &p));
EXPECT_EQ(str, p);
}
+
diff --git a/src/testing/gtest/test/gtest_xml_output_unittest.py b/src/testing/gtest/test/gtest_xml_output_unittest.py
index 1bcd418..f605d4e 100755
--- a/src/testing/gtest/test/gtest_xml_output_unittest.py
+++ b/src/testing/gtest/test/gtest_xml_output_unittest.py
@@ -44,6 +44,7 @@
import gtest_xml_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.xml"
@@ -57,7 +58,7 @@
STACK_TRACE_TEMPLATE = ''
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
-<testsuites tests="23" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests">
+<testsuites tests="23" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite>
@@ -97,7 +98,7 @@
<testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
<testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
</testsuite>
- <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*">
+ <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
<testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
<testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
<testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
@@ -128,9 +129,18 @@
</testsuite>
</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
+EXPECTED_FILTERED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
+<testsuites tests="1" failures="0" disabled="0" errors="0" time="*"
+ timestamp="*" name="AllTests" ad_hoc_property="42">
+ <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0"
+ errors="0" time="*">
+ <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
+ </testsuite>
+</testsuites>"""
EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
-<testsuites tests="0" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
+<testsuites tests="0" failures="0" disabled="0" errors="0" time="*"
+ timestamp="*" name="AllTests">
</testsuites>"""
GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
@@ -169,7 +179,7 @@
Runs a test program that generates an empty XML output, and checks if
the timestamp attribute in the testsuites tag is valid.
"""
- actual = self._GetXmlOutput('gtest_no_test_unittest', 0)
+ actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0)
date_time_str = actual.documentElement.getAttributeNode('timestamp').value
# datetime.strptime() is only available in Python 2.5+ so we have to
# parse the expected datetime manually.
@@ -239,7 +249,17 @@
self.assert_(not os.path.isfile(xml_path))
- def _GetXmlOutput(self, gtest_prog_name, expected_exit_code):
+ def testFilteredTestXmlOutput(self):
+ """Verifies XML 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 XML output.
+ """
+
+ self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0,
+ extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
+
+ def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code):
"""
Returns the xml output generated by running the program gtest_prog_name.
Furthermore, the program's exit code must be expected_exit_code.
@@ -248,7 +268,8 @@
gtest_prog_name + 'out.xml')
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
- command = [gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)]
+ command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] +
+ extra_args)
p = gtest_test_utils.Subprocess(command)
if p.terminated_by_signal:
self.assert_(False,
@@ -262,7 +283,8 @@
actual = minidom.parse(xml_path)
return actual
- def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code):
+ def _TestXmlOutput(self, gtest_prog_name, expected_xml,
+ expected_exit_code, extra_args=None):
"""
Asserts that the XML document generated by running the program
gtest_prog_name matches expected_xml, a string containing another
@@ -270,7 +292,8 @@
expected_exit_code.
"""
- actual = self._GetXmlOutput(gtest_prog_name, expected_exit_code)
+ actual = self._GetXmlOutput(gtest_prog_name, extra_args or [],
+ expected_exit_code)
expected = minidom.parseString(expected_xml)
self.NormalizeXml(actual.documentElement)
self.AssertEquivalentNodes(expected.documentElement,
diff --git a/src/testing/gtest/test/gtest_xml_output_unittest_.cc b/src/testing/gtest/test/gtest_xml_output_unittest_.cc
index bf0c871..48b8771 100644
--- a/src/testing/gtest/test/gtest_xml_output_unittest_.cc
+++ b/src/testing/gtest/test/gtest_xml_output_unittest_.cc
@@ -95,6 +95,9 @@
}
class PropertyRecordingTest : public Test {
+ public:
+ static void SetUpTestCase() { RecordProperty("SetUpTestCase", "yes"); }
+ static void TearDownTestCase() { RecordProperty("TearDownTestCase", "aye"); }
};
TEST_F(PropertyRecordingTest, OneProperty) {
@@ -120,12 +123,12 @@
RecordProperty("key", "1");
}
-void ExternalUtilityThatCallsRecordProperty(const char* key, int value) {
+void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) {
testing::Test::RecordProperty(key, value);
}
-void ExternalUtilityThatCallsRecordProperty(const char* key,
- const char* value) {
+void ExternalUtilityThatCallsRecordProperty(const std::string& key,
+ const std::string& value) {
testing::Test::RecordProperty(key, value);
}
@@ -173,5 +176,6 @@
TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
delete listeners.Release(listeners.default_xml_generator());
}
+ testing::Test::RecordProperty("ad_hoc_property", "42");
return RUN_ALL_TESTS();
}
diff --git a/src/testing/gtest/test/gtest_xml_test_utils.py b/src/testing/gtest/test/gtest_xml_test_utils.py
index 0e5a108..3d0c3b2 100755
--- a/src/testing/gtest/test/gtest_xml_test_utils.py
+++ b/src/testing/gtest/test/gtest_xml_test_utils.py
@@ -80,7 +80,9 @@
actual_attributes = actual_node .attributes
self.assertEquals(
expected_attributes.length, actual_attributes.length,
- 'attribute numbers differ in element ' + actual_node.tagName)
+ 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % (
+ actual_node.tagName, expected_attributes.keys(),
+ actual_attributes.keys()))
for i in range(expected_attributes.length):
expected_attr = expected_attributes.item(i)
actual_attr = actual_attributes.get(expected_attr.name)
@@ -88,9 +90,11 @@
actual_attr is not None,
'expected attribute %s not found in element %s' %
(expected_attr.name, actual_node.tagName))
- self.assertEquals(expected_attr.value, actual_attr.value,
- ' values of attribute %s in element %s differ' %
- (expected_attr.name, actual_node.tagName))
+ self.assertEquals(
+ expected_attr.value, actual_attr.value,
+ ' values of attribute %s in element %s differ: %s vs %s' %
+ (expected_attr.name, actual_node.tagName,
+ expected_attr.value, actual_attr.value))
expected_children = self._GetChildren(expected_node)
actual_children = self._GetChildren(actual_node)