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) {
    125     String(str, ::strlen(str));
    126   }
    127 
    128   String(const String& other) {
    129     String(other.str_, other.size_);
    130   }
    131 
    132   String& operator=(const String& other) {
    133     (*this) += other;
    134     return *this;
    135   }
    136 
    137   char& operator[](size_t index) {
    138     return str_[index];
    139   }
    140 
    141   ~String() { Clear(); }
    142 
    143   const char* c_str() const { return str_; }
    144   const char* data() const { return str_; }
    145   size_t size() const { return size_; }
    146   bool empty() const { return size_ == 0; }
    147 
    148   String& operator+=(const String& other);
    149   String& operator+=(const char* str);
    150   String& operator+=(char ch);
    151 
    152   String operator+(const String& other) const {
    153     String result(*this);
    154     result += other;
    155     return result;
    156   }
    157 
    158   String operator+(const char* str) const {
    159     String result(*this);
    160     result += str;
    161     return result;
    162   }
    163 
    164   // Basic formatting operators.
    165   String& operator<<(const String& other);
    166   String& operator<<(const char* str);
    167 
    168 #define MINITEST_OPERATOR_LL_(ParamType) \
    169     String& operator<<(ParamType v)
    170 
    171   MINITEST_OPERATOR_LL_(bool);
    172   MINITEST_OPERATOR_LL_(char);
    173   MINITEST_OPERATOR_LL_(signed char);
    174   MINITEST_OPERATOR_LL_(short);
    175   MINITEST_OPERATOR_LL_(int);
    176   MINITEST_OPERATOR_LL_(long);
    177   MINITEST_OPERATOR_LL_(long long);
    178   MINITEST_OPERATOR_LL_(unsigned char);
    179   MINITEST_OPERATOR_LL_(unsigned short);
    180   MINITEST_OPERATOR_LL_(unsigned int);
    181   MINITEST_OPERATOR_LL_(unsigned long);
    182   MINITEST_OPERATOR_LL_(unsigned long long);
    183   MINITEST_OPERATOR_LL_(float);
    184   MINITEST_OPERATOR_LL_(double);
    185   MINITEST_OPERATOR_LL_(const void*);
    186 
    187 #undef MINITEST_OPERATOR_LL_
    188 
    189   void Clear();
    190   void Resize(size_t new_size);
    191 
    192 private:
    193   void Reserve(size_t new_capacity);
    194   char* str_;
    195   size_t size_;
    196   size_t capacity_;
    197 };
    198 
    199 }  // namespace internal
    200 
    201 // A helper function that can be used to generate formatted output
    202 // as a temporary string. Use like printf(), but returns a new String
    203 // object. Useful to stream into TEST_TEXT() objects, as in:
    204 //
    205 //   TEST_TEXT << "Using "
    206 //                << minitest::Format("%08d", bytes)
    207 //                << " bytes";
    208 //
    209 internal::String Format(const char* format, ...);
    210 
    211 class TestCase {
    212 public:
    213   enum Result {
    214     PASS = 0,
    215     FAIL,
    216     FATAL
    217   };
    218 
    219   TestCase() : result_(PASS) {}
    220   ~TestCase() {}
    221 
    222   void Failure();
    223   void FatalFailure();
    224 
    225   Result result() { return result_; }
    226 
    227   internal::String& GetText();
    228 
    229 private:
    230   Result result_;
    231   internal::String text_;
    232 };
    233 
    234 // Type of a function defined through the TEST(<test>,<case>) macro.
    235 typedef void (TestFunction)(TestCase* testcase);
    236 
    237 // Used internally to register new test functions.
    238 void RegisterTest(const char* test_name,
    239                   const char* case_name,
    240                   TestFunction* test_function);
    241 
    242 #define MINITEST_TEST_FUNCTION(testname, casename) \
    243     MINITEST_TEST_FUNCTION_(testname, casename)
    244 
    245 #define MINITEST_TEST_FUNCTION_(testname, casename) \
    246     minitest_##testname##_##casename
    247 
    248 #define TEST(testname, casename) \
    249   static void MINITEST_TEST_FUNCTION(testname, casename)(minitest::TestCase*); \
    250   static void __attribute__((constructor)) \
    251   RegisterMiniTest##testname##_##casename() { \
    252     minitest::RegisterTest(#testname, #casename, \
    253                            &MINITEST_TEST_FUNCTION(testname, casename)); \
    254   } \
    255   void MINITEST_TEST_FUNCTION(testname, casename)(\
    256       minitest::TestCase* minitest_testcase)
    257 
    258 // Use this macro to add context text before an EXPECT or ASSERT statement
    259 // For example:
    260 //
    261 //    for (size_t n = 0; n < MAX; ++n) {
    262 //      TEST_TEXT << "When checking " << kStrings[n];
    263 //      EXPECT_STREQ(kExpected[n], kStrings[n]);
    264 //    }
    265 //
    266 // The text will only be printed in case of failure in the next
    267 // EXPECT/ASSERT statement.
    268 //
    269 #define TEST_TEXT minitest_testcase->GetText()
    270 
    271 // EXPECT_TRUE() must evaluate to something that supports the << operator
    272 // to receive debugging strings only in case of failure.
    273 #define EXPECT_TRUE(expression) \
    274   do { \
    275     if (!(expression)) { \
    276       printf("EXPECT_TRUE:%s:%d: expression '%s' returned 'false', expected 'true'\n", \
    277              __FILE__, __LINE__, #expression); \
    278       minitest_testcase->Failure(); \
    279     } \
    280   } while (0)
    281 
    282 #define EXPECT_FALSE(expression) \
    283   do { \
    284     if (!!(expression)) { \
    285       printf("EXPECT_FALSE:%s:%d: expression '%s' returned 'true', expected 'false'\n", \
    286              __FILE__, __LINE__, #expression); \
    287       minitest_testcase->Failure(); \
    288     } \
    289   } while (0)
    290 
    291 #define MINITEST_DEFINE_LOCAL_EXPR_(varname, expr) \
    292   typedef minitest::internal::AddConst<__typeof__(expr)>::type \
    293     varname##Type; \
    294   const varname##Type varname = (expr);
    295 
    296 #define MINITEST_EXPECT_ASSERT_BINOP_(opname, op, expected, expression, is_assert) \
    297   do { \
    298     MINITEST_DEFINE_LOCAL_EXPR_(minitest_expected, expected); \
    299     MINITEST_DEFINE_LOCAL_EXPR_(minitest_actual, expression); \
    300     if (!(minitest_actual op minitest_expected)) { \
    301       printf("%s" #opname ":%s:%d: with expression '%s'\n", \
    302              is_assert ? "ASSERT_" : "EXPECT_", __FILE__, __LINE__, \
    303              #expression); \
    304       minitest::internal::String minitest_str; \
    305       minitest_str << minitest_actual; \
    306       printf("actual   : %s\n", minitest_str.c_str()); \
    307       minitest_str.Clear(); \
    308       minitest_str << minitest_expected; \
    309       printf("expected : %s\n", minitest_str.c_str()); \
    310       if (is_assert) { \
    311         minitest_testcase->FatalFailure(); \
    312         return; \
    313       } \
    314       minitest_testcase->Failure(); \
    315     } \
    316   } while (0)
    317 
    318 #define MINITEST_EXPECT_BINOP_(opname, op, expected, expression) \
    319     MINITEST_EXPECT_ASSERT_BINOP_(opname, op, expected, expression, false)
    320 
    321 #define EXPECT_EQ(expected, expression)  \
    322     MINITEST_EXPECT_BINOP_(EQ, ==, expected, expression)
    323 
    324 #define EXPECT_NE(expected, expression)  \
    325     MINITEST_EXPECT_BINOP_(NE, !=, expected, expression)
    326 
    327 #define EXPECT_LE(expected, expression)  \
    328     MINITEST_EXPECT_BINOP_(LE, <=, expected, expression)
    329 
    330 #define EXPECT_LT(expected, expression)  \
    331     MINITEST_EXPECT_BINOP_(LT, <, expected, expression)
    332 
    333 #define EXPECT_GE(expected, expression)  \
    334     MINITEST_EXPECT_BINOP_(GE, >=, expected, expression)
    335 
    336 #define EXPECT_GT(expected, expression)  \
    337     MINITEST_EXPECT_BINOP_(GT, >, expected, expression)
    338 
    339 #define MINITEST_EXPECT_ASSERT_STR_(expected, expression, is_eq, is_assert) \
    340   do { \
    341     const char* minitest_prefix = is_assert ? "ASSERT_STR" : "EXPECT_STR"; \
    342     const char* minitest_suffix = is_eq ? "EQ" : "NEQ"; \
    343     const char* minitest_expected = (expected); \
    344     const char* minitest_actual = (expression); \
    345     if (minitest_actual == NULL) { \
    346       printf("%s%s:%s:%d: expression '%s' is NULL!\n", \
    347              minitest_prefix, minitest_suffix, \
    348              __FILE__, __LINE__, #expression); \
    349     } else { \
    350       bool minitest_eq = !strcmp(minitest_expected, minitest_actual); \
    351       if (minitest_eq != is_eq) { \
    352         printf("%s%s:%s:%d: with expression '%s'\n", \
    353                minitest_prefix, minitest_suffix, \
    354                __FILE__, __LINE__, #expression); \
    355         printf("actual   : %s\n", minitest_actual); \
    356         printf("expected : %s\n", minitest_expected); \
    357         minitest_testcase->Failure(); \
    358       } \
    359     } \
    360   } while (0)
    361 
    362 #define EXPECT_STREQ(expected, expression) \
    363   MINITEST_EXPECT_ASSERT_STR_(expected, expression, true, false)
    364 
    365 #define EXPECT_STRNEQ(expected, expression) \
    366   MINITEST_EXPECT_ASSERT_STR_(expected, expression, false, true)
    367 
    368 #define ASSERT_TRUE(expression) \
    369   do { \
    370     if (!(expression)) { \
    371       printf("ASSERT_TRUE:%s:%d: expression '%s' return 'false', expected 'true'\n", \
    372              __FILE__, __LINE__, #expression); \
    373       minitest_testcase->FatalFailure(); \
    374       return; \
    375     } \
    376   } while (0)
    377 
    378 #define ASSERT_FALSE(expression) \
    379   do { \
    380     if (!!(expression)) { \
    381       printf("ASSERT_FALSE:%s:%d: expression '%s' return 'true', expected 'false'\n", \
    382              __FILE__, __LINE__, #expression); \
    383       minitest_testcase->FatalFailure(); \
    384       return; \
    385     } \
    386   } while (0)
    387 
    388 #define MINITEST_ASSERT_BINOP_(opname, op, expected, expression) \
    389     MINITEST_EXPECT_ASSERT_BINOP_(opname, op, expected, expression, true)
    390 
    391 #define ASSERT_EQ(expected, expression)  \
    392     MINITEST_ASSERT_BINOP_(EQ, ==, expected, expression)
    393 
    394 #define ASSERT_NE(expected, expression)  \
    395     MINITEST_ASSERT_BINOP_(NE, !=, expected, expression)
    396 
    397 #define ASSERT_LE(expected, expression)  \
    398     MINITEST_ASSERT_BINOP_(LE, <=, expected, expression)
    399 
    400 #define ASSERT_LT(expected, expression)  \
    401     MINITEST_ASSERT_BINOP_(LT, <, expected, expression)
    402 
    403 #define ASSERT_GE(expected, expression)  \
    404     MINITEST_ASSERT_BINOP_(GE, >=, expected, expression)
    405 
    406 #define ASSERT_GT(expected, expression)  \
    407     MINITEST_ASSERT_BINOP_(GT, >, expected, expression)
    408 
    409 #define ASSERT_STREQ(expected, expression) \
    410     MINITEST_EXPECT_ASSERT_STR_(expected, expression, true, true)
    411 
    412 #define ASSERT_STRNEQ(expected, expression) \
    413     MINITEST_EXPECT_ASSERT_STR_(expected, expression, false, true)
    414 
    415 }  // namespace minitest
    416 
    417 #endif  // MINITEST_MINITEST_H
    418