aboutsummaryrefslogtreecommitdiff
path: root/test_harness/test_harness.h
blob: 698e2da49dca30f3f548185addd68b6f96ce1c8b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#ifndef TEST_HARNESS_H_
#define TEST_HARNESS_H_

#include <stdio.h>
#include <string.h>

#define YELLOW "\x1b[00;33m"
#define GREEN "\x1b[01;32m"
#define RED "\x1b[01;31m"
#define RESET "\x1b[0m"

typedef struct {
  const char* test_suite;
  const char* test_name;
  int (*fn_ptr)();
  void* alignment;
} test_t;

#define GENPR(fmt, v1, v2) \
  fprintf(stderr, fmt "\n", v1, v2)

void test_printll(size_t sz, long long v1, long long v2);
void test_printul(size_t sz, unsigned long v1, unsigned long v2);
void test_printd(size_t sz, int v1, int v2);
void test_printl(size_t sz, long v1, long v2);
void test_printui(size_t sz, unsigned int v1, unsigned int v2);
void test_prints(size_t sz, short v1, short v2);
void test_printus(size_t sz, unsigned short v1, unsigned short v2);
void test_printc(size_t sz, char v1, char v2);
void test_printf(size_t sz, double v1, double v2);
void test_printp(size_t sz, void* v1, void* v2);
void test_printuc(size_t sz, unsigned char v1, unsigned char v2);

#define FORMAT_STRING(v1, v2) \
    _Generic((v1), \
                long long: test_printll, \
                unsigned long: test_printul, \
                int: test_printd, \
                long: test_printl, \
                unsigned int: test_printui, \
                short: test_prints, \
                unsigned short: test_printus, \
                char: test_printc, \
                unsigned char: test_printuc, \
                double: test_printf, \
                default: test_printp)(sizeof(v1), v1, v2) \

#define TRY_PRINT_TYPE(v1, v2, type, fmt) \
  else if (__builtin_types_compatible_p(typeof (v1), type)) { \
    fprintf(stderr, fmt " == " fmt "\n", v1, v2); \
  }

#define TYPE_STR(t) #t

#define ASSERT_TRUE(x) \
  do { \
    if (!(x)) { \
      fprintf(stderr, RED "ASSERT_TRUE FAILED!\n" RESET); \
      fprintf(stderr, "  - " YELLOW "In expression ASSERT_TRUE(" #x ")\n"); \
      fprintf(stderr, RESET "  - " YELLOW "At " __FILE__ ":%d\n" RESET, __LINE__); \
      test_harness_abort(1); \
    } \
  } while (0)

#define ASSERT_EQ(x, y) \
  do { \
    if ((x) != (y)) { \
      fprintf(stderr, RED "ASSERT_EQ FAILED! " RESET "Not true that "); \
      FORMAT_STRING((x), (y)); \
      fprintf(stderr, "  - " YELLOW "In expression ASSERT_EQ(" #x ", " #y ")\n"); \
      fprintf(stderr, RESET "  - " YELLOW "At " __FILE__ ":%d\n" RESET, __LINE__); \
      test_harness_abort(1); \
    } \
  } while (0)

#define ASSERT_EQ_STR(x, y) \
  do { \
    if (strcmp(x, y)) { \
      fprintf(stderr, \
          RED "ASSSERT_EQ_STR FAILED! " RESET "Not true that \"%s\" equals \"%s\"", \
          x, y); \
      fprintf(stderr, "  - " YELLOW "In expression ASSERT_EQ_STR(" #x ", " #y ")\n"); \
      fprintf(stderr, RESET "  - " YELLOW "At " __FILE__":%d\n" RESET, __LINE__); \
      test_harness_abort(1); \
    } \
  } while (0)


#define TEST(test_suite, test_name) \
  int test_suite ## _ ## test_name ## _fn (void); \
  volatile test_t test_suite ## _ ## test_name ## _testing_struct__ \
    __attribute((__section__("tests"))) __attribute((__used__)) = \
     {#test_suite, #test_name, test_suite ## _ ## test_name ## _fn}; \
  int test_suite ## _ ## test_name ## _fn (void)

void test_harness_abort(int ec);


void wipeout_fake_env();

#endif