From 8dba3f7f3591f4271522835cb2057acf4ae56f53 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 18 Nov 2014 18:37:56 +0100
Subject: Start with tests for the C API

The C API tests can be run individually via

    build/api_test/api_test

Or together with the spec tests via

    cmake --build build --target test
---
 api_test/CMakeLists.txt |  11 ++++++
 api_test/harness.c      | 102 ++++++++++++++++++++++++++++++++++++++++++++++++
 api_test/harness.h      |  34 ++++++++++++++++
 api_test/main.c         |  57 +++++++++++++++++++++++++++
 4 files changed, 204 insertions(+)
 create mode 100644 api_test/CMakeLists.txt
 create mode 100644 api_test/harness.c
 create mode 100644 api_test/harness.h
 create mode 100644 api_test/main.c

(limited to 'api_test')

diff --git a/api_test/CMakeLists.txt b/api_test/CMakeLists.txt
new file mode 100644
index 0000000..7b6c3d6
--- /dev/null
+++ b/api_test/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(api_test
+  harness.c
+  main.c
+)
+target_include_directories(api_test
+  PRIVATE
+  ${PROJECT_SOURCE_DIR}/src
+  ${PROJECT_BINARY_DIR}/src
+)
+target_link_libraries(api_test libcmark)
+
diff --git a/api_test/harness.c b/api_test/harness.c
new file mode 100644
index 0000000..6b38d41
--- /dev/null
+++ b/api_test/harness.c
@@ -0,0 +1,102 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "harness.h"
+
+test_batch_runner*
+test_batch_runner_new()
+{
+	return (test_batch_runner *)calloc(1, sizeof(test_batch_runner));
+}
+
+static void
+test_result(test_batch_runner *runner, int cond, const char *msg, va_list ap)
+{
+	++runner->test_num;
+
+	if (cond) {
+		++runner->num_passed;
+	}
+	else {
+		fprintf(stderr, "FAILED test %d: ", runner->test_num);
+		vfprintf(stderr, msg, ap);
+		fprintf(stderr, "\n");
+		++runner->num_failed;
+	}
+}
+
+void
+SKIP(test_batch_runner *runner, int num_tests)
+{
+	runner->test_num    += num_tests;
+	runner->num_skipped += num_tests;
+}
+
+void
+OK(test_batch_runner *runner, int cond, const char *msg, ...)
+{
+	va_list ap;
+	va_start(ap, msg);
+	test_result(runner, cond, msg, ap);
+	va_end(ap);
+}
+
+void
+INT_EQ(test_batch_runner *runner, int got, int expected, const char *msg, ...)
+{
+	int cond = got == expected;
+
+	va_list ap;
+	va_start(ap, msg);
+	test_result(runner, cond, msg, ap);
+	va_end(ap);
+
+	if (!cond) {
+		fprintf(stderr, "  Got:      %d\n", got);
+		fprintf(stderr, "  Expected: %d\n", expected);
+	}
+}
+
+void
+STR_EQ(test_batch_runner *runner, const char *got, const char *expected,
+       const char *msg, ...)
+{
+	int cond = strcmp(got, expected) == 0;
+
+	va_list ap;
+	va_start(ap, msg);
+	test_result(runner, cond, msg, ap);
+	va_end(ap);
+
+	if (!cond) {
+		fprintf(stderr, "  Got:      \"%s\"\n", got);
+		fprintf(stderr, "  Expected: \"%s\"\n", expected);
+	}
+}
+
+int
+test_ok(test_batch_runner *runner)
+{
+	return runner->num_failed == 0;
+}
+
+void
+test_print_summary(test_batch_runner *runner)
+{
+	int num_passed  = runner->num_passed;
+	int num_skipped = runner->num_skipped;
+	int num_failed  = runner->num_failed;
+
+	fprintf(stderr, "%d tests passed, %d failed, %d skipped\n",
+		num_passed, num_skipped, num_failed);
+
+	if (test_ok(runner)) {
+		fprintf(stderr, "PASS\n");
+	}
+	else {
+		fprintf(stderr, "FAIL\n");
+	}
+}
+
diff --git a/api_test/harness.h b/api_test/harness.h
new file mode 100644
index 0000000..5fdc7ae
--- /dev/null
+++ b/api_test/harness.h
@@ -0,0 +1,34 @@
+#ifndef CMARK_API_TEST_HARNESS_H
+#define CMARK_API_TEST_HARNESS_H
+
+typedef struct {
+	int test_num;
+	int num_passed;
+	int num_failed;
+	int num_skipped;
+} test_batch_runner;
+
+test_batch_runner*
+test_batch_runner_new();
+
+void
+SKIP(test_batch_runner *runner, int num_tests);
+
+void
+OK(test_batch_runner *runner, int cond, const char *msg, ...);
+
+void
+INT_EQ(test_batch_runner *runner, int got, int expected, const char *msg, ...);
+
+void
+STR_EQ(test_batch_runner *runner, const char *got, const char *expected,
+       const char *msg, ...);
+
+int
+test_ok(test_batch_runner *runner);
+
+void
+test_print_summary(test_batch_runner *runner);
+
+#endif
+
diff --git a/api_test/main.c b/api_test/main.c
new file mode 100644
index 0000000..051d32b
--- /dev/null
+++ b/api_test/main.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cmark.h>
+
+#include "harness.h"
+
+static void
+create_tree(test_batch_runner *runner)
+{
+	cmark_node *doc = cmark_node_new(CMARK_NODE_DOCUMENT);
+
+	cmark_node *p = cmark_node_new(CMARK_NODE_PARAGRAPH);
+	OK(runner, cmark_node_append_child(doc, p), "append1");
+	INT_EQ(runner, cmark_node_check(doc), 0, "append1 consistent");
+
+	cmark_node *emph = cmark_node_new(CMARK_NODE_EMPH);
+	OK(runner, cmark_node_prepend_child(p, emph), "prepend1");
+	INT_EQ(runner, cmark_node_check(doc), 0, "prepend1 consistent");
+
+	cmark_node *str1 = cmark_node_new(CMARK_NODE_STRING);
+	cmark_node_set_content(str1, "Hello, ");
+	OK(runner, cmark_node_prepend_child(p, str1), "prepend2");
+	INT_EQ(runner, cmark_node_check(doc), 0, "prepend2 consistent");
+
+	cmark_node *str3 = cmark_node_new(CMARK_NODE_STRING);
+	cmark_node_set_content(str3, "!");
+	OK(runner, cmark_node_append_child(p, str3), "append2");
+	INT_EQ(runner, cmark_node_check(doc), 0, "append2 consistent");
+
+	cmark_node *str2 = cmark_node_new(CMARK_NODE_STRING);
+	cmark_node_set_content(str2, "world");
+	OK(runner, cmark_node_append_child(emph, str2), "append3");
+	INT_EQ(runner, cmark_node_check(doc), 0, "append3 consistent");
+
+	char *html = cmark_render_html(doc);
+	STR_EQ(runner, html, "<p>Hello, <em>world</em>!</p>\n",
+	       "render_html");
+	free(html);
+
+	cmark_node_destroy(doc);
+}
+
+int main() {
+	int retval;
+	test_batch_runner *runner = test_batch_runner_new();
+
+	create_tree(runner);
+
+	test_print_summary(runner);
+	retval =  test_ok(runner) ? 0 : 1;
+	free(runner);
+
+	return retval;
+}
+
-- 
cgit v1.2.3