Fork me on GitHub

Is there a good pattern for passing context created in a test fixture into a the test? For example, if we have a fixture that creates a new directory named with (System/currentTimeMillis) how would we make the directory's path available within a test? My current best attempt is to use an atom and avoid any parallel test running. That works fine, but I am curious to hear if anyone else has a better approach.


The two recent instances where I was thinking about this are: 1. The per test "scratch" directory I mentioned and 2. Creating a new local Spark warehouse/metadata store after each test.


First off, I'd recommend using a proper temp directory instead of try to make the name up yourself. I'd probably use a ^:dynamic var and have a binding inside the test fixture. That should respect threads so I think it would solve the parallel problem too?


Thanks @seancorfield. Can you elaborate on "proper temp directory"?


Gotcha, thanks! Definitely seems like a smarter way to go.


Yup. No need to reinvent something the JDK already provides.


@erp12 Most of our tests create stateful contexts (e.g., db connection, file system, etc) using with-open in the body for a deftest. Has worked out real nice, completely replacing fixtures.


Good idea@kenny. I have used with-open in tests for reading specific assets, but the reason I originally didn't reach for it in this instance is because I don't want to have to know about the thing I am opening. If I am understanding java.nio.File/createTempDirectory (per @seancorfield's suggestion) correctly, I should be able to write a little boilerplate so that with-open will work again like:

(with-open [test-dir (create-temp-dir)
Thanks all!


is there a lib out there for comparing hashmaps? say i want to talk about hashmaps kind of like how set theorists talk about sets. spec kind of does this, but I was thinking like something that is immanent to the hashmap structure. for example, how do you express this: hashmap1 is a subset of hashmap2


@veix.q5 Check out the functions in for example:

โœ”๏ธ 3

@erp12 thanks, that's useful


Is there a tool that will create a graphiz chart of namespace dependencies?


this works to show the relationships between your namespaces and your deps, but I want something to show the graph of my own namespaces, if that makes sense

Charles Comstock21:09:49

I've used for this in the past, though I think last time it wasn't working as I expected. Still looking for the equivalent tool to use with clj though, keep meaning to translate it.


This worked really well, thanks!


Hey, I found on Clojuredocs, which is buggy and confused a coworker ๐Ÿ˜„ What's the best way to fix that? Should I just edit it inline providing an explanation?


in clojure/tools/[email protected] how do you pass a string as an argument? Iโ€™m getting:

ยป clj -X:convert :repo-path "/tmp"
Unreadable arg: "/tmp"


thanks ๐Ÿ™‚ a bit awkward I think


> a bit awkward wait until you see quoting in powerhell ๐Ÿ˜„


""""/tmp"""" ...

๐Ÿ˜ƒ 3

It seems to be trying to read it as a symbol


Is there a channel for cognitectโ€™s Rebel tool, and/or discussion of datafy/nav? I looked for #rebel channel, but no result came back. It exists, because I couldnโ€™t create it.


#rebl might be what you're looking for?


Cognitect's tool is REBL, but there's also a rebel readline project (not Cognitect): (in case that's where the confusion comes from?).


Thanks! Got the spelling wrong..


somehow I didn't think of this until today

(require (.name *ns*) :reload)

๐Ÿ‘ 3

Iโ€™m playing around creating and deploy clojure lib to clojars this is the url of my code : When Iโ€™m trying to use this library in my test project Iโ€™m getting error. Could not locate clo_utils/core__init.class, clo_utils/core.clj or clo_utils/core.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.


Is your test project a lein project? I saw on your read me that you expect people to use this as a plug-in and that seems wrong. This should just be a regular dependency


Oh sorry thatโ€™s my bad. Itโ€™s wrong in readme. Iโ€™ll correct it, But Iโ€™m using it as a dependency in my test project


/tmp โฏโฏโฏ bat deps.edn
       โ”‚ File: deps.edn
   1   โ”‚ {:deps {clo-utils {:mvn/version "0.2.0-SNAPSHOT"}}}
/tmp โฏโฏโฏ clj
Clojure 1.10.1
user=> (require 'clo-utils.core)
user=> (dir clo-utils.core)


seems to work for me


how are you using it?


(defproject test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url ""}
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [clo-utils "0.2.0-SNAPSHOT"]]
  :repl-options {:init-ns test.core})


(ns test.core
  (:require [clo-utils.core :refer :all] ))

(defn foo []
  (if-empty [] 1 2))


core file


@U11BV7MTK Hey seems to work for me too.


Iโ€™m not sure what was the issue but seems to work fine now.


awesome. did you not restart your repl maybe?


Thank you

eccentric J18:09:04

Does anyone have an example of using migratus with deps.edn on hand?


I just run the relevant migratus.core functions in a -main function of some file that I load in an alias. With the new clj that supports executing arbitrary commands this should be easier.

eccentric J18:09:23

Something like clj -m my.migrate.wrapper :migrate?


Yep, exactly.


Although that -m part is in an alias, so more like clj -Amigrations migrate.

eccentric J18:09:19

Thanks! This is what I have so far. Last thing I need to figure out is how to provide my existing postgres db connection via jdbc driver from the app to migratus. Feels weird having to specify it twice.


My DB connection URI is written in config.edn that's read by both the app and the migration script. I also use Integrant, but having a common config makes sense even without it.


Also, instead of that huge function registry, you can just use

(let [fn (resolve (symbol (str "migratus.core/" op)))]
  (apply fn config args))

eccentric J18:09:27

Iโ€™m following to connect the fulcro app template to a postgres instance. Iโ€™ve got the config in my config/dev.edn and it uses mount to create a database connection pool so in theory I would expect to be able to point migratus to that.

eccentric J18:09:36

Thatโ€™s a great improvement. Thanks again!

๐Ÿ‘ 3

With the new Clojure CLI -X option, I suspect you could streamline it even further, since you could put your config in deps.edn as an alias, and you could directly invoke any migratus.core function that took a single hash map argument -- so you'd only need wrappers for up and down.


How would that look up config? Note that it can be quite complex.


@U2FRKM4TW The :exec-args structure can be an arbitrary hash map, and you can override it on the command-line. I haven't looked in any depth at how Migratus handles configuration but I'm basing this on the code that @U8WFYMFRU showed.


If I get around to trying Migratus some day, that's probably the approach I'd take.


Yeah, I get what you're saying. But how can you actually extract a map from within a common config file? This is the only thing I can come up with, and it doesn't look pleasant.

clj -X migratus.core/migrate <(clj -e ...some-code-to-read-and-extrac-config...)


I'd put the config directly in deps.edn and drive Migratus from that.


Oohh, that does sound interesting, thanks.


{:migratus {:extra-deps {...}
            :ns-default migratus.core
            :exec-args {:store                :database
              :migration-dir        "migrations/"
              :init-script          "init.sql" ;script should be located in the :migration-dir path
              ;defaults to true, some databases do not support
              ;schema initialization in a transaction
              :init-in-transaction? false
              :migration-table-name "foo_bar"
              :db {:classname   "org.h2.Driver"
                   :subprotocol "h2"
                   :subname     "site.db"}}
and then clojure -X:migratus init which will invoke migratus.core/init and pass that config in.


(untested but I suspect it'll work based on the README for Migratus)


You'd need a wrapper for up/`down` because they take two args -- a hash map and a migration ID -- but your wrapper could be

(defn up [config+] (migratus/up (dissoc config+ :id) (:id config+)))
and then you'd say clojure -X:migratus my-wrapper/up :id '"20111206154000"'


You can override any part of the :exec-args, even nested parts, via the command line so you only need your defaults in there.


clojure -X:migratus <migratus-function> :init-script "local.sql" '[:db :subprotocol]' '"h2:mem"'


(I'd prefer to use the {:dbtype "..." :dbname "..."} format for :db since it's easier to work with)

eccentric J20:09:52

That -X feature looks awesome! However, I think I prefer having a single wrapper that supports all the commands vs some being in the config and some as wrappers. Though I can definitely use that feature for other tools\projects though.

eccentric J23:09:26

Got it working if anyone wants it for reference.

Vishal Gautam20:09:54

Hello. I am trying to do write my schema to a file system. This is the function I have.

(s/def :entity/id
   #(s/gen uuid-samples)))

(s/def :entity/type #{:entity.type/user :entity.type/card :entity.type/topic})

(defn gen-initial-schema []
   [[:entity/id    {:db/unique :db.unique/identity
                    :db/doc "ID of the entity"}]
    [:entity/type {:db/doc "Type of entity"}]]))

(spit "resources/datomic/schema.edn" 
      (pr-str {:app/norm1 {:txes [(gen-initial-schema)]}}))
When I try to run the function below. The namespaces gets messed up in the edn file. Like so
#:app{:norm1 {:txes [[#:db{:ident :entity/id,
Whats the best approach deal with this. Thank you ๐Ÿ™‚


Itโ€™s just *print-namespace-maps* being set to true.

๐Ÿ’ฏ 3

However, as @seancorfield said, itโ€™s valid EDN.

Vishal Gautam20:09:58

@U3E46Q1DG Thank you so much. It solved my problem ๐Ÿ˜„

Vishal Gautam20:09:14

@U3E46Q1DG another question. How do you make sure that the data saved is formatted properly. I tried using pprint from clojure.pprint but it returns nil so didnt work


Wrap it inside with-out-str.


@vishal.gautam What do you mean "messed up"? That looks like valid EDN... Have you tried reading it back in? What failures do you get?

Vishal Gautam20:09:15

Sorry on the poor choice of words. I mean the file was saving keys in namespaced keywords, like we normally would write


I'm still not sure what you mean by "messed up". #:foo{:bar 42} is the same as {:foo/bar 42} The #:foo part is a reader shorthand for "all the keys in this map are qualified with foo/"

๐Ÿ˜ฎ 3
๐Ÿคฏ 3

user=> {:foo/bar 42}
#:foo{:bar 42}
user=> {:foo/bar 42 :foo/a "A"}
#:foo{:bar 42, :a "A"}
user=> #:foo{:bar 13 :a "X" :b "Bee"}
#:foo{:bar 13, :a "X", :b "Bee"}
user=> (keys *1)
(:foo/bar :foo/a :foo/b)

Vishal Gautam20:09:50

@seancorfield I was not aware of that, thank you ๐Ÿ˜„


The end spec such that it is( doesn't mention namespace maps, so they may infact not be valid edn (clojure is a superset of edn, a number of features of the clojure reader are not part of edn)


edn/read-string accepts them:

user=> (edn/read-string "#:foo{:a 1}")
#:foo{:a 1}
user=> (keys *1)
user=> (edn/read-string "#:foo{:a 1 :b/c 2 :d 3}")
{:foo/a 1, :b/c 2, :foo/d 3}
user=> (keys *1)
(:foo/a :b/c :foo/d)