1// 2// Copyright 2022 The Abseil Authors. 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// https://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15 16#ifndef ABSL_LOG_CHECK_TEST_IMPL_H_ 17#define ABSL_LOG_CHECK_TEST_IMPL_H_ 18 19// Verify that both sets of macros behave identically by parameterizing the 20// entire test file. 21#ifndef ABSL_TEST_CHECK 22#error ABSL_TEST_CHECK must be defined for these tests to work. 23#endif 24 25#include <ostream> 26#include <string> 27 28#include "gmock/gmock.h" 29#include "gtest/gtest.h" 30#include "absl/base/attributes.h" 31#include "absl/base/config.h" 32#include "absl/log/internal/test_helpers.h" 33#include "absl/status/status.h" 34#include "absl/strings/string_view.h" 35#include "absl/strings/substitute.h" 36 37// NOLINTBEGIN(misc-definitions-in-headers) 38 39namespace absl_log_internal { 40 41using ::testing::AllOf; 42using ::testing::HasSubstr; 43using ::testing::Not; 44 45auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment( 46 new absl::log_internal::LogTestEnvironment); 47 48#if GTEST_HAS_DEATH_TEST 49 50TEST(CHECKDeathTest, TestBasicValues) { 51 ABSL_TEST_CHECK(true); 52 53 EXPECT_DEATH(ABSL_TEST_CHECK(false), "Check failed: false"); 54 55 int i = 2; 56 ABSL_TEST_CHECK(i != 3); // NOLINT 57} 58 59#endif // GTEST_HAS_DEATH_TEST 60 61TEST(CHECKTest, TestLogicExpressions) { 62 int i = 5; 63 ABSL_TEST_CHECK(i > 0 && i < 10); 64 ABSL_TEST_CHECK(i < 0 || i > 3); 65} 66 67ABSL_CONST_INIT const auto global_var_check = [](int i) { 68 ABSL_TEST_CHECK(i > 0); // NOLINT 69 return i + 1; 70}(3); 71 72ABSL_CONST_INIT const auto global_var = [](int i) { 73 ABSL_TEST_CHECK_GE(i, 0); // NOLINT 74 return i + 1; 75}(global_var_check); 76 77TEST(CHECKTest, TestPlacementsInCompoundStatements) { 78 // check placement inside if/else clauses 79 if (true) ABSL_TEST_CHECK(true); 80 81 if (false) 82 ; // NOLINT 83 else 84 ABSL_TEST_CHECK(true); 85 86 switch (0) 87 case 0: 88 ABSL_TEST_CHECK(true); // NOLINT 89 90 constexpr auto var = [](int i) { 91 ABSL_TEST_CHECK(i > 0); // NOLINT 92 return i + 1; 93 }(global_var); 94 (void)var; 95} 96 97TEST(CHECKTest, TestBoolConvertible) { 98 struct Tester { 99 } tester; 100 ABSL_TEST_CHECK([&]() { return &tester; }()); 101} 102 103#if GTEST_HAS_DEATH_TEST 104 105TEST(CHECKDeathTest, TestChecksWithSideEffects) { 106 int var = 0; 107 ABSL_TEST_CHECK([&var]() { 108 ++var; 109 return true; 110 }()); 111 EXPECT_EQ(var, 1); 112 113 EXPECT_DEATH(ABSL_TEST_CHECK([&var]() { 114 ++var; 115 return false; 116 }()) << var, 117 "Check failed: .* 2"); 118} 119 120#endif // GTEST_HAS_DEATH_TEST 121 122template <int a, int b> 123constexpr int sum() { 124 return a + b; 125} 126#define MACRO_ONE 1 127#define TEMPLATE_SUM(a, b) sum<a, b>() 128#define CONCAT(a, b) a b 129#define IDENTITY(x) x 130 131TEST(CHECKTest, TestPassingMacroExpansion) { 132 ABSL_TEST_CHECK(IDENTITY(true)); 133 ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(MACRO_ONE, 2), 3); 134 ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "xy"); 135} 136 137#if GTEST_HAS_DEATH_TEST 138 139TEST(CHECKTest, TestMacroExpansionInMessage) { 140 auto MessageGen = []() { ABSL_TEST_CHECK(IDENTITY(false)); }; 141 EXPECT_DEATH(MessageGen(), HasSubstr("IDENTITY(false)")); 142} 143 144TEST(CHECKTest, TestNestedMacroExpansionInMessage) { 145 EXPECT_DEATH(ABSL_TEST_CHECK(IDENTITY(false)), HasSubstr("IDENTITY(false)")); 146} 147 148TEST(CHECKTest, TestMacroExpansionCompare) { 149 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(IDENTITY(false), IDENTITY(true)), 150 HasSubstr("IDENTITY(false) == IDENTITY(true)")); 151 EXPECT_DEATH(ABSL_TEST_CHECK_GT(IDENTITY(1), IDENTITY(2)), 152 HasSubstr("IDENTITY(1) > IDENTITY(2)")); 153} 154 155TEST(CHECKTest, TestMacroExpansionStrCompare) { 156 EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(IDENTITY("x"), IDENTITY("y")), 157 HasSubstr("IDENTITY(\"x\") == IDENTITY(\"y\")")); 158 EXPECT_DEATH(ABSL_TEST_CHECK_STRCASENE(IDENTITY("a"), IDENTITY("A")), 159 HasSubstr("IDENTITY(\"a\") != IDENTITY(\"A\")")); 160} 161 162TEST(CHECKTest, TestMacroExpansionStatus) { 163 EXPECT_DEATH( 164 ABSL_TEST_CHECK_OK(IDENTITY(absl::FailedPreconditionError("message"))), 165 HasSubstr("IDENTITY(absl::FailedPreconditionError(\"message\"))")); 166} 167 168TEST(CHECKTest, TestMacroExpansionComma) { 169 EXPECT_DEATH(ABSL_TEST_CHECK(TEMPLATE_SUM(MACRO_ONE, 2) == 4), 170 HasSubstr("TEMPLATE_SUM(MACRO_ONE, 2) == 4")); 171} 172 173TEST(CHECKTest, TestMacroExpansionCommaCompare) { 174 EXPECT_DEATH( 175 ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)), 176 HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) == TEMPLATE_SUM(3, 2)")); 177 EXPECT_DEATH( 178 ABSL_TEST_CHECK_GT(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)), 179 HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) > TEMPLATE_SUM(3, 2)")); 180} 181 182TEST(CHECKTest, TestMacroExpansionCommaStrCompare) { 183 EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "z"), 184 HasSubstr("CONCAT(\"x\", \"y\") == \"z\"")); 185 EXPECT_DEATH(ABSL_TEST_CHECK_STRNE(CONCAT("x", "y"), "xy"), 186 HasSubstr("CONCAT(\"x\", \"y\") != \"xy\"")); 187} 188 189#endif // GTEST_HAS_DEATH_TEST 190 191#undef TEMPLATE_SUM 192#undef CONCAT 193#undef MACRO 194#undef ONE 195 196#if GTEST_HAS_DEATH_TEST 197 198TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) { 199 int counter = 0; 200 201 auto GetStr = [&counter]() -> std::string { 202 return counter++ == 0 ? "" : "non-empty"; 203 }; 204 205 EXPECT_DEATH(ABSL_TEST_CHECK(!GetStr().empty()) << GetStr(), 206 HasSubstr("non-empty")); 207} 208 209TEST(CHECKTest, TestSecondaryFailure) { 210 auto FailingRoutine = []() { 211 ABSL_TEST_CHECK(false) << "Secondary"; 212 return false; 213 }; 214 EXPECT_DEATH(ABSL_TEST_CHECK(FailingRoutine()) << "Primary", 215 AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary")))); 216} 217 218TEST(CHECKTest, TestSecondaryFailureInMessage) { 219 auto MessageGen = []() { 220 ABSL_TEST_CHECK(false) << "Secondary"; 221 return "Primary"; 222 }; 223 EXPECT_DEATH(ABSL_TEST_CHECK(false) << MessageGen(), 224 AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary")))); 225} 226 227#endif // GTEST_HAS_DEATH_TEST 228 229TEST(CHECKTest, TestBinaryChecksWithPrimitives) { 230 ABSL_TEST_CHECK_EQ(1, 1); 231 ABSL_TEST_CHECK_NE(1, 2); 232 ABSL_TEST_CHECK_GE(1, 1); 233 ABSL_TEST_CHECK_GE(2, 1); 234 ABSL_TEST_CHECK_LE(1, 1); 235 ABSL_TEST_CHECK_LE(1, 2); 236 ABSL_TEST_CHECK_GT(2, 1); 237 ABSL_TEST_CHECK_LT(1, 2); 238} 239 240// For testing using CHECK*() on anonymous enums. 241enum { CASE_A, CASE_B }; 242 243TEST(CHECKTest, TestBinaryChecksWithEnumValues) { 244 // Tests using CHECK*() on anonymous enums. 245 ABSL_TEST_CHECK_EQ(CASE_A, CASE_A); 246 ABSL_TEST_CHECK_NE(CASE_A, CASE_B); 247 ABSL_TEST_CHECK_GE(CASE_A, CASE_A); 248 ABSL_TEST_CHECK_GE(CASE_B, CASE_A); 249 ABSL_TEST_CHECK_LE(CASE_A, CASE_A); 250 ABSL_TEST_CHECK_LE(CASE_A, CASE_B); 251 ABSL_TEST_CHECK_GT(CASE_B, CASE_A); 252 ABSL_TEST_CHECK_LT(CASE_A, CASE_B); 253} 254 255TEST(CHECKTest, TestBinaryChecksWithNullptr) { 256 const void* p_null = nullptr; 257 const void* p_not_null = &p_null; 258 ABSL_TEST_CHECK_EQ(p_null, nullptr); 259 ABSL_TEST_CHECK_EQ(nullptr, p_null); 260 ABSL_TEST_CHECK_NE(p_not_null, nullptr); 261 ABSL_TEST_CHECK_NE(nullptr, p_not_null); 262} 263 264#if GTEST_HAS_DEATH_TEST 265 266// Test logging of various char-typed values by failing CHECK*(). 267TEST(CHECKDeathTest, TestComparingCharsValues) { 268 { 269 char a = ';'; 270 char b = 'b'; 271 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 272 "Check failed: a == b \\(';' vs. 'b'\\)"); 273 b = 1; 274 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 275 "Check failed: a == b \\(';' vs. char value 1\\)"); 276 } 277 { 278 signed char a = ';'; 279 signed char b = 'b'; 280 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 281 "Check failed: a == b \\(';' vs. 'b'\\)"); 282 b = -128; 283 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 284 "Check failed: a == b \\(';' vs. signed char value -128\\)"); 285 } 286 { 287 unsigned char a = ';'; 288 unsigned char b = 'b'; 289 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 290 "Check failed: a == b \\(';' vs. 'b'\\)"); 291 b = 128; 292 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 293 "Check failed: a == b \\(';' vs. unsigned char value 128\\)"); 294 } 295} 296 297TEST(CHECKDeathTest, TestNullValuesAreReportedCleanly) { 298 const char* a = nullptr; 299 const char* b = nullptr; 300 EXPECT_DEATH(ABSL_TEST_CHECK_NE(a, b), 301 "Check failed: a != b \\(\\(null\\) vs. \\(null\\)\\)"); 302 303 a = "xx"; 304 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 305 "Check failed: a == b \\(xx vs. \\(null\\)\\)"); 306 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(b, a), 307 "Check failed: b == a \\(\\(null\\) vs. xx\\)"); 308 309 std::nullptr_t n{}; 310 EXPECT_DEATH(ABSL_TEST_CHECK_NE(n, nullptr), 311 "Check failed: n != nullptr \\(\\(null\\) vs. \\(null\\)\\)"); 312} 313 314#endif // GTEST_HAS_DEATH_TEST 315 316TEST(CHECKTest, TestSTREQ) { 317 ABSL_TEST_CHECK_STREQ("this", "this"); 318 ABSL_TEST_CHECK_STREQ(nullptr, nullptr); 319 ABSL_TEST_CHECK_STRCASEEQ("this", "tHiS"); 320 ABSL_TEST_CHECK_STRCASEEQ(nullptr, nullptr); 321 ABSL_TEST_CHECK_STRNE("this", "tHiS"); 322 ABSL_TEST_CHECK_STRNE("this", nullptr); 323 ABSL_TEST_CHECK_STRCASENE("this", "that"); 324 ABSL_TEST_CHECK_STRCASENE(nullptr, "that"); 325 ABSL_TEST_CHECK_STREQ((std::string("a") + "b").c_str(), "ab"); 326 ABSL_TEST_CHECK_STREQ(std::string("test").c_str(), 327 (std::string("te") + std::string("st")).c_str()); 328} 329 330TEST(CHECKTest, TestComparisonPlacementsInCompoundStatements) { 331 // check placement inside if/else clauses 332 if (true) ABSL_TEST_CHECK_EQ(1, 1); 333 if (true) ABSL_TEST_CHECK_STREQ("c", "c"); 334 335 if (false) 336 ; // NOLINT 337 else 338 ABSL_TEST_CHECK_LE(0, 1); 339 340 if (false) 341 ; // NOLINT 342 else 343 ABSL_TEST_CHECK_STRNE("a", "b"); 344 345 switch (0) 346 case 0: 347 ABSL_TEST_CHECK_NE(1, 0); 348 349 switch (0) 350 case 0: 351 ABSL_TEST_CHECK_STRCASEEQ("A", "a"); 352 353 constexpr auto var = [](int i) { 354 ABSL_TEST_CHECK_GT(i, 0); 355 return i + 1; 356 }(global_var); 357 (void)var; 358 359 // CHECK_STR... checks are not supported in constexpr routines. 360 // constexpr auto var2 = [](int i) { 361 // ABSL_TEST_CHECK_STRNE("c", "d"); 362 // return i + 1; 363 // }(global_var); 364 365#if defined(__GNUC__) 366 int var3 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0; 367 (void)var3; 368 369 int var4 = (({ ABSL_TEST_CHECK_STREQ("a", "a"); }), global_var < 10) ? 1 : 0; 370 (void)var4; 371#endif // __GNUC__ 372} 373 374TEST(CHECKTest, TestDCHECK) { 375#ifdef NDEBUG 376 ABSL_TEST_DCHECK(1 == 2) << " DCHECK's shouldn't be compiled in normal mode"; 377#endif 378 ABSL_TEST_DCHECK(1 == 1); // NOLINT(readability/check) 379 ABSL_TEST_DCHECK_EQ(1, 1); 380 ABSL_TEST_DCHECK_NE(1, 2); 381 ABSL_TEST_DCHECK_GE(1, 1); 382 ABSL_TEST_DCHECK_GE(2, 1); 383 ABSL_TEST_DCHECK_LE(1, 1); 384 ABSL_TEST_DCHECK_LE(1, 2); 385 ABSL_TEST_DCHECK_GT(2, 1); 386 ABSL_TEST_DCHECK_LT(1, 2); 387 388 // Test DCHECK on std::nullptr_t 389 const void* p_null = nullptr; 390 const void* p_not_null = &p_null; 391 ABSL_TEST_DCHECK_EQ(p_null, nullptr); 392 ABSL_TEST_DCHECK_EQ(nullptr, p_null); 393 ABSL_TEST_DCHECK_NE(p_not_null, nullptr); 394 ABSL_TEST_DCHECK_NE(nullptr, p_not_null); 395} 396 397TEST(CHECKTest, TestQCHECK) { 398 // The tests that QCHECK does the same as CHECK 399 ABSL_TEST_QCHECK(1 == 1); // NOLINT(readability/check) 400 ABSL_TEST_QCHECK_EQ(1, 1); 401 ABSL_TEST_QCHECK_NE(1, 2); 402 ABSL_TEST_QCHECK_GE(1, 1); 403 ABSL_TEST_QCHECK_GE(2, 1); 404 ABSL_TEST_QCHECK_LE(1, 1); 405 ABSL_TEST_QCHECK_LE(1, 2); 406 ABSL_TEST_QCHECK_GT(2, 1); 407 ABSL_TEST_QCHECK_LT(1, 2); 408 409 // Tests using QCHECK*() on anonymous enums. 410 ABSL_TEST_QCHECK_EQ(CASE_A, CASE_A); 411 ABSL_TEST_QCHECK_NE(CASE_A, CASE_B); 412 ABSL_TEST_QCHECK_GE(CASE_A, CASE_A); 413 ABSL_TEST_QCHECK_GE(CASE_B, CASE_A); 414 ABSL_TEST_QCHECK_LE(CASE_A, CASE_A); 415 ABSL_TEST_QCHECK_LE(CASE_A, CASE_B); 416 ABSL_TEST_QCHECK_GT(CASE_B, CASE_A); 417 ABSL_TEST_QCHECK_LT(CASE_A, CASE_B); 418} 419 420TEST(CHECKTest, TestQCHECKPlacementsInCompoundStatements) { 421 // check placement inside if/else clauses 422 if (true) ABSL_TEST_QCHECK(true); 423 424 if (false) 425 ; // NOLINT 426 else 427 ABSL_TEST_QCHECK(true); 428 429 if (false) 430 ; // NOLINT 431 else 432 ABSL_TEST_QCHECK(true); 433 434 switch (0) 435 case 0: 436 ABSL_TEST_QCHECK(true); 437 438 constexpr auto var = [](int i) { 439 ABSL_TEST_QCHECK(i > 0); // NOLINT 440 return i + 1; 441 }(global_var); 442 (void)var; 443 444#if defined(__GNUC__) 445 int var2 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0; 446 (void)var2; 447#endif // __GNUC__ 448} 449 450class ComparableType { 451 public: 452 explicit ComparableType(int v) : v_(v) {} 453 454 void MethodWithCheck(int i) { 455 ABSL_TEST_CHECK_EQ(*this, i); 456 ABSL_TEST_CHECK_EQ(i, *this); 457 } 458 459 int Get() const { return v_; } 460 461 private: 462 friend bool operator==(const ComparableType& lhs, const ComparableType& rhs) { 463 return lhs.v_ == rhs.v_; 464 } 465 friend bool operator!=(const ComparableType& lhs, const ComparableType& rhs) { 466 return lhs.v_ != rhs.v_; 467 } 468 friend bool operator<(const ComparableType& lhs, const ComparableType& rhs) { 469 return lhs.v_ < rhs.v_; 470 } 471 friend bool operator<=(const ComparableType& lhs, const ComparableType& rhs) { 472 return lhs.v_ <= rhs.v_; 473 } 474 friend bool operator>(const ComparableType& lhs, const ComparableType& rhs) { 475 return lhs.v_ > rhs.v_; 476 } 477 friend bool operator>=(const ComparableType& lhs, const ComparableType& rhs) { 478 return lhs.v_ >= rhs.v_; 479 } 480 friend bool operator==(const ComparableType& lhs, int rhs) { 481 return lhs.v_ == rhs; 482 } 483 friend bool operator==(int lhs, const ComparableType& rhs) { 484 return lhs == rhs.v_; 485 } 486 487 friend std::ostream& operator<<(std::ostream& out, const ComparableType& v) { 488 return out << "ComparableType{" << v.Get() << "}"; 489 } 490 491 int v_; 492}; 493 494TEST(CHECKTest, TestUserDefinedCompOp) { 495 ABSL_TEST_CHECK_EQ(ComparableType{0}, ComparableType{0}); 496 ABSL_TEST_CHECK_NE(ComparableType{1}, ComparableType{2}); 497 ABSL_TEST_CHECK_LT(ComparableType{1}, ComparableType{2}); 498 ABSL_TEST_CHECK_LE(ComparableType{1}, ComparableType{2}); 499 ABSL_TEST_CHECK_GT(ComparableType{2}, ComparableType{1}); 500 ABSL_TEST_CHECK_GE(ComparableType{2}, ComparableType{2}); 501} 502 503TEST(CHECKTest, TestCheckInMethod) { 504 ComparableType v{1}; 505 v.MethodWithCheck(1); 506} 507 508TEST(CHECKDeathTest, TestUserDefinedStreaming) { 509 ComparableType v1{1}; 510 ComparableType v2{2}; 511 512 EXPECT_DEATH( 513 ABSL_TEST_CHECK_EQ(v1, v2), 514 HasSubstr( 515 "Check failed: v1 == v2 (ComparableType{1} vs. ComparableType{2})")); 516} 517 518// A type that can be printed using AbslStringify. 519struct StringifiableType { 520 int x = 0; 521 explicit StringifiableType(int x) : x(x) {} 522 friend bool operator==(const StringifiableType& lhs, 523 const StringifiableType& rhs) { 524 return lhs.x == rhs.x; 525 } 526 friend bool operator!=(const StringifiableType& lhs, 527 const StringifiableType& rhs) { 528 return lhs.x != rhs.x; 529 } 530 friend bool operator<(const StringifiableType& lhs, 531 const StringifiableType& rhs) { 532 return lhs.x < rhs.x; 533 } 534 friend bool operator>(const StringifiableType& lhs, 535 const StringifiableType& rhs) { 536 return lhs.x > rhs.x; 537 } 538 friend bool operator<=(const StringifiableType& lhs, 539 const StringifiableType& rhs) { 540 return lhs.x <= rhs.x; 541 } 542 friend bool operator>=(const StringifiableType& lhs, 543 const StringifiableType& rhs) { 544 return lhs.x >= rhs.x; 545 } 546 template <typename Sink> 547 friend void AbslStringify(Sink& sink, const StringifiableType& obj) { 548 absl::Format(&sink, "StringifiableType{%d}", obj.x); 549 } 550 551 // Make sure no unintended copy happens. 552 StringifiableType(const StringifiableType&) = delete; 553}; 554 555TEST(CHECKTest, TestUserDefinedAbslStringify) { 556 const StringifiableType v1(1); 557 const StringifiableType v2(2); 558 559 ABSL_TEST_CHECK_EQ(v1, v1); 560 ABSL_TEST_CHECK_NE(v1, v2); 561 ABSL_TEST_CHECK_LT(v1, v2); 562 ABSL_TEST_CHECK_LE(v1, v2); 563 ABSL_TEST_CHECK_GT(v2, v1); 564 ABSL_TEST_CHECK_GE(v2, v1); 565} 566 567TEST(CHECKDeathTest, TestUserDefinedAbslStringify) { 568 const StringifiableType v1(1); 569 const StringifiableType v2(2); 570 571 // Returns a matcher for the expected check failure message when comparing two 572 // values. 573 auto expected_output = [](int lhs, absl::string_view condition, int rhs) { 574 return HasSubstr( 575 absl::Substitute("Check failed: v$0 $1 v$2 (StringifiableType{$0} vs. " 576 "StringifiableType{$2})", 577 lhs, condition, rhs)); 578 }; 579 // Test comparisons where the check fails. 580 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(v1, v2), expected_output(1, "==", 2)); 581 EXPECT_DEATH(ABSL_TEST_CHECK_NE(v1, v1), expected_output(1, "!=", 1)); 582 EXPECT_DEATH(ABSL_TEST_CHECK_LT(v2, v1), expected_output(2, "<", 1)); 583 EXPECT_DEATH(ABSL_TEST_CHECK_LE(v2, v1), expected_output(2, "<=", 1)); 584 EXPECT_DEATH(ABSL_TEST_CHECK_GT(v1, v2), expected_output(1, ">", 2)); 585 EXPECT_DEATH(ABSL_TEST_CHECK_GE(v1, v2), expected_output(1, ">=", 2)); 586} 587 588// A type that can be printed using both AbslStringify and operator<<. 589struct StringifiableStreamableType { 590 int x = 0; 591 explicit StringifiableStreamableType(int x) : x(x) {} 592 593 friend bool operator==(const StringifiableStreamableType& lhs, 594 const StringifiableStreamableType& rhs) { 595 return lhs.x == rhs.x; 596 } 597 friend bool operator!=(const StringifiableStreamableType& lhs, 598 const StringifiableStreamableType& rhs) { 599 return lhs.x != rhs.x; 600 } 601 template <typename Sink> 602 friend void AbslStringify(Sink& sink, 603 const StringifiableStreamableType& obj) { 604 absl::Format(&sink, "Strigified{%d}", obj.x); 605 } 606 friend std::ostream& operator<<(std::ostream& out, 607 const StringifiableStreamableType& obj) { 608 return out << "Streamed{" << obj.x << "}"; 609 } 610 611 // Avoid unintentional copy. 612 StringifiableStreamableType(const StringifiableStreamableType&) = delete; 613}; 614 615TEST(CHECKDeathTest, TestStreamingPreferredOverAbslStringify) { 616 StringifiableStreamableType v1(1); 617 StringifiableStreamableType v2(2); 618 619 EXPECT_DEATH( 620 ABSL_TEST_CHECK_EQ(v1, v2), 621 HasSubstr("Check failed: v1 == v2 (Streamed{1} vs. Streamed{2})")); 622} 623 624// A type whose pointer can be passed to AbslStringify. 625struct PointerIsStringifiable {}; 626template <typename Sink> 627void AbslStringify(Sink& sink, const PointerIsStringifiable* var) { 628 sink.Append("PointerIsStringifiable"); 629} 630 631// Verifies that a pointer is printed as a number despite having AbslStringify 632// defined. Users may implement AbslStringify that dereferences the pointer, and 633// doing so as part of DCHECK would not be good. 634TEST(CHECKDeathTest, TestPointerPrintedAsNumberDespiteAbslStringify) { 635 const auto* p = reinterpret_cast<const PointerIsStringifiable*>(0x1234); 636 637#ifdef _MSC_VER 638 EXPECT_DEATH( 639 ABSL_TEST_CHECK_EQ(p, nullptr), 640 HasSubstr("Check failed: p == nullptr (0000000000001234 vs. (null))")); 641#else // _MSC_VER 642 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(p, nullptr), 643 HasSubstr("Check failed: p == nullptr (0x1234 vs. (null))")); 644#endif // _MSC_VER 645} 646 647// An uncopyable object with operator<<. 648struct Uncopyable { 649 int x; 650 explicit Uncopyable(int x) : x(x) {} 651 Uncopyable(const Uncopyable&) = delete; 652 friend bool operator==(const Uncopyable& lhs, const Uncopyable& rhs) { 653 return lhs.x == rhs.x; 654 } 655 friend bool operator!=(const Uncopyable& lhs, const Uncopyable& rhs) { 656 return lhs.x != rhs.x; 657 } 658 friend std::ostream& operator<<(std::ostream& os, const Uncopyable& obj) { 659 return os << "Uncopyable{" << obj.x << "}"; 660 } 661}; 662 663// Test that an uncopyable object can be used. 664// Will catch us if implementation has an unintended copy. 665TEST(CHECKDeathTest, TestUncopyable) { 666 const Uncopyable v1(1); 667 const Uncopyable v2(2); 668 669 EXPECT_DEATH( 670 ABSL_TEST_CHECK_EQ(v1, v2), 671 HasSubstr("Check failed: v1 == v2 (Uncopyable{1} vs. Uncopyable{2})")); 672} 673 674} // namespace absl_log_internal 675 676// NOLINTEND(misc-definitions-in-headers) 677 678#endif // ABSL_LOG_CHECK_TEST_IMPL_H_ 679