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