Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(815)

Side by Side Diff: base/logging_unittest.cc

Issue 2288473002: Implement Dump-on-DCHECK (via a new LogSeverity). (Closed)
Patch Set: Pull the Official Windows build default in, and rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/logging.cc ('k') | base/syslog_logging.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/compiler_specific.h" 5 #include "base/compiler_specific.h"
6 #include "base/debug/dump_without_crashing.h"
6 #include "base/logging.h" 7 #include "base/logging.h"
7 #include "base/macros.h" 8 #include "base/macros.h"
8 9
9 #include "testing/gmock/include/gmock/gmock.h" 10 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
11 12
12 namespace logging { 13 namespace logging {
13 14
14 namespace { 15 namespace {
15 16
16 using ::testing::Return; 17 using ::testing::Return;
17 18
18 // Needs to be global since log assert handlers can't maintain state. 19 // Needs to be global since log assert handlers can't maintain state.
19 int log_sink_call_count = 0; 20 int g_log_sink_call_count = 0;
20 21
21 #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG) 22 #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
22 void LogSink(const std::string& str) { 23 void LogSink(const std::string& str) {
23 ++log_sink_call_count; 24 ++g_log_sink_call_count;
24 } 25 }
25 #endif 26 #endif
26 27
27 // Class to make sure any manipulations we do to the min log level are 28 // Class to make sure any manipulations we do to the min log level are
28 // contained (i.e., do not affect other unit tests). 29 // contained (i.e., do not affect other unit tests).
29 class LogStateSaver { 30 class LogStateSaver {
30 public: 31 public:
31 LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {} 32 LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {}
32 33
33 ~LogStateSaver() { 34 ~LogStateSaver() {
34 SetMinLogLevel(old_min_log_level_); 35 SetMinLogLevel(old_min_log_level_);
35 SetLogAssertHandler(NULL); 36 SetLogAssertHandler(NULL);
36 log_sink_call_count = 0; 37 g_log_sink_call_count = 0;
37 } 38 }
38 39
39 private: 40 private:
40 int old_min_log_level_; 41 int old_min_log_level_;
41 42
42 DISALLOW_COPY_AND_ASSIGN(LogStateSaver); 43 DISALLOW_COPY_AND_ASSIGN(LogStateSaver);
43 }; 44 };
44 45
45 class LoggingTest : public testing::Test { 46 class LoggingTest : public testing::Test {
46 private: 47 private:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 DLOG_IF(INFO, true) << mock_log_source.Log(); 80 DLOG_IF(INFO, true) << mock_log_source.Log();
80 DPLOG(INFO) << mock_log_source.Log(); 81 DPLOG(INFO) << mock_log_source.Log();
81 DPLOG_IF(INFO, true) << mock_log_source.Log(); 82 DPLOG_IF(INFO, true) << mock_log_source.Log();
82 DVLOG(0) << mock_log_source.Log(); 83 DVLOG(0) << mock_log_source.Log();
83 DVLOG_IF(0, true) << mock_log_source.Log(); 84 DVLOG_IF(0, true) << mock_log_source.Log();
84 DVPLOG(0) << mock_log_source.Log(); 85 DVPLOG(0) << mock_log_source.Log();
85 DVPLOG_IF(0, true) << mock_log_source.Log(); 86 DVPLOG_IF(0, true) << mock_log_source.Log();
86 } 87 }
87 88
88 TEST_F(LoggingTest, LogIsOn) { 89 TEST_F(LoggingTest, LogIsOn) {
89 #if defined(NDEBUG) 90 #if defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
90 const bool kDfatalIsFatal = false; 91 const bool kDfatalIsActive = true;
92 #elif defined(NDEBUG)
93 const bool kDfatalIsActive = false;
91 #else // defined(NDEBUG) 94 #else // defined(NDEBUG)
92 const bool kDfatalIsFatal = true; 95 const bool kDfatalIsActive = true;
93 #endif // defined(NDEBUG) 96 #endif // defined(NDEBUG)
94 97
95 SetMinLogLevel(LOG_INFO); 98 SetMinLogLevel(LOG_INFO);
96 EXPECT_TRUE(LOG_IS_ON(INFO)); 99 EXPECT_TRUE(LOG_IS_ON(INFO));
97 EXPECT_TRUE(LOG_IS_ON(WARNING)); 100 EXPECT_TRUE(LOG_IS_ON(WARNING));
98 EXPECT_TRUE(LOG_IS_ON(ERROR)); 101 EXPECT_TRUE(LOG_IS_ON(ERROR));
99 EXPECT_TRUE(LOG_IS_ON(FATAL)); 102 EXPECT_TRUE(LOG_IS_ON(FATAL));
100 EXPECT_TRUE(LOG_IS_ON(DFATAL)); 103 EXPECT_TRUE(LOG_IS_ON(DFATAL));
101 104
102 SetMinLogLevel(LOG_WARNING); 105 SetMinLogLevel(LOG_WARNING);
103 EXPECT_FALSE(LOG_IS_ON(INFO)); 106 EXPECT_FALSE(LOG_IS_ON(INFO));
104 EXPECT_TRUE(LOG_IS_ON(WARNING)); 107 EXPECT_TRUE(LOG_IS_ON(WARNING));
105 EXPECT_TRUE(LOG_IS_ON(ERROR)); 108 EXPECT_TRUE(LOG_IS_ON(ERROR));
106 EXPECT_TRUE(LOG_IS_ON(FATAL)); 109 EXPECT_TRUE(LOG_IS_ON(FATAL));
107 EXPECT_TRUE(LOG_IS_ON(DFATAL)); 110 EXPECT_TRUE(LOG_IS_ON(DFATAL));
108 111
109 SetMinLogLevel(LOG_ERROR); 112 SetMinLogLevel(LOG_ERROR);
110 EXPECT_FALSE(LOG_IS_ON(INFO)); 113 EXPECT_FALSE(LOG_IS_ON(INFO));
111 EXPECT_FALSE(LOG_IS_ON(WARNING)); 114 EXPECT_FALSE(LOG_IS_ON(WARNING));
112 EXPECT_TRUE(LOG_IS_ON(ERROR)); 115 EXPECT_TRUE(LOG_IS_ON(ERROR));
113 EXPECT_TRUE(LOG_IS_ON(FATAL)); 116 EXPECT_TRUE(LOG_IS_ON(FATAL));
114 EXPECT_TRUE(LOG_IS_ON(DFATAL)); 117 EXPECT_TRUE(LOG_IS_ON(DFATAL));
115 118
116 // LOG_IS_ON(FATAL) should always be true. 119 // LOG_IS_ON(FATAL) should always be true.
117 SetMinLogLevel(LOG_FATAL + 1); 120 SetMinLogLevel(LOG_FATAL + 1);
118 EXPECT_FALSE(LOG_IS_ON(INFO)); 121 EXPECT_FALSE(LOG_IS_ON(INFO));
119 EXPECT_FALSE(LOG_IS_ON(WARNING)); 122 EXPECT_FALSE(LOG_IS_ON(WARNING));
120 EXPECT_FALSE(LOG_IS_ON(ERROR)); 123 EXPECT_FALSE(LOG_IS_ON(ERROR));
121 EXPECT_TRUE(LOG_IS_ON(FATAL)); 124 EXPECT_TRUE(LOG_IS_ON(FATAL));
122 EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL)); 125 EXPECT_EQ(kDfatalIsActive, LOG_IS_ON(DFATAL));
126
127 EXPECT_EQ(DCHECK_IS_ON() != 0, LOG_IS_ON(DCHECK));
123 } 128 }
124 129
125 TEST_F(LoggingTest, LoggingIsLazyBySeverity) { 130 TEST_F(LoggingTest, LoggingIsLazyBySeverity) {
126 MockLogSource mock_log_source; 131 MockLogSource mock_log_source;
127 EXPECT_CALL(mock_log_source, Log()).Times(0); 132 EXPECT_CALL(mock_log_source, Log()).Times(0);
128 133
129 SetMinLogLevel(LOG_WARNING); 134 SetMinLogLevel(LOG_WARNING);
130 135
131 EXPECT_FALSE(LOG_IS_ON(INFO)); 136 EXPECT_FALSE(LOG_IS_ON(INFO));
132 EXPECT_FALSE(DLOG_IS_ON(INFO)); 137 EXPECT_FALSE(DLOG_IS_ON(INFO));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 PCHECK(!mock_log_source.Log()) << mock_log_source.Log(); 189 PCHECK(!mock_log_source.Log()) << mock_log_source.Log();
185 CHECK_EQ(mock_log_source.Log(), mock_log_source.Log()) 190 CHECK_EQ(mock_log_source.Log(), mock_log_source.Log())
186 << uncalled_mock_log_source.Log(); 191 << uncalled_mock_log_source.Log();
187 CHECK_NE(mock_log_source.Log(), mock_log_source.Log()) 192 CHECK_NE(mock_log_source.Log(), mock_log_source.Log())
188 << mock_log_source.Log(); 193 << mock_log_source.Log();
189 } 194 }
190 195
191 #endif 196 #endif
192 197
193 TEST_F(LoggingTest, DebugLoggingReleaseBehavior) { 198 TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
194 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) 199 #if DCHECK_IS_ON()
195 int debug_only_variable = 1; 200 int debug_only_variable = 1;
196 #endif 201 #endif
197 // These should avoid emitting references to |debug_only_variable| 202 // These should avoid emitting references to |debug_only_variable|
198 // in release mode. 203 // in release mode.
199 DLOG_IF(INFO, debug_only_variable) << "test"; 204 DLOG_IF(INFO, debug_only_variable) << "test";
200 DLOG_ASSERT(debug_only_variable) << "test"; 205 DLOG_ASSERT(debug_only_variable) << "test";
201 DPLOG_IF(INFO, debug_only_variable) << "test"; 206 DPLOG_IF(INFO, debug_only_variable) << "test";
202 DVLOG_IF(1, debug_only_variable) << "test"; 207 DVLOG_IF(1, debug_only_variable) << "test";
203 } 208 }
204 209
205 TEST_F(LoggingTest, DcheckStreamsAreLazy) { 210 TEST_F(LoggingTest, DcheckStreamsAreLazy) {
206 MockLogSource mock_log_source; 211 MockLogSource mock_log_source;
207 EXPECT_CALL(mock_log_source, Log()).Times(0); 212 EXPECT_CALL(mock_log_source, Log()).Times(0);
208 #if DCHECK_IS_ON() 213 #if DCHECK_IS_ON()
209 DCHECK(true) << mock_log_source.Log(); 214 DCHECK(true) << mock_log_source.Log();
210 DCHECK_EQ(0, 0) << mock_log_source.Log(); 215 DCHECK_EQ(0, 0) << mock_log_source.Log();
211 #else 216 #else
212 DCHECK(mock_log_source.Log()) << mock_log_source.Log(); 217 DCHECK(mock_log_source.Log()) << mock_log_source.Log();
213 DPCHECK(mock_log_source.Log()) << mock_log_source.Log(); 218 DPCHECK(mock_log_source.Log()) << mock_log_source.Log();
214 DCHECK_EQ(0, 0) << mock_log_source.Log(); 219 DCHECK_EQ(0, 0) << mock_log_source.Log();
215 DCHECK_EQ(mock_log_source.Log(), static_cast<const char*>(NULL)) 220 DCHECK_EQ(mock_log_source.Log(), static_cast<const char*>(NULL))
216 << mock_log_source.Log(); 221 << mock_log_source.Log();
217 #endif 222 #endif
218 } 223 }
219 224
225 #if !defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
220 void DcheckEmptyFunction1() { 226 void DcheckEmptyFunction1() {
221 // Provide a body so that Release builds do not cause the compiler to 227 // Provide a body so that Release builds do not cause the compiler to
222 // optimize DcheckEmptyFunction1 and DcheckEmptyFunction2 as a single 228 // optimize DcheckEmptyFunction1 and DcheckEmptyFunction2 as a single
223 // function, which breaks the Dcheck tests below. 229 // function, which breaks the Dcheck tests below.
224 LOG(INFO) << "DcheckEmptyFunction1"; 230 LOG(INFO) << "DcheckEmptyFunction1";
225 } 231 }
226 void DcheckEmptyFunction2() {} 232 void DcheckEmptyFunction2() {}
227 233
228 TEST_F(LoggingTest, Dcheck) { 234 TEST_F(LoggingTest, Dcheck) {
229 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) 235 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
230 // Release build. 236 // Release build.
231 EXPECT_FALSE(DCHECK_IS_ON()); 237 EXPECT_FALSE(DCHECK_IS_ON());
232 EXPECT_FALSE(DLOG_IS_ON(DCHECK)); 238 EXPECT_FALSE(DLOG_IS_ON(DCHECK));
233 #elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON) 239 #elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON)
234 // Release build with real DCHECKS. 240 // Release build with real DCHECKS.
235 SetLogAssertHandler(&LogSink); 241 SetLogAssertHandler(&LogSink);
236 EXPECT_TRUE(DCHECK_IS_ON()); 242 EXPECT_TRUE(DCHECK_IS_ON());
237 EXPECT_TRUE(DLOG_IS_ON(DCHECK)); 243 EXPECT_TRUE(DLOG_IS_ON(DCHECK));
238 #else 244 #else
239 // Debug build. 245 // Debug build.
240 SetLogAssertHandler(&LogSink); 246 SetLogAssertHandler(&LogSink);
241 EXPECT_TRUE(DCHECK_IS_ON()); 247 EXPECT_TRUE(DCHECK_IS_ON());
242 EXPECT_TRUE(DLOG_IS_ON(DCHECK)); 248 EXPECT_TRUE(DLOG_IS_ON(DCHECK));
243 #endif 249 #endif
244 250
245 EXPECT_EQ(0, log_sink_call_count); 251 EXPECT_EQ(0, g_log_sink_call_count);
246 DCHECK(false); 252 DCHECK(false);
247 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); 253 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
248 DPCHECK(false); 254 DPCHECK(false);
249 EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count); 255 EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count);
250 DCHECK_EQ(0, 1); 256 DCHECK_EQ(0, 1);
251 EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count); 257 EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, g_log_sink_call_count);
252 258
253 // Test DCHECK on std::nullptr_t 259 // Test DCHECK on std::nullptr_t
254 log_sink_call_count = 0; 260 g_log_sink_call_count = 0;
255 const void* p_null = nullptr; 261 const void* p_null = nullptr;
256 const void* p_not_null = &p_null; 262 const void* p_not_null = &p_null;
257 DCHECK_EQ(p_null, nullptr); 263 DCHECK_EQ(p_null, nullptr);
258 DCHECK_EQ(nullptr, p_null); 264 DCHECK_EQ(nullptr, p_null);
259 DCHECK_NE(p_not_null, nullptr); 265 DCHECK_NE(p_not_null, nullptr);
260 DCHECK_NE(nullptr, p_not_null); 266 DCHECK_NE(nullptr, p_not_null);
261 EXPECT_EQ(0, log_sink_call_count); 267 EXPECT_EQ(0, g_log_sink_call_count);
262 268
263 // Test DCHECK on a scoped enum. 269 // Test DCHECK on a scoped enum.
264 enum class Animal { DOG, CAT }; 270 enum class Animal { DOG, CAT };
265 DCHECK_EQ(Animal::DOG, Animal::DOG); 271 DCHECK_EQ(Animal::DOG, Animal::DOG);
266 EXPECT_EQ(0, log_sink_call_count); 272 EXPECT_EQ(0, g_log_sink_call_count);
267 DCHECK_EQ(Animal::DOG, Animal::CAT); 273 DCHECK_EQ(Animal::DOG, Animal::CAT);
268 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); 274 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
269 275
270 // Test DCHECK on functions and function pointers. 276 // Test DCHECK on functions and function pointers.
271 log_sink_call_count = 0; 277 g_log_sink_call_count = 0;
272 struct MemberFunctions { 278 struct MemberFunctions {
273 void MemberFunction1() { 279 void MemberFunction1() {
274 // See the comment in DcheckEmptyFunction1(). 280 // See the comment in DcheckEmptyFunction1().
275 LOG(INFO) << "Do not merge with MemberFunction2."; 281 LOG(INFO) << "Do not merge with MemberFunction2.";
276 } 282 }
277 void MemberFunction2() {} 283 void MemberFunction2() {}
278 }; 284 };
279 void (MemberFunctions::*mp1)() = &MemberFunctions::MemberFunction1; 285 void (MemberFunctions::*mp1)() = &MemberFunctions::MemberFunction1;
280 void (MemberFunctions::*mp2)() = &MemberFunctions::MemberFunction2; 286 void (MemberFunctions::*mp2)() = &MemberFunctions::MemberFunction2;
281 void (*fp1)() = DcheckEmptyFunction1; 287 void (*fp1)() = DcheckEmptyFunction1;
282 void (*fp2)() = DcheckEmptyFunction2; 288 void (*fp2)() = DcheckEmptyFunction2;
283 void (*fp3)() = DcheckEmptyFunction1; 289 void (*fp3)() = DcheckEmptyFunction1;
284 DCHECK_EQ(fp1, fp3); 290 DCHECK_EQ(fp1, fp3);
285 EXPECT_EQ(0, log_sink_call_count); 291 EXPECT_EQ(0, g_log_sink_call_count);
286 DCHECK_EQ(mp1, &MemberFunctions::MemberFunction1); 292 DCHECK_EQ(mp1, &MemberFunctions::MemberFunction1);
287 EXPECT_EQ(0, log_sink_call_count); 293 EXPECT_EQ(0, g_log_sink_call_count);
288 DCHECK_EQ(mp2, &MemberFunctions::MemberFunction2); 294 DCHECK_EQ(mp2, &MemberFunctions::MemberFunction2);
289 EXPECT_EQ(0, log_sink_call_count); 295 EXPECT_EQ(0, g_log_sink_call_count);
290 DCHECK_EQ(fp1, fp2); 296 DCHECK_EQ(fp1, fp2);
291 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); 297 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, g_log_sink_call_count);
292 DCHECK_EQ(mp2, &MemberFunctions::MemberFunction1); 298 DCHECK_EQ(mp2, &MemberFunctions::MemberFunction1);
293 EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count); 299 EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, g_log_sink_call_count);
294 } 300 }
301 #endif // !defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
295 302
296 TEST_F(LoggingTest, DcheckReleaseBehavior) { 303 TEST_F(LoggingTest, DcheckReleaseBehavior) {
297 int some_variable = 1; 304 int some_variable = 1;
298 // These should still reference |some_variable| so we don't get 305 // These should still reference |some_variable| so we don't get
299 // unused variable warnings. 306 // unused variable warnings.
300 DCHECK(some_variable) << "test"; 307 DCHECK(some_variable) << "test";
301 DPCHECK(some_variable) << "test"; 308 DPCHECK(some_variable) << "test";
302 DCHECK_EQ(some_variable, 1) << "test"; 309 DCHECK_EQ(some_variable, 1) << "test";
303 } 310 }
304 311
(...skipping 14 matching lines...) Expand all
319 if (false) 326 if (false)
320 CHECK_EQ(false, true); // Unreached. 327 CHECK_EQ(false, true); // Unreached.
321 else 328 else
322 CHECK_EQ(true, reached = true); // Reached, passed. 329 CHECK_EQ(true, reached = true); // Reached, passed.
323 ASSERT_TRUE(reached); 330 ASSERT_TRUE(reached);
324 331
325 if (false) 332 if (false)
326 CHECK_EQ(false, true); // Unreached. 333 CHECK_EQ(false, true); // Unreached.
327 } 334 }
328 335
336 namespace {
337
338 int g_fake_dump_without_crashing_count = 0;
339 void FakeDumpWithoutCrashing() {
340 g_fake_dump_without_crashing_count++;
341 }
342
343 } // namespace
344
345 TEST_F(LoggingTest, LogMessageDump) {
346 // Replace the dump-without-crashing function, to test.
347 base::debug::SetDumpWithoutCrashingFunction(&FakeDumpWithoutCrashing);
348
349 // LOG_DUMP is an internal severity level for use by dump-on-DCHECK, so
350 // we must call LogMessage() directly, rather than using LOG(DUMP).
351 LogMessage(__FILE__, __LINE__, LOG_DUMP, new std::string);
352 EXPECT_EQ(1, g_fake_dump_without_crashing_count);
353 LogMessage(__FILE__, __LINE__, LOG_DUMP, new std::string);
354 EXPECT_EQ(1, g_fake_dump_without_crashing_count);
355
356 #if defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
357 EXPECT_EQ(LOG_DUMP, LOG_DFATAL);
358 EXPECT_EQ(LOG_DUMP, LOG_DCHECK);
359 #else // defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
360 EXPECT_NE(LOG_DUMP, LOG_DFATAL);
361 EXPECT_NE(LOG_DUMP, LOG_DCHECK);
362 #endif // defined(DCHECK_IS_DUMP_WITHOUT_CRASH)
363
364 base::debug::SetDumpWithoutCrashingFunction(nullptr);
365 }
366
329 // Test that defining an operator<< for a type in a namespace doesn't prevent 367 // Test that defining an operator<< for a type in a namespace doesn't prevent
330 // other code in that namespace from calling the operator<<(ostream, wstring) 368 // other code in that namespace from calling the operator<<(ostream, wstring)
331 // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be 369 // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be
332 // found by ADL, since defining another operator<< prevents name lookup from 370 // found by ADL, since defining another operator<< prevents name lookup from
333 // looking in the global namespace. 371 // looking in the global namespace.
334 namespace nested_test { 372 namespace nested_test {
335 class Streamable {}; 373 class Streamable {};
336 ALLOW_UNUSED_TYPE std::ostream& operator<<(std::ostream& out, 374 ALLOW_UNUSED_TYPE std::ostream& operator<<(std::ostream& out,
337 const Streamable&) { 375 const Streamable&) {
338 return out << "Streamable"; 376 return out << "Streamable";
339 } 377 }
340 TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) { 378 TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) {
341 std::wstring wstr = L"Hello World"; 379 std::wstring wstr = L"Hello World";
342 std::ostringstream ostr; 380 std::ostringstream ostr;
343 ostr << wstr; 381 ostr << wstr;
344 EXPECT_EQ("Hello World", ostr.str()); 382 EXPECT_EQ("Hello World", ostr.str());
345 } 383 }
346 } // namespace nested_test 384 } // namespace nested_test
347 385
348 } // namespace 386 } // namespace
349 387
350 } // namespace logging 388 } // namespace logging
OLDNEW
« no previous file with comments | « base/logging.cc ('k') | base/syslog_logging.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698