Index: base/logging_unittest.cc |
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc |
index f41cce2f43b390fa9603a14f3f689fe87d0dcb33..28135a82612c414e88b58bae98d99be5b5f14f1f 100644 |
--- a/base/logging_unittest.cc |
+++ b/base/logging_unittest.cc |
@@ -13,7 +13,9 @@ namespace logging { |
namespace { |
+using ::testing::HasSubstr; |
using ::testing::Return; |
+using ::testing::_; |
// Needs to be global since log assert handlers can't maintain state. |
int log_sink_call_count = 0; |
@@ -326,6 +328,84 @@ TEST_F(LoggingTest, CheckEqStatements) { |
CHECK_EQ(false, true); // Unreached. |
} |
+class MockLogMessageListener : logging::LogMessageListener { |
+ public: |
+ MockLogMessageListener(std::string& buffer) : buffer_(buffer) {} |
+ void OnMessage(int severity, |
+ const char* file, |
+ int line, |
+ size_t message_start, |
+ const std::string& str) override { |
+ buffer_.append(str); |
+ } |
+ |
+ private: |
+ std::string& buffer_; |
+}; |
+ |
+TEST_F(LoggingTest, LogListenerBasic) { |
+ std::string buffer; |
+ MockLogMessageListener log(buffer); |
+ |
+ LOG(INFO) << "testing1"; |
+ LOG(WARNING) << "testing2"; |
+ |
+ EXPECT_NE(std::string::npos, buffer.find("testing1")); |
+ EXPECT_NE(std::string::npos, buffer.find("testing2")); |
+} |
+ |
+TEST_F(LoggingTest, LogListenerLifespan) { |
+ size_t count = LogMessageListenerCountForTesting(); |
+ std::string buf1, buf2; |
+ MockLogMessageListener* log1 = nullptr; |
+ { |
+ MockLogMessageListener log2(buf2); |
+ EXPECT_EQ(count + 1, LogMessageListenerCountForTesting()); |
+ |
+ LOG(WARNING) << "testing1"; |
+ log1 = new MockLogMessageListener(buf1); |
+ EXPECT_EQ(count + 2, LogMessageListenerCountForTesting()); |
+ LOG(WARNING) << "testing2"; |
+ } |
+ EXPECT_EQ(count + 1, LogMessageListenerCountForTesting()); |
+ LOG(WARNING) << "testing3"; |
+ delete log1; |
+ EXPECT_EQ(count, LogMessageListenerCountForTesting()); |
+ |
+ EXPECT_EQ(std::string::npos, buf1.find("testing1")); |
+ EXPECT_NE(std::string::npos, buf1.find("testing2")); |
+ EXPECT_NE(std::string::npos, buf1.find("testing3")); |
+ EXPECT_NE(std::string::npos, buf2.find("testing1")); |
+ EXPECT_NE(std::string::npos, buf2.find("testing2")); |
+ EXPECT_EQ(std::string::npos, buf2.find("testing3")); |
+} |
+ |
+class ChattyLogMessageListener : logging::LogMessageListener { |
+ public: |
+ ChattyLogMessageListener() : count_(0) {} |
+ void OnMessage(int severity, |
+ const char* file, |
+ int line, |
+ size_t message_start, |
+ const std::string& str) override { |
+ count_++; |
+ if (count_ == 1) { |
+ LOG(ERROR) << "message inside OnMessage()"; |
+ } |
+ } |
+ int Count() { return count_; } |
+ |
+ private: |
+ int count_; |
+}; |
+ |
+TEST_F(LoggingTest, LogListenerReentrant) { |
+ ChattyLogMessageListener log; |
+ |
+ LOG(INFO) << "testing1"; |
+ EXPECT_EQ(2, log.Count()); |
+} |
+ |
// Test that defining an operator<< for a type in a namespace doesn't prevent |
// other code in that namespace from calling the operator<<(ostream, wstring) |
// defined by logging.h. This can fail if operator<<(ostream, wstring) can't be |