tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

check_test_impl.inc (20170B)


      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 
     39 namespace absl_log_internal {
     40 
     41 using ::testing::AllOf;
     42 using ::testing::HasSubstr;
     43 using ::testing::Not;
     44 
     45 auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
     46    new absl::log_internal::LogTestEnvironment);
     47 
     48 #if GTEST_HAS_DEATH_TEST
     49 
     50 TEST(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 
     61 TEST(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 ABSL_CONST_INIT const auto global_var_check = [](int i) {
     68  ABSL_TEST_CHECK(i > 0);  // NOLINT
     69  return i + 1;
     70 }(3);
     71 
     72 ABSL_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 
     77 TEST(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 
     97 TEST(CHECKTest, TestBoolConvertible) {
     98  struct Tester {
     99  } tester;
    100  ABSL_TEST_CHECK([&]() { return &tester; }());
    101 }
    102 
    103 #if GTEST_HAS_DEATH_TEST
    104 
    105 TEST(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 
    122 template <int a, int b>
    123 constexpr 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 
    131 TEST(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 
    139 TEST(CHECKTest, TestMacroExpansionInMessage) {
    140  auto MessageGen = []() { ABSL_TEST_CHECK(IDENTITY(false)); };
    141  EXPECT_DEATH(MessageGen(), HasSubstr("IDENTITY(false)"));
    142 }
    143 
    144 TEST(CHECKTest, TestNestedMacroExpansionInMessage) {
    145  EXPECT_DEATH(ABSL_TEST_CHECK(IDENTITY(false)), HasSubstr("IDENTITY(false)"));
    146 }
    147 
    148 TEST(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 
    155 TEST(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 
    162 TEST(CHECKTest, TestMacroExpansionStatus) {
    163  EXPECT_DEATH(
    164      ABSL_TEST_CHECK_OK(IDENTITY(absl::FailedPreconditionError("message"))),
    165      HasSubstr("IDENTITY(absl::FailedPreconditionError(\"message\"))"));
    166 }
    167 
    168 TEST(CHECKTest, TestMacroExpansionComma) {
    169  EXPECT_DEATH(ABSL_TEST_CHECK(TEMPLATE_SUM(MACRO_ONE, 2) == 4),
    170               HasSubstr("TEMPLATE_SUM(MACRO_ONE, 2) == 4"));
    171 }
    172 
    173 TEST(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 
    182 TEST(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 
    198 TEST(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 
    209 TEST(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 
    218 TEST(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 
    229 TEST(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.
    241 enum { CASE_A, CASE_B };
    242 
    243 TEST(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 
    255 TEST(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*().
    267 TEST(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 
    297 TEST(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 
    316 TEST(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 
    330 TEST(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 
    374 TEST(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 
    397 TEST(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 
    420 TEST(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 
    450 class 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 
    494 TEST(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 
    503 TEST(CHECKTest, TestCheckInMethod) {
    504  ComparableType v{1};
    505  v.MethodWithCheck(1);
    506 }
    507 
    508 TEST(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.
    519 struct 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 
    555 TEST(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 
    567 TEST(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<<.
    589 struct 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 
    615 TEST(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.
    625 struct PointerIsStringifiable {};
    626 template <typename Sink>
    627 void 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.
    634 TEST(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<<.
    648 struct 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.
    665 TEST(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_