ref: 1ed38b41793a7e5eac6c8280749ccf066577fa68
dir: /lib/testr/testr.myr/
use std pkg testr = type ctx = struct ok : bool reason : byte[:] jmpbuf : std.jmpbuf# ;; type spec = struct name : byte[:] fn : (ctx : ctx# -> void) ;; const run : (specs : spec[:] -> void) const bench : (specs : spec[:] -> void) const ok : (ctx : ctx# -> void) const fail : (ctx : ctx#, msg : byte[:], args : ... -> void) const check : (ctx : ctx#, cond : bool, msg : byte[:], args : ... -> void) const softfail : (ctx : ctx#, msg : byte[:], args : ... -> void) ;; const bench = {specs std.put("MTEST {}\n", specs.len) for s : specs benchspec(&s) ;; } const run = {specs std.put("MTEST {}\n", specs.len) for s : specs testspec(&s) ;; } const ok = {ctx /* nothing to do here */ } const check = {ctx, cond, msg, args var ap if !cond ap = std.vastart(&args) failv(ctx, msg, &ap) ;; } const fail = {ctx, msg, args var ap ap = std.vastart(&args) failv(ctx, msg, &ap) } const failv = {ctx, msg, ap softfailv(ctx, msg, ap) std.longjmp(ctx.jmpbuf) } const softfail = {ctx, msg, args var ap ap = std.vastart(&args) softfailv(ctx, msg, &ap) } const softfailv = {ctx, msg, ap /* keep the first failure */ if ctx.ok ctx.ok = false ctx.reason = std.fmtv(msg, ap) ;; } const benchspec = {ts var avg, m, d, n, nsamp var start, dt var ctx : ctx var jmpbuf ctx.ok = true ctx.reason = "" ctx.jmpbuf = &jmpbuf avg = 0.0; m = 0.0; n = 0.0; nsamp = 0 std.put("test {} <<{{!\n", ts.name) if !std.setjmp(&jmpbuf) /* estimate samples */ start = std.now() ts.fn(&ctx) dt = (std.now() - start : flt64) if dt == 0.0 nsamp = 1000_000 else nsamp = (100_000.0/dt : int64) nsamp = std.max(10, nsamp) ;; for var i = 0; i < nsamp; i++ n +=1.0; start = std.now() ts.fn(&ctx) dt = (std.now() - start : flt64)/1_000_000.0 d = (dt - avg); avg = avg + d/n; m = m + d*(dt - avg); ;; ;; if ctx.ok std.put("!}}>> timing {} {} {}\n", nsamp, avg, m) else std.put("!}}>> fail {}\n", ctx.reason) std.slfree(ctx.reason) ;; } const testspec = {ts var ctx : ctx var jmpbuf ctx.ok = true ctx.reason = "" ctx.jmpbuf = &jmpbuf std.put("test {} <<{{!\n", ts.name) if !std.setjmp(&jmpbuf) ts.fn(&ctx) ;; if ctx.ok std.put("!}}>> ok\n") else std.put("!}}>> fail {}\n", ctx.reason) std.slfree(ctx.reason) ;; }