Skip to content

Instantly share code, notes, and snippets.

@apeckham
Last active November 16, 2022 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apeckham/2e75569bd9369918493c33519839e067 to your computer and use it in GitHub Desktop.
Save apeckham/2e75569bd9369918493c33519839e067 to your computer and use it in GitHub Desktop.
(trying to write) a clojure macro that checks the condition periodically and fails after a timeout
(ns my.eventually-test
(:require
[clojure.test :refer [deftest is] :as t]))
(defn eventually*
[msg form]
`(let [start# (System/currentTimeMillis)
f# ~(nth form 1)
timeout-ms# ~(nth form 2)
sleep-ms# ~(nth form 3)]
(loop []
(let [result# f#] ;; doesn't work yet -- this should be (f#) -- ?
(if result#
(t/do-report {:actual result# :expected f# :message ~msg :type :pass})
(if (< (+ start# timeout-ms#) (System/currentTimeMillis))
(t/do-report {:actual nil :expected f# :message ~msg :type :fail})
(do (Thread/sleep sleep-ms#) (recur))))))))
(defmethod t/assert-expr 'eventually [msg form] (eventually* msg form))
(deftest pass-test
(let [reports (atom [])]
(with-redefs [t/do-report #(swap! reports conj %)] (eval (eventually* "Msg" [nil '(= 1 1) 1000 10])))
(is (= [{:actual true :expected true :message "Msg" :type :pass}] @reports))))
(deftest fail-test
(let [reports (atom [])]
(with-redefs [t/do-report #(swap! reports conj %)] (eval (eventually* "Msg" [nil '(= 1 2) 1000 10])))
(is (= [{:actual nil :expected false :message "Msg" :type :fail}] @reports))))
(deftest macro-test (is (eventually (= 1 1) 1000 10)) #_(is (eventually (= 1 2) 1000 10)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment