/* 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: s64; expects_ok: s64; 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) { idx := strings.find_index_from_left(loc.fully_pathed_filename, "./") + 2; path := loc.fully_pathed_filename; path.data += idx; path.count -= idx; basic.print("%,%: %...", path, loc.line_number, name); t: T; proc(*t); if t.failed { basic.print(" failed!\n"); } else { basic.print(" ok!\n"); } } #scope_file; basic :: #import "Basic"; // @future strings :: #import "String"; // @future compiler :: #import "Compiler"; // @future