ref: 04d647955b3d83e2fb3731d63887ae499809141e
dir: /mbld/test.myr/
use std use "build.use" use "clean.use" use "deps.use" use "opts.use" use "parse.use" use "types.use" use "util.use" use "config.use" pkg bld = const test : (b : build# -> void) ;; const test = {b var ok, bin, hastest /* no implicit tests to run */ ok = true hastest = false if std.fexists("test") hastest = true for tn in b.all match gettarg(b.targs, tn) | `Bin bt: if !dotest(b, bt) ok = false ;; | `Lib lt: if !dotest(b, lt) ok = false ;; | _: /* ignore */ ;; ;; ;; for tn in b.all match gettarg(b.targs, tn) | `Test t: hastest = true if t.incpath.len == 0 || !std.sleq(t.incpath[0], ".") t.incpath = std.slput(t.incpath, 0, std.sldup(".")) ;; buildbin(b, t, false) | _: /* skip */ ;; ;; for tn in b.all match gettarg(b.targs, tn) | `Test t: setdir(b, t.dir) bin = std.strcat("./", t.name) if !runtest(bin) ok = false ;; std.slfree(bin) | _: /* skip */ ;; ;; if hastest if ok std.put("TESTS PASSED\n") else std.put("TESTS FAILED\n") std.exit(1) ;; ;; } const dotest = {b, targ var tt, bin ,path, tests, ok tests = [][:] setdir(b, targ.dir) for s in targ.inputs path = std.pathcat("./test", s) if std.fexists(path) bin = srcswapsuffix(path, "") tt = [ .name = bin, .dir = targ.dir, .inputs = [path][:], .install = false, .libdeps = targ.libdeps, .incpath = targ.incpath, ] cleantest(b, path) buildbin(b, &tt, true) tests = std.slpush(tests, bin) ;; std.slfree(path) ;; ok = true for t in tests if !runtest(t) ok = false ;; std.slfree(t) ;; std.slfree(tests) std.put("test {}: {}\n", targ.name, ok) -> ok } const cleantest = {b, src var obj, bin, log, usef obj = srcswapsuffix(src, config.Objsuffix) log = srcswapsuffix(src, ".log") usef = srcswapsuffix(src, ".use") bin = srcswapsuffix(src, "") std.remove(obj) std.remove(usef) std.remove(log) std.remove(bin) std.slfree(obj) std.slfree(usef) std.slfree(log) std.slfree(bin) } const runtest = {bin var r, log std.put("run {}:\t", bin) log = std.strcat(bin, ".log") match std.spork([bin][:]) | `std.Fail m: std.fatal("unable to run test: {}\n", m) | `std.Ok (pid, infd, outfd): match std.fslurp(outfd) | `std.Ok "": /* empty output; nothing to log */ | `std.Ok buf: std.blat(log, buf, 0o644) | `std.Fail m: ;; std.slfree(log) r = false match std.wait(pid) | `std.Wfailure: std.put("FAIL\n") | `std.Wsignalled: std.put("CRASH\n") | `std.Wsuccess: std.put("PASS\n") r = true | _: std.put("???\n") ;; ;; -> r }