struct tvec_output _o;
struct tvec_state *tv;
struct layout lyt;
+ unsigned last;
char *outbuf; size_t outsz;
int maxlen;
};
{ struct tap_output *t = go; return (layout_char(&t->lyt, ch)); }
static int tap_writem(void *go, const char *p, size_t sz)
- { struct human_output *t = go; return (layout_string(&t->lyt, p, sz)); }
+ { struct tap_output *t = go; return (layout_string(&t->lyt, p, sz)); }
static int tap_nwritef(void *go, size_t maxsz, const char *p, ...)
{
- struct human_output *t = go;
+ struct tap_output *t = go;
size_t n;
va_list ap;
{
struct tap_output *t = (struct tap_output *)o;
- t->tv = tv;
- fputs("TAP version 13\n", t->lyt.fp);
+ t->tv = tv; t->last = 0;
+ fputs("TAP version 13\n", t->lyt.fp); /* but secretly 14 really */
}
static unsigned tap_grpix(struct tap_output *t)
return (n);
}
+static unsigned tap_testix(struct tap_output *t)
+{
+ struct tvec_state *tv = t->tv;
+ unsigned i, n;
+
+ for (n = 0, i = 0; i < TVOUT_LIMIT; i++) n += tv->curr[i];
+ if (tv->f&TVSF_OPEN) n++;
+ return (n);
+}
+
static int tap_esession(struct tvec_output *o)
{
struct tap_output *t = (struct tap_output *)o;
static void tap_bgroup(struct tvec_output *o)
{
struct tap_output *t = (struct tap_output *)o;
+ struct tvec_state *tv = t->tv;
+
t->maxlen = register_maxnamelen(t->tv);
+ fprintf(t->lyt.fp, "# Subtest: %s\n", tv->test->name);
}
static void tap_skipgroup(struct tvec_output *o,
{
struct tap_output *t = (struct tap_output *)o;
+ fprintf(t->lyt.fp, " 1..%u\n", tap_testix(t));
fprintf(t->lyt.fp, "ok %u %s # SKIP", tap_grpix(t), t->tv->test->name);
if (excuse) { fputc(' ', t->lyt.fp); vfprintf(t->lyt.fp, excuse, *ap); }
fputc('\n', t->lyt.fp);
}
-static void tap_report_unusual(struct tap_output *t,
- unsigned nxfail, unsigned nskip)
-{
- const char *sep = " (";
- unsigned f = 0;
-#define f_any 1u
-
- if (nxfail) {
- fprintf(t->lyt.fp, "%s%u expected %s",
- sep, nxfail, nxfail == 1 ? "failure" : "failures");
- sep = ", "; f |= f_any;
- }
-
- if (nskip) {
- fprintf(t->lyt.fp, "%s%u skipped", sep, nskip);
- sep = ", "; f |= f_any;
- }
-
- if (f&f_any) fputc(')', t->lyt.fp);
-
-#undef f_any
-}
-
static void tap_egroup(struct tvec_output *o)
{
struct tap_output *t = (struct tap_output *)o;
struct tvec_state *tv = t->tv;
- unsigned
- grpix = tap_grpix(t),
- win = tv->curr[TVOUT_WIN],
- xfail = tv->curr[TVOUT_XFAIL],
- lose = tv->curr[TVOUT_LOSE],
- skip = tv->curr[TVOUT_SKIP],
- pass = win + xfail;
-
- if (lose)
- fprintf(t->lyt.fp, "not ok %u - %s: FAILED %u/%u",
- grpix, tv->test->name, lose, pass + lose);
- else
- fprintf(t->lyt.fp, "ok %u - %s: passed %u", grpix, tv->test->name, pass);
- tap_report_unusual(t, xfail, skip);
- fputc('\n', t->lyt.fp);
+
+ fprintf(t->lyt.fp, " 1..%u\n", tap_testix(t));
+ fprintf(t->lyt.fp, "%s %u - %s\n",
+ tv->curr[TVOUT_LOSE] ? "not ok" : "ok",
+ tap_grpix(t), tv->test->name);
}
static void tap_btest(struct tvec_output *o) { ; }
-static void tap_outcome(struct tvec_output *o, const char *outcome,
+static void tap_outcome(struct tvec_output *o,
+ const char *head, const char *tail,
const char *detail, va_list *ap)
{
struct tap_output *t = (struct tap_output *)o;
struct tvec_state *tv = t->tv;
+ unsigned ix = tap_testix(t);
- gprintf(&tap_printops, t, "%s:%u: `%s' %s",
- tv->infile, tv->test_lno, tv->test->name, outcome);
- if (detail) {
- layout_string(&t->lyt, ": ", 2);
- vgprintf(&tap_printops, t, detail, ap);
- }
- layout_char(&t->lyt, '\n');
+ fprintf(t->lyt.fp, " %s %u - %s:%u%s",
+ ix == t->last ? "##" : head, ix, tv->infile, tv->test_lno, tail);
+ if (detail)
+ { fputc(' ', t->lyt.fp); vfprintf(t->lyt.fp, detail, *ap); }
+ fputc('\n', t->lyt.fp);
+ t->last = ix;
}
static void tap_skip(struct tvec_output *o, const char *excuse, va_list *ap)
- { tap_outcome(o, "skipped", excuse, ap); }
+ { tap_outcome(o, "ok", " # SKIP", excuse, ap); }
static void tap_fail(struct tvec_output *o, const char *detail, va_list *ap)
- { tap_outcome(o, "FAILED", detail, ap); }
+ { tap_outcome(o, "not ok", "", detail, ap); }
static void tap_dumpreg(struct tvec_output *o,
unsigned disp, const union tvec_regval *rv,
}
static void tap_etest(struct tvec_output *o, unsigned outcome)
- { if (outcome == TVOUT_XFAIL) tap_outcome(o, "EXPECTED failure", 0, 0); }
+{
+ switch (outcome) {
+ case TVOUT_WIN:
+ tap_outcome(o, "ok", "", 0, 0);
+ break;
+ case TVOUT_XFAIL:
+ tap_outcome(o, "not ok", " # TODO expected failure", 0, 0);
+ break;
+ }
+}
static void tap_bbench(struct tvec_output *o,
const char *ident, unsigned unit)
struct tap_output *t;
t = xmalloc(sizeof(*t)); t->_o.ops = &tap_ops;
- init_layout(&t->lyt, fp, "## ");
+ init_layout(&t->lyt, fp, " ## ");
t->outbuf = 0; t->outsz = 0;
return (&t->_o);
}
* (`Test Anything Protocol') format.
*
* TAP comes from the Perl community, but has spread rather
- * further. This driver produces TAP version 13. The driver
- * produces a TAP `test point' -- i.e., a result reported as
- * `ok' or `not ok' -- for each input test group. Failure
- * reports and register dumps are produced as diagnostic
- * messages before the final group result. (TAP permits
- * structuerd YAML data after the test-point result, which could
- * be used to report details, but (a) postponing the details
- * until after the report is inconvenient, and (b) there is no
- * standardization for the YAML anyway, so in practice it's no
- * more useful than the unstructured diagnostics.
+ * further. This driver produces TAP version 14, but pretends
+ * to be version 13. The driver produces a TAP `test point' --
+ * i.e., a result reported as `ok' or `not ok' -- for each input
+ * test group. Failure reports and register dumps are produced
+ * as diagnostic messages before the final group result. (TAP
+ * permits structuerd YAML data after the test-point result,
+ * which could be used to report details, but (a) postponing the
+ * details until after the report is inconvenient, and (b) there
+ * is no standardization for the YAML anyway, so in practice
+ * it's no more useful than the unstructured diagnostics.
*/
extern struct tvec_output *tvec_tapoutput(FILE */*fp*/);