Closed kirillsalykin closed 4 years ago
It's an interesting idea, but why not just change the configuration to use the test key? The effect will be the same without the need to mess around with the hierarchy.
It should be changed more than in one place, right? Also as I mentioned - i dont want the system-map to be changed.
It should be changed more than in one place, right?
What do you mean? You only need to change the keys you want to replace. Everything else, including references, can remain the same.
Also as I mentioned - i dont want the system-map to be changed.
Do you mean the configuration map? The system map is the return value of ig/init
.
Also why don't you want it to be changed?
What do you mean? You only need to change the keys you want to replace. Everything else, including references, can remain the same.
So, if I'll replace :data/store
with :sql/store
all refs to :data/store
will be properly resolved?
(def system-map
{:adapter/jetty {:port 8080, :handler (ig/ref :handler/greet)}
:sql/store {:jdbc-url "some-yrl}
:handler/greet {:name "Alice", :data-store (ig/ref :data/store)}})
if so - it may solve my issues.
Do you mean the configuration map? The system map is the return value of ig/init.
Yes, sorry, I meant configuration map.
Also why don't you want it to be changed?
I think you want to use the same configuration map in tests as in prod.
So, if I'll replace
:data/store
with:sql/store
all refs to:data/store
will be properly resolved?
Yes, that's right. A reference like #ig/ref :data/store
will look for a key that derives from :data/store
.
It's common practice to have both test and production services derive from the same base key, so that you can transparently swap in fake services for testing without altering any other part of the configuration.
I think you want to use the same configuration map in tests as in prod.
Whether you change the keys in the configuration, or change the hierarchy, the resulting system map is the same, and different to production.
My preference is to change the configuration directly, as not only is that simpler (as we don't have to worry about local hierarchies), but it also allows test services to be configured separately to production services.
For example, you might have a fake emailer service that writes to a file, and the filename could be part of the config:
{:fake/emailer {:filename "emails.log"}}
And in production:
{:real/emailer {:smtp "example.com"}}
Makes sense.
Thanks for clarification!
Closing issue and PR.
Consider this scenario:
There is a system described as
For development and production env I want
:data/store
to be some sql db - with init-key:sql/store
. But for test env I want it to be some mock (which just stores data in atom, for instance) - with init-key:inmemory/store
(And obviously I don't want to use different system-maps).It seems natural that I can specify that both keys (
:sql/store
and:inmemory/store
) derived from the:data/store
- but this leads to the exception because clojure cant decide which key to use forinit-key
multimethod.As a solution, I propose to extend
init
fn so it accepts local hierarchy, where one can specify how the particular key should be initialised.For instance, with mentioned system-map it may look like this:
And during key building integrant just get all descendants of the
:data/store
and if there is no ambiguity - the descendant will be used.what do you think?
UPD:
I've started the PR https://github.com/weavejester/integrant/pull/80.
But I see conflicts with how
composite keys
now defined (they are also build withderive
). Please advise how can I proceed.Your feedback is much appreciated!
Thanks!