Test.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #define _POSIX_C_SOURCE 1
  2. #include <dirent.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <unistd.h>
  8. #include "../src/Colors.h"
  9. static bool endsWith(const char* s, const char* end) {
  10. size_t a = strlen(s);
  11. size_t b = strlen(end);
  12. if(a < b) {
  13. return false;
  14. }
  15. return strcmp(s + (a - b), end) == 0;
  16. }
  17. static void printTests() {
  18. const char* path = "./test";
  19. DIR* d = opendir(path);
  20. if(d == nullptr) {
  21. return;
  22. }
  23. while(true) {
  24. struct dirent* file = readdir(d);
  25. if(file == nullptr) {
  26. break;
  27. }
  28. if(endsWith(file->d_name, ".basic")) {
  29. printf("%s/%s\n", path, file->d_name);
  30. }
  31. }
  32. closedir(d);
  33. }
  34. static void printUntilNewline(const char* s) {
  35. while(*s != '\n' && *s != '\0') {
  36. putchar(*(s++));
  37. }
  38. }
  39. static void compareStreams(FILE* file, FILE* result) {
  40. bool diff = false;
  41. int line = 0;
  42. while(true) {
  43. line++;
  44. char bufferA[256] = {};
  45. char bufferB[256] = {};
  46. char* r1 = fgets(bufferA, sizeof(bufferA), file);
  47. char* r2 = fgets(bufferB, sizeof(bufferB), result);
  48. if(r1 == nullptr && r2 == nullptr) {
  49. break;
  50. }
  51. if(strcmp(bufferA, bufferB) != 0) {
  52. printf(TC_RED "Line %d differs '", line);
  53. printUntilNewline(bufferA);
  54. printf("' vs '");
  55. printUntilNewline(bufferB);
  56. puts("'" TC_RESET);
  57. diff = true;
  58. }
  59. }
  60. if(!diff) {
  61. puts(TC_GREEN "Success" TC_RESET);
  62. }
  63. }
  64. int main(int argCount, const char** args) {
  65. if(argCount < 2) {
  66. return 0;
  67. } else if(strcmp(args[1], "help") == 0) {
  68. printTests();
  69. return 0;
  70. }
  71. int fd[2];
  72. if(pipe(fd) == -1) {
  73. puts("pipe failed");
  74. return 1;
  75. }
  76. pid_t f = fork();
  77. if(f == 0) { // child
  78. close(fd[0]);
  79. dup2(fd[1], STDOUT_FILENO);
  80. close(fd[1]);
  81. #ifdef NDEBUG
  82. const char* path = "./build_release/basic";
  83. #else
  84. const char* path = "./build_debug/basic";
  85. #endif
  86. execlp(path, path, args[1], (char*)nullptr);
  87. puts("execlp failed");
  88. exit(1);
  89. } else if(f == -1) { // failure
  90. puts("fork failed");
  91. exit(1);
  92. }
  93. close(fd[1]);
  94. char resultPath[256];
  95. snprintf(resultPath, sizeof(resultPath), "%s_result", args[1]);
  96. FILE* file = fopen(resultPath, "r");
  97. if(file == nullptr) {
  98. printf(TC_RED "'%s' does not exist" TC_RESET "\n", resultPath);
  99. return 1;
  100. }
  101. FILE* result = fdopen(fd[0], "r");
  102. if(result == nullptr) {
  103. puts("Cannot map file descriptor");
  104. } else {
  105. compareStreams(file, result);
  106. fclose(result);
  107. }
  108. fclose(file);
  109. return 1;
  110. }