| // Copyright 2018 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef UTIL_TEST_TEST_H_ | 
 | #define UTIL_TEST_TEST_H_ | 
 |  | 
 | #include <string.h> | 
 |  | 
 | #include <sstream> | 
 | #include <string> | 
 |  | 
 | // This is a minimal googletest-like testing framework. It's originally derived | 
 | // from Ninja's src/test.h. You might prefer that one if you have different | 
 | // tradeoffs (in particular, if you don't need to stream message to assertion | 
 | // failures, Ninja's is a bit simpler.) | 
 | namespace testing { | 
 |  | 
 | class Test { | 
 |  public: | 
 |   Test() : failed_(false) {} | 
 |   virtual ~Test() {} | 
 |   virtual void SetUp() {} | 
 |   virtual void TearDown() {} | 
 |   virtual void Run() = 0; | 
 |  | 
 |   bool Failed() const { return failed_; } | 
 |  | 
 |  private: | 
 |   friend class TestResult; | 
 |  | 
 |   bool failed_; | 
 | }; | 
 |  | 
 | extern testing::Test* g_current_test; | 
 |  | 
 | class TestResult { | 
 |  public: | 
 |   TestResult(bool condition, const char* error) | 
 |       : condition_(condition), error_(error) { | 
 |     if (!condition) | 
 |       g_current_test->failed_ = true; | 
 |   } | 
 |  | 
 |   operator bool() const { return condition_; } | 
 |   const char* error() const { return error_; } | 
 |  | 
 |  private: | 
 |   bool condition_; | 
 |   const char* error_; | 
 | }; | 
 |  | 
 | class Message { | 
 |  public: | 
 |   Message() {} | 
 |   ~Message() { printf("%s\n\n", ss_.str().c_str()); } | 
 |  | 
 |   template <typename T> | 
 |   inline Message& operator<<(const T& val) { | 
 |     ss_ << val; | 
 |     return *this; | 
 |   } | 
 |  | 
 |  private: | 
 |   std::stringstream ss_; | 
 | }; | 
 |  | 
 | class AssertHelper { | 
 |  public: | 
 |   AssertHelper(const char* file, int line, const TestResult& test_result) | 
 |       : file_(file), line_(line), error_(test_result.error()) {} | 
 |  | 
 |   void operator=(const Message& message) const { | 
 |     printf("\n*** FAILURE %s:%d: %s\n", file_, line_, error_); | 
 |   } | 
 |  | 
 |  private: | 
 |   const char* file_; | 
 |   int line_; | 
 |   const char* error_; | 
 | }; | 
 |  | 
 | }  // namespace testing | 
 |  | 
 | void RegisterTest(testing::Test* (*)(), const char*); | 
 |  | 
 | #define TEST_F_(x, y, name)                                                    \ | 
 |   struct y : public x {                                                        \ | 
 |     static testing::Test* Create() { return testing::g_current_test = new y; } \ | 
 |     virtual void Run();                                                        \ | 
 |   };                                                                           \ | 
 |   struct Register##y {                                                         \ | 
 |     Register##y() { RegisterTest(y::Create, name); }                           \ | 
 |   };                                                                           \ | 
 |   Register##y g_register_##y;                                                  \ | 
 |   void y::Run() | 
 |  | 
 | #define TEST_F(x, y) TEST_F_(x, x##y, #x "." #y) | 
 | #define TEST(x, y) TEST_F_(testing::Test, x##y, #x "." #y) | 
 |  | 
 | #define FRIEND_TEST(x, y) friend class x##y | 
 |  | 
 | // Some compilers emit a warning if nested "if" statements are followed by an | 
 | // "else" statement and braces are not used to explicitly disambiguate the | 
 | // "else" binding.  This leads to problems with code like: | 
 | // | 
 | //   if (something) | 
 | //     ASSERT_TRUE(condition) << "Some message"; | 
 | #define TEST_AMBIGUOUS_ELSE_BLOCKER_ \ | 
 |   switch (0)                         \ | 
 |   case 0:                            \ | 
 |   default: | 
 |  | 
 | #define TEST_ASSERT_(expression, on_failure)                  \ | 
 |   TEST_AMBIGUOUS_ELSE_BLOCKER_                                \ | 
 |   if (const ::testing::TestResult test_result = (expression)) \ | 
 |     ;                                                         \ | 
 |   else                                                        \ | 
 |     on_failure(test_result) | 
 |  | 
 | #define TEST_NONFATAL_FAILURE_(message) \ | 
 |   ::testing::AssertHelper(__FILE__, __LINE__, message) = ::testing::Message() | 
 |  | 
 | #define TEST_FATAL_FAILURE_(message)                            \ | 
 |   return ::testing::AssertHelper(__FILE__, __LINE__, message) = \ | 
 |              ::testing::Message() | 
 |  | 
 | #define EXPECT_EQ(a, b)                                     \ | 
 |   TEST_ASSERT_(::testing::TestResult(a == b, #a " == " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_NE(a, b)                                     \ | 
 |   TEST_ASSERT_(::testing::TestResult(a != b, #a " != " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_LT(a, b)                                   \ | 
 |   TEST_ASSERT_(::testing::TestResult(a < b, #a " < " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_GT(a, b)                                   \ | 
 |   TEST_ASSERT_(::testing::TestResult(a > b, #a " > " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_LE(a, b)                                     \ | 
 |   TEST_ASSERT_(::testing::TestResult(a <= b, #a " <= " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_GE(a, b)                                     \ | 
 |   TEST_ASSERT_(::testing::TestResult(a >= b, #a " >= " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_TRUE(a)                                          \ | 
 |   TEST_ASSERT_(::testing::TestResult(static_cast<bool>(a), #a), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_FALSE(a)                                          \ | 
 |   TEST_ASSERT_(::testing::TestResult(!static_cast<bool>(a), #a), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define EXPECT_STREQ(a, b)                                                \ | 
 |   TEST_ASSERT_(::testing::TestResult(strcmp(a, b) == 0, #a " str== " #b), \ | 
 |                TEST_NONFATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_EQ(a, b) \ | 
 |   TEST_ASSERT_(::testing::TestResult(a == b, #a " == " #b), TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_NE(a, b) \ | 
 |   TEST_ASSERT_(::testing::TestResult(a != b, #a " != " #b), TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_LT(a, b) \ | 
 |   TEST_ASSERT_(::testing::TestResult(a < b, #a " < " #b), TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_GT(a, b) \ | 
 |   TEST_ASSERT_(::testing::TestResult(a > b, #a " > " #b), TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_LE(a, b) \ | 
 |   TEST_ASSERT_(::testing::TestResult(a <= b, #a " <= " #b), TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_GE(a, b) \ | 
 |   TEST_ASSERT_(::testing::TestResult(a >= b, #a " >= " #b), TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_TRUE(a)                                          \ | 
 |   TEST_ASSERT_(::testing::TestResult(static_cast<bool>(a), #a), \ | 
 |                TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_FALSE(a)                                          \ | 
 |   TEST_ASSERT_(::testing::TestResult(!static_cast<bool>(a), #a), \ | 
 |                TEST_FATAL_FAILURE_) | 
 |  | 
 | #define ASSERT_STREQ(a, b)                                                \ | 
 |   TEST_ASSERT_(::testing::TestResult(strcmp(a, b) == 0, #a " str== " #b), \ | 
 |                TEST_FATAL_FAILURE_) | 
 |  | 
 | #endif  // UTIL_TEST_TEST_H_ |