Fork me on GitHub

in maven the tests are kept in separate structure (same package), usually Java the classes end with *Test. With clojure, does it make more sense to keep the same namespace the same?


@joel380 Most tools assume -test at the end of the ns.


so foo/bar.clj would have tests in foo/bar_test.clj -- and we also usually have a src tree and a separate test tree because that makes it easier to package source code into a JAR while omitting test code.


(and just to be clear, those would have namespaces and respectively)


Also, since both src and test will be on your classpath during testing, the namespaces must have different names otherwise they will conflict.


thanks, that's the way i started, and then questioned it.


I thought I'd be able to (print/dump) my nested map structure, cut/paste into unit test, and just have it work, but that's not quite the story... have to quote the empty lists... doesn't seem practical now.


I thought most tools used the metadata from deftest and not the namespace name.


The test runners expect to find -test namespaces. Certainly Cognitect's does. I think CIDER assumes some conventions as well? That my.namespace will have my.namespace-test as the place for the tests?

👍 3

Empty lists evaluate to themselves. You shouldn’t need to quote them


must be doing something wrong then.


i have like .... :keys ("x","y") .... and I have to quote the list, as well as the empty ones.


just deep quote the whole thing it looks like does it.


That’s not an empty list


user=> ()


but if you want to just read a list you'll need to quote it.


Is there any way to count lines in un-gzipped file without slurp/reading it as a whole?

(ns gzip-playground
  (:require [ :as io]
            [clojure.string :as str])
   ( StringReader BufferedReader ByteArrayOutputStream ByteArrayInputStream PrintWriter)
   ( GZIPOutputStream)

  (->> (io/input-stream "")


not sure how to get line-seq after this step


sorry, just found a way that seems to work

(->> (io/input-stream "")


Is that any better than one with slurp? I’d guess both read the whole thing to memory and keep it in memory while counting happens.


@jsyrjala it's not, AFAICS, because the last variant is lazy

Alex Miller (Clojure team)12:09:59

If you don’t hold the head then the seq can be gc’ed behind you as you count. Slurp makes a string in memory of the whole contents.


it's recommended to close/clean resources at the end btw. I've had issues with jar files still being opened (which are similar to zip files) in clj-kondo, which sometimes blew up the entire process when you linted a huge classpath (


are private functions considered best practice?


so used to doing it java it's a habit.


I've gone back and forth on them. I started out using them a lot and then often found I wanted to test and/or reuse private functions so I made them private. Then I got into the habit of making every function public except for very specific implementation details that fell out of refactoring (breaking up a larger public function). Now I've started to lean more toward private functions by default because I'm used to clj-kondo telling me a private Var isn't used (and can be deleted) when I'm refactoring code.


If I change the API of a public function, I have to search for all call sites -- including some legacy non-Clojure code that calls into our Clojure code which uses munged names (i.e., _ instead of -, _QMARK_ instead of ? etc). If a function is private, I know I only have to check for uses within the current namespace. Well, unless there's some rogue #'my.ns/private-fn references to it somewhere 🙂


yeah, i think i'm going to use them, and make the test ns match.


@joel380 I'm not sure what you mean by "make the test ns match"?


use the same namespace for the test file. so that i can invoke the private fns.


don't do that


what issue will that run into?


feels right, similar to java/smalltalk approach.


a lot of things assume a 1:1 file to namespace mapping


or at least that there is a single resource on the classpath with a given name that when loaded will create a given namespace


so should i keep tests in same file as code?


no, make a test namespace, but the tests in there


how to invoke private functions though from that namespace?


Test private functions through testing the public functions. I avoid testing private functions as it leads to lots of low value unit tests, slowing down the speed of running tests


i guess answer is "don't"?


i saw there was concept to have a file with a "master namespace"... that doesn't apply here?


what is var quote?


invoke method using a quoted fn name?


ah okay.

Alex Miller (Clojure team)18:09:43

it's ugly, but I think that's actually a good reminder that you're hitting something private in your test

Alex Miller (Clojure team)18:09:54

which is imo perfectly fine


also, another nit related to maven... maven will automatically run the tests (good). But i can't run the tests when developing unless I add the (run-tests 'ns) line to the test file. If I leave that in then the tests run twice during build... I'm thinking there's a better expected way to do this?

Alex Miller (Clojure team)18:09:45

I usually put something like that in a (comment... ) block at the bottom so I can eval it to the repl from my editor

Alex Miller (Clojure team)18:09:09

or some editors have built-in support to "run tests in this ns"


yeah, probably the latter is better... i just know those comment blocks will be forgotten.


btw, thanks for the java-to-clojure examples @alexmiller

Alex Miller (Clojure team)18:09:27

forgotten to use? or forgotten in the code?

Alex Miller (Clojure team)18:09:15

if the former, just a matter of habits (I have them in a lot of files but I always put them at the end) if the latter, who cares?


Likewise. We have a lot of those Rich Comment Forms all over our code for REPL convenience when developing (Stu Halloway's name for them, I gather, because Rich Hickey uses them a lot 🙂 ).


so you uncomment to use them right? then end up committing them by accident, or i'm missing something?

Alex Miller (Clojure team)18:09:33

no, they are always in the comments


No, eval code via the editor from within the comment form.

☝️ 3

In Atom, that's ctl-; b for evaluate block, when the cursor is at the edge of each form you want to evaluate.


(well, with the most common keymap setup)


All editors with Clojure integration should have hotkeys for evaluating a form, evaluating a top-level form, evaluating selected/highlighted code (although that's rarely as useful), and somehow loading or evaluating a complete file.


(I never type into a REPL, I only ever eval code from my editor into my REPL)


I highly recommend if you don't mind paying $49 for a month of access to all Eric's courses. That one RDD course is worth the price on its own.

👍 15

Monthly/yearly subscriptions are available via this page


Developing a really tight REPL-based development workflow pays off over and over, when doing Clojure.


i did think his free web content was really good.


Re: test namespaces -- the standard practice is to have your source files and your test files in separate trees that match in terms of directories, but the test files end in _test.clj (and their namespaces end in -test). Several test runners assume that -- and it's what you'll see if you use any of the "new project" generators (`lein new ...`, clj-new, etc).


@joel380 Like this:

> clj -A:new app joel/example
Generating a project called example based on the 'app' template.
> tree example
| |
| |____.keep
| |____joel
| | |____example.clj
| |____joel
| | |____example_test.clj

👍 3

The namespaces in this new project are joel.example in the source tree and joel.example-test in the test tree.


lein new app joel/example would create almost exactly the same structure, except with project.clj for Leiningen instead of deps.edn for CLI.


yeah, i noticed that the hard way... build kept complaining about unfound tests, as intellij (w/o cursive anyway) renamed the namespace like the file name.


so now i have the _ file and the - test ns.


@joel380 covers the basics for simple unit tests. I also suggest using generative tests to minimise test code whilst increasing testing.


I have a question about clojure.spec. I'm writing a spec for a function and the first parameter is a string out of a set of possible strings. But to get all the options I have to query an API. The question is. In spec is it a normal thing to query for data from an external data source or should that be avoided?

Alex Miller (Clojure team)19:09:33

generally, I would avoid it and spec it as a string

Alex Miller (Clojure team)19:09:51

unless you dynamically generate the static spec (which I have seen some people do)


Thanks for the advice Alex