diff --git a/dev/clj/dev.clj b/dev/clj/dev.clj index 3fccfd4..d40d96d 100644 --- a/dev/clj/dev.clj +++ b/dev/clj/dev.clj @@ -2,7 +2,7 @@ (:require [clojure.pprint :refer [pprint]] [clojure.tools.namespace.repl :as tn] [boot.core :refer [load-data-readers!]] - [mount.core :as mount] + [mount.core :as mount :refer [defstate]] [mount.tools.graph :refer [states-with-deps]] [app.utils.logging :refer [with-logging-status]] [app.www] diff --git a/src/mount/core.cljc b/src/mount/core.cljc index ce16159..d09c26a 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -188,10 +188,25 @@ (with-ns ns name)) v))) +(defn- state-to-sym [state] + (->> state (drop 2) (apply str) symbol)) ;; magic 2 is removing "#'" in state name + +(defn- was-removed? + "checks if a state was removed from a namespace" + [state] + (-> state state-to-sym resolve not)) + +(defn cleanup-deleted [state] + (when (was-removed? state) + (cleanup-if-dirty state) + (swap! meta-state dissoc state))) + (defn- bring [states fun order] (let [done (atom [])] (as-> states $ (map var-to-str $) + #?(:clj ;; needs more thking in cljs, since based on sym resolve + (remove cleanup-deleted $)) (select-keys @meta-state $) (sort-by (comp :order val) order $) (doseq [[k v] $] (fun k v done))) diff --git a/test/core/mount/test/cleanup_deleted_states.cljc b/test/core/mount/test/cleanup_deleted_states.cljc new file mode 100644 index 0000000..79d7a38 --- /dev/null +++ b/test/core/mount/test/cleanup_deleted_states.cljc @@ -0,0 +1,40 @@ +(ns mount.test.cleanup-deleted-states + (:require + #?@(:cljs [[cljs.test :as t :refer-macros [is are deftest testing use-fixtures]] + [mount.core :as mount :refer-macros [defstate]] + [tapp.websockets :refer [system-a]] + [tapp.conf :refer [config]] + [tapp.audit-log :refer [log]]] + :clj [[clojure.test :as t :refer [is are deftest testing use-fixtures]] + [mount.core :as mount :refer [defstate]] + [tapp.example]]) + [mount.test.helper :refer [dval helper forty-two]])) + +(def status (atom :a-not-started)) +(defstate a :start (reset! status :a-started) + :stop (reset! status :a-stopped)) + +#?(:clj (alter-meta! *ns* assoc ::load false)) + +#?(:clj + (deftest cleanup-deleted-state + + (testing "should start all and remove/delete state from ns" + (let [started (-> (mount/start) :started set)] + (is (some #{"#'mount.test.cleanup-deleted-states/a"} + started)) + (is (= :a-started @status)) + (ns-unmap 'mount.test.cleanup-deleted-states 'a) + (is (nil? (resolve 'mount.test.cleanup-deleted-states/a))))) + + (testing "should cleanup/stop a state after it was deleted from ns" + (is (empty? (:started (mount/start)))) ;; on any mount op (not necessarily on "stop") + (is (= :a-stopped @status)) + (is (not (some #{"#'mount.test.cleanup-deleted-states/a"} + (keys @@#'mount.core/meta-state))))) + + (testing "should not stop it again on stop (should not be there by this point)") + (is (not (some #{"#'mount.test.cleanup-deleted-states/a"} + (-> (mount/stop) :stopped set)))))) + +;; (t/run-tests)