diff --git a/test/test.c b/test/test.c index ac4330a..8e5564a 100644 --- a/test/test.c +++ b/test/test.c @@ -32,54 +32,72 @@ #pragma warning(disable : 4127) #endif -TESTCASE(c, ASSERT_TRUE) { ASSERT_TRUE(1); } +UTEST(c, ASSERT_TRUE) { ASSERT_TRUE(1); } -TESTCASE(c, ASSERT_FALSE) { ASSERT_FALSE(0); } +UTEST(c, ASSERT_FALSE) { ASSERT_FALSE(0); } -TESTCASE(c, ASSERT_EQ) { ASSERT_EQ(1, 1); } +UTEST(c, ASSERT_EQ) { ASSERT_EQ(1, 1); } -TESTCASE(c, ASSERT_NE) { ASSERT_NE(1, 2); } +UTEST(c, ASSERT_NE) { ASSERT_NE(1, 2); } -TESTCASE(c, ASSERT_LT) { ASSERT_LT(1, 2); } +UTEST(c, ASSERT_LT) { ASSERT_LT(1, 2); } -TESTCASE(c, ASSERT_LE) { +UTEST(c, ASSERT_LE) { ASSERT_LE(1, 1); ASSERT_LE(1, 2); } -TESTCASE(c, ASSERT_GT) { ASSERT_GT(2, 1); } +UTEST(c, ASSERT_GT) { ASSERT_GT(2, 1); } -TESTCASE(c, ASSERT_GE) { +UTEST(c, ASSERT_GE) { ASSERT_GE(1, 1); ASSERT_GE(2, 1); } -TESTCASE(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } +UTEST(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } -TESTCASE(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } +UTEST(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } -TESTCASE(c, EXPECT_TRUE) { EXPECT_TRUE(1); } +UTEST(c, EXPECT_TRUE) { EXPECT_TRUE(1); } -TESTCASE(c, EXPECT_FALSE) { EXPECT_FALSE(0); } +UTEST(c, EXPECT_FALSE) { EXPECT_FALSE(0); } -TESTCASE(c, EXPECT_EQ) { EXPECT_EQ(1, 1); } +UTEST(c, EXPECT_EQ) { EXPECT_EQ(1, 1); } -TESTCASE(c, EXPECT_NE) { EXPECT_NE(1, 2); } +UTEST(c, EXPECT_NE) { EXPECT_NE(1, 2); } -TESTCASE(c, EXPECT_LT) { EXPECT_LT(1, 2); } +UTEST(c, EXPECT_LT) { EXPECT_LT(1, 2); } -TESTCASE(c, EXPECT_LE) { +UTEST(c, EXPECT_LE) { EXPECT_LE(1, 1); EXPECT_LE(1, 2); } -TESTCASE(c, EXPECT_GT) { EXPECT_GT(2, 1); } +UTEST(c, EXPECT_GT) { EXPECT_GT(2, 1); } -TESTCASE(c, EXPECT_GE) { +UTEST(c, EXPECT_GE) { EXPECT_GE(1, 1); EXPECT_GE(2, 1); } -TESTCASE(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } +UTEST(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } -TESTCASE(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } +UTEST(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } + +struct MyTest { + int foo; +}; + +UTEST_F_SETUP(MyTest) { + ASSERT_EQ(0, fixture->foo); + fixture->foo = 42; +} + +UTEST_F_TEARDOWN(MyTest) { + ASSERT_EQ(13, fixture->foo); +} + +UTEST_F(MyTest, c) { + ASSERT_EQ(42, fixture->foo); + fixture->foo = 13; +} diff --git a/test/test.c b/test/test.c index ac4330a..8e5564a 100644 --- a/test/test.c +++ b/test/test.c @@ -32,54 +32,72 @@ #pragma warning(disable : 4127) #endif -TESTCASE(c, ASSERT_TRUE) { ASSERT_TRUE(1); } +UTEST(c, ASSERT_TRUE) { ASSERT_TRUE(1); } -TESTCASE(c, ASSERT_FALSE) { ASSERT_FALSE(0); } +UTEST(c, ASSERT_FALSE) { ASSERT_FALSE(0); } -TESTCASE(c, ASSERT_EQ) { ASSERT_EQ(1, 1); } +UTEST(c, ASSERT_EQ) { ASSERT_EQ(1, 1); } -TESTCASE(c, ASSERT_NE) { ASSERT_NE(1, 2); } +UTEST(c, ASSERT_NE) { ASSERT_NE(1, 2); } -TESTCASE(c, ASSERT_LT) { ASSERT_LT(1, 2); } +UTEST(c, ASSERT_LT) { ASSERT_LT(1, 2); } -TESTCASE(c, ASSERT_LE) { +UTEST(c, ASSERT_LE) { ASSERT_LE(1, 1); ASSERT_LE(1, 2); } -TESTCASE(c, ASSERT_GT) { ASSERT_GT(2, 1); } +UTEST(c, ASSERT_GT) { ASSERT_GT(2, 1); } -TESTCASE(c, ASSERT_GE) { +UTEST(c, ASSERT_GE) { ASSERT_GE(1, 1); ASSERT_GE(2, 1); } -TESTCASE(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } +UTEST(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } -TESTCASE(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } +UTEST(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } -TESTCASE(c, EXPECT_TRUE) { EXPECT_TRUE(1); } +UTEST(c, EXPECT_TRUE) { EXPECT_TRUE(1); } -TESTCASE(c, EXPECT_FALSE) { EXPECT_FALSE(0); } +UTEST(c, EXPECT_FALSE) { EXPECT_FALSE(0); } -TESTCASE(c, EXPECT_EQ) { EXPECT_EQ(1, 1); } +UTEST(c, EXPECT_EQ) { EXPECT_EQ(1, 1); } -TESTCASE(c, EXPECT_NE) { EXPECT_NE(1, 2); } +UTEST(c, EXPECT_NE) { EXPECT_NE(1, 2); } -TESTCASE(c, EXPECT_LT) { EXPECT_LT(1, 2); } +UTEST(c, EXPECT_LT) { EXPECT_LT(1, 2); } -TESTCASE(c, EXPECT_LE) { +UTEST(c, EXPECT_LE) { EXPECT_LE(1, 1); EXPECT_LE(1, 2); } -TESTCASE(c, EXPECT_GT) { EXPECT_GT(2, 1); } +UTEST(c, EXPECT_GT) { EXPECT_GT(2, 1); } -TESTCASE(c, EXPECT_GE) { +UTEST(c, EXPECT_GE) { EXPECT_GE(1, 1); EXPECT_GE(2, 1); } -TESTCASE(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } +UTEST(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } -TESTCASE(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } +UTEST(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } + +struct MyTest { + int foo; +}; + +UTEST_F_SETUP(MyTest) { + ASSERT_EQ(0, fixture->foo); + fixture->foo = 42; +} + +UTEST_F_TEARDOWN(MyTest) { + ASSERT_EQ(13, fixture->foo); +} + +UTEST_F(MyTest, c) { + ASSERT_EQ(42, fixture->foo); + fixture->foo = 13; +} diff --git a/test/test.cpp b/test/test.cpp index 4d7ef3a..6a3a275 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -32,54 +32,72 @@ #pragma warning(disable : 4127) #endif -TESTCASE(cpp, ASSERT_TRUE) { ASSERT_TRUE(1); } +UTEST(cpp, ASSERT_TRUE) { ASSERT_TRUE(1); } -TESTCASE(cpp, ASSERT_FALSE) { ASSERT_FALSE(0); } +UTEST(cpp, ASSERT_FALSE) { ASSERT_FALSE(0); } -TESTCASE(cpp, ASSERT_EQ) { ASSERT_EQ(1, 1); } +UTEST(cpp, ASSERT_EQ) { ASSERT_EQ(1, 1); } -TESTCASE(cpp, ASSERT_NE) { ASSERT_NE(1, 2); } +UTEST(cpp, ASSERT_NE) { ASSERT_NE(1, 2); } -TESTCASE(cpp, ASSERT_LT) { ASSERT_LT(1, 2); } +UTEST(cpp, ASSERT_LT) { ASSERT_LT(1, 2); } -TESTCASE(cpp, ASSERT_LE) { +UTEST(cpp, ASSERT_LE) { ASSERT_LE(1, 1); ASSERT_LE(1, 2); } -TESTCASE(cpp, ASSERT_GT) { ASSERT_GT(2, 1); } +UTEST(cpp, ASSERT_GT) { ASSERT_GT(2, 1); } -TESTCASE(cpp, ASSERT_GE) { +UTEST(cpp, ASSERT_GE) { ASSERT_GE(1, 1); ASSERT_GE(2, 1); } -TESTCASE(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } +UTEST(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } -TESTCASE(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } +UTEST(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } -TESTCASE(cpp, EXPECT_TRUE) { EXPECT_TRUE(1); } +UTEST(cpp, EXPECT_TRUE) { EXPECT_TRUE(1); } -TESTCASE(cpp, EXPECT_FALSE) { EXPECT_FALSE(0); } +UTEST(cpp, EXPECT_FALSE) { EXPECT_FALSE(0); } -TESTCASE(cpp, EXPECT_EQ) { EXPECT_EQ(1, 1); } +UTEST(cpp, EXPECT_EQ) { EXPECT_EQ(1, 1); } -TESTCASE(cpp, EXPECT_NE) { EXPECT_NE(1, 2); } +UTEST(cpp, EXPECT_NE) { EXPECT_NE(1, 2); } -TESTCASE(cpp, EXPECT_LT) { EXPECT_LT(1, 2); } +UTEST(cpp, EXPECT_LT) { EXPECT_LT(1, 2); } -TESTCASE(cpp, EXPECT_LE) { +UTEST(cpp, EXPECT_LE) { EXPECT_LE(1, 1); EXPECT_LE(1, 2); } -TESTCASE(cpp, EXPECT_GT) { EXPECT_GT(2, 1); } +UTEST(cpp, EXPECT_GT) { EXPECT_GT(2, 1); } -TESTCASE(cpp, EXPECT_GE) { +UTEST(cpp, EXPECT_GE) { EXPECT_GE(1, 1); EXPECT_GE(2, 1); } -TESTCASE(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } +UTEST(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } -TESTCASE(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } +UTEST(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } + +struct MyTest { + int foo; +}; + +UTEST_F_SETUP(MyTest) { + ASSERT_EQ(0, fixture->foo); + fixture->foo = 42; +} + +UTEST_F_TEARDOWN(MyTest) { + ASSERT_EQ(13, fixture->foo); +} + +UTEST_F(MyTest, cpp) { + ASSERT_EQ(42, fixture->foo); + fixture->foo = 13; +} diff --git a/test/test.c b/test/test.c index ac4330a..8e5564a 100644 --- a/test/test.c +++ b/test/test.c @@ -32,54 +32,72 @@ #pragma warning(disable : 4127) #endif -TESTCASE(c, ASSERT_TRUE) { ASSERT_TRUE(1); } +UTEST(c, ASSERT_TRUE) { ASSERT_TRUE(1); } -TESTCASE(c, ASSERT_FALSE) { ASSERT_FALSE(0); } +UTEST(c, ASSERT_FALSE) { ASSERT_FALSE(0); } -TESTCASE(c, ASSERT_EQ) { ASSERT_EQ(1, 1); } +UTEST(c, ASSERT_EQ) { ASSERT_EQ(1, 1); } -TESTCASE(c, ASSERT_NE) { ASSERT_NE(1, 2); } +UTEST(c, ASSERT_NE) { ASSERT_NE(1, 2); } -TESTCASE(c, ASSERT_LT) { ASSERT_LT(1, 2); } +UTEST(c, ASSERT_LT) { ASSERT_LT(1, 2); } -TESTCASE(c, ASSERT_LE) { +UTEST(c, ASSERT_LE) { ASSERT_LE(1, 1); ASSERT_LE(1, 2); } -TESTCASE(c, ASSERT_GT) { ASSERT_GT(2, 1); } +UTEST(c, ASSERT_GT) { ASSERT_GT(2, 1); } -TESTCASE(c, ASSERT_GE) { +UTEST(c, ASSERT_GE) { ASSERT_GE(1, 1); ASSERT_GE(2, 1); } -TESTCASE(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } +UTEST(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } -TESTCASE(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } +UTEST(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } -TESTCASE(c, EXPECT_TRUE) { EXPECT_TRUE(1); } +UTEST(c, EXPECT_TRUE) { EXPECT_TRUE(1); } -TESTCASE(c, EXPECT_FALSE) { EXPECT_FALSE(0); } +UTEST(c, EXPECT_FALSE) { EXPECT_FALSE(0); } -TESTCASE(c, EXPECT_EQ) { EXPECT_EQ(1, 1); } +UTEST(c, EXPECT_EQ) { EXPECT_EQ(1, 1); } -TESTCASE(c, EXPECT_NE) { EXPECT_NE(1, 2); } +UTEST(c, EXPECT_NE) { EXPECT_NE(1, 2); } -TESTCASE(c, EXPECT_LT) { EXPECT_LT(1, 2); } +UTEST(c, EXPECT_LT) { EXPECT_LT(1, 2); } -TESTCASE(c, EXPECT_LE) { +UTEST(c, EXPECT_LE) { EXPECT_LE(1, 1); EXPECT_LE(1, 2); } -TESTCASE(c, EXPECT_GT) { EXPECT_GT(2, 1); } +UTEST(c, EXPECT_GT) { EXPECT_GT(2, 1); } -TESTCASE(c, EXPECT_GE) { +UTEST(c, EXPECT_GE) { EXPECT_GE(1, 1); EXPECT_GE(2, 1); } -TESTCASE(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } +UTEST(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } -TESTCASE(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } +UTEST(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } + +struct MyTest { + int foo; +}; + +UTEST_F_SETUP(MyTest) { + ASSERT_EQ(0, fixture->foo); + fixture->foo = 42; +} + +UTEST_F_TEARDOWN(MyTest) { + ASSERT_EQ(13, fixture->foo); +} + +UTEST_F(MyTest, c) { + ASSERT_EQ(42, fixture->foo); + fixture->foo = 13; +} diff --git a/test/test.cpp b/test/test.cpp index 4d7ef3a..6a3a275 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -32,54 +32,72 @@ #pragma warning(disable : 4127) #endif -TESTCASE(cpp, ASSERT_TRUE) { ASSERT_TRUE(1); } +UTEST(cpp, ASSERT_TRUE) { ASSERT_TRUE(1); } -TESTCASE(cpp, ASSERT_FALSE) { ASSERT_FALSE(0); } +UTEST(cpp, ASSERT_FALSE) { ASSERT_FALSE(0); } -TESTCASE(cpp, ASSERT_EQ) { ASSERT_EQ(1, 1); } +UTEST(cpp, ASSERT_EQ) { ASSERT_EQ(1, 1); } -TESTCASE(cpp, ASSERT_NE) { ASSERT_NE(1, 2); } +UTEST(cpp, ASSERT_NE) { ASSERT_NE(1, 2); } -TESTCASE(cpp, ASSERT_LT) { ASSERT_LT(1, 2); } +UTEST(cpp, ASSERT_LT) { ASSERT_LT(1, 2); } -TESTCASE(cpp, ASSERT_LE) { +UTEST(cpp, ASSERT_LE) { ASSERT_LE(1, 1); ASSERT_LE(1, 2); } -TESTCASE(cpp, ASSERT_GT) { ASSERT_GT(2, 1); } +UTEST(cpp, ASSERT_GT) { ASSERT_GT(2, 1); } -TESTCASE(cpp, ASSERT_GE) { +UTEST(cpp, ASSERT_GE) { ASSERT_GE(1, 1); ASSERT_GE(2, 1); } -TESTCASE(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } +UTEST(c, ASSERT_STREQ) { ASSERT_STREQ("foo", "foo"); } -TESTCASE(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } +UTEST(c, ASSERT_STRNE) { ASSERT_STRNE("foo", "bar"); } -TESTCASE(cpp, EXPECT_TRUE) { EXPECT_TRUE(1); } +UTEST(cpp, EXPECT_TRUE) { EXPECT_TRUE(1); } -TESTCASE(cpp, EXPECT_FALSE) { EXPECT_FALSE(0); } +UTEST(cpp, EXPECT_FALSE) { EXPECT_FALSE(0); } -TESTCASE(cpp, EXPECT_EQ) { EXPECT_EQ(1, 1); } +UTEST(cpp, EXPECT_EQ) { EXPECT_EQ(1, 1); } -TESTCASE(cpp, EXPECT_NE) { EXPECT_NE(1, 2); } +UTEST(cpp, EXPECT_NE) { EXPECT_NE(1, 2); } -TESTCASE(cpp, EXPECT_LT) { EXPECT_LT(1, 2); } +UTEST(cpp, EXPECT_LT) { EXPECT_LT(1, 2); } -TESTCASE(cpp, EXPECT_LE) { +UTEST(cpp, EXPECT_LE) { EXPECT_LE(1, 1); EXPECT_LE(1, 2); } -TESTCASE(cpp, EXPECT_GT) { EXPECT_GT(2, 1); } +UTEST(cpp, EXPECT_GT) { EXPECT_GT(2, 1); } -TESTCASE(cpp, EXPECT_GE) { +UTEST(cpp, EXPECT_GE) { EXPECT_GE(1, 1); EXPECT_GE(2, 1); } -TESTCASE(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } +UTEST(c, EXPECT_STREQ) { EXPECT_STREQ("foo", "foo"); } -TESTCASE(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } +UTEST(c, EXPECT_STRNE) { EXPECT_STRNE("foo", "bar"); } + +struct MyTest { + int foo; +}; + +UTEST_F_SETUP(MyTest) { + ASSERT_EQ(0, fixture->foo); + fixture->foo = 42; +} + +UTEST_F_TEARDOWN(MyTest) { + ASSERT_EQ(13, fixture->foo); +} + +UTEST_F(MyTest, cpp) { + ASSERT_EQ(42, fixture->foo); + fixture->foo = 13; +} diff --git a/utest.h b/utest.h index ea45bb2..2d680c5 100644 --- a/utest.h +++ b/utest.h @@ -53,8 +53,8 @@ #endif #pragma warning(push, 1) -#include #include +#include #pragma warning(pop) #elif defined(__linux__) @@ -72,8 +72,8 @@ // glibc is version 2.17 or above, so we can just use clock_gettime #define UTEST_USE_CLOCKGETTIME #else // ((2 < __GLIBC__) || ((2 == __GLIBC__) && (17 <= __GLIBC_MINOR__))) -#include #include +#include #endif // ((2 < __GLIBC__) || ((2 == __GLIBC__) && (17 <= __GLIBC_MINOR__))) #endif // defined(__GLIBC__) && defined(__GLIBC_MINOR__) @@ -83,7 +83,6 @@ #if defined(_MSC_VER) #define UTEST_PRId64 "I64d" -#define UTEST_PRIu64 "I64u" #define UTEST_INLINE __forceinline #pragma section(".CRT$XCU", read) @@ -92,13 +91,9 @@ __declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = f; \ static void __cdecl f(void) #else -#if defined(__linux__) -#define __STDC_FORMAT_MACROS 1 -#endif #include #define UTEST_PRId64 PRId64 -#define UTEST_PRIu64 PRIu64 #define UTEST_INLINE inline #define UTEST_INITIALIZER(f) \ @@ -140,82 +135,57 @@ typedef void (*utest_testcase_t)(int *); -struct utest_state_s { - utest_testcase_t *testcases; - const char **testcase_names; - size_t testcases_length; - const char *filter; +struct utest_test_state_s { + utest_testcase_t testcase; + const char *name; }; -#if defined(_MSC_VER) -#define UTEST_WEAK __forceinline -#else -#define UTEST_WEAK __attribute__((weak)) -#endif +struct utest_state_s { + struct utest_test_state_s *tests; + size_t tests_length; +}; -#if defined(__cplusplus) -// if we are using c++ we can use overloaded methods (its in the language) -#define UTEST_OVERLOADABLE -#elif defined(__clang__) -// otherwise, if we are using clang with c we can use the overloadable attribute -#define UTEST_OVERLOADABLE __attribute__((overloadable)) -#endif +#define UTEST_ASSERT(x, y, cond) \ + if (!((x)cond(y))) { \ + printf("%s:%u: Failure\n", __FILE__, __LINE__); \ + *utest_result = 1; \ + return; \ + } -#if defined(UTEST_OVERLOADABLE) -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(float f); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(float f) { - printf("%f", f); -} +#define ASSERT_TRUE(x) \ + if (!(x)) { \ + printf("%s:%u: Failure\n", __FILE__, __LINE__); \ + *utest_result = 1; \ + return; \ + } -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(double d); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(double d) { - printf("%f", d); -} +#define ASSERT_FALSE(x) \ + if (x) { \ + printf("%s:%u: Failure\n", __FILE__, __LINE__); \ + *utest_result = 1; \ + return; \ + } -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long double d); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long double d) { - printf("%Lf", d); -} +#define ASSERT_EQ(x, y) UTEST_ASSERT(x, y, ==) +#define ASSERT_NE(x, y) UTEST_ASSERT(x, y, !=) +#define ASSERT_LT(x, y) UTEST_ASSERT(x, y, <) +#define ASSERT_LE(x, y) UTEST_ASSERT(x, y, <=) +#define ASSERT_GT(x, y) UTEST_ASSERT(x, y, >) +#define ASSERT_GE(x, y) UTEST_ASSERT(x, y, >=) -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(int i); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(int i) { - printf("%d", i); -} +#define ASSERT_STREQ(x, y) \ + if (0 != strcmp(x, y)) { \ + printf("%s:%u: Failure\n", __FILE__, __LINE__); \ + *utest_result = 1; \ + return; \ + } -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned int i); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned int i) { - printf("%u", i); -} - -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long int i); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long int i) { - printf("%ld", i); -} - -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long unsigned int i); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long unsigned int i) { - printf("%lu", i); -} - -// long long is a c++11 extension -// TODO: grok for c++11 version here -#if !defined(__cplusplus) -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long int i); -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long int i) { - printf("%lld", i); -} - -UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long unsigned int i); -UTEST_WEAK UTEST_OVERLOADABLE void -utest_type_printer(long long unsigned int i) { - printf("%llu", i); -} -#endif -#else -// we don't have the ability to print the values we got, so we create a macro to -// tell our users we can't do anything fancy -#define utest_type_printer(...) printf("undef") -#endif +#define ASSERT_STRNE(x, y) \ + if (0 == strcmp(x, y)) { \ + printf("%s:%u: Failure\n", __FILE__, __LINE__); \ + *utest_result = 1; \ + return; \ + } #define UTEST_EXPECT(x, y, cond) \ if (!((x)cond(y))) { \ @@ -226,256 +196,126 @@ #define EXPECT_TRUE(x) \ if (!(x)) { \ printf("%s:%u: Failure\n", __FILE__, __LINE__); \ - printf(" Expected : true\n"); \ - printf(" Actual : %s\n", (x) ? "true" : "false"); \ *utest_result = 1; \ } #define EXPECT_FALSE(x) \ if (x) { \ printf("%s:%u: Failure\n", __FILE__, __LINE__); \ - printf(" Expected : false\n"); \ - printf(" Actual : %s\n", (x) ? "true" : "false"); \ *utest_result = 1; \ } -#define EXPECT_EQ(x, y) UTEST_EXPECT(x, y, == ) -#define EXPECT_NE(x, y) UTEST_EXPECT(x, y, != ) -#define EXPECT_LT(x, y) UTEST_EXPECT(x, y, < ) -#define EXPECT_LE(x, y) UTEST_EXPECT(x, y, <= ) -#define EXPECT_GT(x, y) UTEST_EXPECT(x, y, > ) -#define EXPECT_GE(x, y) UTEST_EXPECT(x, y, >= ) +#define EXPECT_EQ(x, y) UTEST_EXPECT(x, y, ==) +#define EXPECT_NE(x, y) UTEST_EXPECT(x, y, !=) +#define EXPECT_LT(x, y) UTEST_EXPECT(x, y, <) +#define EXPECT_LE(x, y) UTEST_EXPECT(x, y, <=) +#define EXPECT_GT(x, y) UTEST_EXPECT(x, y, >) +#define EXPECT_GE(x, y) UTEST_EXPECT(x, y, >=) #define EXPECT_STREQ(x, y) \ if (0 != strcmp(x, y)) { \ printf("%s:%u: Failure\n", __FILE__, __LINE__); \ - printf(" Expected : \"%s\"\n", x); \ - printf(" Actual : \"%s\"\n", y); \ *utest_result = 1; \ } #define EXPECT_STRNE(x, y) \ if (0 == strcmp(x, y)) { \ printf("%s:%u: Failure\n", __FILE__, __LINE__); \ - printf(" Expected : \"%s\"\n", x); \ - printf(" Actual : \"%s\"\n", y); \ *utest_result = 1; \ } -#define UTEST_ASSERT(x, y, cond) \ - UTEST_EXPECT(x, y, cond); \ - if (!((x)cond(y))) { \ - return; \ - } - -#define ASSERT_TRUE(x) \ - EXPECT_TRUE(x); \ - if (!(x)) { \ - return; \ - } - -#define ASSERT_FALSE(x) \ - EXPECT_FALSE(x); \ - if (x) { \ - return; \ - } - -#define ASSERT_EQ(x, y) UTEST_ASSERT(x, y, == ) -#define ASSERT_NE(x, y) UTEST_ASSERT(x, y, != ) -#define ASSERT_LT(x, y) UTEST_ASSERT(x, y, < ) -#define ASSERT_LE(x, y) UTEST_ASSERT(x, y, <= ) -#define ASSERT_GT(x, y) UTEST_ASSERT(x, y, > ) -#define ASSERT_GE(x, y) UTEST_ASSERT(x, y, >= ) - -#define ASSERT_STREQ(x, y) \ - EXPECT_STREQ(x, y); \ - if (0 != strcmp(x, y)) { \ - return; \ - } - -#define ASSERT_STRNE(x, y) \ - EXPECT_STRNE(x, y); \ - if (0 == strcmp(x, y)) { \ - return; \ - } - -#define TESTCASE(set, name) \ - static void utest_run_##set##_##name(int *utest_result); \ - UTEST_INITIALIZER(utest_register_##set##_##name) { \ - const size_t index = utest_state.testcases_length++; \ - utest_state.testcases = UTEST_PTR_CAST( \ - utest_testcase_t *, \ - realloc(UTEST_PTR_CAST(void *, utest_state.testcases), \ - sizeof(utest_testcase_t) * utest_state.testcases_length)); \ - utest_state.testcases[index] = &utest_run_##set##_##name; \ - utest_state.testcase_names = UTEST_PTR_CAST( \ - const char **, \ - realloc(UTEST_PTR_CAST(void *, utest_state.testcase_names), \ - sizeof(char *) * utest_state.testcases_length)); \ - utest_state.testcase_names[index] = #set "." #name; \ +#define UTEST(SET, NAME) \ + UTEST_EXTERN struct utest_state_s utest_state; \ + static void utest_run_##SET##_##NAME(int *utest_result); \ + UTEST_INITIALIZER(utest_register_##SET##_##NAME) { \ + const size_t index = utest_state.tests_length++; \ + utest_state.tests = \ + UTEST_PTR_CAST(struct utest_test_state_s *, \ + realloc(UTEST_PTR_CAST(void *, utest_state.tests), \ + sizeof(struct utest_test_state_s) * \ + utest_state.tests_length)); \ + utest_state.tests[index].testcase = &utest_run_##SET##_##NAME; \ + utest_state.tests[index].name = #SET "." #NAME; \ } \ - void utest_run_##set##_##name(int *utest_result) + void utest_run_##SET##_##NAME(int *utest_result) -// extern to the global state utest needs to execute -UTEST_EXTERN struct utest_state_s utest_state; +#define UTEST_F_SETUP(FIXTURE) \ + static void utest_setup_##FIXTURE(int *utest_result, struct FIXTURE *fixture) -UTEST_WEAK int utest_should_filter_test(const char *filter, - const char *testcase); -UTEST_WEAK int utest_should_filter_test(const char *filter, - const char *testcase) { - if (filter) { - const char *filter_cur = filter; - const char *testcase_cur = testcase; - const char *filter_wildcard = 0; +#define UTEST_F_TEARDOWN(FIXTURE) \ + static void utest_teardown_##FIXTURE(int *utest_result, \ + struct FIXTURE *fixture) - while (('\0' != *filter_cur) && ('\0' != *testcase_cur)) { - if ('*' == *filter_cur) { - // store the position of the wildcard - filter_wildcard = filter_cur; +#define UTEST_F(FIXTURE, NAME) \ + UTEST_EXTERN struct utest_state_s utest_state; \ + static void utest_run_##FIXTURE##_##NAME(int *, struct FIXTURE *); \ + static void utest_fixture_##FIXTURE##_##NAME(int *utest_result) { \ + struct FIXTURE fixture = {0}; \ + utest_setup_##FIXTURE(utest_result, &fixture); \ + if (0 != *utest_result) { \ + return; \ + } \ + utest_run_##FIXTURE##_##NAME(utest_result, &fixture); \ + utest_teardown_##FIXTURE(utest_result, &fixture); \ + } \ + UTEST_INITIALIZER(utest_register_##FIXTURE##_##NAME) { \ + const size_t index = utest_state.tests_length++; \ + utest_state.tests = \ + UTEST_PTR_CAST(struct utest_test_state_s *, \ + realloc(UTEST_PTR_CAST(void *, utest_state.tests), \ + sizeof(struct utest_test_state_s) * \ + utest_state.tests_length)); \ + utest_state.tests[index].testcase = &utest_fixture_##FIXTURE##_##NAME; \ + utest_state.tests[index].name = #FIXTURE "." #NAME; \ + } \ + void utest_run_##FIXTURE##_##NAME(int *utest_result, struct FIXTURE *fixture) - // skip the wildcard character - filter_cur++; - - while (('\0' != *filter_cur) && ('\0' != *testcase_cur)) { - if ('*' == *filter_cur) { - // we found another wildcard (filter is something like *foo*) so we - // exit the current loop, and return to the parent loop to handle - // the wildcard case - break; - } else if (*filter_cur != *testcase_cur) { - // otherwise our filter didn't match, so reset it - filter_cur = filter_wildcard; - } - - // move testcase along - testcase_cur++; - - // move filter along - filter_cur++; - } - - if (('\0' == *filter_cur) && ('\0' == *testcase_cur)) { - return 0; - } - - // if the testcase has been exhausted, we don't have a match! - if ('\0' == *testcase_cur) { - return 1; - } - } else { - if (*testcase_cur != *filter_cur) { - // test case doesn't match filter - return 1; - } else { - // move our filter and testcase forward - testcase_cur++; - filter_cur++; - } - } - } - - if (('\0' != *filter_cur) || - (('\0' != *testcase_cur) && - ((filter == filter_cur) || ('*' != filter_cur[-1])))) { - // we have a mismatch! - return 1; - } - } - - return 0; -} - -UTEST_WEAK int utest_main(int argc, const char *const argv[]); -UTEST_WEAK int utest_main(int argc, const char *const argv[]) { - size_t failed = 0; - size_t index = 0; - size_t *failed_testcases = 0; - size_t failed_testcases_length = 0; - const char *filter = 0; - size_t ran_tests = 0; - - // loop through all arguments looking for our options - for (index = 1; index < UTEST_CAST(size_t, argc); index++) { - const char filter_str[] = "--filter="; - - if (0 < strcmp(argv[index], filter_str)) { - // user wants to filter what test cases run! - filter = argv[index] + strlen(filter_str); - } - } - - for (index = 0; index < utest_state.testcases_length; index++) { - if (utest_should_filter_test(filter, utest_state.testcase_names[index])) { - continue; - } - - ran_tests++; - } - - printf("\033[32m[==========]\033[0m Running %" UTEST_PRIu64 " test cases.\n", - UTEST_CAST(uint64_t, ran_tests)); - - for (index = 0; index < utest_state.testcases_length; index++) { - int result = 0; - int64_t ns = 0; - - if (utest_should_filter_test(filter, utest_state.testcase_names[index])) { - continue; - } - - printf("\033[32m[ RUN ]\033[0m %s\n", - utest_state.testcase_names[index]); - ns = utest_ns(); - utest_state.testcases[index](&result); - ns = utest_ns() - ns; - if (0 != result) { - const size_t failed_testcase_index = failed_testcases_length++; - failed_testcases = UTEST_PTR_CAST( - size_t *, realloc(UTEST_PTR_CAST(void *, failed_testcases), - sizeof(size_t) * failed_testcases_length)); - failed_testcases[failed_testcase_index] = index; - failed++; - printf("\033[31m[ FAILED ]\033[0m %s (%" UTEST_PRId64 "ns)\n", - utest_state.testcase_names[index], ns); - } else { - printf("\033[32m[ OK ]\033[0m %s (%" UTEST_PRId64 "ns)\n", - utest_state.testcase_names[index], ns); - } - } - printf("\033[32m[==========]\033[0m %" UTEST_PRIu64 " test cases ran.\n", - UTEST_CAST(uint64_t, ran_tests)); - printf("\033[32m[ PASSED ]\033[0m %" UTEST_PRIu64 " tests.\n", - UTEST_CAST(uint64_t, ran_tests - failed)); - if (0 != failed) { - printf("\033[31m[ FAILED ]\033[0m %" UTEST_PRIu64 - " tests, listed below:\n", - UTEST_CAST(uint64_t, failed)); - for (index = 0; index < failed_testcases_length; index++) { - printf("\033[31m[ FAILED ]\033[0m %s\n", - utest_state.testcase_names[failed_testcases[index]]); - } - } - free(UTEST_PTR_CAST(void *, failed_testcases)); - free(UTEST_PTR_CAST(void *, utest_state.testcases)); - free(UTEST_PTR_CAST(void *, utest_state.testcase_names)); - return UTEST_CAST(int, failed); -} - -// we need, in exactly one source file, define the global struct that will hold -// the data we need to run utest. This macro allows the user to declare the -// data without having to use the UTEST_MAIN macro, thus allowing them to write -// their own main() function. -#define UTEST_STATE() struct utest_state_s utest_state - -// define a main() function to call into utest.h and start executing tests! A -// user can optionally not use this macro, and instead define their own main() -// function and manually call utest_main. The user must, in exactly one source -// file, use the UTEST_STATE macro to declare a global struct variable that -// utest requires. #define UTEST_MAIN() \ - UTEST_STATE(); \ - int main(int argc, const char *const argv[]) { \ - return utest_main(argc, argv); \ + UTEST_EXTERN struct utest_state_s utest_state; \ + struct utest_state_s utest_state; \ + int main(void) { \ + size_t failed = 0; \ + size_t index = 0; \ + size_t *failed_tests = 0; \ + size_t failed_tests_length = 0; \ + printf("\033[32m[==========]\033[0m Running %u test cases.\n", \ + (unsigned)utest_state.tests_length); \ + for (index = 0; index < utest_state.tests_length; index++) { \ + int result = 0; \ + int64_t ns = 0; \ + printf("\033[32m[ RUN ]\033[0m %s\n", \ + utest_state.tests[index].name); \ + ns = utest_ns(); \ + utest_state.tests[index].testcase(&result); \ + ns = utest_ns() - ns; \ + if (0 != result) { \ + const size_t failed_test_index = failed_tests_length++; \ + failed_tests = realloc(UTEST_PTR_CAST(void *, failed_tests), \ + sizeof(size_t) * failed_tests_length); \ + failed_tests[failed_test_index] = index; \ + failed++; \ + printf("\033[31m[ FAILED ]\033[0m %s (%" UTEST_PRId64 "ns)\n", \ + utest_state.tests[index].name, ns); \ + } else { \ + printf("\033[32m[ OK ]\033[0m %s (%" UTEST_PRId64 "ns)\n", \ + utest_state.tests[index].name, ns); \ + } \ + } \ + printf("\033[32m[==========]\033[0m %u test cases ran.\n", \ + (unsigned)utest_state.tests_length); \ + printf("\033[32m[ PASSED ]\033[0m %u tests.\n", \ + (unsigned)(utest_state.tests_length - failed)); \ + if (0 != failed) { \ + printf("\033[31m[ FAILED ]\033[0m %u tests, listed below:\n", \ + (unsigned)failed); \ + for (index = 0; index < failed_tests_length; index++) { \ + printf("\033[31m[ FAILED ]\033[0m %s\n", \ + utest_state.tests[failed_tests[index]].name); \ + } \ + } \ + free(UTEST_PTR_CAST(void *, failed_tests)); \ + free(UTEST_PTR_CAST(void *, utest_state.tests)); \ + return (int)failed; \ } #endif // SHEREDOM_UTEST_H_INCLUDED