Fork me on GitHub
#beginners
<
2022-01-15
>
Timofey Sitnikov13:01:58

Good morning Clojurians!, when I use (use-fixtures :once my_fixture) the fixture is applied to all tests, is it possible to explicitly specify which tests should use or should not use fixtures?

Timofey Sitnikov13:01:25

I looked through books, I just do not know what to look for, everyone just talks about :once and :each , but I cannot find how to do test specific fixturing.

Cora (she/her)13:01:09

just wrap your test in the setup

Timofey Sitnikov13:01:02

@U02N27RK69K, example snippet of a wrap? I am still fresh with Clojure.

Cora (she/her)13:01:55

(deftest my-test
  (let [db (fetch-db-connection)]
    (testing "foo"
      (is (= 1 (foo db))))))

(deftest my-other-test
  (try
    (some-setup)
    (testing "bar"
      (is (= 1 (bar))))
    (finally
      (some-teardown))))

Cora (she/her)13:01:57

(defn my-fixture
  [f]
  (try
    (some-setup)
    (f)
    (finally
      (some-teardown))))

(deftest my-other-other-test
  (my-fixture
   (fn []
     (testing "baz"
       (is (= 1 (baz)))))))

🙂 1
1
Timofey Sitnikov13:01:27

Ahhh, ok, so this way, fixtures are not use automatically, you just specify per test. Awesome!!!

Cora (she/her)14:01:50

(ns my-ns)

