(ns ird.p2p.db.test-util
"Macro half of the test utilities: `deftest-async`.")
(defmacro deftest-async
"cljs.test deftest whose body runs inside a go block (via
ird.p2p.async/go-try) and may use <! / <?. The test finishes when the
body delivers; an error value or a silence longer than the timeout
(default 10 s; override with a leading {:timeout-ms n} map) becomes a
failing assertion instead of a hung runner, and `done` is always called."
[name & body]
(let [[opts body] (if (and (map? (first body)) (contains? (first body) :timeout-ms))
[(first body) (rest body)]
[{} body])
timeout-ms (:timeout-ms opts 10000)]
`(cljs.test/deftest ~name
(cljs.test/async done#
(let [result# (ird.p2p.async/go-try ~@body)
timer# (cljs.core.async/timeout ~timeout-ms)]
(cljs.core.async/go
(let [[v# port#] (cljs.core.async/alts! [result# timer#])]
(cond
(= port# timer#)
(cljs.test/is false ~(str name " timed out after " timeout-ms " ms"))
(ird.p2p.async/error? v#)
(cljs.test/is false (str ~(str name) " delivered an error: "
(ex-message v#) " " (pr-str (ex-data v#)))))
(done#))))))))