aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/diagnostic.c208
-rw-r--r--test/meson.build8
2 files changed, 212 insertions, 4 deletions
diff --git a/test/diagnostic.c b/test/diagnostic.c
index 7a6670e..640e0d2 100644
--- a/test/diagnostic.c
+++ b/test/diagnostic.c
@@ -18,11 +18,213 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
#include "test.h"
+#include "rin/diagnostic.h"
+
+struct stdiocap {
+ int pipefd[2];
+ int origfd;
+ int backupfd;
+ FILE *pipe;
+};
+
+static int err_test(void);
+static int warn_test(void);
+static int fixme_test(void);
+static int info_test(void);
+static int prefix_test(void);
+static int thread_test(void);
+static int clean_test(void);
+static struct stdiocap capture_stdio_start(FILE *stream);
+static void capture_stdio_stop(struct stdiocap *cap);
+static char *visible_newlines(const char * const in);
+static int test_default_channels(const char * const in, const char * const expected, size_t i, int usearg, void (*func)(const char *, ...));
int diagnostic_test(char *testname)
{
- (void) testname;
- /* basically a NOOP */
- return ok(0, "");
+ static const struct test tests[] = {
+ {"err", err_test},
+ {"warn", warn_test},
+ {"fixme", fixme_test},
+ {"info", info_test},
+ {"prefix", prefix_test},
+ {"thread", thread_test},
+ {"clean", clean_test} };
+ size_t i;
+
+ for (i = 0; i < arrlen(tests); ++i) {
+ if (!strcmp(testname, tests[i].name)) {
+ return tests[i].testfunc();
+ }
+ }
+
+ return EXIT_FAILURE;
+}
+
+static int err_test(void)
+{
+ size_t i;
+ int usearg;
+ int ret;
+
+ static const char *in[] = {"", "test", "test number is %zu", "%zu tests ran"};
+ static const char *expected[] = {"error:\n", "error:test\n", "error:test number is 3\n", "error:4 tests ran\n"};
+
+ for (i = 0; i < arrlen(in); ++i) {
+ usearg = i < (arrlen(in) / 2) ? 0 : 1;
+ ret = test_default_channels(in[i], expected[i], i, usearg, rin_err);
+ }
+
+ return ret;
+}
+
+static int warn_test(void)
+{
+ return 77;
+}
+
+static int fixme_test(void)
+{
+ return 77;
+}
+
+static int info_test(void)
+{
+ return 77;
+}
+
+static int prefix_test(void)
+{
+ return 77;
+}
+
+static int thread_test(void)
+{
+ return 77;
+}
+
+static int clean_test(void)
+{
+ return 77;
+}
+
+static struct stdiocap capture_stdio_start(FILE *stream)
+{
+ struct stdiocap ret;
+
+ ret.origfd = fileno(stream);
+ ret.backupfd = dup(ret.origfd);
+
+ if (pipe(ret.pipefd)) {
+ close(ret.backupfd);
+ ret.backupfd = -1;
+ ret.origfd = -1;
+ ret.pipefd[0] = -1;
+ ret.pipefd[1] = -1;
+ ret.pipe = NULL;
+ }
+
+ dup2(ret.pipefd[1], ret.origfd);
+ ret.pipe = fdopen(ret.pipefd[0], "r");
+ return ret;
+}
+
+static void capture_stdio_stop(struct stdiocap *cap)
+{
+ /* restore original fd to the stream */
+ dup2(cap->backupfd, cap->origfd);
+ close(cap->backupfd);
+ close(cap->pipefd[1]);
+ close(cap->pipefd[0]);
+
+ /* close everything we opened and invalidate all the descriptors */
+ fclose(cap->pipe);
+ cap->backupfd = -1;
+ cap->origfd = -1;
+ cap->pipefd[0] = -1;
+ cap->pipefd[1] = -1;
+ cap->pipe = NULL;
+}
+
+static char *visible_newlines(const char * const in)
+{
+ char *ret;
+ const char *newline;
+ const char *readptr;
+ char *writeptr;
+
+ readptr = in;
+ ret = malloc(strlen(readptr) * 2 + 1);
+ writeptr = ret;
+ newline = strchr(readptr, '\n');
+
+ while (newline) {
+ /* write chunk until the next newline */
+ memcpy(writeptr, readptr, newline - readptr);
+ writeptr += newline - readptr; /* advance writing position */
+ readptr = newline;
+ ++readptr; /* skip the newline */
+ /* toss in replacement */
+ memcpy(writeptr, "\\n", 2);
+ writeptr += 2;
+ newline = strchr(readptr, '\n');
+ }
+
+ /* write all that remains */
+ strcpy(writeptr, readptr);
+ return ret;
+}
+
+static int test_default_channels(const char * const in, const char * const expected, size_t i, int usearg, void (*func)(const char *, ...))
+{
+ char buf[32] = {0};
+ struct stdiocap cap;
+ size_t len;
+ int ret = 0;
+
+ len = strlen(expected);
+ ++len;
+
+ cap = capture_stdio_start(stderr);
+
+ if (!cap.pipe) {
+ ret = -1;
+ goto fail;
+ }
+
+ if (usearg) {
+ func(in, i + 1);
+ } else {
+ func(in);
+ }
+
+ if (!(fgets(buf, sizeof(buf) < len ? sizeof(buf) : len, cap.pipe))) {
+ ret = 1;
+ goto fail;
+ }
+
+fail:
+ capture_stdio_stop(&cap);
+
+ if (ret == -1) {
+ ret = ok(1, "%s: unexpected test program failure on iteration %zu", __func__, i);
+ } else {
+ char *tmp[2];
+
+ ret = strncmp(buf, expected, sizeof(buf) < len ? sizeof(buf) : len);
+
+ tmp[0] = visible_newlines(buf);
+ tmp[1] = visible_newlines(expected);
+
+ ret = ok(ret, "%s: expected: \"%s\", got: \"%s\"", __func__, tmp[1], tmp[0]);
+
+ free(tmp[0]);
+ free(tmp[1]);
+ }
+
+ return ret;
}
diff --git a/test/meson.build b/test/meson.build
index 5e0a100..7864166 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -16,7 +16,13 @@ test('flaot to string', test_e, args : ['float', 'floattohexstring'])
test('double to string', test_e, args : ['float', 'doubletohexstring'])
test('compare floats', test_e, args : ['float', 'comparefloat'])
test('compare doubles', test_e, args : ['float', 'comparedouble'])
-test('diagnostic', test_e, args : ['diagnostic', 'none'])
+test('diagnostic err', test_e, args : ['diagnostic', 'err'])
+test('diagnostic warn', test_e, args : ['diagnostic', 'warn'])
+test('diagnostic fixme', test_e, args : ['diagnostic', 'fixme'])
+test('diagnostic info', test_e, args : ['diagnostic', 'info'])
+test('diagnostic prefix', test_e, args : ['diagnostic', 'prefix'])
+test('diagnostic thread', test_e, args : ['diagnostic', 'thread'])
+test('diagnostic clean', test_e, args : ['diagnostic', 'clean'])
test('timespec add', test_e, args : ['time', 'timespec add'])
test('timespec subtract', test_e, args : ['time', 'timespec sub'])
test('timespec normalize', test_e, args : ['time', 'timespec normalize'])