ref: cefdbe00dfad4086e2f3ba7cd0007d729e77e137
dir: /lib/testr/testr.myr/
use std pkg testr = type ctx = struct ok : bool reason : byte[:] retctx : std.jmpbuf# ;; type spec = struct name : byte[:] fn : (ctx : ctx# -> void) ;; const run : (specs : spec[:] -> void) const check : (ctx : ctx#, cond : bool, msg : byte[:], args : ... -> void) const ok : (ctx : ctx# -> void) const fail : (ctx : ctx#, msg : byte[:], args : ... -> void) const softfail : (ctx : ctx#, msg : byte[:], args : ... -> void) ;; const run = {specs std.put("MTEST {}\n", specs.len) for s in specs runspec(&s) ;; } const check = {ctx, cond, msg, args var ap var msg if !cond ap = std.vastart(&args) failv(ctx, msg, &ap) ;; } const ok = {ctx /* nothing to do here? */ } const fail = {ctx, msg, args var ap ap = std.vastart(&args) failv(ctx, msg, &ap) } const softfail = {ctx, msg, args var ap ap = std.vastart(&args) softfailv(ctx, msg, &ap) } const failv = {ctx, msg, ap softfailv(ctx, msg, ap) std.longjmp(ctx.retctx) } const softfailv = {ctx, msg, ap ctx.ok = false ctx.reason = std.fmtv(msg, ap) } const runspec = {ts var status, reason, jbuf var ctx : ctx ctx.ok = true ctx.reason = "" ctx.retctx = &jbuf std.put("test {} <<{{!\n", ts.name) if !std.setjmp(&jbuf) ts.fn(&ctx) ;; if ctx.ok status = "ok" reason = "" else status = "fail" reason = ctx.reason ;; std.put("!}}>> {} {}\n", status, reason) std.slfree(reason) }