/*
   A very simple test runner that can be used at compile-time.

   Usage:
      test :: #import "jx/test";

      #if RUN_TESTS #run {
         test.run("collection of tests", t => {
            test.expect(t, some_condition, "error message: %", value);
         });
      }
*/
T :: struct {
   location:    Source_Code_Location;
   expects_run: sint;
   expects_ok:  sint;
   failed:      bool;
}

Proc :: #type (t: *T);

expect :: (t: *T, cond: bool, message := "", args: ..Any, loc := #caller_location) {
   t.expects_run += 1;
   if cond {
      t.expects_ok += 1;
      return;
   }

   msg := "expectation failed";
   if message.count != 0 {
      msg = basic.tprint(message, ..args);
   }

   t.failed = true;
   if #compile_time {
      compiler.compiler_report(msg, loc = loc, mode = .ERROR_CONTINUABLE);
   }
   else {
      basic.assert(false, msg, loc = loc);
   }
}

run :: (name: string, proc: Proc, loc := #caller_location) {
   filename := strings.path_filename(loc.fully_pathed_filename);
   basic.print("%,%: %...", filename, loc.line_number, name);

   t: T;
   proc(*t);

   if t.failed {
      basic.print(" failed!\n");
   }
   else {
      basic.print(" ok!\n");
   }
}


#scope_file;

#import,file "../base.jai";

basic    :: #import "Basic";
strings  :: #import "String";
compiler :: #import "Compiler";
