#ifndef SIMPLE_TEST_H #define SIMPLE_TEST_H #define _XOPEN_SOURCE #include #include #include #include #include #include #include #include /**************************** * INTERNAL FUNCTIONALITY * ****************************/ typedef enum { SIMPLE_TEST_BOOL, SIMPLE_TEST_INT, SIMPLE_TEST_UINT, SIMPLE_TEST_FLOAT, SIMPLE_TEST_PTR, SIMPLE_TEST_CHAR, SIMPLE_TEST_STR, SIMPLE_TEST_WCHAR, SIMPLE_TEST_WSTR, SIMPLE_TEST_DEFAULT, } simple_test_type_t; typedef enum { SIMPLE_TEST_TRUE, SIMPLE_TEST_EQ, SIMPLE_TEST_NEQ, SIMPLE_TEST_G, SIMPLE_TEST_GEQ, SIMPLE_TEST_L, SIMPLE_TEST_LEQ } simple_test_cond_t; int simple_test_mbslen(char *arg) { int blen = strlen(arg), clen = 0, i = 0; wchar_t wc; setlocale(LC_ALL, ""); while(i < blen) { i += mbtowc(&wc, arg + i, blen - i); clen += wcwidth(wc); } return clen; } void simple_test_get_escape(char c, char *buf) { buf[0] = '\\'; buf[2] = '\0'; switch(c) { case '\a': buf[1] = 'a'; break; case '\b': buf[1] = 'b'; break; case '\t': buf[1] = 't'; break; case '\n': buf[1] = 'n'; break; case '\v': buf[1] = 'v'; break; case '\f': buf[1] = 'f'; break; case '\r': buf[1] = 'r'; break; default: buf[0] = c; buf[1] = '\0'; } } void simple_test_get_escape_wide(wchar_t c, wchar_t *buf) { buf[0] = L'\\'; buf[2] = L'\0'; switch(c) { case L'\a': buf[1] = L'a'; break; case L'\b': buf[1] = L'b'; break; case L'\t': buf[1] = L't'; break; case L'\n': buf[1] = L'n'; break; case L'\v': buf[1] = L'v'; break; case L'\f': buf[1] = L'f'; break; case L'\r': buf[1] = L'r'; break; default: buf[0] = c; buf[1] = L'\0'; } } /* extra levels of abstraction are necessary * to get __LINE__ to evaluate first */ #define SIMPLE_TEST_STRINGIFY(x) SIMPLE_TEST_STRINGIFY_EVAL(x) #define SIMPLE_TEST_STRINGIFY_EVAL(x) \ #x #define SIMPLE_TEST_LEN_DIFF(arg1, arg2) \ ( simple_test_mbslen(arg1) - simple_test_mbslen(arg2) ) #define SIMPLE_TEST_FAIL_ONE(summary, file, line, fmt, sarg, arg) \ do { \ { \ printf("\e[1m :: "); \ printf("%s", file); \ printf(":%i: \e[31;1mfail:\e[m ", line); \ printf(summary); \ printf("\e[m\n"); \ printf("\e[1m :: "); \ printf("%s == \e[m" fmt "\n", sarg, arg); \ exit(1); \ } \ } while(0) #define SIMPLE_TEST_FAIL(summary, file, line, fmt1, fmt2, sarg1, sarg2, arg1, arg2) \ do { \ { \ int simple_test_i, simple_test_diff = SIMPLE_TEST_LEN_DIFF(sarg1, sarg2); \ printf("\e[1m :: "); \ printf("%s", file); \ printf(":%i: \e[31;1mfail:\e[m ", line); \ printf(summary); \ printf("\e[m\n"); \ printf("\e[1m :: "); \ for(simple_test_i = 0; simple_test_i < -simple_test_diff; simple_test_i++) \ printf(" "); \ printf("%s == \e[m", sarg1); \ printf(fmt1, arg1); \ printf("\n\e[1m :: "); \ for(simple_test_i = 0; simple_test_i < simple_test_diff; simple_test_i++) \ printf(" "); \ printf("%s == \e[m", sarg2); \ printf(fmt2, arg2); \ printf("\n"); \ exit(1); \ } \ } while(0) #define SIMPLE_TEST_INTERN_ERR(file, line) \ do { \ printf("\e[1m :: "); \ printf("%s:%i: \e[31;1merr:\e[m ", file, line); \ printf("bad call to internal func\n"); \ exit(1); \ } while(0) void simple_test_assert_bool(char *sarg1, char *sarg2, bool arg1, bool arg2, const char *file, const int line, simple_test_cond_t cond) { switch(cond) { case SIMPLE_TEST_TRUE: if(!(arg2)) SIMPLE_TEST_FAIL_ONE("unexpected false value", file, line, "%s", sarg2, arg2 ? "true" : "false"); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("bool values do not match", file, line, "%s", "%s", sarg1, sarg2, arg1 ? "true" : "false", arg2 ? "true" : "false"); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("bool values match", file, line, "%s", "%s", sarg1, sarg2, arg1 ? "true" : "false", arg2 ? "true" : "false"); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_int(char *sarg1, char *sarg2, intmax_t arg1, intmax_t arg2, const char *file, const int line, simple_test_cond_t cond) { switch(cond) { case SIMPLE_TEST_TRUE: if(!(arg2)) SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, "%" PRIiMAX, sarg2, arg2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("int values do not match", file, line, "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("int values match", file, line, "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_uint(char *sarg1, char *sarg2, uintmax_t arg1, uintmax_t arg2, const char *file, const int line, simple_test_cond_t cond) { switch(cond) { case SIMPLE_TEST_TRUE: if(!(arg2)) SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, "%" PRIuMAX, sarg2, arg2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("uint values do not match", file, line, "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("uint values match", file, line, "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_hex(char *sarg1, char *sarg2, uintmax_t arg1, uintmax_t arg2, const char *file, const int line, simple_test_cond_t cond) { switch(cond) { case SIMPLE_TEST_TRUE: if(!(arg2)) SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, "%" PRIxMAX, sarg2, arg2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("uint values do not match", file, line, "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("uint values match", file, line, "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_float(char *sarg1, char *sarg2, long double arg1, long double arg2, const char *file, const int line, simple_test_cond_t cond) { switch(cond) { case SIMPLE_TEST_TRUE: if(!(arg2)) SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, "%Lg", sarg2, arg2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("float values do not match", file, line, "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("float values match", file, line, "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_ptr(char *sarg1, char *sarg2, void *arg1, void *arg2, const char *file, const int line, simple_test_cond_t cond) { switch(cond) { case SIMPLE_TEST_TRUE: if(arg2 == NULL) SIMPLE_TEST_FAIL_ONE("unexpected NULL value", file, line, "%p", sarg2, arg2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("pointer values do not match", file, line, "%p", "%p", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("pointer values match", file, line, "%p", "%p", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "%p", "%p", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "%p", "%p", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "%p", "%p", sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "%p", "%p", sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_char(char *sarg1, char *sarg2, char arg1, char arg2, const char *file, const int line, simple_test_cond_t cond) { char buf1[3]; char buf2[3]; simple_test_get_escape(arg1, buf1); simple_test_get_escape(arg2, buf2); switch(cond) { case SIMPLE_TEST_TRUE: if(arg2 == '\0') SIMPLE_TEST_FAIL_ONE("unexpected '\\0' value", file, line, "‘%s’", sarg2, buf2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("char values do not match", file, line, "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("char values match", file, line, "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_str(char *sarg1, char *sarg2, char *arg1, char *arg2, const char *file, const int line, simple_test_cond_t cond) { bool barg1 = (arg1 == NULL ? true : false); bool barg2 = (arg2 == NULL ? true : false); arg1 = (arg1 == NULL ? "(nil)" : arg1); arg2 = (arg2 == NULL ? "(nil)" : arg2); switch(cond) { case SIMPLE_TEST_TRUE: if(!strcmp(arg2, "(nil)")) SIMPLE_TEST_FAIL_ONE("unexpected NULL string", file, line, "%s", sarg2, arg2); break; case SIMPLE_TEST_EQ: if( strcmp(arg1, arg2) ) SIMPLE_TEST_FAIL("strings do not match", file, line, (barg1 ? "%s" : "‘%s’"), (barg2 ? "%s" : "‘%s’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if( !strcmp(arg1, arg2) ) SIMPLE_TEST_FAIL("strings match", file, line, (barg1 ? "%s" : "‘%s’"), (barg2 ? "%s" : "‘%s’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if( strcmp(arg1, arg2) <= 0) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, (barg1 ? "%s" : "‘%s’"), (barg2 ? "%s" : "‘%s’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if( strcmp(arg1, arg2) < 0) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, (barg1 ? "%s" : "‘%s’"), (barg2 ? "%s" : "‘%s’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if( strcmp(arg1, arg2) >= 0) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, (barg1 ? "%s" : "‘%s’"), (barg2 ? "%s" : "‘%s’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if( strcmp(arg1, arg2) > 0) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, (barg1 ? "%s" : "‘%s’"), (barg2 ? "%s" : "‘%s’"), sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_wchar(char *sarg1, char *sarg2, wchar_t arg1, wchar_t arg2, const char *file, const int line, simple_test_cond_t cond) { wchar_t buf1[3]; wchar_t buf2[3]; simple_test_get_escape_wide(arg1, buf1); simple_test_get_escape_wide(arg2, buf2); switch(cond) { case SIMPLE_TEST_TRUE: if(arg2 == L'\0') SIMPLE_TEST_FAIL_ONE("unexpected '\\0' value", file, line, "‘%ls’", sarg2, buf2); break; case SIMPLE_TEST_EQ: if(arg1 != arg2) SIMPLE_TEST_FAIL("char values do not match", file, line, "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_NEQ: if(arg1 == arg2) SIMPLE_TEST_FAIL("char values match", file, line, "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_G: if(arg1 <= arg2) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_GEQ: if(arg1 < arg2) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_L: if(arg1 >= arg2) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); break; case SIMPLE_TEST_LEQ: if(arg1 > arg2) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } void simple_test_assert_wstr(char *sarg1, char *sarg2, wchar_t *arg1, wchar_t *arg2, const char *file, const int line, simple_test_cond_t cond) { bool barg1 = (arg1 == NULL ? true : false); bool barg2 = (arg2 == NULL ? true : false); arg1 = (arg1 == NULL ? L"(nil)" : arg1); arg2 = (arg2 == NULL ? L"(nil)" : arg2); switch(cond) { case SIMPLE_TEST_TRUE: if(!wcscmp(arg2, L"(nil)")) SIMPLE_TEST_FAIL_ONE("unexpected NULL string", file, line, "%ls", sarg2, arg2); break; case SIMPLE_TEST_EQ: if( wcscmp(arg1, arg2) ) SIMPLE_TEST_FAIL("strings do not match", file, line, (barg1 ? "%ls" : "‘%ls’"), (barg2 ? "%ls" : "‘%ls’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_NEQ: if( !wcscmp(arg1, arg2) ) SIMPLE_TEST_FAIL("strings match", file, line, (barg1 ? "%ls" : "‘%ls’"), (barg2 ? "%ls" : "‘%ls’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_G: if( wcscmp(arg1, arg2) <= 0) SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, (barg1 ? "%ls" : "‘%ls’"), (barg2 ? "%ls" : "‘%ls’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_GEQ: if( wcscmp(arg1, arg2) < 0) SIMPLE_TEST_FAIL("arg1 < arg2", file, line, (barg1 ? "%ls" : "‘%ls’"), (barg2 ? "%ls" : "‘%ls’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_L: if( wcscmp(arg1, arg2) >= 0) SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, (barg1 ? "%ls" : "‘%ls’"), (barg2 ? "%ls" : "‘%ls’"), sarg1, sarg2, arg1, arg2); break; case SIMPLE_TEST_LEQ: if( wcscmp(arg1, arg2) > 0) SIMPLE_TEST_FAIL("arg1 > arg2", file, line, (barg1 ? "%ls" : "‘%ls’"), (barg2 ? "%ls" : "‘%ls’"), sarg1, sarg2, arg1, arg2); break; default: SIMPLE_TEST_INTERN_ERR(file, line); } } /* reporting bool as SIMPLE_TEST_INT because that's how the compiler * sees true / false constants */ #define SIMPLE_TEST_TYPE_ENUM_VAL(arg) \ _Generic((arg), \ bool: SIMPLE_TEST_INT, \ int8_t: SIMPLE_TEST_INT, int16_t: SIMPLE_TEST_INT, \ int32_t: SIMPLE_TEST_INT, int64_t: SIMPLE_TEST_INT, \ uint8_t: SIMPLE_TEST_UINT, uint16_t: SIMPLE_TEST_UINT, \ uint32_t: SIMPLE_TEST_UINT, uint64_t: SIMPLE_TEST_UINT, \ float: SIMPLE_TEST_FLOAT, double: SIMPLE_TEST_FLOAT, \ long double: SIMPLE_TEST_FLOAT, \ default: SIMPLE_TEST_DEFAULT \ ) #define SIMPLE_TEST_TYPE_CHECK(arg1, arg2) \ do { \ if(SIMPLE_TEST_TYPE_ENUM_VAL(arg1) != SIMPLE_TEST_TYPE_ENUM_VAL(arg2)) { \ printf("\e[1m :: "); \ printf("%s:%i: \e[31;1merr:\e[m ", __FILE__, __LINE__); \ printf("type mismatch\n"); \ exit(1); \ } \ } while(0) #define SIMPLE_TEST_GENERIC_CAST(arg) \ _Generic((arg), \ int8_t: (intmax_t)(arg), int16_t: (intmax_t)(arg), int32_t: (intmax_t)(arg), \ int64_t: (intmax_t)(arg), \ uint8_t: (uintmax_t)(arg), uint16_t: (uintmax_t)(arg), uint32_t: (uintmax_t)(arg), \ uint64_t: (uintmax_t)(arg), \ float: (long double)(arg), double: (long double)(arg), \ long double: (long double)(arg) \ ) #define SIMPLE_TEST_GENERIC_NOT(arg) \ _Generic((arg), \ int8_t: 0, int16_t: 0, int32_t: 0, int64_t: 0, \ uint8_t: 0, uint16_t: 0, uint32_t: 0, uint64_t: 0, \ float: 0.0, double: 0.0, \ long double: 0.0 \ ) #define SIMPLE_TEST_GENERIC_NOT_STR(arg) \ _Generic((arg), \ int8_t: "0", int16_t: "0", int32_t: "0", int64_t: "0", \ uint8_t: "0", uint16_t: "0", uint32_t: "0", uint64_t: "0", \ float: "0.0", double: "0.0", \ long double: "0.0" \ ) #define SIMPLE_TEST_GENERIC_FUNCCALL(sarg1, sarg2, arg1, arg2, cond) \ _Generic((arg2), \ int8_t: simple_test_assert_int, int16_t: simple_test_assert_int, \ int32_t: simple_test_assert_int, int64_t: simple_test_assert_int, \ uint8_t: simple_test_assert_uint, uint16_t: simple_test_assert_uint, \ uint32_t: simple_test_assert_uint, uint64_t: simple_test_assert_uint, \ float: simple_test_assert_float, double: simple_test_assert_float, \ long double: simple_test_assert_float \ )(sarg1, sarg2, SIMPLE_TEST_GENERIC_CAST(arg1), \ SIMPLE_TEST_GENERIC_CAST(arg2), __FILE__, __LINE__, cond) /********************** * TOP-LEVEL MACROS * **********************/ /* the whole thing is inside one * big function. yay! */ #define BEGIN_TEST \ int simple_test_count_current=1; \ int main(int argc, char *argv[]) \ { \ printf("\e[1m" __FILE__ "\n"); /* yaaaay! */ #define END_TEST \ printf("\e[1m :: \e[m\e[32msuccess!\e[m\n"); \ return 0; \ } #define TEST(description) \ printf("\e[1m%3i :: \e[m\e[33m%s\e[m\n", simple_test_count_current++, description); /* pretty printing for the current state within * a test */ #define ECHO(...) \ do { \ printf("\e[1m :: \e[m\e[34m"); \ printf(__VA_ARGS__); \ printf("...\e[m\n"); \ } while(0) /************************ * TYPE-GENERIC TESTS * ************************/ #define ASSERT(arg) \ do { \ SIMPLE_TEST_GENERIC_FUNCCALL(SIMPLE_TEST_GENERIC_NOT_STR(arg), #arg, \ SIMPLE_TEST_GENERIC_NOT(arg), arg, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ arg1, arg2, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ arg1, arg2, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ arg1, arg2, SIMPLE_TEST_G); \ } while(0) #define ASSERT_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ arg1, arg2, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ arg1, arg2, SIMPLE_TEST_L); \ } while(0) #define ASSERT_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ arg1, arg2, SIMPLE_TEST_LEQ); \ } while(0) /************************* * TYPE-SPECIFIC TESTS * *************************/ #define ASSERT_BOOL(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(false, arg); \ simple_test_assert_bool("false", #arg, \ false, (bool)(arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_BOOL_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_bool(#arg1, #arg2, \ (bool)(arg1), (bool)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_BOOL_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_bool(#arg1, #arg2, \ (bool)(arg1), (bool)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_INT(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(0, arg); \ simple_test_assert_int("0", #arg, \ (intmax_t)0, (intmax_t)(arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_INT_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_int(#arg1, #arg2, \ (intmax_t)(arg1), (intmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_INT_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_int(#arg1, #arg2, \ (intmax_t)(arg1), (intmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_INT_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_int(#arg1, #arg2, \ (intmax_t)(arg1), (intmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_INT_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_int(#arg1, #arg2, \ (intmax_t)(arg1), (intmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_INT_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_int(#arg1, #arg2, \ (intmax_t)(arg1), (intmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_INT_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_int(#arg1, #arg2, \ (intmax_t)(arg1), (intmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_UINT(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(0, arg); \ simple_test_assert_uint("0", #arg, \ (uintmax_t)0, (uintmax_t)(arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_UINT_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_UINT_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_UINT_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_UINT_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_UINT_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_UINT_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_HEX(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(0, arg2); \ simple_test_assert_uint("0", #arg, \ (uintmax_t)0, (uintmax_t)(arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_HEX_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_uint(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_HEX_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_hex(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_HEX_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_hex(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_HEX_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_hex(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_HEX_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_hex(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_HEX_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_hex(#arg1, #arg2, \ (uintmax_t)(arg1), (uintmax_t)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_FLOAT(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(0.0, arg); \ simple_test_assert_float("0", #arg, \ (long double)0, (long double)(arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_FLOAT_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_float(#arg1, #arg2, \ (long double)(arg1), (long double)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_FLOAT_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_float(#arg1, #arg2, \ (long double)(arg1), (long double)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_FLOAT_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_float(#arg1, #arg2, \ (long double)(arg1), (long double)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_FLOAT_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_float(#arg1, #arg2, \ (long double)(arg1), (long double)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_FLOAT_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_float(#arg1, #arg2, \ (long double)(arg1), (long double)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_FLOAT_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_float(#arg1, #arg2, \ (long double)(arg1), (long double)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_PTR(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(NULL, arg); \ simple_test_assert_ptr("NULL", #arg, \ NULL, (void *)(arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_PTR_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_ptr(#arg1, #arg2, \ (void *)(arg1), (void *)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_PTR_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_ptr(#arg1, #arg2, \ (void *)(arg1), (void *)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_PTR_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_ptr(#arg1, #arg2, \ (void *)(arg1), (void *)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_PTR_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_ptr(#arg1, #arg2, \ (void *)(arg1), (void *)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_PTR_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_ptr(#arg1, #arg2, \ (void *)(arg1), (void *)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_PTR_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_ptr(#arg1, #arg2, \ (void *)(arg1), (void *)(arg2), \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_CHAR(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK('\0', arg); \ simple_test_assert_char("\\0", #arg, \ '\0', arg, \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_CHAR_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_char(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_CHAR_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_char(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_CHAR_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_char(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_CHAR_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_char(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_CHAR_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_char(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_CHAR_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_char(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_STR(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK("0", arg); \ simple_test_assert_str("0", #arg, \ 0, (arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_STR_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_str(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_STR_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_str(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_STR_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_str(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_STR_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_str(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_STR_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_str(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_STR_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_str(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_WCHAR(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(L'\0', arg2); \ simple_test_assert_wchar("\\0", #arg, \ L'\0', arg, \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_WCHAR_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wchar(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_WCHAR_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wchar(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_WCHAR_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wchar(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_WCHAR_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wchar(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_WCHAR_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wchar(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_WCHAR_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wchar(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #define ASSERT_WSTR(arg) \ do { \ SIMPLE_TEST_TYPE_CHECK(L"0", arg); \ simple_test_assert_wstr("0", #arg, \ 0, (arg), \ __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ } while(0) #define ASSERT_WSTR_EQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wstr(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_EQ); \ } while(0) #define ASSERT_WSTR_NEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wstr(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ } while(0) #define ASSERT_WSTR_G(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wstr(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_G); \ } while(0) #define ASSERT_WSTR_GEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wstr(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ } while(0) #define ASSERT_WSTR_L(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wstr(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_L); \ } while(0) #define ASSERT_WSTR_LEQ(arg1, arg2) \ do { \ SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ simple_test_assert_wstr(#arg1, #arg2, \ arg1, arg2, \ __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ } while(0) #endif