• 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
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