138# include <inttypes.h>
147#if defined(__GNUC__) && defined(__GNUC_MINOR__)
148# define TUKTEST_GNUC_REQ(major, minor) \
149 ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \
150 || __GNUC__ > (major))
152# define TUKTEST_GNUC_REQ(major, minor) 0
158#if TUKTEST_GNUC_REQ(3, 0)
159# define tuktest_maybe_unused __attribute__((__unused__))
161# define tuktest_maybe_unused
165#if TUKTEST_GNUC_REQ(4, 2)
166# pragma GCC diagnostic ignored "-Wformat-zero-length"
174#define TUKTEST_PRId PRId64
175#define TUKTEST_PRIu PRIu64
176#define TUKTEST_PRIX PRIX64
180#define TUKTEST_EXIT_PASS EXIT_SUCCESS
181#define TUKTEST_EXIT_FAIL EXIT_FAILURE
182#define TUKTEST_EXIT_SKIP 77
183#define TUKTEST_EXIT_ERROR 99
198# define TUKTEST_TAP 1
199# define TUKTEST_STR_PASS "ok -"
200# define TUKTEST_STR_FAIL "not ok -"
201# define TUKTEST_STR_SKIP "ok - # SKIP"
202# define TUKTEST_STR_ERROR "Bail out!"
204# define TUKTEST_TAP 0
206# define TUKTEST_COLOR_PASS "\x1B[0;32m"
207# define TUKTEST_COLOR_FAIL "\x1B[0;31m"
208# define TUKTEST_COLOR_SKIP "\x1B[1;34m"
209# define TUKTEST_COLOR_ERROR "\x1B[0;35m"
210# define TUKTEST_COLOR_TOTAL "\x1B[1m"
211# define TUKTEST_COLOR_OFF "\x1B[m"
212# define TUKTEST_COLOR_IF(cond, color) ((cond) ? (color) : "" )
214# define TUKTEST_COLOR_PASS ""
215# define TUKTEST_COLOR_FAIL ""
216# define TUKTEST_COLOR_SKIP ""
217# define TUKTEST_COLOR_ERROR ""
218# define TUKTEST_COLOR_TOTAL ""
219# define TUKTEST_COLOR_OFF ""
220# define TUKTEST_COLOR_IF(cond, color) ""
222# define TUKTEST_COLOR_ADD(str, color) color str TUKTEST_COLOR_OFF
223# define TUKTEST_STR_PASS \
224 TUKTEST_COLOR_ADD("PASS:", TUKTEST_COLOR_PASS)
225# define TUKTEST_STR_FAIL \
226 TUKTEST_COLOR_ADD("FAIL:", TUKTEST_COLOR_FAIL)
227# define TUKTEST_STR_SKIP \
228 TUKTEST_COLOR_ADD("SKIP:", TUKTEST_COLOR_SKIP)
229# define TUKTEST_STR_ERROR \
230 TUKTEST_COLOR_ADD("ERROR:", TUKTEST_COLOR_ERROR)
235# define TUKTEST_QUIET 0
238# define TUKTEST_QUIET 1
244static unsigned tuktest_stats[4] = { 0, 0, 0, 0 };
247static int tuktest_argc = 0;
248static char **tuktest_argv =
NULL;
253static const char *tuktest_name =
NULL;
256static jmp_buf tuktest_jmpenv;
260static int tuktest_end(
void);
265#define tuktest_error_impl(filename, line, ...) \
267 tuktest_print_result_prefix(TUKTEST_ERROR, filename, line); \
268 printf(__VA_ARGS__); \
270 ++tuktest_stats[TUKTEST_ERROR]; \
271 exit(tuktest_end()); \
278tuktest_catch_stdout_errors(
void)
280 if (ferror(stdout) || fclose(stdout)) {
281 fputs(
"Error while writing to stdout\n", stderr);
292tuktest_basename(
const char *filename)
294 for (
const char *p = filename + strlen(filename); p > filename; --p)
295 if (*p ==
'/' || *p ==
'\\')
305 const char *filename,
unsigned line)
308 const char *result_str
314 const char *short_filename = tuktest_basename(filename);
316 if (tuktest_name !=
NULL)
317 printf(
"%s %s [%s:%u] ", result_str, tuktest_name,
318 short_filename, line);
320 printf(
"%s [%s:%u] ", result_str, short_filename, line);
347#define tuktest_malloc(size) tuktest_malloc_impl(size, __FILE__, __LINE__)
350tuktest_malloc_impl(
size_t size,
const char *filename,
unsigned line)
352 void *
p = malloc(
size);
368 if (tuktest_name ==
NULL) {
370 r->
next = tuktest_malloc_global;
371 tuktest_malloc_global = r;
374 r->
next = tuktest_malloc_test;
375 tuktest_malloc_test = r;
390#define tuktest_free(ptr) tuktest_free_impl(ptr, __FILE__, __LINE__)
393tuktest_free_impl(
void *
p,
const char *filename,
unsigned line)
399 ? &tuktest_malloc_test : &tuktest_malloc_global;
415 "Allocation matching the pointer was not found");
439#define tuktest_start(argc, argv) \
441 tuktest_argc = argc; \
442 tuktest_argv = argv; \
443 if (!TUKTEST_TAP && !TUKTEST_QUIET) \
444 printf("=== %s ===\n", tuktest_basename(__FILE__)); \
455#define tuktest_early_skip(...) \
457 printf("%s [%s:%u] ", \
458 TUKTEST_TAP ? "1..0 # SKIP" : TUKTEST_STR_SKIP, \
459 tuktest_basename(__FILE__), __LINE__); \
460 printf(__VA_ARGS__); \
462 if (!TUKTEST_TAP && !TUKTEST_QUIET) \
463 printf("=== END ===\n"); \
464 tuktest_catch_stdout_errors(); \
465 exit(TUKTEST_TAP ? EXIT_SUCCESS : TUKTEST_EXIT_SKIP); \
484#define tuktest_error(...) tuktest_error_impl(__FILE__, __LINE__, __VA_ARGS__)
497 tuktest_free_all(&tuktest_malloc_test);
498 tuktest_free_all(&tuktest_malloc_global);
500 unsigned total_tests = 0;
502 total_tests += tuktest_stats[
i];
505 && (
unsigned)(tuktest_argc - 1) > total_tests) {
507 "specified on the command line. "
508 "Was a test name mistyped?\n");
518 printf(
"1..%u%s\n", total_tests,
519 total_tests == 0 ?
" # SKIP" :
"");
521 tuktest_catch_stdout_errors();
551 tuktest_catch_stdout_errors();
559 if (tuktest_stats[
TUKTEST_SKIP] > 0 || total_tests == 0)
569#define tuktest_run(testfunc) \
570 tuktest_run_test(&(testfunc), #testfunc)
574tuktest_run_test(
void (*testfunc)(
void),
const char *testfunc_str)
578 if (tuktest_argc > 1) {
580 while (strcmp(tuktest_argv[
i], testfunc_str) != 0)
581 if (++
i == tuktest_argc)
588 tuktest_name = testfunc_str;
594 switch (setjmp(tuktest_jmpenv)) {
615 tuktest_free_all(&tuktest_malloc_test);
621#ifndef TUKTEST_FILE_SIZE_MAX
622# define TUKTEST_FILE_SIZE_MAX (64L << 20)
642#define tuktest_file_from_srcdir(filename, sizeptr) \
643 tuktest_file_from_x(getenv("srcdir"), filename, sizeptr, \
647#define tuktest_file_from_builddir(filename, sizeptr) \
648 tuktest_file_from_x(NULL, filename, sizeptr, __FILE__, __LINE__)
653tuktest_file_from_x(
const char *prefix,
const char *filename,
size_t *
size,
654 const char *prog_filename,
unsigned prog_line)
657 char *alloc_name =
NULL;
666 const char *error_msg =
NULL;
668 if (filename ==
NULL) {
669 error_msg =
"Filename is NULL";
674 if (filename[0] ==
'\0') {
675 error_msg =
"Filename is an empty string";
676 filename =
"(empty string)";
681 error_msg =
"The size argument is NULL";
686 if (prefix !=
NULL && prefix[0] !=
'\0') {
687 const size_t prefix_len = strlen(prefix);
688 const size_t filename_len = strlen(filename);
690 const size_t alloc_name_size
691 = prefix_len + 1 + filename_len + 1;
692 alloc_name = tuktest_malloc_impl(alloc_name_size,
693 prog_filename, prog_line);
695 memcpy(alloc_name, prefix, prefix_len);
696 alloc_name[prefix_len] =
'/';
697 memcpy(alloc_name + prefix_len + 1, filename, filename_len);
698 alloc_name[prefix_len + 1 + filename_len] =
'\0';
703 filename = alloc_name;
706 f = fopen(filename,
"rb");
708 error_msg =
"Failed to open the file";
718 error_msg =
"Seeking failed (fseek end)";
722 const long end =
ftell(
f);
724 error_msg =
"Seeking failed (ftell)";
729 error_msg =
"File is empty";
734 error_msg =
"File size exceeds TUKTEST_FILE_SIZE_MAX";
741 buf = tuktest_malloc_impl(*
size, prog_filename, prog_line);
743 const size_t amount = fread(
buf, 1, *
size,
f);
745 error_msg =
"Read error";
749 if (amount != *
size) {
750 error_msg =
"File is smaller than indicated by ftell()";
754 const int fclose_ret = fclose(
f);
756 if (fclose_ret != 0) {
757 error_msg =
"Error closing the file";
769 "tuktest_file_from_x: %s: %s\n", filename, error_msg);
774#define tuktest_print_and_jump(result, ...) \
776 tuktest_print_result_prefix(result, __FILE__, __LINE__); \
777 printf(__VA_ARGS__); \
779 longjmp(tuktest_jmpenv, result); \
788#define assert_fail(...) tuktest_print_and_jump(TUKTEST_FAIL, __VA_ARGS__)
803#define assert_skip(...) tuktest_print_and_jump(TUKTEST_SKIP, __VA_ARGS__)
811#define assert_error(...) tuktest_print_and_jump(TUKTEST_ERROR, __VA_ARGS__)
815#define assert_false(test_expr) \
818 assert_fail("assert_fail: '%s' is true but should be false", \
824#define assert_true(test_expr) \
827 assert_fail("assert_true: '%s' is false but should be true", \
840#define assert_int(test_expr, cmp_op, ref_value) \
842 const tuktest_int v_test_ = (test_expr); \
843 const tuktest_int v_ref_ = (ref_value); \
844 if (!(v_test_ cmp_op v_ref_)) \
845 assert_fail("assert_int: '%s == %" TUKTEST_PRId \
846 "' but expected '... %s %" TUKTEST_PRId "'", \
847 #test_expr, v_test_, #cmp_op, v_ref_); \
855#define assert_uint(test_expr, cmp_op, ref_value) \
857 const tuktest_uint v_test_ = (test_expr); \
858 const tuktest_uint v_ref_ = (ref_value); \
859 if (!(v_test_ cmp_op v_ref_)) \
860 assert_fail("assert_uint: '%s == %" TUKTEST_PRIu \
861 "' but expected '... %s %" TUKTEST_PRIu "'", \
862 #test_expr, v_test_, #cmp_op, v_ref_); \
868#define assert_int_eq(test_expr, ref_value) \
869 assert_int(test_expr, ==, ref_value)
874#define assert_uint_eq(test_expr, ref_value) \
875 assert_uint(test_expr, ==, ref_value)
894#define assert_enum_eq(test_expr, ref_value, enum_strings) \
896 const tuktest_int v_test_ = (test_expr); \
897 const tuktest_int v_ref_ = (ref_value); \
898 if (v_test_ != v_ref_) { \
899 const int array_len_ = (int)(sizeof(enum_strings) \
900 / sizeof((enum_strings)[0])); \
901 if (v_ref_ < 0 || v_ref_ >= array_len_) \
902 assert_fail("assert_enum_eq: '%s == %" TUKTEST_PRId \
904 "'... == %" TUKTEST_PRId "'", \
905 #test_expr, v_test_, v_ref_); \
906 else if (v_test_ < 0 || v_test_ >= array_len_) \
907 assert_fail("assert_enum_eq: '%s == %" TUKTEST_PRId \
908 "' but expected '... == %s'", \
909 #test_expr, v_test_, \
910 (enum_strings)[v_ref_]); \
912 assert_fail("assert_enum_eq: '%s == %s' " \
913 "but expected '... = %s'", \
914 #test_expr, (enum_strings)[v_test_], \
915 (enum_strings)[v_ref_]); \
921#define assert_bit_set(test_expr, bit) \
923 const tuktest_uint v_test_ = (test_expr); \
924 const unsigned v_bit_ = (bit); \
925 const tuktest_uint v_mask_ = (tuktest_uint)1 << v_bit_; \
926 if (!(v_test_ & v_mask_)) \
927 assert_fail("assert_bit_set: '%s == 0x%" TUKTEST_PRIX \
928 "' but bit %u (0x%" TUKTEST_PRIX ") " \
930 #test_expr, v_test_, v_bit_, v_mask_); \
935#define assert_bit_not_set(test_expr, bit) \
937 const tuktest_uint v_test_ = (test_expr); \
938 const unsigned v_bit_ = (bit); \
939 const tuktest_uint v_mask_ = (tuktest_uint)1 << v_bit_; \
940 if (v_test_ & v_mask_) \
941 assert_fail("assert_bit_not_set: '%s == 0x%" TUKTEST_PRIX \
942 "' but bit %u (0x%" TUKTEST_PRIX ") is set", \
943 #test_expr, v_test_, v_bit_, v_mask_); \
949#define assert_bitmask_set(test_expr, mask) \
951 const tuktest_uint v_mask_ = (mask); \
952 const tuktest_uint v_test_ = (test_expr) & v_mask_; \
953 if (v_test_ != v_mask_) \
954 assert_fail("assert_bitmask_set: " \
955 "'((%s) & 0x%" TUKTEST_PRIX ") == " \
956 "0x%" TUKTEST_PRIX "' but expected " \
957 "'... == 0x%" TUKTEST_PRIX "'", \
958 #test_expr, v_mask_, v_test_, v_mask_); \
964#define assert_bitmask_not_set(test_expr, mask) \
966 const tuktest_uint v_mask_ = (mask); \
967 const tuktest_uint v_test_ = (test_expr) & v_mask_; \
969 assert_fail("assert_bitmask_not_set: "\
970 "'((%s) & 0x%" TUKTEST_PRIX ") == " \
971 "0x%" TUKTEST_PRIX "' but expected " \
973 #test_expr, v_mask_, v_test_); \
978#define tuktest_str_helper1(macro_name, test_expr, ref_value) \
979 const char *v_test_ = (test_expr); \
980 const char *v_ref_ = (ref_value); \
981 if (v_test_ == NULL) \
982 assert_fail(macro_name ": Test expression '%s' is NULL", \
984 if (v_ref_ == NULL) \
985 assert_fail(macro_name ": Reference value '%s' is NULL", \
991#define tuktest_str_helper2(macro_name, test_expr, ref_value) \
992 tuktest_str_helper1(macro_name, test_expr, ref_value); \
993 if (v_ref_[0] == '\0') \
994 assert_fail(macro_name ": Reference value is an empty string")
999#define assert_str_eq(test_expr, ref_value) \
1001 tuktest_str_helper1("assert_str_eq", test_expr, ref_value); \
1002 if (strcmp(v_ref_, v_test_) != 0) \
1003 assert_fail("assert_str_eq: '%s' evaluated to '%s' " \
1004 "but expected '%s'", \
1005 #test_expr, v_test_, v_ref_); \
1012#define assert_str_contains(test_expr, ref_value) \
1014 tuktest_str_helper2("assert_str_contains", test_expr, ref_value); \
1015 if (strstr(v_test_, v_ref_) == NULL) \
1016 assert_fail("assert_str_contains: '%s' evaluated to '%s' " \
1017 "which doesn't contain '%s'", \
1018 #test_expr, v_test_, v_ref_); \
1025#define assert_str_doesnt_contain(test_expr, ref_value) \
1027 tuktest_str_helper2("assert_str_doesnt_contain", \
1028 test_expr, ref_value); \
1029 if (strstr(v_test_, v_ref_) != NULL) \
1030 assert_fail("assert_str_doesnt_contain: " \
1031 "'%s' evaluated to '%s' which contains '%s'", \
1032 #test_expr, v_test_, v_ref_); \
1041#define assert_array_eq(test_array, correct_array, array_size) \
1043 for (size_t i_ = 0; i_ < (array_size); ++i_) \
1044 if ((test_array)[i_] != (correct_array)[i_]) \
1045 assert_fail("assert_array_eq: " \
1046 "%s[%" TUKTEST_PRIu "] != "\
1047 "%s[%" TUKTEST_PRIu "] " \
1048 "but should be equal", \
1049 #test_array, (tuktest_uint)i_, \
1050 #correct_array, (tuktest_uint)i_); \
char buf[N_BUF]
Definition spewG.c:36
void * p
Definition tuktest.h:327
struct tuktest_malloc_record * next
Definition tuktest.h:326
#define SEEK_END
Definition zconf.h:500
#define f(i)
Definition sha256.c:46
lzma_index ** i
Definition index.h:629
#define NULL
Definition getopt1.c:37
#define TUKTEST_COLOR_SKIP
Definition tuktest.h:216
#define tuktest_maybe_unused
Definition tuktest.h:161
#define TUKTEST_COLOR_IF(cond, color)
Definition tuktest.h:220
#define TUKTEST_EXIT_PASS
Definition tuktest.h:180
#define tuktest_error_impl(filename, line,...)
Definition tuktest.h:265
uint64_t tuktest_uint
Definition tuktest.h:173
#define TUKTEST_STR_PASS
Definition tuktest.h:223
#define TUKTEST_PRIu
Definition tuktest.h:175
#define tuktest_free(ptr)
Definition tuktest.h:390
tuktest_result
Definition tuktest.h:186
@ TUKTEST_ERROR
Definition tuktest.h:190
@ TUKTEST_FAIL
Definition tuktest.h:188
@ TUKTEST_SKIP
Definition tuktest.h:189
@ TUKTEST_PASS
Definition tuktest.h:187
#define TUKTEST_STR_FAIL
Definition tuktest.h:225
#define TUKTEST_QUIET
Definition tuktest.h:235
#define TUKTEST_COLOR_TOTAL
Definition tuktest.h:218
#define TUKTEST_COLOR_ERROR
Definition tuktest.h:217
#define TUKTEST_EXIT_ERROR
Definition tuktest.h:183
#define TUKTEST_COLOR_FAIL
Definition tuktest.h:215
#define TUKTEST_FILE_SIZE_MAX
Definition tuktest.h:622
#define TUKTEST_COLOR_OFF
Definition tuktest.h:219
#define TUKTEST_EXIT_FAIL
Definition tuktest.h:181
#define TUKTEST_EXIT_SKIP
Definition tuktest.h:182
#define TUKTEST_STR_SKIP
Definition tuktest.h:227
#define TUKTEST_STR_ERROR
Definition tuktest.h:229
#define TUKTEST_COLOR_PASS
Definition tuktest.h:214
int64_t tuktest_int
Definition tuktest.h:172
void error(char *msg) const
Definition minigzip.c:356