summaryrefslogtreecommitdiff
path: root/unittest/mytap/tap.h
blob: 3e9bd4d6e5d58641ca61276e97df062eca653965 (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef TAP_H
#define TAP_H

/*
  
 */

#define NO_PLAN  (0)
#define SKIP_ALL (-1)

/**
   Data about test plan.

   @internal We are using the "typedef struct X { ... } X" idiom to
   create class/struct X both in C and C++.
 */
typedef struct TEST_DATA {
  /**
     Number of tests that is planned to execute.

     Can be zero (<code>NO_PLAN</code>) meaning that the plan string
     will be printed at the end of test instead.
  */
  int plan;

  /** Number of last test that was done or skipped. */
  int last;

  /** Number of tests that failed. */
  int failed;

  /** Todo reason. */
  char todo[128];
} TEST_DATA;

#ifdef __cplusplus
extern "C" {
#endif

/**
   Set number of tests that is planned to execute.

   The function also accepts the predefined constants SKIP_ALL and
   NO_PLAN.

   @param count
   The planned number of tests to run.  Alternatively, the SKIP_ALL
   and NO_PLAN can be supplied.
*/
void plan(int count);


/**
   Report test result as a TAP line.

   Function used to write status of an individual test.  Call this
   function in the following manner:

   @code
   ok(ducks == paddling,
      "%d ducks did not paddle", ducks - paddling);
   @endcode

   @param pass Zero if the test failed, non-zero if it passed.
   @param fmt  Format string in printf() format. NULL is allowed, in
               which case nothing is printed.
*/
void ok(int pass, char const *fmt, ...)
  __attribute__ ((format(printf,2,3)));

/**
   Skip a determined number of tests.

   Function to print that <em>how_many</em> tests have been
   skipped.  The reason is printed for each skipped test.  Observe
   that this function does not do the actual skipping for you, it just
   prints information that tests have been skipped.  It shall be used
   in the following manner:

   @code
   if (ducks == 0) {
     skip(2, "No ducks in the pond");
   } else {
      int i;
      for (i = 0 ; i < 2 ; ++i)
        ok(duck[i] == paddling, "is duck %d paddling?", i);
   }
   @endcode

   @see SKIP_BLOCK_IF

   @param how_many   Number of tests that are to be skipped.
   @param reason     A reason for skipping the tests
 */
void skip(int how_many, char const *reason, ...)
    __attribute__ ((format(printf,2,3)));


/**
   Helper macro to skip a block of code.  The macro can be used to
   simplify conditionally skipping a block of code.  It is used in the
   following manner:

   @code
   SKIP_BLOCK_IF(ducks == 0, 2, "No ducks in the pond")
   {
     int i;
     for (i = 0 ; i < 2 ; ++i)
       ok(duck[i] == paddling, "is duck %d paddling?", i);
   }

   @see skip

   @endcode
 */
#define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \
  if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else

/**
   Print a diagnostics message.

   @param fmt  Diagnostics message in printf() format.
 */
void diag(char const *fmt, ...)
  __attribute__ ((format(printf,1,2)));

/**
   Print summary report and return exit status.

   This function will print a summary report of how many tests passed,
   how many were skipped, and how many remains to do.  The function
   should be called after all tests are executed in the following
   manner:

   @code
   return exit_status();
   @endcode

   @returns EXIT_SUCCESS if all tests passed, EXIT_FAILURE if one or
   more tests failed.
 */
int exit_status(void);


/**
   Skip entire test suite.

   To skip the entire test suite, use this function. It will
   automatically call exit(), so there is no need to have checks
   around it.
 */
void skip_all(char const *reason, ...)
  __attribute__ ((noreturn, format(printf, 1, 2)));

/**
   Start section of tests that are not yet ready.

   To start a section of tests that are not ready and are expected to
   fail, use this function and todo_end() in the following manner:

   @code
   todo_start("Not ready yet");
   ok(is_rocketeering(duck), "Rocket-propelled ducks");
   ok(is_kamikaze(duck), "Kamikaze ducks");
   todo_end();
   @endcode

   @see todo_end

   @note
   It is not possible to nest todo sections.

   @param message Message that will be printed before the todo tests.
*/
void todo_start(char const *message, ...)
  __attribute__ ((format (printf, 1, 2)));

/**
   End a section of tests that are not yet ready.
*/
void todo_end();

#ifdef __cplusplus
}
#endif

#endif /* TAP_H */