#ifndef __TEST_H_
#define __TEST_H_
#include <stdbool.h>

int printf(const char*, ...);

#define DEFINE_TEST(name) bool test_##name()
#define START_TEST(name) printf("testing whether %s works... ", #name)
#define START_TEST_CASE(name) printf("testing %s...\n", #name)

#define TEST_SUCCESS()                                                                                                 \
    do {                                                                                                               \
        printf("yes!\n");                                                                                              \
        return true;                                                                                                   \
    } while (0)

#define TEST_FAIL(expr)                                                                                                \
    do {                                                                                                               \
        printf("no (%s)\n", #expr);                                                                                    \
        return false;                                                                                                  \
    } while (0)

#define TEST_NOT_SURE(expr)                                                                                            \
    do {                                                                                                               \
        printf("not sure (%s)\n", #expr);                                                                              \
        return true;                                                                                                   \
    } while (0)

#define EXPECT(expr)                                                                                                   \
    do {                                                                                                               \
        if (!(expr)) { TEST_FAIL(expr); }                                                                              \
    } while (0)

#define EXPECT_EQ(a, b) EXPECT((a) == (b))

#define EXPECT_NOT_EQ(a, b) EXPECT((a) != (b))

#define EXPECT_NOT_CRASHED() TEST_SUCCESS()

#define RUN_TEST(name)                                                                                                 \
    do {                                                                                                               \
        if (!test_##name()) return 1;                                                                                  \
    } while (0)

#endif