(ns darkleaf.di.tutorial.a-intro-test
(:require
[clojure.test :as t]
[darkleaf.di.core :as di])
(:import
(java.time Instant)))
Let's start. In this chapter I'll show you how to deal with components.
The following test describes the most trivial system that contains the most trivial component.
(def a ::a)
root is a system root.
To get root's value deref it.
To stop a system use di/stop.
(t/deftest a-test
(let [root (di/start `a)]
(t/is (= ::a @root))
(di/stop root)))
A root implements AutoCloseable
so in tests we should use with-open macro
for properly stopping.
(t/deftest a'-test
(with-open [root (di/start `a)]
(t/is (= ::a @root))))
A component definition is a function of 0 or 1 arity
with {::di/kind :component} meta.
(defn b
{::di/kind :component}
[]
(Instant/now))
(t/deftest b-test
(with-open [root (di/start `b)]
(t/is (inst? @root))))
To define a component that depends on other components, define a function of one argument. DI will parse associative destructuring to get dependencies of the component. We'll consider component dependencies in the next chapter. But now we will use placeholder.
(defn c
{::di/kind :component}
[-deps]
::c)
(t/deftest c-test
(with-open [root (di/start `c)]
(t/is (= ::c @root))))
A service is a function with or without dependencies.
(defn d []
::d)
root is a wrapper, and it implements clojure.lang.IFn, just like clojure.lang.Var.
So you can just call root.
(t/deftest d-test
(with-open [root (di/start `d)]
(t/is (= ::d (@root) (root)))))
(defn d* [-deps]
::d)
(t/deftest d*-test
(with-open [root (di/start `d*)]
(t/is (= ::d (@root) (root)))))
(defn e [-deps arg]
[::e arg])
(t/deftest e-test
(with-open [root (di/start `e)]
(t/is (= [::e 42] (root 42)))))
You don't need to restart the whole system if you redefine a service. Just redefine a Var. It's very helpful for interactive development.
It does not work if you change definition of dependencies, so in this case you have to restart the system.
The new implementation of a service will receive the same dependencies. To check that, I have to look a little ahead and define component with a dependency. As I said we consider deps in the next chapter.
(t/deftest f-test
(defn f [{x ::x} arg]
[::f x arg])
(with-open [root (di/start `f {::x :x})]
(defn f [deps arg]
[::new-f (deps ::x) arg])
(t/is (= [::new-f :x 42] (root 42)))))
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |