Skip to content

Instantly share code, notes, and snippets.

@jandorfer
Created April 13, 2015 19:33
Show Gist options
  • Save jandorfer/81a2ce650a575b2d2351 to your computer and use it in GitHub Desktop.
Save jandorfer/81a2ce650a575b2d2351 to your computer and use it in GitHub Desktop.
;; Works from repl, but not 'lein test'...
(def waiting (atom false))
(def latest-report (atom nil))
(defn- wrap-report-fn [original]
(fn [m]
(if @waiting
(swap! latest-report (fn [_] m))
(original m))))
(defn- wrap-report-fns []
(let [existing (methods report)]
(doseq [[key fn] existing]
(let [wrapper (wrap-report-fn fn)]
(defmethod report key [m] (wrapper m))))
existing))
(defn- unwrap-report-fns [original]
(doseq [[key o] original]
(defmethod report key [m] (o m))))
(defn test-eventually
"Use this test fixture :once on any tests that will use the is-eventually check.
(use-fixtures :once test-eventually)
All test reporting will be redirected while it is active, don't run tests in
parallel or the results will be indeterminate."
[f]
(let [original (wrap-report-fns)]
(f)
(unwrap-report-fns original)))
(defmacro is-eventually
"Checks a condition every second until given timeout elapses. Returns the
value from the check or reports timeout if timeout."
([form] `(is-eventually ~form 10 nil))
([form timeout] `(is-eventually ~form ~timeout nil))
([form timeout msg]
`(do
(compare-and-set! waiting false true)
(loop [~'s ~timeout]
(is ~form ~msg)
(let [~'report @latest-report]
(cond (= :pass (:type ~'report)) ~'report
(<= ~'s 0) (do (compare-and-set! waiting true false)
(report (merge ~'report {:type :fail :message (str "Timed out (" ~timeout " s.)")})))
:else (do (Thread/sleep 1000) (recur (dec ~'s)))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment