chiark / gitweb /
Initial sketch.
[finally] / test-guts.c
1 /* -*-c-*-
2  *
3  * Main test machinery
4  *
5  * (c) 2023 Mark Wooding
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the `Finally' package.
11  *
12  * Finally is free software: you can redistribute it and/or modify it
13  * under the terms of the GNU Library General Public License as published
14  * by the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * Finally is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Finally.  If not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25  * USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "finally-test.h"
35
36 /*----- Global variables --------------------------------------------------*/
37
38 const int secretly_true = 1;
39
40 /*----- Static variables --------------------------------------------------*/
41
42 static const char *curr;
43 static unsigned nrun = 0, nskip = 0, nlose = 0;
44 static unsigned flags = 0;
45 enum { HUMAN, TAP }; static unsigned outform = HUMAN;
46 #define f_failthis 1u
47
48 static int step;
49
50 /*----- Main code ---------------------------------------------------------*/
51
52 void init_test(void)
53 {
54   const char *p;
55
56   p = getenv("TEST_OUTFORM");
57   if (!p || strcmp(p, "human") == 0) outform = HUMAN;
58   else if (strcmp(p, "tap") == 0) outform = TAP;
59   else { fprintf(stderr, "unknown output format `%s'\n", p); exit(2); }
60 }
61
62 void begin_test(const char *name)
63   { step = 0; flags &= ~f_failthis; curr = name; }
64
65 void check_step(int s, const char *where)
66 {
67   FILE *fp;
68
69   if (step != s) {
70     switch (outform) {
71       case HUMAN: fp = stderr; break;
72       case TAP: fp = stdout; fputs("# ", stdout); break;
73       default: abort();
74     }
75     fprintf(fp, "%s (%s): misstep: expected %d but found %d\n",
76             where, curr, step, s);
77     flags |= f_failthis;
78   }
79   step++;
80 }
81
82 void end_test(void)
83 {
84   nrun++; if (flags&f_failthis) nlose++;
85
86   switch (outform) {
87     case HUMAN:
88       printf("%s: %s\n", curr, flags&f_failthis ? "FAILED" : "ok");
89       break;
90     case TAP:
91       printf("%s %u %s\n", flags&f_failthis ? "not ok" : "ok", nrun, curr);
92       break;
93     default:
94       abort();
95   }
96 }
97
98 void skip_test(const char *name, const char *excuse)
99 {
100   nrun++; nskip++;
101
102   switch (outform) {
103     case HUMAN: printf("%s: (skipped: %s)\n", name, excuse); break;
104     case TAP: printf("ok %u %s # skip (%s)\n", nrun, name, excuse); break;
105     default: abort();
106   }
107 }
108
109 int test_report(void)
110 {
111 #define TESTS(n) ((n) == 1 ? "test" : "tests")
112
113   switch (outform) {
114     case HUMAN:
115       if (nlose)
116         printf("FAILED %u out of %u %s", nlose, nrun, TESTS(nrun));
117       else if (nskip)
118         printf("passed %u out of %u %s",
119                nrun - nlose - nskip, nrun, TESTS(nrun));
120       else
121         printf("passed all %u %s", nrun, TESTS(nrun));
122       if (nskip) printf(" (skipped %u %s)", nskip, TESTS(nskip));
123       putchar('\n');
124       return (nlose ? 2 : 0);
125     case TAP:
126       printf("1..%u\n", nrun);
127       return (0);
128     default:
129       abort();
130   }
131
132 #undef TESTS
133 }
134
135 /*----- That's all, folks -------------------------------------------------*/