cljs var-to-str + parts test
This commit is contained in:
parent
f049f4fad6
commit
c32f7a892f
10 changed files with 237 additions and 14 deletions
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
:source-paths ["src"]
|
||||
|
||||
:dependencies [] ;; yep
|
||||
:dependencies [] ;; for visual clarity
|
||||
|
||||
:profiles {:dev {:source-paths ["dev" "dev/clj" "test"]
|
||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
||||
|
|
@ -53,4 +53,6 @@
|
|||
{:source-paths ["src" "test"]
|
||||
:compiler {:output-to "dev/resources/public/js/compiled/mount.js"
|
||||
:optimizations :advanced
|
||||
:pretty-print false}}}}}})
|
||||
:pretty-print false}}}}}
|
||||
|
||||
:test {:source-paths ["dev" "test/clj" "test"]}})
|
||||
|
|
|
|||
|
|
@ -174,10 +174,22 @@
|
|||
all)
|
||||
(sort-by :order))))
|
||||
|
||||
|
||||
#?(:clj
|
||||
(defn- var-to-str [v]
|
||||
(str v)))
|
||||
|
||||
#?(:cljs
|
||||
(defn var-to-str [v]
|
||||
(if (var? v)
|
||||
(let [{:keys [ns name]} (meta v)]
|
||||
(with-ns ns name))
|
||||
v)))
|
||||
|
||||
(defn- bring [states fun order]
|
||||
(let [done (atom [])]
|
||||
(as-> states $
|
||||
(map str $)
|
||||
(map var-to-str $)
|
||||
(select-keys @meta-state $)
|
||||
(sort-by (comp :order val) order $)
|
||||
(doseq [[k v] $] (fun k v done)))
|
||||
|
|
@ -226,7 +238,7 @@
|
|||
|
||||
(defn stop-except [& states]
|
||||
(let [all (set (find-all-states))
|
||||
states (map str states)
|
||||
states (map var-to-str states)
|
||||
states (remove (set states) all)]
|
||||
(apply stop states)))
|
||||
|
||||
|
|
@ -238,13 +250,14 @@
|
|||
|
||||
(defn start-with [with]
|
||||
(doseq [[from to] with]
|
||||
(substitute! (str from) (str to)))
|
||||
(substitute! (var-to-str from)
|
||||
(var-to-str to)))
|
||||
(start))
|
||||
|
||||
(defn start-without [& states]
|
||||
(if (first states)
|
||||
(let [app (set (all-without-subs))
|
||||
states (map str states)
|
||||
states (map var-to-str states)
|
||||
without (remove (set states) app)]
|
||||
(apply start without))
|
||||
(start)))
|
||||
|
|
|
|||
13
test/clj/app/conf.clj
Normal file
13
test/clj/app/conf.clj
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
(ns app.conf
|
||||
(:require [mount.core :as mount :refer [defstate]]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.tools.logging :refer [info]]))
|
||||
|
||||
(defn load-config [path]
|
||||
(info "loading config from" path)
|
||||
(-> path
|
||||
slurp
|
||||
edn/read-string))
|
||||
|
||||
(defstate config
|
||||
:start (load-config "dev/resources/config.edn"))
|
||||
65
test/clj/app/example.clj
Normal file
65
test/clj/app/example.clj
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
(ns app.example
|
||||
(:require [datomic.api :as d]
|
||||
[clojure.tools.nrepl.server :refer [start-server stop-server]]
|
||||
[mount.core :as mount :refer [defstate]]
|
||||
[app.utils.datomic :refer [touch]]
|
||||
[app.conf :refer [config]]
|
||||
[app.nyse :as nyse]))
|
||||
|
||||
;; example on creating a network REPL
|
||||
(defn- start-nrepl [{:keys [host port]}]
|
||||
(start-server :bind host :port port))
|
||||
|
||||
;; nREPL is just another simple state
|
||||
(defstate nrepl :start (start-nrepl (:nrepl @config))
|
||||
:stop (stop-server @nrepl))
|
||||
|
||||
;; datomic schema
|
||||
(defn create-schema [conn]
|
||||
(let [schema [{:db/id #db/id [:db.part/db]
|
||||
:db/ident :order/symbol
|
||||
:db/valueType :db.type/string
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db/index true
|
||||
:db.install/_attribute :db.part/db}
|
||||
|
||||
{:db/id #db/id [:db.part/db]
|
||||
:db/ident :order/bid
|
||||
:db/valueType :db.type/bigdec
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db.install/_attribute :db.part/db}
|
||||
|
||||
{:db/id #db/id [:db.part/db]
|
||||
:db/ident :order/qty
|
||||
:db/valueType :db.type/long
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db.install/_attribute :db.part/db}
|
||||
|
||||
{:db/id #db/id [:db.part/db]
|
||||
:db/ident :order/offer
|
||||
:db/valueType :db.type/bigdec
|
||||
:db/cardinality :db.cardinality/one
|
||||
:db.install/_attribute :db.part/db}]]
|
||||
|
||||
@(d/transact conn schema)))
|
||||
|
||||
(defn add-order [ticker bid offer qty] ;; can take connection as param
|
||||
@(d/transact @nyse/conn [{:db/id (d/tempid :db.part/user)
|
||||
:order/symbol ticker
|
||||
:order/bid bid
|
||||
:order/offer offer
|
||||
:order/qty qty}]))
|
||||
|
||||
|
||||
(defn find-orders [ticker] ;; can take connection as param
|
||||
(let [orders (d/q '[:find ?e :in $ ?ticker
|
||||
:where [?e :order/symbol ?ticker]]
|
||||
(d/db @nyse/conn) ticker)]
|
||||
(touch @nyse/conn orders)))
|
||||
|
||||
(defn create-nyse-schema []
|
||||
(create-schema @nyse/conn))
|
||||
|
||||
;; example of an app entry point
|
||||
(defn -main [& args]
|
||||
(mount/start))
|
||||
21
test/clj/app/nyse.clj
Normal file
21
test/clj/app/nyse.clj
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(ns app.nyse
|
||||
(:require [mount.core :as mount :refer [defstate]]
|
||||
[datomic.api :as d]
|
||||
[clojure.tools.logging :refer [info]]
|
||||
[app.conf :refer [config]]))
|
||||
|
||||
(defn- new-connection [conf]
|
||||
(info "conf: " conf)
|
||||
(let [uri (get-in @conf [:datomic :uri])]
|
||||
(info "creating a connection to datomic:" uri)
|
||||
(d/create-database uri)
|
||||
(d/connect uri)))
|
||||
|
||||
(defn disconnect [conf conn]
|
||||
(let [uri (get-in @conf [:datomic :uri])]
|
||||
(info "disconnecting from " uri)
|
||||
(.release @conn) ;; usually it's not released, here just to illustrate the access to connection on (stop)
|
||||
(d/delete-database uri)))
|
||||
|
||||
(defstate conn :start (new-connection config)
|
||||
:stop (disconnect config conn))
|
||||
11
test/clj/app/utils/datomic.clj
Normal file
11
test/clj/app/utils/datomic.clj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
(ns app.utils.datomic
|
||||
(:require [datomic.api :as d]))
|
||||
|
||||
(defn entity [conn id]
|
||||
(d/entity (d/db conn) id))
|
||||
|
||||
(defn touch [conn results]
|
||||
"takes 'entity ids' results from a query
|
||||
e.g. '#{[272678883689461] [272678883689462] [272678883689459] [272678883689457]}'"
|
||||
(let [e (partial entity conn)]
|
||||
(map #(-> % first e d/touch) results)))
|
||||
46
test/clj/app/utils/logging.clj
Normal file
46
test/clj/app/utils/logging.clj
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
(ns app.utils.logging ;; << change to your namespace/path
|
||||
(:require [mount.core]
|
||||
[robert.hooke :refer [add-hook clear-hooks]]
|
||||
[clojure.string :refer [split]]
|
||||
[clojure.tools.logging :refer [info]]))
|
||||
|
||||
(alter-meta! *ns* assoc ::load false)
|
||||
|
||||
(defn- f-to-action [f]
|
||||
(let [fname (-> (str f)
|
||||
(split #"@")
|
||||
first)]
|
||||
(case fname
|
||||
"mount.core$up" :up
|
||||
"mount.core$down" :down
|
||||
"mount.core$sigstop" :suspend
|
||||
"mount.core$sigcont" :resume
|
||||
:noop)))
|
||||
|
||||
(defn whatcha-doing? [{:keys [status suspend]} action]
|
||||
(case action
|
||||
:up (if (status :suspended) ">> resuming"
|
||||
(if-not (status :started) ">> starting"))
|
||||
:down (if (or (status :started) (status :suspended)) "<< stopping")
|
||||
:suspend (if (and (status :started) suspend) "<< suspending")
|
||||
:resume (if (status :suspended) ">> resuming")))
|
||||
|
||||
(defn log-status [f & args]
|
||||
(let [{:keys [var] :as state} (second args)
|
||||
action (f-to-action f)]
|
||||
(when-let [taking-over-the-world (whatcha-doing? state action)]
|
||||
(info (str taking-over-the-world ".. " var)))
|
||||
(apply f args)))
|
||||
|
||||
(defonce lifecycle-fns
|
||||
#{#'mount.core/up
|
||||
#'mount.core/down
|
||||
#'mount.core/sigstop
|
||||
#'mount.core/sigcont})
|
||||
|
||||
(defn without-logging-status []
|
||||
(doall (map #(clear-hooks %) lifecycle-fns)))
|
||||
|
||||
(defn with-logging-status []
|
||||
(without-logging-status)
|
||||
(doall (map #(add-hook % log-status) lifecycle-fns)))
|
||||
|
|
@ -3,18 +3,23 @@
|
|||
#?@(:cljs [[cljs.test :as t]
|
||||
[doo.runner :refer-macros [doo-tests]]]
|
||||
:clj [[clojure.test :as t]])
|
||||
[mount.core :as mount]
|
||||
|
||||
mount.test.fun-with-values
|
||||
mount.test.private-fun))
|
||||
mount.core
|
||||
|
||||
(mount/in-cljc-mode)
|
||||
mount.test.fun-with-values
|
||||
mount.test.private-fun
|
||||
mount.test.parts
|
||||
))
|
||||
|
||||
(mount.core/in-cljc-mode)
|
||||
|
||||
#?(:cljs
|
||||
(doo-tests 'mount.test.fun-with-values
|
||||
'mount.test.private-fun))
|
||||
|
||||
;; (doo.runner/do-all-tests)
|
||||
;; (doo.runner/do-all-tests)
|
||||
(doo-tests
|
||||
'mount.test.fun-with-values
|
||||
'mount.test.private-fun
|
||||
'mount.test.parts
|
||||
))
|
||||
|
||||
(defn run-tests []
|
||||
(t/run-all-tests #"mount.test.*"))
|
||||
|
|
|
|||
11
test/mount/test/helper.cljc
Normal file
11
test/mount/test/helper.cljc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
(ns mount.test.helper
|
||||
(:require mount.core))
|
||||
|
||||
(defn dval
|
||||
"returns a value of DerefableState without deref'ing it"
|
||||
[d]
|
||||
(-> (@@(var mount.core/meta-state)
|
||||
#?(:clj (.name d)
|
||||
:cljs (.-name d)))
|
||||
:inst
|
||||
deref))
|
||||
36
test/mount/test/parts.cljc
Normal file
36
test/mount/test/parts.cljc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
(ns mount.test.parts
|
||||
(:require
|
||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||
[mount.core :as mount :refer-macros [defstate]]
|
||||
[app.websockets :refer [system-a]]
|
||||
[app.conf :refer [config]]
|
||||
[app.audit-log :refer [log]]]
|
||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||
[mount.core :as mount :refer [defstate]]
|
||||
[app.nyse :refer [conn]]])
|
||||
[mount.test.helper :refer [dval]]))
|
||||
|
||||
(defstate should-not-start :start (constantly 42))
|
||||
|
||||
#?(:clj
|
||||
(defn with-parts [f]
|
||||
(mount/start #'app.conf/config #'app.nyse/conn)
|
||||
(f)
|
||||
(mount/stop)))
|
||||
|
||||
(use-fixtures :once
|
||||
#?(:cljs {:before #(mount/start #'app.conf/config #'app.audit-log/log)
|
||||
:after mount/stop}
|
||||
:clj with-parts))
|
||||
|
||||
#?(:clj
|
||||
(deftest start-only-parts
|
||||
(is (instance? datomic.peer.LocalConnection (dval conn)))
|
||||
(is (instance? mount.core.NotStartedState (dval should-not-start)))))
|
||||
|
||||
#?(:cljs
|
||||
(deftest start-only-parts
|
||||
(is (instance? datascript.db/DB @(dval log)))
|
||||
(is (map? (dval config)))
|
||||
(is (instance? mount.core.NotStartedState (dval should-not-start)))
|
||||
(is (instance? mount.core.NotStartedState (dval system-a)))))
|
||||
Loading…
Reference in a new issue