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