mount

richiardiandrea 2018-06-27T19:25:16.000282Z

so an example of what I was talking about is the following. At the moment I have a state for the client.

(defstate ^{:doc "The Azure Blob Service instance

AZURE_STORAGE_CONNECTION_STRING will be used under the hood." }
  blob-service
  :start (az-storage/BlobService.))

richiardiandrea 2018-06-27T19:25:51.000164Z

and then a state for the fetch function

(defstate ^{:doc "A stateful function that fetches the schema files"}
  fetch-schema-fn
  :start do-fetch!)

richiardiandrea 2018-06-27T19:26:30.000066Z

would it be a good idea to drop the blob-service state? in any case I don't see myself mocking the javascript object directly

richiardiandrea 2018-06-27T19:39:41.000058Z

also at the point I would then need to surround each test with (-> (mount/only ..) (mount/swap-states ...))

tolitius 2018-06-27T19:47:30.000048Z

if I understand correctly, I would do something like this:

tolitius 2018-06-27T19:47:35.000333Z

(defstate ^{:doc "the azure connection" }
   az-conn
  :start (az/connect config))
(defstate schemas :start (fetch-schemas az-conn))

tolitius 2018-06-27T19:48:31.000278Z

it is a personal preference, I try to narrow down state to primitives: i.e. connections, thread pools, queues, etc..

tolitius 2018-06-27T19:51:02.000150Z

depending on how schemas are used it might not need to be a separate state

richiardiandrea 2018-06-27T19:56:29.000342Z

yep got it..the only difference in my case is that schemas is on-demand

richiardiandrea 2018-06-27T19:56:41.000212Z

so it has to be a function returning a function

tolitius 2018-06-27T19:57:37.000521Z

ah ok, it's a "factory" (i.e. partial function)

richiardiandrea 2018-06-27T19:58:00.000070Z

yep...btw I am trying {:start #(fetch-schema-success! %)}

richiardiandrea 2018-06-27T19:58:08.000481Z

but it seems to trigger the call

richiardiandrea 2018-06-27T19:58:21.000240Z

maybe I am doing something wrong

tolitius 2018-06-27T19:59:28.000173Z

you probably want something like: https://github.com/tolitius/mount/blob/master/test/core/mount/test/fun_with_values.cljc#L26

tolitius 2018-06-27T20:00:21.000291Z

where is it called from? i.e. why those places can't just call it as (fetch-schema-success! az-conn ...)?

richiardiandrea 2018-06-27T20:01:14.000080Z

the schema is parameterized by key at runtime

tolitius 2018-06-27T20:02:03.000420Z

right, but you know the key at runtime

richiardiandrea 2018-06-27T20:02:10.000400Z

yep

tolitius 2018-06-27T20:02:25.000181Z

and you have a reference to az-conn, so why close over it?

richiardiandrea 2018-06-27T20:03:02.000145Z

well why not? I am never going to need to pass another conn

richiardiandrea 2018-06-27T20:03:20.000179Z

if i do at test time it is a mount state

richiardiandrea 2018-06-27T20:03:39.000103Z

but that is probably not going to happen

tolitius 2018-06-27T20:05:11.000132Z

> well why not? I am never going to need to pass the another conn could be a personal preference: I usually minimize the number of stateful components

tolitius 2018-06-27T20:05:34.000059Z

to keep functions "unaware"

richiardiandrea 2018-06-27T20:06:31.000474Z

yep I used to think the same and that is why I was having doubts

richiardiandrea 2018-06-27T20:08:01.000095Z

btw this works for me:

(-> (mount/only #{#'df-svc/fetch-schema-fn})
        (mount/swap-states {#'df-svc/fetch-schema-fn {:start (constantly fetch-schema-success!)}})
        (mount/start))
still torn about passing conn in to everything

richiardiandrea 2018-06-27T20:08:28.000304Z

mount makes it easy NOT to have that and still handle the swap/mock cleanly

richiardiandrea 2018-06-27T20:08:53.000223Z

definitely food for thought for me 😉

tolitius 2018-06-27T20:10:16.000468Z

yea, this is all on you 🙂

tolitius 2018-06-27T20:10:26.000226Z

I don't believe in the "ultimate truth"

richiardiandrea 2018-06-27T20:12:05.000271Z

another thing I have noticed in cljs apps

richiardiandrea 2018-06-27T20:12:16.000056Z

I have tests like the following

richiardiandrea 2018-06-27T20:12:30.000299Z

(testing "successfully fetching a definition schema - mocking the providers"

    (-> (mount/only #{#'df-svc/fetch-schema-fn})
        (mount/swap-states {#'df-svc/fetch-schema-fn {:start (constantly fetch-schema-success!)}})
        (mount/start))

    (let [event {:data #js {:amount 2.5 :method "cash"}
                 :key "42"
                 :entity "order"
                 :domain "salad-man"
                 :name "payment-added"}
          schema {:title "payment-added",
                  :description "Payment was taken for the order",
                  :properties {:method {:type "string"},
                               :amount {:type "number"}},
                  :required ["method" "amount"]}]
      (tu/async
        (-> (df-svc/fetch-schema! event)
            (.then #(is (= schema (js->clj % :keywordize-keys true)) "should return the right schema"))
            (.then #(mount/stop))))))

richiardiandrea 2018-06-27T20:12:55.000152Z

the last mount/stop kind of bothers me but I understand it is a necessary evil

richiardiandrea 2018-06-27T20:13:26.000013Z

a macro would solve that probably

tolitius 2018-06-27T20:24:29.000281Z

does fetch-schema have a :stop function?

tolitius 2018-06-27T20:25:40.000038Z

or you create az-conn in a :each / :once fixtures?

richiardiandrea 2018-06-27T20:26:00.000492Z

no I just ignore the connection in this test because I am replacing the caller

tolitius 2018-06-27T20:26:50.000346Z

if the only thing that is started is {:start (constantly fetch-schema-success!)} "mount/stop" won't do anything since there are no stop functions

richiardiandrea 2018-06-27T20:27:15.000184Z

oh I thought I needed to call it anyways

tolitius 2018-06-27T20:27:28.000259Z

only if you need to stop something 🙂

richiardiandrea 2018-06-27T20:28:04.000363Z

so derefing a state starts it implicitely...good to know 🙂

tolitius 2018-06-27T20:28:54.000490Z

right, and you would call (mount/stop) to cleanup/destroy, but only when you have things to cleanup/destroy

richiardiandrea 2018-06-27T21:53:07.000296Z

@tolitius so I see a discrepancy that I do not understand:

(defstate fetch-schema-fn
  "A stateful function that fetches the schema files."
  :start do-provider-fetch!)
but in the tests I need
(-> (mount/only #{#'df-svc/fetch-schema-fn})
      (mount/swap-states {#'df-svc/fetch-schema-fn {:start (constantly fn)}}))

richiardiandrea 2018-06-27T21:57:55.000103Z

is there an additional eval going on for swap-states? just wanted to understand the difference...probably it has smth to do with the macro nature of defstate ?