Răsfoiți Sursa

Test system

Kajetan Johannes Hammerle 2 săptămâni în urmă
părinte
comite
a02814f10b
10 a modificat fișierele cu 172 adăugiri și 6 ștergeri
  1. 4 3
      CMakeLists.txt
  2. 7 2
      src/Code.c
  3. 2 0
      src/Code.h
  4. 23 0
      src/Colors.h
  5. 11 1
      src/Main.c
  6. 1 0
      test/Add.basic
  7. 1 0
      test/Add.basic_result
  8. 3 0
      test/Print.basic
  9. 3 0
      test/Print.basic_result
  10. 117 0
      test/Test.c

+ 4 - 3
CMakeLists.txt

@@ -52,6 +52,7 @@ elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
 endif()
 
 add_executable(${PROJECT_NAME} ${SRC})
-target_compile_options(${PROJECT_NAME} PUBLIC
-    ${COMPILER_ARGUMENTS}
-)
+target_compile_options(${PROJECT_NAME} PUBLIC ${COMPILER_ARGUMENTS})
+
+add_executable(test test/Test.c)
+target_compile_options(test PUBLIC ${COMPILER_ARGUMENTS})

+ 7 - 2
src/Code.c

@@ -6,6 +6,11 @@ static u8 code[MAX_CODE];
 static size_t codeIndex = 0;
 static size_t codeExecutionIndex = 0;
 
+void resetCode() {
+    codeIndex = 0;
+    codeExecutionIndex = 0;
+}
+
 static bool pushU8(u8 u) {
     if(codeIndex >= MAX_CODE) {
         return true;
@@ -52,13 +57,13 @@ static void read(void* p, size_t n) {
 }
 
 i64 readI64() {
-    i64 i;
+    i64 i = 0;
     read(&i, sizeof(i));
     return i;
 }
 
 size_t readSize() {
-    size_t i;
+    size_t i = 0;
     read(&i, sizeof(i));
     return i;
 }

+ 2 - 0
src/Code.h

@@ -11,6 +11,8 @@ typedef enum : u8 {
     STOP
 } Instruction;
 
+void resetCode();
+
 [[nodiscard]] bool pushInstruction(Instruction i);
 [[nodiscard]] bool pushI64(i64 i);
 [[nodiscard]] bool pushSize(size_t i);

+ 23 - 0
src/Colors.h

@@ -0,0 +1,23 @@
+#ifndef BASIC_COLORS_H
+#define BASIC_COLORS_H
+
+#define TC_RESET "\33[0m"
+#define TC_BOLD "\33[1m"
+#define TC_BLACK "\33[30m"
+#define TC_RED "\33[31m"
+#define TC_GREEN "\33[32m"
+#define TC_YELLOW "\33[33m"
+#define TC_BLUE "\33[34m"
+#define TC_MAGENTA "\33[35m"
+#define TC_CYAN "\33[36m"
+#define TC_WHITE "\33[37m"
+#define TC_BRIGHT_BLACK "\33[90m"
+#define TC_BRIGHT_RED "\33[91m"
+#define TC_BRIGHT_GREEN "\33[92m"
+#define TC_BRIGHT_YELLOW "\33[93m"
+#define TC_BRIGHT_BLUE "\33[94m"
+#define TC_BRIGHT_MAGENTA "\33[95m"
+#define TC_BRIGHT_CYAN "\33[96m"
+#define TC_BRIGHT_WHITE "\33[97m"
+
+#endif

+ 11 - 1
src/Main.c

@@ -1,5 +1,6 @@
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "Code.h"
 #include "Values.h"
@@ -43,7 +44,16 @@ static bool execute(Instruction command) {
     return false;
 }
 
-int main(void) {
+int main(int argCount, const char** args) {
+    if(argCount < 2) {
+        return 0;
+    }
+    if(argCount >= 2 && strcmp(args[1], "help") == 0) {
+        return 0;
+    }
+    printf("RUNNING TEST %s\n", args[1]);
+    return 0;
+
     (void)pushInstruction(PUSH_INT);
     (void)pushI64(16);
     (void)pushInstruction(PUSH_INT);

+ 1 - 0
test/Add.basic

@@ -0,0 +1 @@
+print 1 + 20

+ 1 - 0
test/Add.basic_result

@@ -0,0 +1 @@
+21

+ 3 - 0
test/Print.basic

@@ -0,0 +1,3 @@
+print "Hi"
+print 6
+print "Hi there " 8 "great"

+ 3 - 0
test/Print.basic_result

@@ -0,0 +1,3 @@
+Hi
+6
+Hi there 8 great

+ 117 - 0
test/Test.c

@@ -0,0 +1,117 @@
+#define _POSIX_C_SOURCE 1
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../src/Colors.h"
+
+static bool endsWith(const char* s, const char* end) {
+    size_t a = strlen(s);
+    size_t b = strlen(end);
+    if(a < b) {
+        return false;
+    }
+    return strcmp(s + (a - b), end) == 0;
+}
+
+static void printTests() {
+    const char* path = "./test";
+    DIR* d = opendir(path);
+    if(d == nullptr) {
+        return;
+    }
+    while(true) {
+        struct dirent* file = readdir(d);
+        if(file == nullptr) {
+            break;
+        }
+        if(endsWith(file->d_name, ".basic")) {
+            printf("%s/%s\n", path, file->d_name);
+        }
+    }
+    closedir(d);
+}
+
+static void printUntilNewline(const char* s) {
+    while(*s != '\n' && *s != '\0') {
+        putchar(*(s++));
+    }
+}
+
+static void compareStreams(FILE* file, FILE* result) {
+    bool diff = false;
+    int line = 0;
+    while(true) {
+        line++;
+        char bufferA[256] = {};
+        char bufferB[256] = {};
+        char* r1 = fgets(bufferA, sizeof(bufferA), file);
+        char* r2 = fgets(bufferB, sizeof(bufferB), result);
+        if(r1 == nullptr && r2 == nullptr) {
+            break;
+        }
+        if(strcmp(bufferA, bufferB) != 0) {
+            printf(TC_RED "Line %d differs '", line);
+            printUntilNewline(bufferA);
+            printf("' vs '");
+            printUntilNewline(bufferB);
+            puts("'" TC_RESET);
+            diff = true;
+        }
+    }
+    if(!diff) {
+        puts(TC_GREEN "Success" TC_RESET);
+    }
+}
+
+int main(int argCount, const char** args) {
+    if(argCount < 2) {
+        return 0;
+    } else if(strcmp(args[1], "help") == 0) {
+        printTests();
+        return 0;
+    }
+    int fd[2];
+    if(pipe(fd) == -1) {
+        puts("pipe failed");
+        return 1;
+    }
+    pid_t f = fork();
+    if(f == 0) { // child
+        close(fd[0]);
+        dup2(fd[1], STDOUT_FILENO);
+        close(fd[1]);
+#ifdef NDEBUG
+        const char* path = "./build_release/basic";
+#else
+        const char* path = "./build_debug/basic";
+#endif
+        execlp(path, path, args[1], (char*)nullptr);
+        puts("execlp failed");
+        exit(1);
+    } else if(f == -1) { // failure
+        puts("fork failed");
+        exit(1);
+    }
+    close(fd[1]);
+
+    char resultPath[256];
+    snprintf(resultPath, sizeof(resultPath), "%s_result", args[1]);
+    FILE* file = fopen(resultPath, "r");
+    if(file == nullptr) {
+        printf(TC_RED "'%s' does not exist" TC_RESET "\n", resultPath);
+        return 1;
+    }
+    FILE* result = fdopen(fd[0], "r");
+    if(result == nullptr) {
+        puts("Cannot map file descriptor");
+    } else {
+        compareStreams(file, result);
+        fclose(result);
+    }
+    fclose(file);
+    return 1;
+}