20 #define GREATEST_VERSION_MAJOR 0 21 #define GREATEST_VERSION_MINOR 9 22 #define GREATEST_VERSION_PATCH 3 36 TEST foo_should_foo() {
40 static void setup_cb(
void *data) {
41 printf(
"setup callback for each test case\n");
44 static void teardown_cb(
void *data) {
45 printf(
"teardown callback for each test case\n");
52 SET_SETUP(setup_cb, voidp_to_callback_data);
61 int main(
int argc,
char **argv) {
82 #ifndef GREATEST_DEFAULT_WIDTH 83 #define GREATEST_DEFAULT_WIDTH 72 87 #ifndef GREATEST_STDOUT 88 #define GREATEST_STDOUT stdout 92 #ifndef GREATEST_USE_ABBREVS 93 #define GREATEST_USE_ABBREVS 1 189 #define GREATEST_SUITE(NAME) void NAME(void) 193 #define GREATEST_TEST static int 196 #define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME) 199 #define GREATEST_RUN_TEST(TEST) \ 201 if (greatest_pre_test(#TEST) == 1) { \ 203 greatest_post_test(#TEST, res); \ 204 } else if (GREATEST_LIST_ONLY()) { \ 205 fprintf(GREATEST_STDOUT, " %s\n", #TEST); \ 211 #define GREATEST_RUN_TEST1(TEST, ENV) \ 213 if (greatest_pre_test(#TEST) == 1) { \ 214 int res = TEST(ENV); \ 215 greatest_post_test(#TEST, res); \ 216 } else if (GREATEST_LIST_ONLY()) { \ 217 fprintf(GREATEST_STDOUT, " %s\n", #TEST); \ 223 #if __STDC_VERSION__ >= 19901L 224 #define GREATEST_RUN_TESTp(TEST, ...) \ 226 if (greatest_pre_test(#TEST) == 1) { \ 227 int res = TEST(__VA_ARGS__); \ 228 greatest_post_test(#TEST, res); \ 229 } else if (GREATEST_LIST_ONLY()) { \ 230 fprintf(GREATEST_STDOUT, " %s\n", #TEST); \ 237 #define GREATEST_IS_VERBOSE() (greatest_info.flags & GREATEST_FLAG_VERBOSE) 238 #define GREATEST_LIST_ONLY() (greatest_info.flags & GREATEST_FLAG_LIST_ONLY) 239 #define GREATEST_FIRST_FAIL() (greatest_info.flags & GREATEST_FLAG_FIRST_FAIL) 240 #define GREATEST_FAILURE_ABORT() (greatest_info.suite.failed > 0 && GREATEST_FIRST_FAIL()) 243 #define GREATEST_PASS() GREATEST_PASSm(NULL) 244 #define GREATEST_FAIL() GREATEST_FAILm(NULL) 245 #define GREATEST_SKIP() GREATEST_SKIPm(NULL) 246 #define GREATEST_ASSERT(COND) GREATEST_ASSERTm(#COND, COND) 247 #define GREATEST_ASSERT_FALSE(COND) GREATEST_ASSERT_FALSEm(#COND, COND) 248 #define GREATEST_ASSERT_EQ(EXP, GOT) GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT) 249 #define GREATEST_ASSERT_STR_EQ(EXP, GOT) GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT) 255 #define GREATEST_ASSERTm(MSG, COND) \ 257 greatest_info.msg = MSG; \ 258 greatest_info.fail_file = __FILE__; \ 259 greatest_info.fail_line = __LINE__; \ 260 if (!(COND)) return -1; \ 261 greatest_info.msg = NULL; \ 264 #define GREATEST_ASSERT_FALSEm(MSG, COND) \ 266 greatest_info.msg = MSG; \ 267 greatest_info.fail_file = __FILE__; \ 268 greatest_info.fail_line = __LINE__; \ 269 if ((COND)) return -1; \ 270 greatest_info.msg = NULL; \ 273 #define GREATEST_ASSERT_EQm(MSG, EXP, GOT) \ 275 greatest_info.msg = MSG; \ 276 greatest_info.fail_file = __FILE__; \ 277 greatest_info.fail_line = __LINE__; \ 278 if ((EXP) != (GOT)) return -1; \ 279 greatest_info.msg = NULL; \ 282 #define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT) \ 284 const char *exp_s = (EXP); \ 285 const char *got_s = (GOT); \ 286 greatest_info.msg = MSG; \ 287 greatest_info.fail_file = __FILE__; \ 288 greatest_info.fail_line = __LINE__; \ 289 if (0 != strcmp(exp_s, got_s)) { \ 290 fprintf(GREATEST_STDOUT, \ 291 "Expected:\n####\n%s\n####\n", exp_s); \ 292 fprintf(GREATEST_STDOUT, \ 293 "Got:\n####\n%s\n####\n", got_s); \ 296 greatest_info.msg = NULL; \ 299 #define GREATEST_PASSm(MSG) \ 301 greatest_info.msg = MSG; \ 305 #define GREATEST_FAILm(MSG) \ 307 greatest_info.fail_file = __FILE__; \ 308 greatest_info.fail_line = __LINE__; \ 309 greatest_info.msg = MSG; \ 313 #define GREATEST_SKIPm(MSG) \ 315 greatest_info.msg = MSG; \ 319 #define GREATEST_SET_TIME(NAME) \ 321 if (NAME == (clock_t) -1) { \ 322 fprintf(GREATEST_STDOUT, \ 323 "clock error: %s\n", #NAME); \ 324 exit(EXIT_FAILURE); \ 327 #define GREATEST_CLOCK_DIFF(C1, C2) \ 328 fprintf(GREATEST_STDOUT, " (%lu ticks, %.3f sec)", \ 329 (long unsigned int) (C2) - (C1), \ 330 (double)((C2) - (C1)) / (1.0 * (double)CLOCKS_PER_SEC)) \ 333 #define GREATEST_MAIN_DEFS() \ 336 static int greatest_name_match(const char *name, \ 337 const char *filter) { \ 339 size_t filter_len = strlen(filter); \ 340 while (name[offset] != '\0') { \ 341 if (name[offset] == filter[0]) { \ 342 if (0 == strncmp(&name[offset], filter, filter_len)) { \ 352 int greatest_pre_test(const char *name) { \ 353 if (!GREATEST_LIST_ONLY() \ 354 && (!GREATEST_FIRST_FAIL() || greatest_info.suite.failed == 0) \ 355 && (greatest_info.test_filter == NULL || \ 356 greatest_name_match(name, greatest_info.test_filter))) { \ 357 GREATEST_SET_TIME(greatest_info.suite.pre_test); \ 358 if (greatest_info.setup) { \ 359 greatest_info.setup(greatest_info.setup_udata); \ 367 void greatest_post_test(const char *name, int res) { \ 368 GREATEST_SET_TIME(greatest_info.suite.post_test); \ 369 if (greatest_info.teardown) { \ 370 void *udata = greatest_info.teardown_udata; \ 371 greatest_info.teardown(udata); \ 375 greatest_do_fail(name); \ 376 } else if (res > 0) { \ 377 greatest_do_skip(name); \ 378 } else if (res == 0) { \ 379 greatest_do_pass(name); \ 381 greatest_info.suite.tests_run++; \ 382 greatest_info.col++; \ 383 if (GREATEST_IS_VERBOSE()) { \ 384 GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test, \ 385 greatest_info.suite.post_test); \ 386 fprintf(GREATEST_STDOUT, "\n"); \ 387 } else if (greatest_info.col % greatest_info.width == 0) { \ 388 fprintf(GREATEST_STDOUT, "\n"); \ 389 greatest_info.col = 0; \ 391 if (GREATEST_STDOUT == stdout) fflush(stdout); \ 394 static void greatest_run_suite(greatest_suite_cb *suite_cb, \ 395 const char *suite_name) { \ 396 if (greatest_info.suite_filter && \ 397 !greatest_name_match(suite_name, greatest_info.suite_filter)) \ 399 if (GREATEST_FIRST_FAIL() && greatest_info.failed > 0) return; \ 400 greatest_info.suite.tests_run = 0; \ 401 greatest_info.suite.failed = 0; \ 402 greatest_info.suite.passed = 0; \ 403 greatest_info.suite.skipped = 0; \ 404 greatest_info.suite.pre_suite = 0; \ 405 greatest_info.suite.post_suite = 0; \ 406 greatest_info.suite.pre_test = 0; \ 407 greatest_info.suite.post_test = 0; \ 408 greatest_info.col = 0; \ 409 fprintf(GREATEST_STDOUT, "\n* Suite %s:\n", suite_name); \ 410 GREATEST_SET_TIME(greatest_info.suite.pre_suite); \ 412 GREATEST_SET_TIME(greatest_info.suite.post_suite); \ 413 if (greatest_info.suite.tests_run > 0) { \ 414 fprintf(GREATEST_STDOUT, \ 415 "\n%u tests - %u pass, %u fail, %u skipped", \ 416 greatest_info.suite.tests_run, \ 417 greatest_info.suite.passed, \ 418 greatest_info.suite.failed, \ 419 greatest_info.suite.skipped); \ 420 GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite, \ 421 greatest_info.suite.post_suite); \ 422 fprintf(GREATEST_STDOUT, "\n"); \ 424 greatest_info.setup = NULL; \ 425 greatest_info.setup_udata = NULL; \ 426 greatest_info.teardown = NULL; \ 427 greatest_info.teardown_udata = NULL; \ 428 greatest_info.passed += greatest_info.suite.passed; \ 429 greatest_info.failed += greatest_info.suite.failed; \ 430 greatest_info.skipped += greatest_info.suite.skipped; \ 431 greatest_info.tests_run += greatest_info.suite.tests_run; \ 434 void greatest_do_pass(const char *name) { \ 435 if (GREATEST_IS_VERBOSE()) { \ 436 fprintf(GREATEST_STDOUT, "PASS %s: %s", \ 437 name, greatest_info.msg ? greatest_info.msg : ""); \ 439 fprintf(GREATEST_STDOUT, "."); \ 441 greatest_info.suite.passed++; \ 444 void greatest_do_fail(const char *name) { \ 445 if (GREATEST_IS_VERBOSE()) { \ 446 fprintf(GREATEST_STDOUT, \ 447 "FAIL %s: %s (%s:%u)", \ 448 name, greatest_info.msg ? greatest_info.msg : "", \ 449 greatest_info.fail_file, greatest_info.fail_line); \ 451 fprintf(GREATEST_STDOUT, "F"); \ 453 if (greatest_info.col % greatest_info.width != 0) \ 454 fprintf(GREATEST_STDOUT, "\n"); \ 455 greatest_info.col = 0; \ 456 fprintf(GREATEST_STDOUT, "FAIL %s: %s (%s:%u)\n", \ 458 greatest_info.msg ? greatest_info.msg : "", \ 459 greatest_info.fail_file, greatest_info.fail_line); \ 461 greatest_info.suite.failed++; \ 464 void greatest_do_skip(const char *name) { \ 465 if (GREATEST_IS_VERBOSE()) { \ 466 fprintf(GREATEST_STDOUT, "SKIP %s: %s", \ 468 greatest_info.msg ? \ 469 greatest_info.msg : "" ); \ 471 fprintf(GREATEST_STDOUT, "s"); \ 473 greatest_info.suite.skipped++; \ 476 void greatest_usage(const char *name) { \ 477 fprintf(GREATEST_STDOUT, \ 478 "Usage: %s [-hlfv] [-s SUITE] [-t TEST]\n" \ 479 " -h print this Help\n" \ 480 " -l List suites and their tests, then exit\n" \ 481 " -f Stop runner after first failure\n" \ 482 " -v Verbose output\n" \ 483 " -s SUITE only run suite named SUITE\n" \ 484 " -t TEST only run test named TEST\n", \ 488 void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata) { \ 489 greatest_info.setup = cb; \ 490 greatest_info.setup_udata = udata; \ 493 void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, \ 495 greatest_info.teardown = cb; \ 496 greatest_info.teardown_udata = udata; \ 499 greatest_run_info greatest_info 502 #define GREATEST_MAIN_BEGIN() \ 505 memset(&greatest_info, 0, sizeof(greatest_info)); \ 506 if (greatest_info.width == 0) { \ 507 greatest_info.width = GREATEST_DEFAULT_WIDTH; \ 509 for (i = 1; i < argc; i++) { \ 510 if (0 == strcmp("-t", argv[i])) { \ 511 if (argc <= i + 1) { \ 512 greatest_usage(argv[0]); \ 513 exit(EXIT_FAILURE); \ 515 greatest_info.test_filter = argv[i+1]; \ 517 } else if (0 == strcmp("-s", argv[i])) { \ 518 if (argc <= i + 1) { \ 519 greatest_usage(argv[0]); \ 520 exit(EXIT_FAILURE); \ 522 greatest_info.suite_filter = argv[i+1]; \ 524 } else if (0 == strcmp("-f", argv[i])) { \ 525 greatest_info.flags |= GREATEST_FLAG_FIRST_FAIL; \ 526 } else if (0 == strcmp("-v", argv[i])) { \ 527 greatest_info.flags |= GREATEST_FLAG_VERBOSE; \ 528 } else if (0 == strcmp("-l", argv[i])) { \ 529 greatest_info.flags |= GREATEST_FLAG_LIST_ONLY; \ 530 } else if (0 == strcmp("-h", argv[i])) { \ 531 greatest_usage(argv[0]); \ 532 exit(EXIT_SUCCESS); \ 534 fprintf(GREATEST_STDOUT, \ 535 "Unknown argument '%s'\n", argv[i]); \ 536 greatest_usage(argv[0]); \ 537 exit(EXIT_FAILURE); \ 541 GREATEST_SET_TIME(greatest_info.begin) 543 #define GREATEST_MAIN_END() \ 545 if (!GREATEST_LIST_ONLY()) { \ 546 GREATEST_SET_TIME(greatest_info.end); \ 547 fprintf(GREATEST_STDOUT, \ 548 "\nTotal: %u tests", greatest_info.tests_run); \ 549 GREATEST_CLOCK_DIFF(greatest_info.begin, \ 550 greatest_info.end); \ 551 fprintf(GREATEST_STDOUT, "\n"); \ 552 fprintf(GREATEST_STDOUT, \ 553 "Pass: %u, fail: %u, skip: %u.\n", \ 554 greatest_info.passed, \ 555 greatest_info.failed, greatest_info.skipped); \ 557 return (greatest_info.failed > 0 \ 558 ? EXIT_FAILURE : EXIT_SUCCESS); \ 563 #if GREATEST_USE_ABBREVS 564 #define TEST GREATEST_TEST 565 #define SUITE GREATEST_SUITE 566 #define RUN_TEST GREATEST_RUN_TEST 567 #define RUN_TEST1 GREATEST_RUN_TEST1 568 #define RUN_SUITE GREATEST_RUN_SUITE 569 #define ASSERT GREATEST_ASSERT 570 #define ASSERTm GREATEST_ASSERTm 571 #define ASSERT_FALSE GREATEST_ASSERT_FALSE 572 #define ASSERT_EQ GREATEST_ASSERT_EQ 573 #define ASSERT_STR_EQ GREATEST_ASSERT_STR_EQ 574 #define ASSERT_FALSEm GREATEST_ASSERT_FALSEm 575 #define ASSERT_EQm GREATEST_ASSERT_EQm 576 #define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm 577 #define PASS GREATEST_PASS 578 #define FAIL GREATEST_FAIL 579 #define SKIP GREATEST_SKIP 580 #define PASSm GREATEST_PASSm 581 #define FAILm GREATEST_FAILm 582 #define SKIPm GREATEST_SKIPm 583 #define SET_SETUP GREATEST_SET_SETUP_CB 584 #define SET_TEARDOWN GREATEST_SET_TEARDOWN_CB 586 #if __STDC_VERSION__ >= 19901L 588 #define RUN_TESTp GREATEST_RUN_TESTp void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata)
void greatest_do_skip(const char *name)
greatest_run_info greatest_info
int greatest_pre_test(const char *name)
greatest_setup_cb * setup
void() greatest_teardown_cb(void *udata)
greatest_teardown_cb * teardown
void() greatest_setup_cb(void *udata)
void() greatest_suite_cb(void)
void greatest_do_fail(const char *name)
struct greatest_run_info greatest_run_info
void greatest_do_pass(const char *name)
int main(int argc, char **argv)
void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata)
struct greatest_suite_info greatest_suite_info
#define GREATEST_MAIN_DEFS()
greatest_suite_info suite
void greatest_usage(const char *name)
void greatest_post_test(const char *name, int res)
#define GREATEST_MAIN_BEGIN()
#define GREATEST_MAIN_END()