-
-
Save trikitrok/a39f5fbec6ab0ee0c6f8db68e87a552c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns horizon.test-helpers.async-test-tools | |
(:require | |
[cljs.test :refer-macros [is]] | |
[cljs.core.async :as core.async]) | |
(:require-macros | |
[cljs.core.async.macros :refer [go go-loop]])) | |
(def ^:private timeout-in-ms 2000) | |
(defn- channel-timed-out-error [received-messages] | |
(ex-info | |
"Channel timed out!!!" | |
{:cause :channel-timeout | |
:received-messages received-messages})) | |
(defn- maybe-exclude-keys [x ks] | |
(if (and (map? x) ks) | |
(apply dissoc x ks) | |
x)) | |
(defn- invoke! [f] | |
{:pre [(if f (ifn? f) true)]} | |
(when f | |
(f))) | |
(defn- check-result | |
[& {:keys [expected result done-fn excluding-keys] :as options}] | |
{:pre [(every? #{:expected :result :done-fn :excluding-keys} | |
(keys options)) | |
(if done-fn (ifn? done-fn) true)]} | |
(let [expected (maybe-exclude-keys expected excluding-keys) | |
result (maybe-exclude-keys result excluding-keys)] | |
(try | |
(is (= expected result)) | |
(finally | |
(invoke! done-fn))))) | |
(defn check-results | |
[& {:keys [expected result done-fn excluding-keys] :as options}] | |
{:pre [(every? #{:expected :result :done-fn :excluding-keys} | |
(keys options)) | |
(if done-fn (ifn? done-fn) true)]} | |
(try | |
(mapv #(check-result :expected %1 | |
:result %2 | |
:excluding-keys excluding-keys) | |
expected | |
result) | |
(finally | |
(invoke! done-fn)))) | |
(defn- fail-because-of-timeout | |
[expected-message received-messages done-fn] | |
(check-result :expected expected-message | |
:result (channel-timed-out-error received-messages) | |
:done-fn done-fn)) | |
(defn expect-async-message | |
[channel & {:keys [expected-message done-fn excluding-keys]}] | |
{:pre [expected-message (if done-fn (ifn? done-fn) true)]} | |
(go | |
(let [[message ch] (core.async/alts! | |
[channel (core.async/timeout timeout-in-ms)])] | |
(if (= ch channel) | |
(check-result :expected expected-message | |
:result message | |
:done-fn done-fn | |
:excluding-keys excluding-keys) | |
(fail-because-of-timeout expected-message [] done-fn))))) | |
(defn expect-async-message-with-specific-type | |
[channel & {:keys [expected-message-type expected-message done-fn excluding-keys]}] | |
{:pre [expected-message expected-message-type (if done-fn (ifn? done-fn) true)]} | |
(go-loop [received-messages []] | |
(let [[message ch] (core.async/alts! | |
[channel (core.async/timeout timeout-in-ms)])] | |
(if (= ch channel) | |
(if (= expected-message-type (:type message)) | |
(check-result :expected expected-message | |
:result message | |
:done-fn done-fn | |
:excluding-keys excluding-keys) | |
(recur (conj received-messages message))) | |
(fail-because-of-timeout expected-message received-messages done-fn))))) | |
(defn expect-n-async-messages | |
[channel & {:keys [expected-messages done-fn excluding-keys]}] | |
{:pre [(sequential? expected-messages) (if done-fn (ifn? done-fn) true)]} | |
(go-loop [received-messages []] | |
(let [[message ch] (core.async/alts! | |
[channel (core.async/timeout timeout-in-ms)]) | |
total (count expected-messages)] | |
(if (= ch channel) | |
(let [received-messages (conj received-messages message)] | |
(if (= total (count received-messages)) | |
(check-results :expected expected-messages | |
:result received-messages | |
:done-fn done-fn | |
:excluding-keys excluding-keys) | |
(recur received-messages))) | |
(fail-because-of-timeout expected-messages received-messages done-fn))))) | |
(defn async-used-fn [channel func-kw] | |
(fn [& args] | |
(go | |
(core.async/>! channel {:used func-kw :with-args (vec args)})))) | |
(defn send-fake-msg! [channel msg] | |
(go | |
(core.async/>! channel msg))) | |
(defn expect-event-handler-receives-args | |
[& {:keys [event channel expected-args done-fn close-fn]}] | |
{:pre [event | |
channel | |
expected-args | |
(if done-fn (ifn? done-fn) true) | |
(if close-fn (ifn? close-fn) true)]} | |
(let [events-channel (core.async/chan) | |
close-and-done-fn (fn [] | |
(when close-fn (close-fn channel)) | |
(when done-fn (done-fn channel)))] | |
(event | |
channel | |
(fn [& args] | |
(go | |
(core.async/>! events-channel args)))) | |
(go | |
(let [[args ch] (core.async/alts! | |
[events-channel (core.async/timeout timeout-in-ms)])] | |
(if (= ch events-channel) | |
(check-result | |
:expected expected-args :result args :done-fn close-and-done-fn) | |
(fail-because-of-timeout | |
expected-args :never-called close-and-done-fn)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment