Home | History | Annotate | Download | only in minitest
      1 // Copyright (C) 2013 The Android Open Source Project
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions
      6 // are met:
      7 // // Redistributions of source code must retain the above copyright
      8 //    notice, this list of conditions and the following disclaimer.
      9 // // Redistributions in binary form must reproduce the above copyright
     10 //    notice, this list of conditions and the following disclaimer in
     11 //    the documentation and/or other materials provided with the
     12 //    distribution.
     13 //
     14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     15 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     16 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     17 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     18 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     19 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     20 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     21 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     22 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     23 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     24 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25 // SUCH DAMAGE.
     26 
     27 #ifndef MINITEST_MINITEST_H
     28 #define MINITEST_MINITEST_H
     29 
     30 // Minitest is a minimalistic unit testing framework designed specifically
     31 // for the Android support library.
     32 //
     33 // - Unit tests must be written in C++, but no C++ runtime implementation
     34 //   is either required or _supported_. This is by design.
     35 //
     36 // _ Inspired by GoogleTest, you can use the TEST macro to define a new
     37 //   test case easily, and it can contain EXPECT_XX|ASSERT_XX statements.
     38 //
     39 //   For example:
     40 //
     41 //      TEST(stdio, strlen) {
     42 //        EXPECT_EQ(3, strlen("foo"));
     43 //        EXPECT_EQ(1, srlen("a"));
     44 //      }
     45 //
     46 //   However, there are important differences / limitations:
     47 //
     48 //   o You cannot stream strings into an except or assert statement.
     49 //     Minitest provides a TEST_TEXT macro to do that instead.
     50 //
     51 //     In other words, replace:
     52 //
     53 //       EXPECT_EQ(expected, expression) << "When checking 'foo'";
     54 //
     55 //     With:
     56 //       TEST_TEXT << "When checking 'foo'";
     57 //       EXPECT_EQ(expected, expression);
     58 //
     59 //    The context text is only printed on failure.
     60 //
     61 //   o TEST_F() is not supported (for now).
     62 //
     63 //   o EXPECT/ASSERT statements only work inside a TESET() function, not
     64 //     in a function called by it.
     65 //
     66 //   o No test death detection.
     67 //
     68 // - You can use minitest::Format() to stream formatted output into
     69 //   a TEST_TEXT context, as in:
     70 //
     71 //      for (size_t n = 0; n < kMaxCount; n++) {
     72 //        TEST_TEXT << "Checking string : "
     73 //                  << minitest;:Format("%z/%z", n+1, kMaxCount);
     74 //        EXPECT_EQ(kExpected[n], Foo(kString[n]));
     75 //      }
     76 //
     77 #include <stdio.h>
     78 #include <string.h>
     79 
     80 namespace minitest {
     81 
     82 namespace internal {
     83 
     84 // AddConst<T>::type adds a 'const' qualifier to type T.
     85 // Examples:
     86 //   int -> const int
     87 //   char* -> const char* const
     88 //   const char* -> const char* const
     89 //   char* const -> const char* const
     90 template <typename T>
     91 struct AddConst {
     92   typedef const T type;
     93 };
     94 template <typename T>
     95 struct AddConst<const T> {
     96   typedef const T type;
     97 };
     98 template <typename T>
     99 struct AddConst<T*> {
    100   typedef const T* const type;
    101 };
    102 template <typename T>
    103 struct AddConst<const T*> {
    104   typedef const T* const type;
    105 };
    106 
    107 // String class used to accumulate error messages.
    108 // Very similar to std::string but also supports streaming into it
    109 // for easier formatted output, as in:
    110 //
    111 //    String str;
    112 //    int x = 42;
    113 //    str << "x is '" << x << "'\n";
    114 //
    115 // You can also use minitest::Format() as in:
    116 //
    117 //    str << minitest::Format("Hex value %08x\n", x);
    118 //
    119 class String {
    120  public:
    121   String() : str_(NULL), size_(0), capacity_(0) {}
    122   String(const char* str, size_t len);
    123 
    124   explicit String(const char* str) { String(str, ::strlen(str)); }
    125 
    126   String(const String& other) { String(other.str_, other.size_); }
    127 
    128   String& operator=(const String& other) {
    129     (*this) += other;
    130     return *this;
    131   }
    132 
    133   char& operator[](size_t index) { return str_[index]; }
    134 
    135   ~String() { Clear(); }
    136 
    137   const char* c_str() const { return str_; }
    138   const char* data() const { return str_; }
    139   size_t size() const { return size_; }
    140   bool empty() const { return size_ == 0; }
    141 
    142   String& operator+=(const String& other);
    143   String& operator+=(const char* str);
    144   String& operator+=(char ch);
    145 
    146   String operator+(const String& other) const {
    147     String result(*this);
    148     result += other;
    149     return result;
    150   }
    151 
    152   String operator+(const char* str) const {
    153     String result(*this);
    154     result += str;
    155     return result;
    156   }
    157 
    158   // Basic formatting operators.
    159   String& operator<<(const String& other);
    160   String& operator<<(const char* str);
    161 
    162 #define MINITEST_OPERATOR_LL_(ParamType) String& operator<<(ParamType v)
    163 
    164   MINITEST_OPERATOR_LL_(bool);
    165   MINITEST_OPERATOR_LL_(char);
    166   MINITEST_OPERATOR_LL_(signed char);
    167   MINITEST_OPERATOR_LL_(short);
    168   MINITEST_OPERATOR_LL_(int);
    169   MINITEST_OPERATOR_LL_(long);
    170   MINITEST_OPERATOR_LL_(long long);
    171   MINITEST_OPERATOR_LL_(unsigned char);
    172   MINITEST_OPERATOR_LL_(unsigned short);
    173   MINITEST_OPERATOR_LL_(unsigned int);
    174   MINITEST_OPERATOR_LL_(unsigned long);
    175   MINITEST_OPERATOR_LL_(unsigned long long);
    176   MINITEST_OPERATOR_LL_(float);
    177   MINITEST_OPERATOR_LL_(double);
    178   MINITEST_OPERATOR_LL_(long double);
    179   MINITEST_OPERATOR_LL_(const void*);
    180 
    181 #undef MINITEST_OPERATOR_LL_
    182 
    183   void Clear();
    184   void Resize(size_t new_size);
    185 
    186  private:
    187   void Reserve(size_t new_capacity);
    188   char* str_;
    189   size_t size_;
    190   size_t capacity_;
    191 };
    192 
    193 }  // namespace internal
    194 
    195 // A helper function that can be used to generate formatted output
    196 // as a temporary string. Use like printf(), but returns a new String
    197 // object. Useful to stream into TEST_TEXT() objects, as in:
    198 //
    199 //   TEST_TEXT << "Using "
    200 //                << minitest::Format("%08d", bytes)
    201 //                << " bytes";
    202 //
    203 internal::String Format(const char* format, ...);
    204 
    205 class TestCase {
    206  public:
    207   enum Result {
    208     PASS = 0,
    209     FAIL,
    210     FATAL
    211   };
    212 
    213   TestCase() : result_(PASS) {}
    214   ~TestCase() {}
    215 
    216   void Failure();
    217   void FatalFailure();
    218 
    219   Result result() { return result_; }
    220 
    221   internal::String& GetText();
    222 
    223  private:
    224   Result result_;
    225   internal::String text_;
    226 };
    227 
    228 // Type of a function defined through the TEST(<test>,<case>) macro.
    229 typedef void(TestFunction)(TestCase* testcase);
    230 
    231 // Used internally to register new test functions.
    232 void RegisterTest(const char* test_name,
    233                   const char* case_name,
    234                   TestFunction* test_function);
    235 
    236 #define MINITEST_TEST_FUNCTION(testname, casename) \
    237   MINITEST_TEST_FUNCTION_(testname, casename)
    238 
    239 #define MINITEST_TEST_FUNCTION_(testname, casename) \
    240   minitest_##testname##_##casename
    241 
    242 #define TEST(testname, casename)                                               \
    243   static void MINITEST_TEST_FUNCTION(testname, casename)(minitest::TestCase*); \
    244   static void                                                                  \
    245       __attribute__((constructor)) RegisterMiniTest##testname##_##casename() { \
    246     minitest::RegisterTest(                                                    \
    247         #testname, #casename, &MINITEST_TEST_FUNCTION(testname, casename));    \
    248   }                                                                            \
    249   void MINITEST_TEST_FUNCTION(testname,                                        \
    250                               casename)(minitest::TestCase* minitest_testcase)
    251 
    252 // Use this macro to add context text before an EXPECT or ASSERT statement
    253 // For example:
    254 //
    255 //    for (size_t n = 0; n < MAX; ++n) {
    256 //      TEST_TEXT << "When checking " << kStrings[n];
    257 //      EXPECT_STREQ(kExpected[n], kStrings[n]);
    258 //    }
    259 //
    260 // The text will only be printed in case of failure in the next
    261 // EXPECT/ASSERT statement.
    262 //
    263 #define TEST_TEXT minitest_testcase->GetText()
    264 
    265 // EXPECT_TRUE() must evaluate to something that supports the << operator
    266 // to receive debugging strings only in case of failure.
    267 #define EXPECT_TRUE(expression)                                            \
    268   do {                                                                     \
    269     if (!(expression)) {                                                   \
    270       printf(                                                              \
    271           "EXPECT_TRUE:%s:%d: expression '%s' returned 'false', expected " \
    272           "'true'\n",                                                      \
    273           __FILE__,                                                        \
    274           __LINE__,                                                        \
    275           #expression);                                                    \
    276       minitest_testcase->Failure();                                        \
    277     }                                                                      \
    278   } while (0)
    279 
    280 #define EXPECT_FALSE(expression)                                           \
    281   do {                                                                     \
    282     if (!!(expression)) {                                                  \
    283       printf(                                                              \
    284           "EXPECT_FALSE:%s:%d: expression '%s' returned 'true', expected " \
    285           "'false'\n",                                                     \
    286           __FILE__,                                                        \
    287           __LINE__,                                                        \
    288           #expression);                                                    \
    289       minitest_testcase->Failure();                                        \
    290     }                                                                      \
    291   } while (0)
    292 
    293 #define MINITEST_DEFINE_LOCAL_EXPR_(varname, expr)                            \
    294   typedef minitest::internal::AddConst<__typeof__(expr)>::type varname##Type; \
    295   const varname##Type varname = (expr);
    296 
    297 #define MINITEST_EXPECT_ASSERT_BINOP_(                        \
    298     opname, op, expected, expression, is_assert)              \
    299   do {                                                        \
    300     MINITEST_DEFINE_LOCAL_EXPR_(minitest_expected, expected); \
    301     MINITEST_DEFINE_LOCAL_EXPR_(minitest_actual, expression); \
    302     if (!(minitest_actual op minitest_expected)) {            \
    303       printf("%s" #opname ":%s:%d: with expression '%s'\n",   \
    304              is_assert ? "ASSERT_" : "EXPECT_",               \
    305              __FILE__,                                        \
    306              __LINE__,                                        \
    307              #expression);                                    \
    308       minitest::internal::String minitest_str;                \
    309       minitest_str << minitest_actual;                        \
    310       printf("actual   : %s\n", minitest_str.c_str());        \
    311       minitest_str.Clear();                                   \
    312       minitest_str << minitest_expected;                      \
    313       printf("expected : %s\n", minitest_str.c_str());        \
    314       if (is_assert) {                                        \
    315         minitest_testcase->FatalFailure();                    \
    316         return;                                               \
    317       }                                                       \
    318       minitest_testcase->Failure();                           \
    319     }                                                         \
    320   } while (0)
    321 
    322 #define MINITEST_EXPECT_BINOP_(opname, op, expected, expression) \
    323   MINITEST_EXPECT_ASSERT_BINOP_(opname, op, expected, expression, false)
    324 
    325 #define EXPECT_EQ(expected, expression) \
    326   MINITEST_EXPECT_BINOP_(EQ, ==, expected, expression)
    327 
    328 #define EXPECT_NE(expected, expression) \
    329   MINITEST_EXPECT_BINOP_(NE, !=, expected, expression)
    330 
    331 #define EXPECT_LE(expected, expression) \
    332   MINITEST_EXPECT_BINOP_(LE, <=, expected, expression)
    333 
    334 #define EXPECT_LT(expected, expression) \
    335   MINITEST_EXPECT_BINOP_(LT, <, expected, expression)
    336 
    337 #define EXPECT_GE(expected, expression) \
    338   MINITEST_EXPECT_BINOP_(GE, >=, expected, expression)
    339 
    340 #define EXPECT_GT(expected, expression) \
    341   MINITEST_EXPECT_BINOP_(GT, >, expected, expression)
    342 
    343 #define MINITEST_EXPECT_ASSERT_STR_(expected, expression, is_eq, is_assert) \
    344   do {                                                                      \
    345     const char* minitest_prefix = is_assert ? "ASSERT_STR" : "EXPECT_STR";  \
    346     const char* minitest_suffix = is_eq ? "EQ" : "NEQ";                     \
    347     const char* minitest_expected = (expected);                             \
    348     const char* minitest_actual = (expression);                             \
    349     if (minitest_actual == NULL) {                                          \
    350       printf("%s%s:%s:%d: expression '%s' is NULL!\n",                      \
    351              minitest_prefix,                                               \
    352              minitest_suffix,                                               \
    353              __FILE__,                                                      \
    354              __LINE__,                                                      \
    355              #expression);                                                  \
    356       minitest_testcase->Failure();                                         \
    357     } else {                                                                \
    358       bool minitest_eq = !strcmp(minitest_expected, minitest_actual);       \
    359       if (minitest_eq != is_eq) {                                           \
    360         printf("%s%s:%s:%d: with expression '%s'\n",                        \
    361                minitest_prefix,                                             \
    362                minitest_suffix,                                             \
    363                __FILE__,                                                    \
    364                __LINE__,                                                    \
    365                #expression);                                                \
    366         printf("actual   : %s\n", minitest_actual);                         \
    367         printf("expected : %s\n", minitest_expected);                       \
    368         minitest_testcase->Failure();                                       \
    369       }                                                                     \
    370     }                                                                       \
    371   } while (0)
    372 
    373 #define EXPECT_STREQ(expected, expression) \
    374   MINITEST_EXPECT_ASSERT_STR_(expected, expression, true, false)
    375 
    376 #define EXPECT_STRNEQ(expected, expression) \
    377   MINITEST_EXPECT_ASSERT_STR_(expected, expression, false, false)
    378 
    379 #define MINITEST_EXPECT_ASSERT_MEM_(                                           \
    380     expected, expected_len, expression, expression_len, is_eq, is_assert)      \
    381   do {                                                                         \
    382     const char* minitest_prefix = is_assert ? "ASSERT_MEM" : "EXPECT_MEM";     \
    383     const char* minitest_suffix = is_eq ? "EQ" : "NEQ";                        \
    384     const char* minitest_expected = (expected);                                \
    385     size_t minitest_expected_len = static_cast<size_t>(expected_len);          \
    386     const char* minitest_actual = (expression);                                \
    387     size_t minitest_actual_len = static_cast<size_t>(expression_len);          \
    388     if (minitest_actual == NULL) {                                             \
    389       printf("%s%s:%s:%d: expression '%s' is NULL!\n",                         \
    390              minitest_prefix,                                                  \
    391              minitest_suffix,                                                  \
    392              __FILE__,                                                         \
    393              __LINE__,                                                         \
    394              #expression);                                                     \
    395       minitest_testcase->Failure();                                            \
    396     } else if (minitest_actual_len != minitest_expected_len) {                 \
    397       printf("%s:%s:%s:%d: size mistmatch for expression '%s'\n",              \
    398              minitest_prefix,                                                  \
    399              minitest_suffix,                                                  \
    400              __FILE__,                                                         \
    401              __LINE__,                                                         \
    402              #expression);                                                     \
    403       printf("actual size   : %zu (0x%zx)\n",                                  \
    404              minitest_actual_len,                                              \
    405              minitest_actual_len);                                             \
    406       printf("expected size : %zu (0x%zx)\n",                                  \
    407              minitest_expected_len,                                            \
    408              minitest_expected_len);                                           \
    409       minitest_testcase->Failure();                                            \
    410     } else {                                                                   \
    411       bool minitest_eq =                                                       \
    412           !memcmp(minitest_expected, minitest_actual, minitest_expected_len);  \
    413       if (minitest_eq != is_eq) {                                              \
    414         printf("%s%s:%s:%d: with expression '%s' of %zu bytes\n",              \
    415                minitest_prefix,                                                \
    416                minitest_suffix,                                                \
    417                __FILE__,                                                       \
    418                __LINE__,                                                       \
    419                #expression,                                                    \
    420                minitest_expected_len);                                         \
    421         printf("actual   : '%.*s'\n", (int)minitest_expected_len,              \
    422                                       minitest_actual);                        \
    423         printf(                                                                \
    424             "expected : '%.*s'\n", (int)minitest_expected_len,                 \
    425                                    minitest_expected);                         \
    426         minitest_testcase->Failure();                                          \
    427       }                                                                        \
    428     }                                                                          \
    429   } while (0)
    430 
    431 #define EXPECT_MEMEQ(expected, expected_len, expression, expression_len) \
    432   MINITEST_EXPECT_ASSERT_MEM_(                                           \
    433       expected, expected_len, expression, expression_len, true, false)
    434 
    435 #define EXPECT_MEMNEQ(expected, expected_len, expression, expression_len) \
    436   MINITEST_EXPECT_ASSERT_MEM_(                                            \
    437       expected, expected_len, expression, expression_len, false, false)
    438 
    439 #define ASSERT_TRUE(expression)                                          \
    440   do {                                                                   \
    441     if (!(expression)) {                                                 \
    442       printf(                                                            \
    443           "ASSERT_TRUE:%s:%d: expression '%s' return 'false', expected " \
    444           "'true'\n",                                                    \
    445           __FILE__,                                                      \
    446           __LINE__,                                                      \
    447           #expression);                                                  \
    448       minitest_testcase->FatalFailure();                                 \
    449       return;                                                            \
    450     }                                                                    \
    451   } while (0)
    452 
    453 #define ASSERT_FALSE(expression)                                         \
    454   do {                                                                   \
    455     if (!!(expression)) {                                                \
    456       printf(                                                            \
    457           "ASSERT_FALSE:%s:%d: expression '%s' return 'true', expected " \
    458           "'false'\n",                                                   \
    459           __FILE__,                                                      \
    460           __LINE__,                                                      \
    461           #expression);                                                  \
    462       minitest_testcase->FatalFailure();                                 \
    463       return;                                                            \
    464     }                                                                    \
    465   } while (0)
    466 
    467 #define MINITEST_ASSERT_BINOP_(opname, op, expected, expression) \
    468   MINITEST_EXPECT_ASSERT_BINOP_(opname, op, expected, expression, true)
    469 
    470 #define ASSERT_EQ(expected, expression) \
    471   MINITEST_ASSERT_BINOP_(EQ, ==, expected, expression)
    472 
    473 #define ASSERT_NE(expected, expression) \
    474   MINITEST_ASSERT_BINOP_(NE, !=, expected, expression)
    475 
    476 #define ASSERT_LE(expected, expression) \
    477   MINITEST_ASSERT_BINOP_(LE, <=, expected, expression)
    478 
    479 #define ASSERT_LT(expected, expression) \
    480   MINITEST_ASSERT_BINOP_(LT, <, expected, expression)
    481 
    482 #define ASSERT_GE(expected, expression) \
    483   MINITEST_ASSERT_BINOP_(GE, >=, expected, expression)
    484 
    485 #define ASSERT_GT(expected, expression) \
    486   MINITEST_ASSERT_BINOP_(GT, >, expected, expression)
    487 
    488 #define ASSERT_STREQ(expected, expression) \
    489   MINITEST_EXPECT_ASSERT_STR_(expected, expression, true, true)
    490 
    491 #define ASSERT_STRNEQ(expected, expression) \
    492   MINITEST_EXPECT_ASSERT_STR_(expected, expression, false, true)
    493 
    494 #define ASSERT_MEMEQ(expected, expected_len, expression, expression_len) \
    495   MINITEST_EXPECT_ASSERT_MEM_(                                           \
    496       expected, expected_len, expression, expression_len, true, true)
    497 
    498 #define ASSERT_MEMNEQ(expected, expected_len, expression, expression_len) \
    499   MINITEST_EXPECT_ASSERT_MEM_(                                            \
    500       expected, expected_len, expression, expression_len, false, true)
    501 
    502 #define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
    503 
    504 }  // namespace minitest
    505 
    506 #endif  // MINITEST_MINITEST_H
    507