Back

build (clj)

(source)

function

(build config keys f) (build config keys f assertf) (build config keys f assertf resolvef)
Apply a function f to each key value pair in a configuration map. Keys are traversed in dependency order, and any references in the value expanded. The function should take two arguments, a key and value, and return a new value. An optional fourth argument, assertf, may be supplied to provide an assertion check on the system, key and expanded value.

Examples

integrant
(ns integrant.core-test
  (:require #?(:clj  [clojure.test :refer [are deftest is testing]]
               :cljs [cljs.test :refer-macros [are deftest is testing]])
            [integrant.core :as ig]
            [weavejester.dependency :as dep]))

  (testing "with failing asserts"
    (is (thrown-with-msg?
         #?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
         (re-pattern (str "Assertion failed on key " ::n
                          " when building system"))
         (ig/init {::n (ig/ref ::k), ::k 1.1}))))

  (testing "with failing composite specs"
    (is (thrown-with-msg?
         #?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
         (re-pattern (str "Assertion failed on key \\[" ::n " " ::nnn "\\] "
                          "when building system"))
         (ig/init {[::n ::nnn] 1.1})))))

(defn build-log [config]
  (let [log (atom [])]
    [(ig/build config (keys config)
               (fn [k v] (last (swap! log conj [:build k v]))))
     @log]))

(deftest build-test
  (is (= [{::a [:build ::a [:build ::b 1]]
           ::b [:build ::b 1]}
          [[:build ::b 1]
           [:build ::a [:build ::b 1]]]]
         (build-log {::a (ig/ref ::b)
                     ::b 1}))))

(deftest run-test
  (let [config {::a (ig/ref ::b), ::b 1}
        [system _] (build-log config)]
    (is (= [nil
            [[:test ::b [:build ::b 1]]
             [:test ::a [:build ::a [:build ::b 1]]]]]
           (test-log ig/run! system)))
    (is (= [nil
            [[:test ::a [:build ::a [:build ::b 1]]]
             [:test ::b [:build ::b 1]]]]
           (test-log ig/reverse-run! system)))))

(deftest wrapped-exception-test
  (testing "exception when building"
    (let [ex (try (ig/init {::a 1, ::error-init (ig/ref ::a)}) nil
                  (catch #?(:clj Throwable :cljs :default) t t))]
      (is (some? ex))
      (is (= (#?(:clj .getMessage :cljs ex-message) ex)
             (str "Error on key " ::error-init " when building system")))
      (is (= (ex-data ex)
             {:reason   ::ig/build-threw-exception
              :system   {::a [1]}
              :function ig/init-key
              :key      ::error-init
              :value    [1]}))
      (let [cause (#?(:clj .getCause :cljs ex-cause) ex)]
        (is (some? cause))
        (is (= (#?(:clj .getMessage :cljs ex-message) cause) "Testing"))
        (is (= (ex-data cause) {:reason ::test})))))
Zetawar/zetawar
(ns zetawar.system.game-views
  (:require
   [integrant.core :as ig]
   [posh.reagent :as posh]
   [tongue.core :as tongue]
   [zetawar.data :as data]
   [zetawar.logging :as log]
   [zetawar.router :as router]))

;; TODO: start Reagent components when running in the browser
(defmethod ig/init-key :zetawar.system/game-views [_ opts]
  (let [{:keys [datascript router locale]} opts
        {:keys [conn]} datascript
        {:keys [ev-chan]} router
        dispatch #(router/dispatch ev-chan %)
        translate (-> data/dicts
                      tongue/build-translate
                      (partial locale))]
    (posh/posh! conn)
    {:conn conn
     :dispatch dispatch
     :translate translate}))

(defmethod ig/resume-key :zetawar.system/game-views [_ opts old-opts old-impl]
  (let [{:keys [datascript router locale]} opts
        {:keys [conn]} datascript
        {:keys [ev-chan]} router
        old-conn (get-in old-opts [:datascript :conn])
        dispatch #(router/dispatch ev-chan %)
        translate (-> data/dicts
                      tongue/build-translate
                      (partial locale))]
    (when-not (= conn old-conn)
      (posh/posh! conn))
    {:conn conn
     :dispatch dispatch
     :translate translate}))