Merge branch '0.1.7'
Conflicts: .gitignore src/mount/core.cljc
This commit is contained in:
commit
a4dfe74c66
37 changed files with 479 additions and 212 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -7,6 +7,7 @@ pom.xml.asc
|
||||||
dev/resources/public/js/*
|
dev/resources/public/js/*
|
||||||
figwheel_server.log
|
figwheel_server.log
|
||||||
build.xml
|
build.xml
|
||||||
|
doo-index.html
|
||||||
*.jar
|
*.jar
|
||||||
*.class
|
*.class
|
||||||
/.lein-*
|
/.lein-*
|
||||||
|
|
|
||||||
108
build.boot
Normal file
108
build.boot
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
(set-env!
|
||||||
|
:source-paths #{"src"}
|
||||||
|
:dependencies '[;; mount brings _no dependencies_, everything here is for
|
||||||
|
;; mount dev, examples apps and tests
|
||||||
|
|
||||||
|
[org.clojure/clojure "1.7.0" :scope "provided"]
|
||||||
|
[org.clojure/clojurescript "1.7.189" :scope "provided" :classifier "aot"]
|
||||||
|
[datascript "0.13.3" :scope "provided"]
|
||||||
|
[compojure "1.4.0" :scope "provided"]
|
||||||
|
[ring/ring-jetty-adapter "1.1.0" :scope "provided"]
|
||||||
|
[cheshire "5.5.0" :scope "provided"]
|
||||||
|
[hiccups "0.3.0" :scope "provided" :exclusions [org.clojure/clojurescript]]
|
||||||
|
[com.andrewmcveigh/cljs-time "0.3.14" :scope "provided"]
|
||||||
|
[ch.qos.logback/logback-classic "1.1.3" :scope "provided"]
|
||||||
|
[org.clojure/tools.logging "0.3.1" :scope "provided"]
|
||||||
|
[robert/hooke "1.3.0" :scope "provided"]
|
||||||
|
[org.clojure/tools.namespace "0.2.11" :scope "provided"]
|
||||||
|
[org.clojure/tools.nrepl "0.2.12" :scope "provided"]
|
||||||
|
[com.datomic/datomic-free "0.9.5327" :scope "provided" :exclusions [joda-time]]
|
||||||
|
|
||||||
|
;; boot clj
|
||||||
|
[boot/core "2.5.1" :scope "provided"]
|
||||||
|
[adzerk/bootlaces "0.1.13" :scope "test"]
|
||||||
|
[adzerk/boot-logservice "1.0.1" :scope "test"]
|
||||||
|
[adzerk/boot-test "1.0.6" :scope "test"]
|
||||||
|
|
||||||
|
;; boot cljs
|
||||||
|
[adzerk/boot-cljs "1.7.170-3" :scope "test"]
|
||||||
|
[adzerk/boot-cljs-repl "0.3.0" :scope "test"]
|
||||||
|
[pandeiro/boot-http "0.7.1-SNAPSHOT" :scope "test"]
|
||||||
|
[com.cemerick/piggieback "0.2.1" :scope "test" :exclusions [org.clojure/clojurescript]]
|
||||||
|
[weasel "0.7.0" :scope "test" :exclusions [org.clojure/clojurescript]]
|
||||||
|
[adzerk/boot-reload "0.4.2" :scope "test"]
|
||||||
|
[crisptrutski/boot-cljs-test "0.2.1-SNAPSHOT" :scope "test"]])
|
||||||
|
|
||||||
|
(require '[adzerk.bootlaces :refer :all]
|
||||||
|
'[adzerk.boot-test :as bt]
|
||||||
|
'[adzerk.boot-logservice :as log-service]
|
||||||
|
'[adzerk.boot-cljs :refer [cljs]]
|
||||||
|
'[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]]
|
||||||
|
'[adzerk.boot-reload :refer [reload]]
|
||||||
|
'[pandeiro.boot-http :refer :all]
|
||||||
|
'[crisptrutski.boot-cljs-test :as tcs]
|
||||||
|
'[clojure.tools.logging :as log]
|
||||||
|
'[clojure.tools.namespace.repl :refer [set-refresh-dirs]])
|
||||||
|
|
||||||
|
(def +version+ "0.1.7-SNAPSHOT")
|
||||||
|
|
||||||
|
(bootlaces! +version+)
|
||||||
|
|
||||||
|
(def log4b
|
||||||
|
[:configuration
|
||||||
|
[:appender {:name "STDOUT" :class "ch.qos.logback.core.ConsoleAppender"}
|
||||||
|
[:encoder [:pattern "%-5level %logger{36} - %msg%n"]]]
|
||||||
|
[:root {:level "TRACE"}
|
||||||
|
[:appender-ref {:ref "STDOUT"}]]])
|
||||||
|
|
||||||
|
(deftask dev []
|
||||||
|
(set-env! :source-paths #(conj % "dev/clj" "dev/cljs"))
|
||||||
|
|
||||||
|
(alter-var-root #'log/*logger-factory*
|
||||||
|
(constantly (log-service/make-factory log4b)))
|
||||||
|
(apply set-refresh-dirs (get-env :directories))
|
||||||
|
(load-data-readers!)
|
||||||
|
|
||||||
|
(require 'dev)
|
||||||
|
(in-ns 'dev))
|
||||||
|
|
||||||
|
(deftask test []
|
||||||
|
(set-env! :source-paths #(conj % "test/core" "test/clj")) ;; (!) :source-paths must not overlap.
|
||||||
|
(bt/test))
|
||||||
|
|
||||||
|
(deftask test-cljs []
|
||||||
|
(set-env! :source-paths #(conj % "test/core" "test/cljs"))
|
||||||
|
(set-env! :resource-paths #{"test/resources"})
|
||||||
|
|
||||||
|
(comp
|
||||||
|
(tcs/test-cljs ;; :optimizations :advanced
|
||||||
|
:out-file "mount.js")))
|
||||||
|
|
||||||
|
(deftask test-cljs-advanced []
|
||||||
|
(set-env! :source-paths #(conj % "dev/clj" "dev/cljs"))
|
||||||
|
(set-env! :resource-paths #{"dev/resources"})
|
||||||
|
|
||||||
|
(comp
|
||||||
|
(cljs :optimizations :advanced :ids #{"mount"})))
|
||||||
|
|
||||||
|
(deftask cljs-example
|
||||||
|
"mount cljs example"
|
||||||
|
[]
|
||||||
|
(set-env! :source-paths #(conj % "dev/clj" "dev/cljs"))
|
||||||
|
(set-env! :resource-paths #{"dev/resources"})
|
||||||
|
|
||||||
|
(comp
|
||||||
|
(wait)
|
||||||
|
(serve :dir "dev/resources/public/")
|
||||||
|
(cljs-repl)
|
||||||
|
(cljs :optimizations :advanced :ids #{"mount"})))
|
||||||
|
|
||||||
|
(task-options!
|
||||||
|
push #(-> (into {} %) (assoc :ensure-branch nil))
|
||||||
|
pom {:project 'mount
|
||||||
|
:version +version+
|
||||||
|
:description "managing Clojure and ClojureScript app state since (reset)"
|
||||||
|
:url "https://github.com/tolitius/mount"
|
||||||
|
:scm {:url "https://github.com/tolitius/mount"}
|
||||||
|
:license {"Eclipse Public License"
|
||||||
|
"http://www.eclipse.org/legal/epl-v10.html"}})
|
||||||
11
circle.yml
11
circle.yml
|
|
@ -2,9 +2,14 @@ machine:
|
||||||
java:
|
java:
|
||||||
version: oraclejdk8
|
version: oraclejdk8
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
pre:
|
||||||
|
- wget https://github.com/boot-clj/boot-bin/releases/download/2.4.2/boot.sh
|
||||||
|
- mv boot.sh boot && chmod a+x boot && sudo mv boot /usr/local/bin
|
||||||
|
|
||||||
test:
|
test:
|
||||||
override:
|
override:
|
||||||
- lein do clean, test
|
- boot test
|
||||||
- lein do clean, doo phantom test once
|
- boot test-cljs
|
||||||
- lein do clean, cljsbuild once prod
|
- boot test-cljs-advanced
|
||||||
- lein test2junit
|
- lein test2junit
|
||||||
|
|
|
||||||
50
dev/clj/app/db.clj
Normal file
50
dev/clj/app/db.clj
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
(ns app.db
|
||||||
|
(:require [mount.core :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))
|
||||||
|
|
||||||
|
;; datomic schema (staging as an example)
|
||||||
|
(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)))
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
(ns app.example
|
(ns app.example
|
||||||
(:require [datomic.api :as d]
|
(:require [clojure.tools.nrepl.server :refer [start-server stop-server]]
|
||||||
[clojure.tools.nrepl.server :refer [start-server stop-server]]
|
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.utils.datomic :refer [touch]]
|
|
||||||
[app.conf :refer [config]]
|
[app.conf :refer [config]]
|
||||||
[app.nyse :as nyse]))
|
[app.www])
|
||||||
|
(:gen-class)) ;; for -main / uberjar (no need in dev)
|
||||||
|
|
||||||
;; example on creating a network REPL
|
;; example on creating a network REPL
|
||||||
(defn- start-nrepl [{:keys [host port]}]
|
(defn- start-nrepl [{:keys [host port]}]
|
||||||
|
|
@ -14,52 +13,6 @@
|
||||||
(defstate nrepl :start (start-nrepl (:nrepl config))
|
(defstate nrepl :start (start-nrepl (:nrepl config))
|
||||||
:stop (stop-server nrepl))
|
: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
|
;; example of an app entry point
|
||||||
(defn -main [& args]
|
(defn -main [& args]
|
||||||
(mount/start))
|
(mount/start))
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,20 @@
|
||||||
(ns app.nyse
|
(ns app.nyse
|
||||||
(:require [mount.core :as mount :refer [defstate]]
|
(:require [datomic.api :as d]
|
||||||
[datomic.api :as d]
|
[app.db :refer [create-schema] :as db]
|
||||||
[clojure.tools.logging :refer [info]]
|
[app.utils.datomic :refer [touch]]))
|
||||||
[app.conf :refer [config]]))
|
|
||||||
|
|
||||||
(defn- new-connection [conf]
|
(defn add-order [ticker bid offer qty] ;; can take connection as param
|
||||||
(info "conf: " conf)
|
@(d/transact db/conn [{:db/id (d/tempid :db.part/user)
|
||||||
(let [uri (get-in conf [:datomic :uri])]
|
:order/symbol ticker
|
||||||
(info "creating a connection to datomic:" uri)
|
:order/bid bid
|
||||||
(d/create-database uri)
|
:order/offer offer
|
||||||
(d/connect uri)))
|
:order/qty qty}]))
|
||||||
|
|
||||||
(defn disconnect [conf conn]
|
(defn find-orders [ticker] ;; can take connection as param
|
||||||
(let [uri (get-in conf [:datomic :uri])]
|
(let [orders (d/q '[:find ?e :in $ ?ticker
|
||||||
(info "disconnecting from " uri)
|
:where [?e :order/symbol ?ticker]]
|
||||||
(.release conn) ;; usually it's not released, here just to illustrate the access to connection on (stop)
|
(d/db db/conn) ticker)]
|
||||||
(d/delete-database uri)))
|
(touch db/conn orders)))
|
||||||
|
|
||||||
(defstate conn :start (new-connection config)
|
(defn create-nyse-schema []
|
||||||
:stop (disconnect config conn))
|
(create-schema db/conn))
|
||||||
|
|
|
||||||
31
dev/clj/app/www.clj
Normal file
31
dev/clj/app/www.clj
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
(ns app.www
|
||||||
|
(:require [app.nyse :refer [add-order find-orders create-nyse-schema]]
|
||||||
|
[app.conf :refer [config]]
|
||||||
|
[mount.core :refer [defstate]]
|
||||||
|
[cheshire.core :refer [generate-string]]
|
||||||
|
[compojure.core :refer [routes defroutes GET POST]]
|
||||||
|
[compojure.handler :as handler]
|
||||||
|
[ring.adapter.jetty :refer [run-jetty]]))
|
||||||
|
|
||||||
|
(defroutes mount-example-routes
|
||||||
|
|
||||||
|
(GET "/" [] "welcome to mount sample app!")
|
||||||
|
(GET "/nyse/orders/:ticker" [ticker]
|
||||||
|
(generate-string (find-orders ticker)))
|
||||||
|
|
||||||
|
(POST "/nyse/orders" [ticker qty bid offer]
|
||||||
|
(add-order ticker (bigdec bid) (bigdec offer) (Integer/parseInt qty))
|
||||||
|
(generate-string {:added {:ticker ticker
|
||||||
|
:qty qty
|
||||||
|
:bid bid
|
||||||
|
:offer offer}})))
|
||||||
|
|
||||||
|
(defn start-nyse [{:keys [www]}]
|
||||||
|
(create-nyse-schema) ;; creating schema (usually done long before the app is started..)
|
||||||
|
(-> (routes mount-example-routes)
|
||||||
|
(handler/site)
|
||||||
|
(run-jetty {:join? false
|
||||||
|
:port (:port www)})))
|
||||||
|
|
||||||
|
(defstate nyse-app :start (start-nyse config)
|
||||||
|
:stop (.stop nyse-app)) ;; it's a "org.eclipse.jetty.server.Server" at this point
|
||||||
|
|
@ -1,23 +1,18 @@
|
||||||
(ns dev
|
(ns dev
|
||||||
"Tools for interactive development with the REPL. This file should
|
(:require [clojure.pprint :refer [pprint]]
|
||||||
not be included in a production build of the application."
|
|
||||||
(:require [clojure.java.io :as io]
|
|
||||||
[clojure.java.javadoc :refer [javadoc]]
|
|
||||||
[clojure.pprint :refer [pprint]]
|
|
||||||
[clojure.reflect :refer [reflect]]
|
|
||||||
[clojure.repl :refer [apropos dir doc find-doc pst source]]
|
|
||||||
[clojure.set :as set]
|
|
||||||
[clojure.string :as str]
|
|
||||||
[clojure.test :as test]
|
|
||||||
[clojure.tools.namespace.repl :as tn]
|
[clojure.tools.namespace.repl :as tn]
|
||||||
|
[boot.core :refer [load-data-readers!]]
|
||||||
[mount.core :as mount]
|
[mount.core :as mount]
|
||||||
[app.utils.logging :refer [with-logging-status]]
|
[app.utils.logging :refer [with-logging-status]]
|
||||||
[app.example :refer [create-nyse-schema find-orders add-order]])) ;; <<<< replace this your "app" namespace(s) you want to be available at REPL time
|
[app.www]
|
||||||
|
[app.example]
|
||||||
|
[app.nyse :refer [create-nyse-schema find-orders add-order]])) ;; <<<< replace this your "app" namespace(s) you want to be available at REPL time
|
||||||
|
|
||||||
(defn start []
|
(defn start []
|
||||||
(with-logging-status)
|
(with-logging-status)
|
||||||
(mount/start #'app.conf/config
|
(mount/start #'app.conf/config
|
||||||
#'app.nyse/conn
|
#'app.db/conn
|
||||||
|
#'app.www/nyse-app
|
||||||
#'app.example/nrepl)) ;; example on how to start app with certain states
|
#'app.example/nrepl)) ;; example on how to start app with certain states
|
||||||
|
|
||||||
(defn stop []
|
(defn stop []
|
||||||
|
|
@ -44,3 +39,4 @@
|
||||||
(tn/refresh :after 'dev/go))
|
(tn/refresh :after 'dev/go))
|
||||||
|
|
||||||
(mount/in-clj-mode)
|
(mount/in-clj-mode)
|
||||||
|
(load-data-readers!)
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{:datomic
|
{:datomic
|
||||||
{:uri "datomic:mem://mount"}
|
{:uri "datomic:mem://mount"}
|
||||||
|
|
||||||
|
:www {:port 4242}
|
||||||
|
|
||||||
:h2
|
:h2
|
||||||
{:classname "org.h2.Driver"
|
{:classname "org.h2.Driver"
|
||||||
:subprotocol "h2"
|
:subprotocol "h2"
|
||||||
|
|
|
||||||
1
dev/resources/mount.cljs.edn
Normal file
1
dev/resources/mount.cljs.edn
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{:require [app.example]}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<script src="js/compiled/mount.js" type="text/javascript"></script>
|
<script src="../mount.js" type="text/javascript"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
13
project.clj
13
project.clj
|
|
@ -1,5 +1,5 @@
|
||||||
(defproject mount "0.1.6"
|
(defproject mount "0.1.7-SNAPSHOT"
|
||||||
:description "managing Clojure app state since (reset)"
|
:description "managing Clojure and ClojureScript app state since (reset)"
|
||||||
:url "https://github.com/tolitius/mount"
|
:url "https://github.com/tolitius/mount"
|
||||||
:license {:name "Eclipse Public License"
|
:license {:name "Eclipse Public License"
|
||||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||||
|
|
@ -8,10 +8,13 @@
|
||||||
|
|
||||||
:dependencies [] ;; for visual clarity
|
:dependencies [] ;; for visual clarity
|
||||||
|
|
||||||
:profiles {:dev {:source-paths ["dev" "dev/clj"]
|
:profiles {:dev {:source-paths ["dev" "dev/clj" "test/clj"]
|
||||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
:dependencies [[org.clojure/clojure "1.7.0"]
|
||||||
[org.clojure/clojurescript "1.7.170"]
|
[org.clojure/clojurescript "1.7.170"]; :classifier "aot"]
|
||||||
[datascript "0.13.3"]
|
[datascript "0.13.3"]
|
||||||
|
[compojure "1.4.0"]
|
||||||
|
[ring/ring-jetty-adapter "1.1.0"]
|
||||||
|
[cheshire "5.5.0"]
|
||||||
[hiccups "0.3.0"]
|
[hiccups "0.3.0"]
|
||||||
[com.andrewmcveigh/cljs-time "0.3.14"]
|
[com.andrewmcveigh/cljs-time "0.3.14"]
|
||||||
[ch.qos.logback/logback-classic "1.1.3"]
|
[ch.qos.logback/logback-classic "1.1.3"]
|
||||||
|
|
@ -58,4 +61,4 @@
|
||||||
:optimizations :advanced
|
:optimizations :advanced
|
||||||
:pretty-print false}}}}}
|
:pretty-print false}}}}}
|
||||||
|
|
||||||
:test {:source-paths ["dev" "test/clj" "test"]}})
|
:test {:source-paths ["test/core" "test/clj" "test/cljs"]}})
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
(ns mount.core
|
(ns mount.core
|
||||||
#?(:clj (:require [mount.tools.macro :refer [on-error throw-runtime] :as macro])
|
#?(:clj (:require [mount.tools.macro :refer [on-error throw-runtime] :as macro])
|
||||||
:cljs (:require [mount.tools.macro :as macro]
|
:cljs (:require [mount.tools.macro :as macro]))
|
||||||
[mount.tools.cljs :as cljs]))
|
#?(:cljs (:require-macros [mount.core]
|
||||||
#?(:cljs (:require-macros [mount.tools.macro :refer [on-error throw-runtime]])))
|
[mount.tools.macro :refer [on-error throw-runtime]])))
|
||||||
|
|
||||||
(defonce ^:private -args (atom :no-args)) ;; mostly for command line args and external files
|
(defonce ^:private -args (atom :no-args)) ;; mostly for command line args and external files
|
||||||
(defonce ^:private state-seq (atom 0))
|
(defonce ^:private state-seq (atom 0))
|
||||||
|
|
@ -35,8 +35,7 @@
|
||||||
|
|
||||||
(defn- pounded? [f]
|
(defn- pounded? [f]
|
||||||
(let [pound "(fn* [] "] ;;TODO: think of a better (i.e. typed) way to distinguish #(f params) from (fn [params] (...)))
|
(let [pound "(fn* [] "] ;;TODO: think of a better (i.e. typed) way to distinguish #(f params) from (fn [params] (...)))
|
||||||
#?(:clj (.startsWith (str f) pound)
|
(.startsWith (str f) pound)))
|
||||||
:cljs (cljs/starts-with? (str f) pound))))
|
|
||||||
|
|
||||||
(defn unpound [f]
|
(defn unpound [f]
|
||||||
(if (pounded? f)
|
(if (pounded? f)
|
||||||
|
|
@ -50,6 +49,7 @@
|
||||||
it is meant to be called by defstate before defining a new state"
|
it is meant to be called by defstate before defining a new state"
|
||||||
[state]
|
[state]
|
||||||
(when-let [stop (@running state)]
|
(when-let [stop (@running state)]
|
||||||
|
(prn (str "<< stopping.. " state " (namespace was recompiled)"))
|
||||||
(stop)
|
(stop)
|
||||||
(swap! running dissoc state)))
|
(swap! running dissoc state)))
|
||||||
|
|
||||||
|
|
@ -127,11 +127,11 @@
|
||||||
(up name state (atom #{})))
|
(up name state (atom #{})))
|
||||||
@inst)))
|
@inst)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
(defmacro defstate [state & body]
|
(defmacro defstate [state & body]
|
||||||
(let [[state params] (macro/name-with-attributes state body)
|
(let [[state params] (macro/name-with-attributes state body)
|
||||||
{:keys [start stop suspend resume] :as lifecycle} (apply hash-map params)
|
{:keys [start stop suspend resume] :as lifecycle} (apply hash-map params)
|
||||||
state-name (with-ns #?(:clj *ns*
|
state-name (with-ns *ns* state)
|
||||||
:cljs (cljs/this-ns)) state) ;; on cljs side (cljs.analyzer/*cljs-ns*) may do it, but still might not be good for :advanced
|
|
||||||
order (make-state-seq state-name)
|
order (make-state-seq state-name)
|
||||||
sym (str state)]
|
sym (str state)]
|
||||||
(validate lifecycle)
|
(validate lifecycle)
|
||||||
|
|
@ -144,9 +144,18 @@
|
||||||
resume (assoc :resume `(fn [] ~resume)))]
|
resume (assoc :resume `(fn [] ~resume)))]
|
||||||
`(do
|
`(do
|
||||||
(def ~state (DerefableState. ~state-name))
|
(def ~state (DerefableState. ~state-name))
|
||||||
((var update-meta!) [~state-name] (assoc ~s-meta :inst (atom (NotStartedState. ~state-name))
|
((var mount.core/update-meta!) [~state-name] (assoc ~s-meta :inst (atom (NotStartedState. ~state-name))
|
||||||
:var (var ~state)))
|
:var (var ~state)))
|
||||||
(var ~state)))))
|
(var ~state))))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defmacro defstate! [state & {:keys [start! stop!]}]
|
||||||
|
(let [state-name (with-ns *ns* state)]
|
||||||
|
`(defstate ~state
|
||||||
|
:start (~'let [~state (mount/current-state ~state-name)]
|
||||||
|
~start!)
|
||||||
|
:stop (~'let [~state (mount/current-state ~state-name)]
|
||||||
|
~stop!)))))
|
||||||
|
|
||||||
(defn in-cljc-mode []
|
(defn in-cljc-mode []
|
||||||
(reset! mode :cljc))
|
(reset! mode :cljc))
|
||||||
|
|
@ -182,7 +191,7 @@
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(defn var-to-str [v]
|
(defn var-to-str [v]
|
||||||
(if (var? v)
|
(if (instance? cljs.core.Var v)
|
||||||
(let [{:keys [ns name]} (meta v)]
|
(let [{:keys [ns name]} (meta v)]
|
||||||
(with-ns ns name))
|
(with-ns ns name))
|
||||||
v)))
|
v)))
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
(ns mount.tools.cljs
|
|
||||||
(:require [cljs.analyzer :as ana]
|
|
||||||
[goog.string :as gstring]))
|
|
||||||
|
|
||||||
(defn this-ns []
|
|
||||||
ana/*cljs-ns*)
|
|
||||||
|
|
||||||
(defn starts-with? [s pre]
|
|
||||||
(gstring/startsWith s pre))
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
(ns mount.tools.macro)
|
(ns mount.tools.macro
|
||||||
|
#?(:cljs (:require-macros [mount.tools.macro])))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
(defmacro on-error [msg f]
|
(defmacro on-error [msg f]
|
||||||
`(try
|
`(try
|
||||||
~f
|
~f
|
||||||
(catch #?(:clj Throwable
|
(catch #?(:clj Throwable
|
||||||
:cljs :default) t#
|
:cljs :default) t#
|
||||||
(throw #?(:clj (RuntimeException. ~msg t#)
|
(throw #?(:clj (RuntimeException. ~msg t#)
|
||||||
:cljs (js/Error (str ~msg (.-stack t#))))))))
|
:cljs (js/Error (str ~msg (.-stack t#)))))))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
(defmacro throw-runtime [msg]
|
(defmacro throw-runtime [msg]
|
||||||
`(throw #?(:clj (RuntimeException. ~msg)
|
`(throw #?(:clj (RuntimeException. ~msg)
|
||||||
:cljs (js/Error (str ~msg)))))
|
:cljs (js/Error (str ~msg))))))
|
||||||
|
|
||||||
;; this is a one to one copy from https://github.com/clojure/tools.macro
|
;; this is a one to one copy from https://github.com/clojure/tools.macro
|
||||||
;; to avoid a lib dependency for a single function
|
;; to avoid a lib dependency for a single function
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
(ns app.conf
|
(ns tapp.conf
|
||||||
(:require [mount.core :as mount :refer [defstate]]
|
(:require [mount.core :as mount :refer [defstate]]
|
||||||
[clojure.edn :as edn]
|
[clojure.edn :as edn]
|
||||||
[clojure.tools.logging :refer [info]]))
|
[clojure.tools.logging :refer [info]]))
|
||||||
|
|
||||||
|
(alter-meta! *ns* assoc ::load false)
|
||||||
|
|
||||||
(defn load-config [path]
|
(defn load-config [path]
|
||||||
(info "loading config from" path)
|
(info "loading config from" path)
|
||||||
(-> path
|
(-> path
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
(ns app.example
|
(ns tapp.example
|
||||||
(:require [datomic.api :as d]
|
(:require [datomic.api :as d]
|
||||||
[clojure.tools.nrepl.server :refer [start-server stop-server]]
|
[clojure.tools.nrepl.server :refer [start-server stop-server]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.utils.datomic :refer [touch]]
|
[tapp.utils.datomic :refer [touch]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.nyse :as nyse]))
|
[tapp.nyse :as nyse]))
|
||||||
|
|
||||||
|
(alter-meta! *ns* assoc ::load false)
|
||||||
|
|
||||||
;; example on creating a network REPL
|
;; example on creating a network REPL
|
||||||
(defn- start-nrepl [{:keys [host port]}]
|
(defn- start-nrepl [{:keys [host port]}]
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
(ns app.nyse
|
(ns tapp.nyse
|
||||||
(:require [mount.core :as mount :refer [defstate]]
|
(:require [mount.core :as mount :refer [defstate]]
|
||||||
[datomic.api :as d]
|
[datomic.api :as d]
|
||||||
[clojure.tools.logging :refer [info]]
|
[clojure.tools.logging :refer [info]]
|
||||||
[app.conf :refer [config]]))
|
[tapp.conf :refer [config]]))
|
||||||
|
|
||||||
|
(alter-meta! *ns* assoc ::load false)
|
||||||
|
|
||||||
(defn- new-connection [conf]
|
(defn- new-connection [conf]
|
||||||
(info "conf: " conf)
|
(info "conf: " conf)
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
(ns app.utils.datomic
|
(ns tapp.utils.datomic
|
||||||
(:require [datomic.api :as d]))
|
(:require [datomic.api :as d]))
|
||||||
|
|
||||||
|
(alter-meta! *ns* assoc ::load false)
|
||||||
|
|
||||||
(defn entity [conn id]
|
(defn entity [conn id]
|
||||||
(d/entity (d/db conn) id))
|
(d/entity (d/db conn) id))
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
(ns app.utils.logging ;; << change to your namespace/path
|
(ns tapp.utils.logging ;; << change to your namespace/path
|
||||||
(:require [mount.core]
|
(:require [mount.core]
|
||||||
[robert.hooke :refer [add-hook clear-hooks]]
|
[robert.hooke :refer [add-hook clear-hooks]]
|
||||||
[clojure.string :refer [split]]
|
[clojure.string :refer [split]]
|
||||||
25
test/cljs/tapp/audit_log.cljs
Normal file
25
test/cljs/tapp/audit_log.cljs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
(ns tapp.audit-log
|
||||||
|
(:require [datascript.core :as d]
|
||||||
|
[cljs-time.core :refer [now]])
|
||||||
|
(:require-macros [mount.core :refer [defstate]]))
|
||||||
|
|
||||||
|
(defstate log :start (d/create-conn {}))
|
||||||
|
|
||||||
|
(defn audit [db source & msg]
|
||||||
|
(d/transact! @db [{:db/id -1
|
||||||
|
:source source
|
||||||
|
:timestamp (now)
|
||||||
|
:msg (apply str msg)}]))
|
||||||
|
|
||||||
|
(defn find-source-logs [db source]
|
||||||
|
(d/q '{:find [?t ?msg]
|
||||||
|
:in [$ ?s]
|
||||||
|
:where [[?e :source ?s]
|
||||||
|
[?e :timestamp ?t]
|
||||||
|
[?e :msg ?msg]]}
|
||||||
|
@@db source))
|
||||||
|
|
||||||
|
(defn find-all-logs [db]
|
||||||
|
(->> (map :e (d/datoms @@db :aevt :timestamp))
|
||||||
|
dedupe
|
||||||
|
(d/pull-many @@db '[:timestamp :source :msg])))
|
||||||
9
test/cljs/tapp/conf.cljs
Normal file
9
test/cljs/tapp/conf.cljs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
(ns tapp.conf
|
||||||
|
(:require [tapp.audit-log :refer [audit log]])
|
||||||
|
(:require-macros [mount.core :refer [defstate]]))
|
||||||
|
|
||||||
|
(defn load-config [path]
|
||||||
|
(audit log :app-conf "loading config from '" path "' (at least pretending)")
|
||||||
|
{:system-a {:uri "ws://echo.websocket.org/"}})
|
||||||
|
|
||||||
|
(defstate config :start (load-config "resources/config.end"))
|
||||||
26
test/cljs/tapp/example.cljs
Normal file
26
test/cljs/tapp/example.cljs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
(ns tapp.example
|
||||||
|
(:require [mount.core :as mount]
|
||||||
|
[tapp.conf]
|
||||||
|
[tapp.websockets]
|
||||||
|
[tapp.audit-log :refer [log find-all-logs]]
|
||||||
|
[cljs-time.format :refer [unparse formatters]]
|
||||||
|
[hiccups.runtime :as hiccupsrt])
|
||||||
|
(:require-macros [hiccups.core :as hiccups :refer [html]]))
|
||||||
|
|
||||||
|
(defn format-log-event [{:keys [timestamp source msg]}]
|
||||||
|
(str (unparse (formatters :date-hour-minute-second-fraction) timestamp)
|
||||||
|
" → [" (name source) "]: " msg))
|
||||||
|
|
||||||
|
(defn show-log []
|
||||||
|
(.write js/document
|
||||||
|
(html [:ul (doall (for [e (find-all-logs log)]
|
||||||
|
[:li (format-log-event e)]))])))
|
||||||
|
|
||||||
|
(mount/start)
|
||||||
|
|
||||||
|
;; time to establish a websocket connection before disconnecting
|
||||||
|
(js/setTimeout #(mount/stop-except "#'tapp.audit-log/log") 500)
|
||||||
|
|
||||||
|
;; time to close a connection to show it in audit
|
||||||
|
(js/setTimeout #(show-log) 1000)
|
||||||
|
|
||||||
22
test/cljs/tapp/websockets.cljs
Normal file
22
test/cljs/tapp/websockets.cljs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
(ns tapp.websockets
|
||||||
|
(:require [tapp.conf :refer [config]]
|
||||||
|
[tapp.audit-log :refer [audit log]])
|
||||||
|
(:require-macros [mount.core :refer [defstate]]))
|
||||||
|
|
||||||
|
(defn ws-status [ws]
|
||||||
|
{:url (.-url ws) :ready-state (.-readyState ws)})
|
||||||
|
|
||||||
|
(defn connect [uri]
|
||||||
|
(let [ws (js/WebSocket. uri)]
|
||||||
|
(audit log :system-a "connecting to " (ws-status ws))
|
||||||
|
(set! (.-onopen ws) #(audit log :system-a "opened " (ws-status ws)))
|
||||||
|
(set! (.-onclose ws) #(audit log :system-a "closed " (ws-status ws)))
|
||||||
|
ws))
|
||||||
|
|
||||||
|
(defn disconnect [ws]
|
||||||
|
(audit log :system-a "closing " (ws-status @ws))
|
||||||
|
(.close @ws)
|
||||||
|
(audit log :system-a "disconnecting " (ws-status @ws)))
|
||||||
|
|
||||||
|
(defstate system-a :start (connect (get-in @config [:system-a :uri]))
|
||||||
|
:stop (disconnect system-a))
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
mount.test.suspend-resume
|
mount.test.suspend-resume
|
||||||
))
|
))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(mount.core/in-cljc-mode)
|
(mount.core/in-cljc-mode)
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
|
|
@ -2,23 +2,25 @@
|
||||||
(:require
|
(:require
|
||||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer-macros [defstate]]
|
[mount.core :as mount :refer-macros [defstate]]
|
||||||
[app.websockets :refer [system-a]]
|
[tapp.websockets :refer [system-a]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.audit-log :refer [log]]]
|
[tapp.audit-log :refer [log]]]
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.example]])
|
[tapp.example]])
|
||||||
[mount.test.helper :refer [dval helper forty-two]]))
|
[mount.test.helper :refer [dval helper forty-two]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(deftest cleanup-dirty-states
|
(deftest cleanup-dirty-states
|
||||||
(let [_ (mount/start)]
|
(let [_ (mount/start)]
|
||||||
(is (not (.isClosed (:server-socket (dval app.example/nrepl)))))
|
(is (not (.isClosed (:server-socket (dval tapp.example/nrepl)))))
|
||||||
(require 'app.example :reload)
|
(require 'tapp.example :reload)
|
||||||
(mount/start) ;; should not result in "BindException Address already in use" since the clean up will stop the previous instance
|
(mount/start) ;; should not result in "BindException Address already in use" since the clean up will stop the previous instance
|
||||||
(is (not (.isClosed (:server-socket (dval app.example/nrepl)))))
|
(is (not (.isClosed (:server-socket (dval tapp.example/nrepl)))))
|
||||||
(mount/stop)
|
(mount/stop)
|
||||||
(is (instance? mount.core.NotStartedState (dval app.example/nrepl))))))
|
(is (instance? mount.core.NotStartedState (dval tapp.example/nrepl))))))
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(deftest cleanup-dirty-states
|
(deftest cleanup-dirty-states
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]])))
|
[mount.core :as mount :refer [defstate]]])))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(defn f [n]
|
(defn f [n]
|
||||||
(fn [m]
|
(fn [m]
|
||||||
(+ n m)))
|
(+ n m)))
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
#?@(:cljs [[mount.core :as mount :refer-macros [defstate]]]
|
#?@(:cljs [[mount.core :as mount :refer-macros [defstate]]]
|
||||||
:clj [[mount.core :as mount :refer [defstate]]])))
|
:clj [[mount.core :as mount :refer [defstate]]])))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(defn dval
|
(defn dval
|
||||||
"returns a value of DerefableState without deref'ing it"
|
"returns a value of DerefableState without deref'ing it"
|
||||||
[d]
|
[d]
|
||||||
|
|
@ -2,24 +2,26 @@
|
||||||
(:require
|
(:require
|
||||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer-macros [defstate]]
|
[mount.core :as mount :refer-macros [defstate]]
|
||||||
[app.websockets :refer [system-a]]
|
[tapp.websockets :refer [system-a]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.audit-log :refer [log]]]
|
[tapp.audit-log :refer [log]]]
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.nyse :refer [conn]]])
|
[tapp.nyse :refer [conn]]])
|
||||||
[mount.test.helper :refer [dval]]))
|
[mount.test.helper :refer [dval]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(defstate should-not-start :start (constantly 42))
|
(defstate should-not-start :start (constantly 42))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn with-parts [f]
|
(defn with-parts [f]
|
||||||
(mount/start #'app.conf/config #'app.nyse/conn)
|
(mount/start #'tapp.conf/config #'tapp.nyse/conn)
|
||||||
(f)
|
(f)
|
||||||
(mount/stop)))
|
(mount/stop)))
|
||||||
|
|
||||||
(use-fixtures :once
|
(use-fixtures :once
|
||||||
#?(:cljs {:before #(mount/start #'app.conf/config #'app.audit-log/log)
|
#?(:cljs {:before #(mount/start #'tapp.conf/config #'tapp.audit-log/log)
|
||||||
:after mount/stop}
|
:after mount/stop}
|
||||||
:clj with-parts))
|
:clj with-parts))
|
||||||
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
[mount.test.fun-with-values :refer [private-f]]))
|
[mount.test.fun-with-values :refer [private-f]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(use-fixtures :once
|
(use-fixtures :once
|
||||||
#?(:cljs {:before #(mount/start #'mount.test.fun-with-values/private-f)
|
#?(:cljs {:before #(mount/start #'mount.test.fun-with-values/private-f)
|
||||||
:after mount/stop}
|
:after mount/stop}
|
||||||
|
|
@ -2,16 +2,18 @@
|
||||||
(:require
|
(:require
|
||||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer-macros [defstate]]
|
[mount.core :as mount :refer-macros [defstate]]
|
||||||
[app.websockets :refer [system-a]]
|
[tapp.websockets :refer [system-a]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.audit-log :refer [log]]]
|
[tapp.audit-log :refer [log]]]
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.nyse :refer [conn]]
|
[tapp.nyse :refer [conn]]
|
||||||
[app.example :refer [nrepl]]])
|
[tapp.example :refer [nrepl]]])
|
||||||
[mount.test.helper :refer [dval helper]]))
|
[mount.test.helper :refer [dval helper]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(defstate test-conn :start 42
|
(defstate test-conn :start 42
|
||||||
:stop (constantly 0))
|
:stop (constantly 0))
|
||||||
|
|
||||||
|
|
@ -21,7 +23,7 @@
|
||||||
(deftest start-with
|
(deftest start-with
|
||||||
|
|
||||||
(testing "should start with substitutes"
|
(testing "should start with substitutes"
|
||||||
(let [_ (mount/start-with {#'app.websockets/system-a #'mount.test.start-with/test-conn
|
(let [_ (mount/start-with {#'tapp.websockets/system-a #'mount.test.start-with/test-conn
|
||||||
#'mount.test.helper/helper #'mount.test.start-with/test-nrepl})]
|
#'mount.test.helper/helper #'mount.test.start-with/test-nrepl})]
|
||||||
(is (map? (dval config)))
|
(is (map? (dval config)))
|
||||||
(is (vector? (dval helper)))
|
(is (vector? (dval helper)))
|
||||||
|
|
@ -30,7 +32,7 @@
|
||||||
(mount/stop)))
|
(mount/stop)))
|
||||||
|
|
||||||
(testing "should not start the substitute itself"
|
(testing "should not start the substitute itself"
|
||||||
(let [_ (mount/start-with {#'app.websockets/system-a #'mount.test.start-with/test-conn})]
|
(let [_ (mount/start-with {#'tapp.websockets/system-a #'mount.test.start-with/test-conn})]
|
||||||
(is (instance? mount.core.NotStartedState (dval test-conn)))
|
(is (instance? mount.core.NotStartedState (dval test-conn)))
|
||||||
(is (= 42 (dval system-a)))
|
(is (= 42 (dval system-a)))
|
||||||
(mount/stop)))
|
(mount/stop)))
|
||||||
|
|
@ -60,15 +62,15 @@
|
||||||
(deftest start-with
|
(deftest start-with
|
||||||
|
|
||||||
(testing "should start with substitutes"
|
(testing "should start with substitutes"
|
||||||
(let [_ (mount/start-with {#'app.nyse/conn #'mount.test.start-with/test-conn
|
(let [_ (mount/start-with {#'tapp.nyse/conn #'mount.test.start-with/test-conn
|
||||||
#'app.example/nrepl #'mount.test.start-with/test-nrepl})]
|
#'tapp.example/nrepl #'mount.test.start-with/test-nrepl})]
|
||||||
(is (map? (dval config)))
|
(is (map? (dval config)))
|
||||||
(is (vector? (dval nrepl)))
|
(is (vector? (dval nrepl)))
|
||||||
(is (= (dval conn) 42))
|
(is (= (dval conn) 42))
|
||||||
(mount/stop)))
|
(mount/stop)))
|
||||||
|
|
||||||
(testing "should not start the substitute itself"
|
(testing "should not start the substitute itself"
|
||||||
(let [_ (mount/start-with {#'app.nyse/conn #'mount.test.start-with/test-conn})]
|
(let [_ (mount/start-with {#'tapp.nyse/conn #'mount.test.start-with/test-conn})]
|
||||||
(is (instance? mount.core.NotStartedState (dval test-conn)))
|
(is (instance? mount.core.NotStartedState (dval test-conn)))
|
||||||
(is (= (dval conn) 42))
|
(is (= (dval conn) 42))
|
||||||
(mount/stop)))
|
(mount/stop)))
|
||||||
|
|
@ -2,24 +2,26 @@
|
||||||
(:require
|
(:require
|
||||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer-macros [defstate]]
|
[mount.core :as mount :refer-macros [defstate]]
|
||||||
[app.websockets :refer [system-a]]
|
[tapp.websockets :refer [system-a]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.audit-log :refer [log]]]
|
[tapp.audit-log :refer [log]]]
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.nyse :refer [conn]]
|
[tapp.nyse :refer [conn]]
|
||||||
[app.example :refer [nrepl]]])
|
[tapp.example :refer [nrepl]]])
|
||||||
[mount.test.helper :refer [dval helper]]))
|
[mount.test.helper :refer [dval helper]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn without [f]
|
(defn without [f]
|
||||||
(mount/start-without #'app.nyse/conn #'app.example/nrepl)
|
(mount/start-without #'tapp.nyse/conn #'tapp.example/nrepl)
|
||||||
(f)
|
(f)
|
||||||
(mount/stop)))
|
(mount/stop)))
|
||||||
|
|
||||||
(use-fixtures :once
|
(use-fixtures :once
|
||||||
#?(:cljs {:before #(mount/start-without #'mount.test.helper/helper #'app.websockets/system-a)
|
#?(:cljs {:before #(mount/start-without #'mount.test.helper/helper #'tapp.websockets/system-a)
|
||||||
:after mount/stop}
|
:after mount/stop}
|
||||||
:clj without))
|
:clj without))
|
||||||
|
|
||||||
|
|
@ -2,22 +2,24 @@
|
||||||
(:require
|
(:require
|
||||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer-macros [defstate]]
|
[mount.core :as mount :refer-macros [defstate]]
|
||||||
[app.websockets :refer [system-a]]
|
[tapp.websockets :refer [system-a]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.audit-log :refer [log]]]
|
[tapp.audit-log :refer [log]]]
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.nyse :refer [conn]]
|
[tapp.nyse :refer [conn]]
|
||||||
[app.example :refer [nrepl]]])
|
[tapp.example :refer [nrepl]]])
|
||||||
[mount.test.helper :refer [dval helper]]))
|
[mount.test.helper :refer [dval helper]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(deftest stop-except
|
(deftest stop-except
|
||||||
|
|
||||||
(testing "should stop all except nrepl"
|
(testing "should stop all except nrepl"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/stop-except #'app.audit-log/log #'mount.test.helper/helper)]
|
_ (mount/stop-except #'tapp.audit-log/log #'mount.test.helper/helper)]
|
||||||
(is (= :started (dval helper)))
|
(is (= :started (dval helper)))
|
||||||
(is (instance? datascript.db/DB @(dval log)))
|
(is (instance? datascript.db/DB @(dval log)))
|
||||||
(is (instance? mount.core.NotStartedState (dval config)))
|
(is (instance? mount.core.NotStartedState (dval config)))
|
||||||
|
|
@ -33,7 +35,7 @@
|
||||||
|
|
||||||
(testing "should stop all normally after stop-except"
|
(testing "should stop all normally after stop-except"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/stop-except #'app.audit-log/log #'mount.test.helper/helper)
|
_ (mount/stop-except #'tapp.audit-log/log #'mount.test.helper/helper)
|
||||||
_ (mount/stop)]
|
_ (mount/stop)]
|
||||||
(is (instance? mount.core.NotStartedState (dval config)))
|
(is (instance? mount.core.NotStartedState (dval config)))
|
||||||
(is (instance? mount.core.NotStartedState (dval log)))
|
(is (instance? mount.core.NotStartedState (dval log)))
|
||||||
|
|
@ -44,7 +46,7 @@
|
||||||
|
|
||||||
(testing "should stop all except nrepl"
|
(testing "should stop all except nrepl"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/stop-except #'app.nyse/conn #'app.conf/config)]
|
_ (mount/stop-except #'tapp.nyse/conn #'tapp.conf/config)]
|
||||||
(is (map? (dval config)))
|
(is (map? (dval config)))
|
||||||
(is (instance? datomic.peer.LocalConnection (dval conn)))
|
(is (instance? datomic.peer.LocalConnection (dval conn)))
|
||||||
(is (instance? mount.core.NotStartedState (dval nrepl)))
|
(is (instance? mount.core.NotStartedState (dval nrepl)))
|
||||||
|
|
@ -59,7 +61,7 @@
|
||||||
|
|
||||||
(testing "should stop all normally after stop-except"
|
(testing "should stop all normally after stop-except"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/stop-except #'app.nyse/conn #'app.conf/config)
|
_ (mount/stop-except #'tapp.nyse/conn #'tapp.conf/config)
|
||||||
_ (mount/stop)]
|
_ (mount/stop)]
|
||||||
(is (instance? mount.core.NotStartedState (dval config)))
|
(is (instance? mount.core.NotStartedState (dval config)))
|
||||||
(is (instance? mount.core.NotStartedState (dval conn)))
|
(is (instance? mount.core.NotStartedState (dval conn)))
|
||||||
|
|
@ -2,16 +2,18 @@
|
||||||
(:require
|
(:require
|
||||||
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
#?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer-macros [defstate]]
|
[mount.core :as mount :refer-macros [defstate]]
|
||||||
[app.websockets :refer [system-a]]
|
[tapp.websockets :refer [system-a]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.audit-log :refer [log]]]
|
[tapp.audit-log :refer [log]]]
|
||||||
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
:clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[app.conf :refer [config]]
|
[tapp.conf :refer [config]]
|
||||||
[app.nyse :refer [conn]]
|
[tapp.nyse :refer [conn]]
|
||||||
[app.example :refer [nrepl]]])
|
[tapp.example :refer [nrepl]]])
|
||||||
[mount.test.helper :refer [dval]]))
|
[mount.test.helper :refer [dval]]))
|
||||||
|
|
||||||
|
#?(:clj (alter-meta! *ns* assoc ::load false))
|
||||||
|
|
||||||
(defn koncat [k s]
|
(defn koncat [k s]
|
||||||
(-> (name k)
|
(-> (name k)
|
||||||
(str "-" (name s))
|
(str "-" (name s))
|
||||||
|
|
@ -48,7 +50,7 @@
|
||||||
|
|
||||||
(testing "should resume _only suspendable_ states that are currently suspended"
|
(testing "should resume _only suspendable_ states that are currently suspended"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/stop #'app.websockets/system-a)
|
_ (mount/stop #'tapp.websockets/system-a)
|
||||||
_ (mount/suspend)
|
_ (mount/suspend)
|
||||||
_ (mount/resume)]
|
_ (mount/resume)]
|
||||||
(is (map? (dval config)))
|
(is (map? (dval config)))
|
||||||
|
|
@ -82,7 +84,7 @@
|
||||||
(testing "when replacing a non suspendable state with a suspendable one,
|
(testing "when replacing a non suspendable state with a suspendable one,
|
||||||
the later should be able to suspend/resume,
|
the later should be able to suspend/resume,
|
||||||
the original should not be suspendable after resume and preserve its lifecycle fns after rollback/stop"
|
the original should not be suspendable after resume and preserve its lifecycle fns after rollback/stop"
|
||||||
(let [_ (mount/start-with {#'app.websockets/system-a #'mount.test.suspend-resume/web-server})
|
(let [_ (mount/start-with {#'tapp.websockets/system-a #'mount.test.suspend-resume/web-server})
|
||||||
_ (mount/suspend)]
|
_ (mount/suspend)]
|
||||||
(is (= (dval system-a) :w-suspended))
|
(is (= (dval system-a) :w-suspended))
|
||||||
(is (instance? mount.core.NotStartedState (dval web-server)))
|
(is (instance? mount.core.NotStartedState (dval web-server)))
|
||||||
|
|
@ -107,7 +109,7 @@
|
||||||
|
|
||||||
(testing "should resume _only suspendable_ states that are currently suspended"
|
(testing "should resume _only suspendable_ states that are currently suspended"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/stop #'app.example/nrepl)
|
_ (mount/stop #'tapp.example/nrepl)
|
||||||
_ (mount/suspend)
|
_ (mount/suspend)
|
||||||
_ (mount/resume)]
|
_ (mount/resume)]
|
||||||
(is (map? (dval config)))
|
(is (map? (dval config)))
|
||||||
|
|
@ -142,7 +144,7 @@
|
||||||
(testing "when replacing a non suspendable state with a suspendable one,
|
(testing "when replacing a non suspendable state with a suspendable one,
|
||||||
the later should be able to suspend/resume,
|
the later should be able to suspend/resume,
|
||||||
the original should not be suspendable after resume and preserve its lifecycle fns after rollback/stop"
|
the original should not be suspendable after resume and preserve its lifecycle fns after rollback/stop"
|
||||||
(let [_ (mount/start-with {#'app.example/nrepl #'mount.test.suspend-resume/web-server})
|
(let [_ (mount/start-with {#'tapp.example/nrepl #'mount.test.suspend-resume/web-server})
|
||||||
_ (mount/suspend)]
|
_ (mount/suspend)]
|
||||||
(is (= (dval nrepl) :w-suspended))
|
(is (= (dval nrepl) :w-suspended))
|
||||||
(is (instance? mount.core.NotStartedState (dval web-server)))
|
(is (instance? mount.core.NotStartedState (dval web-server)))
|
||||||
|
|
@ -176,7 +178,7 @@
|
||||||
the original should still be suspended and preserve its lifecycle fns after the rollback/stop"
|
the original should still be suspended and preserve its lifecycle fns after the rollback/stop"
|
||||||
(let [_ (mount/start)
|
(let [_ (mount/start)
|
||||||
_ (mount/suspend)
|
_ (mount/suspend)
|
||||||
_ (mount/start-with {#'mount.test.suspend-resume/web-server #'app.nyse/conn}) ;; TODO: good to WARN on started states during "start-with"
|
_ (mount/start-with {#'mount.test.suspend-resume/web-server #'tapp.nyse/conn}) ;; TODO: good to WARN on started states during "start-with"
|
||||||
_ (mount/suspend)]
|
_ (mount/suspend)]
|
||||||
(is (instance? datomic.peer.LocalConnection (dval conn)))
|
(is (instance? datomic.peer.LocalConnection (dval conn)))
|
||||||
(is (= (dval web-server) :w-suspended)) ;; since the "conn" does not have a resume method, so web-server was not started
|
(is (= (dval web-server) :w-suspended)) ;; since the "conn" does not have a resume method, so web-server was not started
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
(:require [clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
(:require [clojure.test :as t :refer [is are deftest testing use-fixtures]]
|
||||||
[mount.core :as mount :refer [defstate]]))
|
[mount.core :as mount :refer [defstate]]))
|
||||||
|
|
||||||
|
(alter-meta! *ns* assoc ::load false)
|
||||||
|
|
||||||
(defn f [n]
|
(defn f [n]
|
||||||
(fn [m]
|
(fn [m]
|
||||||
(+ n m)))
|
(+ n m)))
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
[mount.core :as mount :refer [defstate]]
|
[mount.core :as mount :refer [defstate]]
|
||||||
[mount.test.var.fun-with-values :refer [private-f]]))
|
[mount.test.var.fun-with-values :refer [private-f]]))
|
||||||
|
|
||||||
|
(alter-meta! *ns* assoc ::load false)
|
||||||
|
|
||||||
(defn in-clj-mode [f]
|
(defn in-clj-mode [f]
|
||||||
(mount/in-clj-mode)
|
(mount/in-clj-mode)
|
||||||
(require :reload 'mount.test.var.fun-with-values 'mount.test.var.private-fun)
|
(require :reload 'mount.test.var.fun-with-values 'mount.test.var.private-fun)
|
||||||
1
test/resources/mount.cljs.edn
Normal file
1
test/resources/mount.cljs.edn
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{:require [mount.test]}
|
||||||
Loading…
Reference in a new issue