2016-07-21 02:42:25 +00:00
|
|
|
(ns re-frame.interop
|
2016-08-16 03:24:21 +00:00
|
|
|
(:import [java.util.concurrent Executor Executors]))
|
2016-07-21 02:42:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
;; The purpose of this file is to provide JVM-runnable implementations of the
|
|
|
|
;; CLJS equivalents in interop.cljs.
|
|
|
|
;;
|
|
|
|
;; These implementations are to enable you to bring up a re-frame app on the JVM
|
|
|
|
;; in order to run tests, or to develop at a JVM REPL instead of a CLJS one.
|
|
|
|
;;
|
|
|
|
;; Please note, though, that the purpose here *isn't* to fully replicate all of
|
|
|
|
;; re-frame's behaviour in a real CLJS environment. We don't have Reagent or
|
|
|
|
;; React on the JVM, and we don't try to mimic the stateful lifecycles that they
|
|
|
|
;; embody.
|
|
|
|
;;
|
|
|
|
;; In particular, if you're performing side effects in any code that's triggered
|
|
|
|
;; by a change to a Ratom's value, and not via a call to `dispatch`, then you're
|
|
|
|
;; going to have a hard time getting any accurate tests with this code.
|
|
|
|
;; However, if your subscriptions and Reagent render functions are pure, and
|
2016-08-17 12:47:20 +00:00
|
|
|
;; your side-effects are all managed by effect handlers, then hopefully this will
|
2016-07-21 02:42:25 +00:00
|
|
|
;; allow you to write some useful tests that can run on the JVM.
|
|
|
|
|
|
|
|
|
|
|
|
(defonce ^:private executor (Executors/newSingleThreadExecutor))
|
2016-07-20 08:57:46 +00:00
|
|
|
|
|
|
|
(defn next-tick [f]
|
2016-08-09 08:52:54 +00:00
|
|
|
(let [bound-f (bound-fn [& args] (apply f args))]
|
2016-08-16 03:24:21 +00:00
|
|
|
(.execute ^Executor executor bound-f))
|
2016-07-21 02:42:25 +00:00
|
|
|
nil)
|
2016-07-20 08:57:46 +00:00
|
|
|
|
|
|
|
(def empty-queue clojure.lang.PersistentQueue/EMPTY)
|
|
|
|
|
|
|
|
(def after-render next-tick)
|
|
|
|
|
|
|
|
(def debug-enabled? true)
|
|
|
|
|
|
|
|
(defn ratom [x]
|
2016-07-21 02:42:25 +00:00
|
|
|
(atom x))
|
2016-07-20 08:57:46 +00:00
|
|
|
|
2016-07-21 02:42:25 +00:00
|
|
|
(defn ratom? [x]
|
2016-07-21 07:08:01 +00:00
|
|
|
(instance? clojure.lang.IAtom x))
|
2016-07-20 08:57:46 +00:00
|
|
|
|
2016-08-17 12:47:20 +00:00
|
|
|
(defn deref? [x]
|
|
|
|
(instance? clojure.lang.IDeref x))
|
|
|
|
|
2016-07-20 08:57:46 +00:00
|
|
|
(defn make-reaction
|
2016-07-21 02:42:25 +00:00
|
|
|
"On JVM Clojure, return a `deref`-able thing which invokes the given function
|
|
|
|
on every `deref`. That is, `make-reaction` here provides precisely none of the
|
2016-07-20 08:57:46 +00:00
|
|
|
benefits of `reagent.ratom/make-reaction` (which only invokes its function if
|
|
|
|
the reactions that the function derefs have changed value). But so long as `f`
|
|
|
|
only depends on other reactions (which also behave themselves), the only
|
|
|
|
difference is one of efficiency. That is, your tests should see no difference
|
|
|
|
other than that they do redundant work."
|
|
|
|
[f]
|
|
|
|
(reify clojure.lang.IDeref
|
|
|
|
(deref [_] (f))))
|
|
|
|
|
|
|
|
(defn add-on-dispose!
|
|
|
|
"No-op in JVM Clojure, since for testing purposes, we don't care about
|
|
|
|
releasing resources for efficiency purposes."
|
|
|
|
[a-ratom f]
|
|
|
|
nil)
|
|
|
|
|
2016-08-19 08:20:21 +00:00
|
|
|
(defn dispose! [a-ratom]
|
|
|
|
"No-op in JVM Clojure, since for testing purposes, we don't care about
|
|
|
|
releasing resources for efficiency purposes."
|
|
|
|
nil)
|
|
|
|
|
2016-07-20 08:57:46 +00:00
|
|
|
(defn set-timeout!
|
|
|
|
"Note that we ignore the `ms` value and just invoke the function, because
|
|
|
|
there isn't often much point firing a timed event in a test."
|
|
|
|
[f ms]
|
|
|
|
(next-tick f))
|
2016-11-06 04:40:39 +00:00
|
|
|
|
|
|
|
(defn now []
|
|
|
|
;; currentTimeMillis may count backwards in some scenarios, but as this is used for tracing
|
|
|
|
;; it is preferable to the slower but more accurate System.nanoTime.
|
|
|
|
(System/currentTimeMillis))
|