#include "test.h"

static int num_tests = 0;
static struct Test tests[128];
static int longest_test_name = 0;

void test(int (*function)(), char *test_name) {
  int test_name_length = strlen(test_name);
  if (test_name_length > longest_test_name) {
    longest_test_name = test_name_length;
  }

  pid_t pid = fork();
  if (pid == 0) {
    // test process
    int exit_status = function();
    exit(exit_status);
  } else {
    int status;
    waitpid(pid, &status, 0);

    struct Test test;
    strcpy(test.name, test_name);

    if (WIFEXITED(status)) {
      int exit_status = WEXITSTATUS(status);
      if (exit_status == 0) {
	test.failed = 0;
	strcpy(test.result_msg, "passed");
      } else {
	test.failed = 1;
	strcpy(test.result_msg,  "FAILED");
      }
    } else if (WIFSIGNALED(status)) {
      test.failed = 1;
      strcpy(test.result_msg, "ERROR!");
    }

    tests[num_tests++] = test;
  }
}

int test_summary() {
  unsigned char at_least_one_test_failed = 0;
  int num_failed = 0;
  puts("---------------------------------");
  puts("Test results:");
  puts("");
  int i = 0;
  for (i = 0; i < num_tests; i += 1) {
    printf("#%3d: %-*s (%s)\n", i + 1, longest_test_name, tests[i].name, tests[i].result_msg);
    num_failed += tests[i].failed;
    at_least_one_test_failed |= tests[i].failed;
  }
  puts("");
  printf("Total: %3d of %-3d tests passed\n", num_tests - num_failed, num_tests);
  puts("---------------------------------");
  num_tests = 0;
  longest_test_name = 0;
  return at_least_one_test_failed;
}