• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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