aboutsummaryrefslogtreecommitdiff
path: root/tests/testing.h
diff options
context:
space:
mode:
Diffstat (limited to 'tests/testing.h')
-rw-r--r--tests/testing.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/tests/testing.h b/tests/testing.h
new file mode 100644
index 0000000..35bfbd2
--- /dev/null
+++ b/tests/testing.h
@@ -0,0 +1,174 @@
+#ifndef OMC_TESTING_H
+#define OMC_TESTING_H
+#include "omc.h"
+#define OMC_TEST_RUN_MAX 10000
+#define OMC_TEST_SUITE_FATAL 1
+#define OMC_TEST_SUITE_SKIP 127
+
+#ifndef __FILE_NAME__
+#define __FILE_NAME__ __FILE__
+#endif
+
+typedef void(OMC_TEST_FUNC)();
+struct omc_test_result_t {
+ const char *filename;
+ const char *funcname;
+ int lineno;
+ const char *msg_assertion;
+ const char *msg_reason;
+ const int status;
+ const int skip;
+} omc_test_results[OMC_TEST_RUN_MAX];
+size_t omc_test_results_i = 0;
+
+void omc_testing_record_result(struct omc_test_result_t result);
+
+void omc_testing_record_result(struct omc_test_result_t result) {
+ memcpy(&omc_test_results[omc_test_results_i], &result, sizeof(result));
+ omc_test_results_i++;
+}
+
+int omc_testing_has_failed() {
+ for (size_t i = 0; i < omc_test_results_i; i++) {
+ if (omc_test_results[i].status == false) {
+ return 1;
+ }
+ }
+ return 0;
+}
+void omc_testing_record_result_summary() {
+ size_t failed = 0;
+ size_t skipped = 0;
+ size_t passed = 0;
+ int do_message;
+ static char status_msg[255] = {0};
+ for (size_t i = 0; i < omc_test_results_i; i++) {
+ if (omc_test_results[i].status && omc_test_results[i].skip) {
+ strcpy(status_msg, "SKIP");
+ do_message = 1;
+ skipped++;
+ } else if (!omc_test_results[i].status) {
+ strcpy(status_msg, "FAIL");
+ do_message = 1;
+ failed++;
+ } else {
+ strcpy(status_msg, "PASS");
+ do_message = 0;
+ passed++;
+ }
+ fprintf(stdout, "[%s] %s:%d :: %s() => %s",
+ status_msg,
+ omc_test_results[i].filename,
+ omc_test_results[i].lineno,
+ omc_test_results[i].funcname,
+ omc_test_results[i].msg_assertion);
+ if (do_message) {
+ fprintf(stdout, "\n \\_ %s", omc_test_results[i].msg_reason);
+ }
+ fprintf(stdout, "\n");
+ }
+ fprintf(stdout, "\n[UNIT] %zu tests passed, %zu tests failed, %zu tests skipped out of %zu\n", passed, failed, skipped, omc_test_results_i);
+}
+
+char *omc_testing_read_ascii(const char *filename) {
+ struct stat st;
+ if (stat(filename, &st)) {
+ perror(filename);
+ return NULL;
+ }
+
+ FILE *fp;
+ fp = fopen(filename, "r");
+ if (!fp) {
+ perror(filename);
+ return NULL;
+ }
+
+ char *result;
+ result = calloc(st.st_size + 1, sizeof(*result));
+ if (fread(result, sizeof(*result), st.st_size, fp) < 1) {
+ perror(filename);
+ fclose(fp);
+ return NULL;
+ }
+
+ fclose(fp);
+ return result;
+}
+
+int omc_testing_write_ascii(const char *filename, const char *data) {
+ FILE *fp;
+ fp = fopen(filename, "w+");
+ if (!fp) {
+ perror(filename);
+ return -1;
+ }
+
+ if (!fprintf(fp, "%s", data)) {
+ perror(filename);
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+#define OMC_TEST_BEGIN_MAIN() do { \
+ setenv("PYTHONUNBUFFERED", "1", 1); \
+ fflush(stdout); \
+ fflush(stderr); \
+ setvbuf(stdout, NULL, _IONBF, 0); \
+ setvbuf(stderr, NULL, _IONBF, 0); \
+ atexit(omc_testing_record_result_summary); \
+ } while (0)
+#define OMC_TEST_END_MAIN() do { return omc_testing_has_failed(); } while (0)
+
+#define OMC_ASSERT(COND, REASON) do { \
+ omc_testing_record_result((struct omc_test_result_t) { \
+ .filename = __FILE_NAME__, \
+ .funcname = __FUNCTION__, \
+ .lineno = __LINE__, \
+ .status = (COND), \
+ .msg_assertion = "ASSERT(" #COND ")", \
+ .msg_reason = REASON } ); \
+ } while (0)
+
+#define OMC_ASSERT_FATAL(COND, REASON) do { \
+ omc_testing_record_result((struct omc_test_result_t) { \
+ .filename = __FILE_NAME__, \
+ .funcname = __FUNCTION__, \
+ .lineno = __LINE__, \
+ .status = (COND), \
+ .msg_assertion = "ASSERT FATAL (" #COND ")", \
+ .msg_reason = REASON } \
+ ); \
+ if (omc_test_results[omc_test_results_i ? omc_test_results_i - 1 : omc_test_results_i].status == false) {\
+ exit(OMC_TEST_SUITE_FATAL); \
+ } \
+ } while (0)
+
+#define OMC_SKIP_IF(COND, REASON) do { \
+ omc_testing_record_result((struct omc_test_result_t) { \
+ .filename = __FILE_NAME__, \
+ .funcname = __FUNCTION__, \
+ .lineno = __LINE__, \
+ .status = true, \
+ .skip = (COND), \
+ .msg_assertion = "SKIP (" #COND ")", \
+ .msg_reason = REASON } \
+ ); \
+ if (omc_test_results[omc_test_results_i ? omc_test_results_i - 1 : omc_test_results_i].skip == true) {\
+ return; \
+ } \
+ } while (0)
+
+#define OMC_TEST_RUN(X) do { \
+ for (size_t i = 0; i < sizeof(X) / sizeof(*X); i++) { \
+ if (X[i]) { \
+ X[i](); \
+ } \
+ } \
+ } while (0)
+
+#endif //OMC_TESTING_H