0001 #include <cgreen/reporter.h>
0002 #include <cgreen/messaging.h>
0003 #include <cgreen/breadcrumb.h>
0004 #include <stdio.h>
0005 #include <string.h>
0006 #include <stdarg.h>
0007 #ifndef __cplusplus
0008 #include <stdbool.h>
0009 #endif
0010 #include <stdio.h>
0011 #include <stdlib.h>
0012
0013 #ifdef __cplusplus
0014 namespace cgreen {
0015 #endif
0016
0017 enum { pass = 1, fail, completion, exception };
0018 enum { FINISH_NOTIFICATION_RECEIVED = 0, FINISH_NOTIFICATION_NOT_RECEIVED };
0019
0020 static TestContext context;
0021
0022 static void show_pass(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments);
0023 static void show_fail(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments);
0024 static void show_incomplete(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments);
0025 static void assert_true(TestReporter *reporter, const char *file, int line, int result, const char *message, ...);
0026 static int read_reporter_results(TestReporter *reporter);
0027
0028 TestReporter *get_test_reporter() {
0029 return context.reporter;
0030 }
0031
0032 void setup_reporting(TestReporter *reporter) {
0033 reporter->ipc = start_cgreen_messaging(45);
0034 context.reporter = reporter;
0035 }
0036
0037 void set_reporter_options(TestReporter *reporter, void *options) {
0038 if (reporter->options != NULL)
0039 free(reporter->options);
0040 reporter->options = options;
0041 }
0042
0043 TestReporter *create_reporter() {
0044 CgreenBreadcrumb *breadcrumb;
0045 TestReporter *reporter = (TestReporter *) malloc(sizeof(TestReporter));
0046 if (reporter == NULL) {
0047 return NULL;
0048 }
0049
0050 breadcrumb = create_breadcrumb();
0051 if (breadcrumb == NULL) {
0052 free(reporter);
0053 return NULL;
0054 }
0055
0056 reporter->destroy = &destroy_reporter;
0057 reporter->start_suite = &reporter_start_suite;
0058 reporter->start_test = &reporter_start;
0059 reporter->show_pass = &show_pass;
0060 reporter->show_fail = &show_fail;
0061 reporter->show_incomplete = &show_incomplete;
0062 reporter->assert_true = &assert_true;
0063 reporter->finish_test = &reporter_finish;
0064 reporter->finish_suite = &reporter_finish_suite;
0065 reporter->passes = 0;
0066 reporter->failures = 0;
0067 reporter->exceptions = 0;
0068 reporter->breadcrumb = breadcrumb;
0069 reporter->memo = NULL;
0070 reporter->options = NULL;
0071 return reporter;
0072 }
0073
0074 void destroy_reporter(TestReporter *reporter) {
0075 destroy_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb);
0076 destroy_memo((TestReportMemo *)reporter->memo);
0077 free(reporter);
0078
0079
0080
0081 if (context.reporter == reporter)
0082 {
0083 context.reporter = NULL;
0084 }
0085 }
0086
0087 void destroy_memo(TestReportMemo *memo) {
0088 if (NULL != memo) {
0089 free(memo);
0090 }
0091 }
0092
0093 void reporter_start(TestReporter *reporter, const char *name) {
0094 push_breadcrumb((CgreenBreadcrumb *) reporter->breadcrumb, name);
0095 }
0096
0097 void reporter_start_suite(TestReporter *reporter, const char *name, const int count) {
0098 (void) count;
0099 reporter_start(reporter, name);
0100 }
0101
0102 void reporter_finish(TestReporter *reporter, const char *filename, int line, const char *message) {
0103 int status = read_reporter_results(reporter);
0104
0105 if (status == FINISH_NOTIFICATION_NOT_RECEIVED) {
0106 va_list no_arguments;
0107 memset(&no_arguments, 0, sizeof(va_list));
0108 reporter->exceptions++;
0109 (*reporter->show_incomplete)(reporter, filename, line, message, no_arguments);
0110 }
0111
0112 pop_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb);
0113 }
0114
0115 void reporter_finish_suite(TestReporter *reporter, const char *filename, int line) {
0116 (void) filename;
0117 (void) line;
0118 read_reporter_results(reporter);
0119 pop_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb);
0120 }
0121
0122 void add_reporter_result(TestReporter *reporter, int result) {
0123 send_cgreen_message(reporter->ipc, result ? pass : fail);
0124 }
0125
0126 void send_reporter_exception_notification(TestReporter *reporter) {
0127 send_cgreen_message(reporter->ipc, exception);
0128 }
0129
0130 void send_reporter_completion_notification(TestReporter *reporter) {
0131 send_cgreen_message(reporter->ipc, completion);
0132 }
0133
0134 static void show_pass(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) {
0135 (void)reporter;
0136 (void)file;
0137 (void)line;
0138 (void)message;
0139 (void)arguments;
0140 }
0141
0142 static void show_fail(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) {
0143 (void)reporter;
0144 (void)file;
0145 (void)line;
0146 (void)message;
0147 (void)arguments;
0148 }
0149
0150 static void show_incomplete(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) {
0151 (void)reporter;
0152 (void)file;
0153 (void)line;
0154 (void)message;
0155 (void)arguments;
0156 }
0157
0158 static const unsigned int MAX_ASSERTIONS_PER_TEST = 8100;
0159
0160 static void assert_true(TestReporter *reporter, const char *file, int line, int result, const char *message, ...) {
0161 va_list arguments;
0162 memset(&arguments, 0, sizeof(va_list));
0163
0164 va_start(arguments, message);
0165 if (result) {
0166 (*reporter->show_pass)(reporter, file, line, message, arguments);
0167 } else {
0168 (*reporter->show_fail)(reporter, file, line, message, arguments);
0169 }
0170
0171 add_reporter_result(reporter, result);
0172 va_end(arguments);
0173 }
0174
0175 static int read_reporter_results(TestReporter *reporter) {
0176 int result;
0177 while ((result = receive_cgreen_message(reporter->ipc)) > 0) {
0178 if (result == pass) {
0179 reporter->passes++;
0180 } else if (result == fail) {
0181 reporter->failures++;
0182 } else if (result == exception) {
0183 reporter->exceptions++;
0184 } else if (result == completion) {
0185
0186 return FINISH_NOTIFICATION_RECEIVED;
0187 }
0188 }
0189
0190 return FINISH_NOTIFICATION_NOT_RECEIVED;
0191 }
0192
0193 #ifdef __cplusplus
0194 }
0195 #endif
0196
0197