Simple XUnit test library / objects in plain C Snapshot
cuitestrunner.c
Go to the documentation of this file.
00001 /* Copyright (c) Michael Moser (2011) . 3-clause BSD License applies */
00002 
00003 #include "vtest.h"
00004 #include "vtestrunner.h"
00005 #include "vtestcui.h"
00006 #include <stdio.h>
00007 #include <string.h>
00008 #include <stdarg.h>
00009 
00010 
00011 
00012 static PFN_DEBUG_FUNCTION  debug_output_hook = 0;
00013 
00014 
00015 static void MSG( const char * format, ... )
00016 {
00017   va_list ap;
00018   
00019   va_start(ap, format);
00020   if (!debug_output_hook) {
00021     vfprintf( stdout, format, ap );   
00022   } else {
00023     char big_buf[ 32 * 1024 ];
00024 
00025     vsnprintf( big_buf, sizeof( big_buf ), format, ap );
00026     debug_output_hook( big_buf );
00027     fputs( big_buf, stdout );
00028   }
00029   va_end(ap);
00030 
00031 }
00032 
00033 void VTEST_CUI_set_debug_output_hook( PFN_DEBUG_FUNCTION debug_output_hook_ ) {
00034         debug_output_hook = debug_output_hook_;
00035 }
00036 
00037 void CUI_report_suite_start (const char *suite_name)
00038 {
00039         MSG( "Suite %s\n", suite_name );
00040 }
00041 
00042 void CUI_report_test_start (const char *suite_name, const char *test_name, int iteration, int maxiteration)
00043 {
00044         if (maxiteration == 1) {
00045                 MSG( "  Test: %s/%s started\n", suite_name, test_name);
00046         } else {
00047                 MSG( "  Test: %s/%s started. iteration #%d out of #%d\n", suite_name, test_name, iteration, maxiteration);
00048         }
00049 }
00050 
00051 #ifdef TIME_TEST_GETTIMEOFDAY
00052 
00053 static void format_time( char *time_str, size_t time_str_len, struct timeval *duration)
00054 {
00055    if (duration->tv_sec != 0) {
00056      snprintf(time_str, time_str_len," (Duration - %ld sec %ld micro secs)\n", duration->tv_sec, duration->tv_usec);
00057    } else {
00058      snprintf(time_str, time_str_len," (Duration - %ld micro secs)\n", duration->tv_usec);
00059    }
00060 
00061 }
00062 #endif
00063 
00064 
00065 void CUI_report_results(        VTEST_STATUS status, 
00066                                                 const char *suite_name, const char *test_name,
00067                                                 struct timeval *duration,
00068                                                 const char *fail_cond, const char *fail_file,int fail_line)
00069 {
00070         (void) (test_name);
00071 
00072         switch(status) {
00073                 case VTEST_TEST_OK: {
00074                         #ifdef TIME_TEST_GETTIMEOFDAY
00075                           char msg[100];
00076                           char *ptr;
00077                           size_t size;
00078 
00079                           ptr = msg;
00080                           size = sizeof(msg);
00081 
00082                           strcpy(msg, "    Status: Ok" );
00083                         
00084                           size -= strlen(msg);
00085                           ptr  += strlen(msg);
00086 
00087                           format_time( ptr, size, duration );
00088 
00089                           MSG( msg );
00090                           
00091                         #else
00092                           (void) (duration);
00093                           MSG( "    Status: Ok\n");
00094                         #endif
00095                         }
00096                         break;
00097                 case VTEST_TEST_FAILED:
00098                         MSG( "    Status: Failed - %s at %s:%d\n", 
00099                                                         fail_cond, fail_file, fail_line);
00100                         break;
00101                 case VTEST_SUITE_SETUP_FAILED:
00102                         MSG( "Suite %s setup failed - %s at %s:%d\n",
00103                                                         suite_name, fail_cond, fail_file, fail_line);
00104                         break;
00105 
00106                 case VTEST_SUITE_TEARDOWN_FAILED:
00107                         MSG( "Suite %s teardown failed - %s at %s:%d\n",
00108                                                         suite_name, fail_cond, fail_file, fail_line);
00109                         break;
00110 
00111                 default: {
00112                                  }
00113         }
00114 }
00115 
00116 void CUI_report_wrapup     (int suitesinitfailed, int suitesteardownfailed, 
00117                                                         int tests_passed, int tests_failed, int testnotrun)
00118 {
00119         MSG( "\nTest summary\n"
00120                                    "  Tests passed:                     %d\n"
00121                                    "  Tests failed:                     %d\n"
00122                                    "  Tests not run:            %d (due to suite setup failure)\n"
00123                                    "  Suites setup failed:              %d\n"
00124                                    "  Suites teardown failed:   %d\n",
00125 
00126                                         tests_passed, tests_failed, testnotrun,
00127                                         suitesinitfailed, suitesteardownfailed);
00128 
00129         if (!suitesinitfailed && !suitesteardownfailed && 
00130                 !tests_failed  && !testnotrun) {
00131 
00132                 MSG( "\nALL TESTS PASSED\n");
00133 
00134         } else {
00135 
00136                 MSG( "\n***YOU HAVE TESTS TO FIX***\n");
00137 
00138         }
00139 
00140 }
00141 
00142 int VTEST_CUI_test_runner(VTEST_TEST_SUITE *suite)
00143 {
00144   VTEST_RUNNER_IMPL impl;
00145 
00146   impl.suite_start                      = CUI_report_suite_start;
00147   impl.test_start                       = CUI_report_test_start;
00148   impl.results                          = CUI_report_results;
00149   impl.wrapup                           = CUI_report_wrapup;
00150 
00151   return VTEST_test_runner( suite, &impl );
00152 
00153 }
00154 
00155 int VTEST_CUI_test_runner_cmdline(VTEST_TEST_SUITE *suite, int argc, char *argv[])
00156 {
00157   VTEST_RUNNER_IMPL impl;
00158 
00159   impl.suite_start                      = CUI_report_suite_start;
00160   impl.test_start                       = CUI_report_test_start;
00161   impl.results                          = CUI_report_results;
00162   impl.wrapup                           = CUI_report_wrapup;
00163 
00164   return VTEST_test_runner_cmdline( suite, &impl, argc, argv);
00165 
00166 }
00167 
00168 void VTEST_CUI_list_suite(VTEST_TEST_SUITE *suite)
00169 {
00170         for(;suite; suite = suite->next_suite) {
00171                 MSG( "%s ",suite->name);
00172         }
00173 }
00174 
00175 int VTEST_CUI_list_tests_of_suite(VTEST_TEST_SUITE *suite,const char *suite_name)
00176 {
00177         int ret = 0;
00178         VTEST_TEST *test;
00179                         
00180 
00181         for(;suite; suite = suite->next_suite) {
00182                 if (strcmp(suite->name,suite_name) == 0) {
00183                         ret = 1;
00184 
00185                         for(test = suite->test_cases; test->name != 0; test++) {
00186                                 
00187                                 MSG( "%s ",test->name);
00188                         }
00189                 }
00190         }
00191 
00192         return ret;
00193 }
00194