#include <string.h>
#include "dstr.h"
+#include "macros.h"
+#include "report.h"
+#include "tvec.h"
-static int win = 0, lose = 0;
+static struct tvec_state tvstate;
static dstr d = DSTR_INIT;
-static char buf[1024];
+static char strbuf[1024];
-static void check(const char *what, const char *want)
-{
- if (strcmp(want, d.buf) == 0)
- win++;
- else {
- lose++;
- fprintf(stderr, "test failed: %s\n expected: %s\n found: %s\n",
- what, want, d.buf);
- }
-}
+#define TESTGROUP(name) TVEC_TESTGROUP_TAG(grp, &tvstate, name)
-static void PRINTF_LIKE(1, 2) format(const char *fmt, ...)
+static PRINTF_LIKE(1, 2) int format(const char *fmt, ...)
{
va_list ap;
+ int n;
+
va_start(ap, fmt);
dstr_reset(&d);
- dstr_vputf(&d, fmt, &ap);
+ n = dstr_vputf(&d, fmt, &ap);
va_end(ap);
+ return (n);
}
-static void PRINTF_LIKE(1, 2) prepare(const char *fmt, ...)
+static PRINTF_LIKE(1, 2) void prepare(const char *fmt, ...)
{
va_list ap;
int n;
va_start(ap, fmt);
#ifdef HAVE_SNPRINTF
- n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ n = vsnprintf(strbuf, sizeof(strbuf), fmt, ap);
#else
- n = vsprintf(buf, fmt, ap);
+ n = vsprintf(strbuf, fmt, ap);
#endif
- assert(0 <= n && n < sizeof(buf));
+ assert(0 <= n && n < sizeof(strbuf));
}
-#define TEST1(fmtargs) do { \
- format fmtargs; \
- prepare fmtargs; \
- check(#fmtargs, buf); \
+#define TEST_KNOWN(fmtargs, want) do { \
+ int n; n = format fmtargs; \
+ tvec_claimeq_int(&tvstate, n, strlen(want), \
+ __FILE__, __LINE__, "format " #fmtargs); \
+ tvec_claimeq_string(&tvstate, d.buf, d.len, want, strlen(want), \
+ __FILE__, __LINE__, "format " #fmtargs); \
} while (0)
-#define TEST2(fmtargs, want) do { \
- format fmtargs; \
- check(#fmtargs, want); \
+#define TEST_REF(fmtargs) do { \
+ int n = format fmtargs; \
+ prepare fmtargs; \
+ tvec_claimeq_int(&tvstate, n, strlen(strbuf), \
+ __FILE__, __LINE__, "format " #fmtargs); \
+ tvec_claimeq_string(&tvstate, d.buf, d.len, strbuf, strlen(strbuf), \
+ __FILE__, __LINE__, "format " #fmtargs); \
} while (0)
#define LENGTHY \
"This is a rather longer string than the code is expecting: will it fit?"
-int main(void)
+int main(int argc, char *argv[])
{
- TEST2(("Hello, world!"), "Hello, world!");
- TEST2(("just a ->%%<- sign"), "just a ->%<- sign");
- TEST2(("Testing, testing, %d, %d, %d.", 1, 2, 3),
- "Testing, testing, 1, 2, 3.");
- TEST2(("->%5d<-", 138), "-> 138<-");
- TEST2(("->%*d<-", 5, 138), "-> 138<-");
- TEST2(("->%-*d<-", 5, 138), "->138 <-");
- TEST2(("->%*d<-", -5, 138), "->138 <-");
- TEST2(("->%-*d<-", -5, 138), "->138 <-");
- TEST2(("->%.*s<-", 5, "truncate me"), "->trunc<-");
- TEST2(("->%.*s<-", -5, "don't truncate me"), "->don't truncate me<-");
- TEST2(("Truncation indirect: ->%.*s<-", 10, "a long string to be chopped"),
- "Truncation indirect: ->a long str<-");
- TEST2(("%08lx:%s", 0x65604204ul, "tripe-ec"), "65604204:tripe-ec");
- TEST2(("%s", LENGTHY), LENGTHY);
-
- TEST1(("big float: ->%f<- and integer %d\n", DBL_MAX, 42));
-
- TEST2(("Testing, testing, %3$d, %2$d, %1$d.", 3, 2, 1),
- "Testing, testing, 1, 2, 3.");
- TEST2(("Truncation indirect: ->%1$.*2$s<-",
- "a long string to be chopped", 10),
- "Truncation indirect: ->a long str<-");
-
- if (!lose) printf("All tests successful.\n");
- else printf("FAILED %d of %d tests.\n", lose, win + lose);
- return (!!lose);
+ struct tvec_test test;
+ int argpos;
+
+ tvec_parseargs(argc, argv, &tvstate, &argpos, &tvec_adhocconfig);
+ if (argpos < argc) die(2, "no input files expected");
+ tvec_adhoc(&tvstate, &test);
+
+ TESTGROUP("basics") {
+ TEST_KNOWN(("Hello, world!"), "Hello, world!");
+ TEST_KNOWN(("just a ->%%<- sign"), "just a ->%<- sign");
+ }
+
+ TESTGROUP("integers") {
+ TEST_KNOWN(("Testing, testing, %d, %d, %d.", 1, 2, 3),
+ "Testing, testing, 1, 2, 3.");
+ TEST_KNOWN(("->%5d<-", 138), "-> 138<-");
+ TEST_KNOWN(("->%*d<-", 5, 138), "-> 138<-");
+ TEST_KNOWN(("->%-*d<-", 5, 138), "->138 <-");
+ TEST_KNOWN(("->%*d<-", -5, 138), "->138 <-");
+ TEST_KNOWN(("->%-*d<-", -5, 138), "->138 <-");
+ }
+
+ TESTGROUP("strings") {
+ TEST_KNOWN(("->%.*s<-", 5, "truncate me"), "->trunc<-");
+ TEST_KNOWN(("->%.*s<-", -5, "don't truncate me"),
+ "->don't truncate me<-");
+ TEST_KNOWN(("Truncation indirect: ->%.*s<-", 10,
+ "a long string to be chopped"),
+ "Truncation indirect: ->a long str<-");
+ }
+
+ TESTGROUP("combinations") {
+ TEST_KNOWN(("%08lx:%s", 0x65604204ul, "tripe-ec"), "65604204:tripe-ec");
+ TEST_REF(("big float: ->%f<- and integer %d\n", DBL_MAX, 42));
+ }
+
+ TESTGROUP("argument-order") {
+ TEST_KNOWN(("Testing, testing, %3$d, %2$d, %1$d.", 3, 2, 1),
+ "Testing, testing, 1, 2, 3.");
+ TEST_KNOWN(("Truncation indirect: ->%1$.*2$s<-",
+ "a long string to be chopped", 10),
+ "Truncation indirect: ->a long str<-");
+ }
+
+ TESTGROUP("misc")
+ TEST_KNOWN(("%s", LENGTHY), LENGTHY);
+
+ return (tvec_end(&tvstate));
}