Fork me on GitHub
#mount
<
2018-06-27
>
richiardiandrea19:06:16

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.))

richiardiandrea19:06:51

and then a state for the fetch function

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

richiardiandrea19:06:30

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

richiardiandrea19:06:41

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

tolitius19:06:30

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

tolitius19:06:35

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

tolitius19:06:31

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

tolitius19:06:02

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

richiardiandrea19:06:29

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

richiardiandrea19:06:41

so it has to be a function returning a function

tolitius19:06:37

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

richiardiandrea19:06:00

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

richiardiandrea19:06:08

but it seems to trigger the call

richiardiandrea19:06:21

maybe I am doing something wrong

tolitius20:06:21

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

richiardiandrea20:06:14

the schema is parameterized by key at runtime

tolitius20:06:03

right, but you know the key at runtime

tolitius20:06:25

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

richiardiandrea20:06:02

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

richiardiandrea20:06:20

if i do at test time it is a mount state

richiardiandrea20:06:39

but that is probably not going to happen

tolitius20:06:11

> 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

tolitius20:06:34

to keep functions "unaware"

richiardiandrea20:06:31

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

richiardiandrea20:06:01

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

richiardiandrea20:06:28

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

richiardiandrea20:06:53

definitely food for thought for me 😉

tolitius20:06:16

yea, this is all on you 🙂

tolitius20:06:26

I don't believe in the "ultimate truth"

richiardiandrea20:06:05

another thing I have noticed in cljs apps

richiardiandrea20:06:16

I have tests like the following

richiardiandrea20:06:30

(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))))))

richiardiandrea20:06:55

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

richiardiandrea20:06:26

a macro would solve that probably

tolitius20:06:29

does fetch-schema have a :stop function?

tolitius20:06:40

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

richiardiandrea20:06:00

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

tolitius20:06:50

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

richiardiandrea20:06:15

oh I thought I needed to call it anyways

tolitius20:06:28

only if you need to stop something 🙂

richiardiandrea20:06:04

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

tolitius20:06:54

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

richiardiandrea21:06:07

@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)}}))

richiardiandrea21:06:55

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 ?