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