/* * portable_basename.test.c * * Also compile `portable_basename.c` and `../benchmarking/clock_hr_microsec.c` * * Author: Intel A80486DX2-66 * License: Unlicense */ #include #include #include #include #include "portable_basename.h" #include "../benchmarking/clock_hr_microsec.h" // global variables uintmax_t tests_failed = 0; // function prototypes static void func_expect(const char* path, const char* expected_output, bool expect_to_succeed); // function implementations static void func_expect(const char* path, const char* expected_output, bool expect_to_succeed) { clock_hr_microsec_t t1 = 0, t2 = 0; t1 = clock_hr_microsec(); char* output = portable_basename(path); t2 = clock_hr_microsec(); if (output == NULL) { perror("portable_basename"); exit(EXIT_FAILURE); } const char* caption = expect_to_succeed ? "Expected output " : "Unexpected output"; clock_hr_microsec_t t = clock_hr_microsec_diff(t2, t1); printf("Input path : '%s'\n" "%s: '%s'\n" "Actual output : '%s'\n" "Time, clock_t : %" CLOCK_HR_MICROSEC_PRI " microsec\n" "Test result : ", path, caption, expected_output, output, t); if ((bool) (strcmp(output, expected_output)) == expect_to_succeed) { tests_failed++; free(output); puts("Failed!\n"); return; } puts("Passed\n"); free(output); fflush(stdout); } // macros #define STRINGIZE(x) #x #define INT2STR(x) STRINGIZE(x) #define TIMES_TO_CALL 65535 int main(void) { clock_hr_microsec_init(); // positive tests func_expect("/", "", true); func_expect("/usr/include/stdlib.h", "stdlib.h", true); func_expect("C:\\Windows\\Fonts\\consola.ttf", "consola.ttf", true); func_expect("\\..\\..\\directory\\.e.x.e.c.u.t.a.b.l.e.", ".e.x.e.c.u.t.a.b.l.e.", true); // negative tests func_expect("/a/.b.c.", "b.c", false); func_expect("/a/.b.c.", ".b.c", false); func_expect("/a/.b.c.", "b.c.", false); func_expect("/a/.b.c.\\", ".b.c.", false); printf("Failed tests: %" PRIuMAX "\n", tests_failed); // timing test puts("\nBenchmarking (" INT2STR(TIMES_TO_CALL) " calls):"); fflush(stdout); #define BENCHMARKING_STRING_SET \ "a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r\\s\\t\\u\\v\\w\\x\\y\\z\\.\\file", \ "/mnt/cdrom/usr/bin/include/library/test_files/test.h" const char* string_set[] = { BENCHMARKING_STRING_SET, // HACK: try to prevent caching by using different pointers BENCHMARKING_STRING_SET, BENCHMARKING_STRING_SET, BENCHMARKING_STRING_SET }; const size_t string_set_len = sizeof(string_set) / sizeof(char*); clock_hr_microsec_t t_beginning = 0, t_end = 0; clock_hr_microsec_t t_total = 0.l; for (uint_fast16_t i = 0; i < TIMES_TO_CALL; i++) { const char* selected_string = string_set[i % string_set_len]; t_beginning = clock_hr_microsec(); char* output = portable_basename(selected_string); t_end = clock_hr_microsec(); if (output == NULL) { perror("portable_basename"); return EXIT_FAILURE; } free(output); t_total += clock_hr_microsec_diff(t_end, t_beginning); } printf("Total time: %" CLOCK_HR_MICROSEC_PRI " microsec, avg. " "%" CLOCK_HR_MICROSEC_PRI "microsec\n", t_total, t_total / ((long double) TIMES_TO_CALL)); return (tests_failed > 0 ? EXIT_FAILURE : EXIT_SUCCESS); }