A Clojure map which implements java.io.Closeable
.
;; in your project
(defn start
"Return an running context with stateful references which can be closed."
[config]
(assoc config
:server (http/start-server (api context) {:port 3030})
:producer (kafka-producer config)
:consumer (kafka-consumer config)))
;; in test file
(with-open [context (piotr-yuxuan/closeable-map (start config))]
(testing "unit test with isolated, repeatable context"
(is (= :yay/🚀 (some-business/function context)))))
You might not need closeable-map
, perhaps
jarohen/with-open or
robertluo/fun-map are better fit
for you. They provide more general, more powerful tools. This library
focus on doing one thing: a map which represents a execution context,
which you can close.
Some Clojure datastructures implement IFn
:
({:a 1} :a) ;; => 1
(remove #{:a} [:a :b :c]) ;; => '(:b :c)
([:a :b :c] 1) ;; => :b
Clojure maps (IPersistentMap
) implement IFn
, for invoke()
of one
argument (a key) with an optional second argument (a default value),
i.e. maps are functions of their keys. nil
keys and values are fine.
I have found desirable in some cases to put stateful references in a
context
map:
;; Start an API
(defn -main
[]
(let [config (config/load-config)
context {:producer (kafka-producer config)
:consumer (kafka-consumer config)}]
(http/start-server
(api context)
{:port 3030})))
So far so good, but what about testing? It would be nice to have tests like:
;; doesn't work
(with-open [context {:producer (kafka-producer config)
:consumer (kafka-consumer config)}]
(is (= :yay/🚀 (some-business/function context))))
so that a test context is declared, assumptions are checked against it, and finally context is closed.
This library defines a new type of map, CloseableMap
, which implements
java.io.Closeable
. It provides one function to create such map from a
Clojure map. When key :close
is present, it is assumed that it is a
function which knows how to destroy the state, or a collection of
functions, of which each destroys of part of the state.
(with-open [context (closeable-map {:producer (kafka-producer config)
:consumer (kafka-consumer config)
:close [(fn [{:keys [producer]}] (.close producer))
(fn [{:keys [consumer]}] (.close consumer))]})]
(is (= :yay/🚀 (some-business/function context))))
deps.edn
guide: https://clojure.org/guides/deps_and_clideps.edn
reference: https://clojure.org/reference/deps_and_cliInvoking the function provided by this library from the command-line. It returns an unimpressive map, which is what we expect:
clojure -X:run-x :arg '{:a 1}'
{:a 1}
Also, see ./test/piotr~yuxuan~/closeable~maptest~.clj.
This project was created with:
clojure -X:project/new :name piotr-yuxuan/closeable-map
Run the project's tests:
clojure -M:test:runner
Lint your code with:
clojure -M:lint/idiom
clojure -M:lint/kondo
Visualise links between project vars with:
mkdir graphs
clojure -M:graph/vars-svg
Build a deployable jar of this library:
lein pom
clojure -X:jar
This will update the generated pom.xml
file to keep the dependencies
synchronized with your deps.edn
file.
Install it locally:
lein pom
clojure -X:install
Create a new version once a jar has been created:
lein pom
Version x.y.z
Deploy it to Clojars -- needs CLOJARS_USERNAME
and CLOJARS_PASSWORD
environment variables (requires the pom.xml
file):
lein pom
clojure -X:deploy
Deploy it to GitHub packages with this guide and:
mvn deploy -DaltDeploymentRepository=github::default::https://maven.pkg.github.com/piotr-yuxuan/closeable-map
pom.xml
If you don't plan to install/deploy the library, you can remove the
pom.xml
file but you will also need to remove :sync-pom true
from
the deps.edn
file (in the :exec-args
for depstar
).
As of now it is suggested to run lein pom
to update the pom before
installing a jar or deploying a new version, so that the file pom.xml
is correctly updated by Leiningen (especially the scm revision), which I
don't know yet how to do with deps.edn
tooling.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close