00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023
00024
00025
00026
00027
00028 #include <irplib_test.h>
00029
00030
00031 #include <irplib_utils.h>
00032
00033 #include <cpl.h>
00034
00035
00036 #include <math.h>
00037
00038 #include <string.h>
00039
00040
00041 #include <time.h>
00042
00043 #ifndef CPL_HAS_UNIT_TEST
00044
00045
00049
00050
00051
00052
00053
00054
00058 static unsigned long irplib_test_nfail = 0;
00059 static clock_t irplib_test_start;
00060
00061
00070
00071 static void
00072 test(int expression, const char *message,
00073 const char *function, const char *file, unsigned line)
00074 {
00075 const char *error_state = (cpl_error_get_code() != CPL_ERROR_NONE) ?
00076 irplib_sprintf(" (CPL-error state: '%s' at %s)",
00077 cpl_error_get_message(), cpl_error_get_where()) :
00078 NULL;
00079
00080 if (expression) {
00081 cpl_msg_debug(function,
00082 "OK at %s:%u%s: %s",
00083 file, line, error_state != NULL ? error_state : "",
00084 message);
00085 } else {
00086 if (irplib_test_nfail + 1 > irplib_test_nfail) {
00087 irplib_test_nfail++;
00088 }
00089 else {
00090 cpl_msg_error(function, "Number of errors (%lu) overflow!",
00091 irplib_test_nfail);
00092 }
00093
00094 cpl_msg_error(function,
00095 "Failure at %s:%u%s: %s",
00096 file, line, error_state != NULL ? error_state : "",
00097 message);
00098 }
00099
00100 if (error_state != NULL)
00101 {
00102 cpl_free((char *)error_state);
00103 }
00104
00105 return;
00106 }
00107
00108
00109
00119
00120 void
00121 irplib_test_macro(int expression, const char *expr_string,
00122 const char *function, const char *file, unsigned line)
00123 {
00124 const char *message = irplib_sprintf("(%s) = %d", expr_string, expression);
00125
00126 test(expression, message,
00127 function, file, line);
00128
00129 cpl_free((char *)message);
00130
00131 return;
00132 }
00133
00134
00146
00147 void
00148 irplib_test_eq_macro(int first, const char *first_string,
00149 int second, const char *second_string,
00150 const char *function, const char *file, unsigned line)
00151 {
00152 const char *message =
00153 irplib_sprintf("(%s) = %d; (%s) = %d",
00154 first_string, first,
00155 second_string, second);
00156
00157 test(first == second, message,
00158 function, file, line);
00159
00160 cpl_free((char *)message);
00161
00162 return;
00163 }
00164
00165
00177
00178 void
00179 irplib_test_eq_string_macro(const char *first, const char *first_string,
00180 const char *second, const char *second_string,
00181 const char *function,
00182 const char *file, unsigned line)
00183 {
00184 const char *message;
00185
00186 message = irplib_sprintf("%s = '%s'; %s = '%s'",
00187 first_string, first != NULL ? first : "NULL",
00188 second_string, second != NULL ? second : "NULL");
00189
00190 test(first != NULL && second != NULL && strcmp(first, second) == 0,
00191 message,
00192 function, file, line);
00193
00194 cpl_free((char *)message);
00195
00196 return;
00197 }
00198
00199
00215
00216 void
00217 irplib_test_abs_macro(double first, const char *first_string,
00218 double second, const char *second_string,
00219 double tolerance, const char *tolerance_string,
00220 const char *function, const char *file, unsigned line)
00221 {
00222 const char *message =
00223 irplib_sprintf("|%s - (%s)| = |%g - (%g)| <= %g = %s",
00224 first_string, second_string, first, second,
00225 tolerance, tolerance_string);
00226
00227 test(fabs(first - second) <= tolerance, message,
00228 function, file, line);
00229
00230
00231 cpl_free((char *)message);
00232
00233 return;
00234 }
00235
00236
00252
00253 void
00254 irplib_test_rel_macro(double first, const char *first_string,
00255 double second, const char *second_string,
00256 double tolerance, const char *tolerance_string,
00257 const char *function, const char *file, unsigned line)
00258 {
00259 const char *message;
00260
00261 if (first == 0 || second == 0) {
00262
00263 message = irplib_sprintf("%s = %g; %s = %g (division by zero)",
00264 first_string, first,
00265 second_string, second);
00266 test(0, message,
00267 function, file, line);
00268 }
00269 else {
00270 message =
00271 irplib_sprintf("|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s and "
00272 "|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s",
00273 first_string, second_string, first_string,
00274 first, second, first, tolerance, tolerance_string,
00275 first_string, second_string, second_string,
00276 first, second, second, tolerance, tolerance_string);
00277
00278 test(fabs((first - second)/first ) <= tolerance &&
00279 fabs((first - second)/second) <= tolerance, message,
00280 function, file, line);
00281
00282 }
00283
00284 cpl_free((char *)message);
00285
00286 return;
00287 }
00288
00289
00290
00297
00298 void
00299 irplib_test_init_macro(const char *file)
00300 {
00301
00302
00303
00304 unsigned len = strlen(file);
00305 int able_to_parse_filename;
00306
00307 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 0, 0)
00308 cpl_init(CPL_INIT_DEFAULT);
00309 #else
00310 cpl_init();
00311 #endif
00312 irplib_reset();
00313
00314 if (len < strlen("s.c") || strcmp(file + len - strlen(".c"), ".c") != 0)
00315 {
00316 able_to_parse_filename = 0;
00317
00318
00319 }
00320 else
00321 {
00322
00323
00324
00325 const char dir_delimiter = '/';
00326 unsigned path_length = 0;
00327
00328 int i;
00329
00330 for (i = len - strlen(".c") - 1; i >= 0; i--)
00331 {
00332 if (file[i] == dir_delimiter && path_length == 0)
00333 {
00334 path_length = i + 1;
00335 }
00336 }
00337
00338 able_to_parse_filename = (len - path_length - strlen(".c") >= 1);
00339 if (able_to_parse_filename)
00340 {
00341 const char *logfile;
00342 char *domain;
00343
00344 domain = cpl_strdup(file + path_length);
00345 domain[len - path_length - strlen(".c")] = '\0';
00346
00347 cpl_msg_set_domain(domain);
00348
00349 logfile = irplib_sprintf("%s.log", domain);
00350 cpl_msg_set_log_name(logfile);
00351
00352 cpl_free((char *)logfile);
00353 cpl_free(domain);
00354 }
00355
00356 }
00357
00358
00359
00360
00361 cpl_msg_set_level(CPL_MSG_WARNING);
00362 cpl_msg_set_log_level(CPL_MSG_DEBUG);
00363
00364 if (!able_to_parse_filename)
00365 {
00366 cpl_msg_warning(cpl_func,
00367 "Source file name '%s' does not match [base].c. ",
00368 file);
00369 }
00370
00371 if (cpl_error_get_code() != CPL_ERROR_NONE)
00372 {
00373 cpl_msg_error(cpl_func,
00374 "Failure during initialization: %s at %s",
00375 cpl_error_get_message(), cpl_error_get_where());
00376 }
00377
00378 irplib_test_start = clock();
00379
00380 return;
00381 }
00382
00383
00393
00394 unsigned
00395 irplib_test_end_macro(const char *function, const char *file, unsigned line)
00396 {
00397 const clock_t time_to_test = clock() - irplib_test_start;
00398 const int memory_is_empty = cpl_memory_is_empty();
00399
00400 cpl_msg_info(cpl_func, "Time to test [s]: %g",
00401 (double)time_to_test/CLOCKS_PER_SEC);
00402
00403 irplib_test_eq_macro(cpl_error_get_code(), "cpl_error_get_code()",
00404 CPL_ERROR_NONE, "CPL_ERROR_NONE",
00405 function, file, line);
00406
00407 irplib_test_macro(memory_is_empty,
00408 "memory_is_empty",
00409 function, file, line);
00410
00411 if (!memory_is_empty) {
00412 cpl_msg_error(function, "Memory leak detected:");
00413 cpl_memory_dump();
00414 }
00415
00416 cpl_end();
00417
00418 return irplib_test_nfail;
00419 }
00420
00423 #endif