summaryrefslogtreecommitdiff
path: root/src/common/libtap/tap.h
blob: 2e89b90d00d4ddebf7e723848cb020d0e21d68fb (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
/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __TAP_H__
#define __TAP_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#define NO_PLAN          -1
#define ok(...)          ok_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL)
#define pass(...)        ok(1, ## __VA_ARGS__)
#define fail(...)        ok(0, ## __VA_ARGS__)
#define is(...)          is_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL)
#define isnt(...)        isnt_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL)
#define cmp_ok(...)      cmp_ok_at_loc(__FILE__, __LINE__, __VA_ARGS__, NULL)

int     vok_at_loc      (const char *file, int line, int test, const char *fmt,
                         va_list args);
void    plan            (int tests);
int     ok_at_loc       (const char *file, int line, int test, const char *fmt,
                         ...);
int     diag            (const char *fmt, ...);
int     note            (const char *fmt, ...);
int     exit_status     (void);
void    skippy          (int n, const char *fmt, ...);
void    ctodo           (int ignore, const char *fmt, ...);
void    cendtodo        (void);
int     is_at_loc       (const char *file, int line, const char *got,
                         const char *expected, const char *fmt, ...);
int     isnt_at_loc     (const char *file, int line, const char *got,
                         const char *expected, const char *fmt, ...);
int     cmp_ok_at_loc   (const char *file, int line, int a, const char *op,
                         int b, const char *fmt, ...);

#ifdef _WIN32
#define like(...)   skippy(1, "like is not implemented on MSWin32")
#define unlike(...) like()
#else
#define like(...)   like_at_loc(1, __FILE__, __LINE__, __VA_ARGS__, NULL)
#define unlike(...) like_at_loc(0, __FILE__, __LINE__, __VA_ARGS__, NULL)
int     like_at_loc     (int for_match, const char *file, int line,
                         const char *got, const char *expected,
                         const char *fmt, ...);
#endif

#define skip(test, ...)  do {if (test) {skippy(__VA_ARGS__, NULL); break;}
#define endskip          } while (0)

#define todo(...)        ctodo(0, ## __VA_ARGS__, NULL)
#define endtodo          cendtodo()

#define dies_ok(code, ...)  dies_ok_common(code, 1, ## __VA_ARGS__)
#define lives_ok(code, ...) dies_ok_common(code, 0, ## __VA_ARGS__)

#ifdef _WIN32
#define dies_ok_common(...) \
    skippy(1, "Death detection is not supported on MSWin32")
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int tap_test_died (int status);
#define dies_ok_common(code, for_death, ...)                \
    do {                                                    \
        tap_test_died(1);                                   \
        int cpid = fork();                                  \
        switch (cpid) {                                     \
        case -1:                                            \
            perror("fork error");                           \
            exit(EXIT_FAILURE);                             \
        case 0: /* child  */                                \
            close(1); close(2);                             \
            code                                            \
            tap_test_died(0);                               \
            exit(EXIT_SUCCESS);                             \
        }                                                   \
        if (waitpid(cpid, NULL, 0) < 0) {                   \
            perror("waitpid error");                        \
            exit(EXIT_FAILURE);                             \
        }                                                   \
        int it_died = tap_test_died(0);                     \
        if (!it_died) {code}                                \
        ok(for_death ? it_died : !it_died, ## __VA_ARGS__); \
    } while (0)
#endif
#endif