(defmacro my-fixture-macro
  [& body]
  `(try
     (some-setup)
     ~@body
     (finally
       (some-teardown))))

(macroexpand '(my-fixture-macro
               (testing "quux"
                 (is (= 1 (quux))))))

;; (try
;;  (my-ns/some-setup)
;;  (testing "quux" (is (= 1 (quux))))
;;  (finally (my-ns/some-teardown)))

Cora (she/her)14:01:01

you could use a macro, too, if that's something you want

dorab19:01:33

You might find https://stuartsierra.com/2016/05/19/fixtures-as-caches useful, once you have the basics.

Josh Horwitz13:01:24

Happy weekend! Have a question for you, have had a few people reach out to me who want to get started with Clojure and what the current best book is to work through for experienced programmers. Back when I started it was The Joy of Clojure, just wondering what is the best recommendation I can make today?

Cora (she/her)13:01:02

I think this belongs here

Josh Horwitz16:01:38

Thank you!

💜 1
erre lin14:01:01

Hello there. I just started experimenting with reitit. I have a quick question: what are reitit.core and reitit.ring for respectively? I mistakenly used core for a while but realized in the examples it is ring module instead. The doc first starts with core but it seems to serve to show if my routes are correct. In the ring part of the doc, I can see real examples where an app with handlers appears. Thank you.

practicalli-johnny15:01:06

A very simplistic answer, reitit.core defines a data centric approach to routing, which I assume can be used in any context (clojurescript, clojure without a web server). reitit.ring is a specific way to use reitit routing with the https://github.com/ring-clojure/ring/wiki/Concepts for Clojure web apps, to define handlers and middleware that pass ring request and response hash-maps around to recieve and respond to http requests via a ring adaptor (i.e. jetty, http-kit). I am sure there is a better explanation though :)

👍 1
practicalli-johnny15:01:16

I am used to building Clojure web apps with ring and compojure with jetty or http-kit, so I mainly use reitit.ring namespaces for building a server-side web service e.g. the requires for my last reitit project were

[muuntaja.core :as transform]
   [reitit.ring :as ring]
   [reitit.ring.middleware.muuntaja :as middleware-transform]
   [reitit.ring.middleware.parameters :as middleware-parameters]
   [reitit.ring.middleware.exception :as middleware-exception]

👍 1
erre lin16:01:29

Hi practicalli, thank you so much for replying. Your answer makes a lot of sense to me, since I'm trying to develop a small web app with Clojure. No wonder I found I should go reitit.ring way.

David Reno17:01:39

Hopefully lein vs tools.build isn't a controversial subject, forgive me if so. I've searched history for the question but not quite found the answer yet. When creating new apps, deps-new (tools.build wrapper?) seems like a reasonable thing to use to do the initial directory layout and code generation (if I understand it's purpose correctly). However, most of the online examples I see still use lein. As a clojure noob and a person with no Java background that often struggles with packaging, deployment, and generally understanding the dependencies, hooks and other tools configuration, should I prefer one approach over another?

dorab19:01:14

My recommendation/suggestion/guidance: 1. If you're following some tutorial that uses lein, use lein. 2. If you want to use an existing lein or boot template, use clj-new. 3. Anything new, use deps-new.

👍 2
practicalli-johnny02:01:02

The Clojure code written for a project should be the same regardless of using Leiningen templates or the relatively new deps-new approach. A deps.edn file with all the same project dependencies can be added to a Leiningen project to enable use of the Clojure CLI.

👍 1
kennytilton20:01:51

Well, definitely get used to lein, for the reason you discovered. <rant> Me, I have not learned anything else, and I barely grok lein, because I like to program applications, not futz forever with the seemingly endless stream of Clojure build mechanisms. And when we get to CLJS, we can drop the "seemingly". </rant>

👍 1
Cora (she/her)17:01:14

there's also clj-new

David Reno17:01:54

clj-new README.md seems to say that I should look at deps-new if I want simplicity: > If you want to create basic application or library projects, or you want to develop your own templates, I recommend looking at https://github.com/seancorfield/deps-new which is a simpler, newer project, based around tools.build.

Cora (she/her)17:01:37

yep, just pointing out that it exists in case you want to use a specific lein template but with deps.edn

👍 1
Cora (she/her)17:01:31

lein is generally easier as long as you're not straying from The Golden Path, but deps.edn is simpler. having generators like deps-new also makes deps.edn a lot easier. preferences vary quite a bit and people use both ¯\(ツ)/¯

Pavel KlavĂ­k19:01:34

Hi, why do I get the following output in REPL?

(->> (range 10)
     (map #(do (println "Number" %) %))
     (take 5))
Number 0
Number 1
Number 2
Number 3
Number 4
Number 5
Number 6
Number 7
Number 8
Number 9
=> (0 1 2 3 4)
I thought that map is lazy, so only Number 0 till Number 4 should be printed out.

dorab19:01:09

You are running into chunking. Perhaps http://www.tianxiangxiong.com/2016/11/05/chunking-and-laziness-in-clojure.html will help understand what is going on.

Pavel KlavĂ­k19:01:12

Cool, makes sense, thanks for the link.

dorab19:01:24

In general, mixing side-effects with laziness is fraught with issues. See https://stuartsierra.com/2015/08/25/clojure-donts-lazy-effects for more.

Pavel KlavĂ­k19:01:09

(->> (range 1000)
     (map #(do (println "Number" %) %))
     (take 5))
Number 0
Number 1
Number 2
Number 3
Number 4
Number 5
Number 6
Number 7
Number 8
Number 9
Number 10
Number 11
Number 12
Number 13
Number 14
Number 15
Number 16
Number 17
Number 18
Number 19
Number 20
Number 21
Number 22
Number 23
Number 24
Number 25
Number 26
Number 27
Number 28
Number 29
Number 30
Number 31
=> (0 1 2 3 4)
This makes it more clear.

dorab19:01:33

Correct. That is a good example.

Pavel KlavĂ­k19:01:41

Ya, not something I would write normally but I am working on a tutorial for beginners and wanted to illustrate lazyness to them.

Pavel KlavĂ­k19:01:28

Thanks for the help and links 🙂

noisesmith20:01:27

one common misconception is that "lazy" means "maximally lazy" - clojure's laziness allows laziness but never promises it for a consumer - if your program correctness relies on whether or not some expression was calculated (or the order in which expressions were calculated) then you shouldn't be using laziness for that part of the program

Muhammad Hamza Chippa22:01:54

I am using material-ui clojurescript wrapper https://github.com/arttuka/reagent-material-ui and trying to do grid I wrote this code for the grid but it is not working as desire. Any idea what I am doing wrong

[:div
    [:grid {:spacing 2 :container true }
     [:grid {:item true :xs 8}
      [:p {:style {:background-color "blue"}}"xs=8"]
      ]
     [:grid {:item true :xs 4}
      [:p {:style {:background-color "blue"}}"xs=4"]
      ]
     ]
    ]
Common HTML is
<Grid container spacing={2}>
  <Grid item xs={8}>
    <Item>xs=8</Item>
  </Grid>
  <Grid item xs={4}>
    <Item>xs=4</Item>
  </Grid>
  <Grid item xs={4}>
    <Item>xs=4</Item>
  </Grid>
</Grid>

Arthur02:01:42

The second snippet doesn’t look like “common html”. Are you sure it isn’t react? And if it is, then you’ll need to use these react components in your code, by importing them and doing something like [:> Grid {:item true :xs 4}]