This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-09-02
Channels
- # announcements (2)
- # babashka (21)
- # beginners (80)
- # bristol-clojurians (1)
- # calva (1)
- # cider (4)
- # clara (2)
- # clj-kondo (5)
- # cljs-dev (41)
- # clojure (8)
- # clojure-dev (2)
- # clojure-europe (28)
- # clojure-italy (11)
- # clojure-nl (4)
- # clojure-spec (13)
- # clojure-sweden (1)
- # clojure-uk (11)
- # clojuredesign-podcast (5)
- # clojurescript (5)
- # code-reviews (4)
- # cursive (25)
- # data-science (5)
- # datomic (25)
- # duct (15)
- # emacs (6)
- # fulcro (13)
- # graalvm (1)
- # graphql (5)
- # helix (2)
- # jobs (3)
- # jobs-discuss (4)
- # luminus (1)
- # malli (13)
- # meander (3)
- # off-topic (16)
- # pathom (2)
- # pedestal (1)
- # re-frame (5)
- # ring-swagger (3)
- # spacemacs (4)
- # sql (16)
- # tools-deps (1)
- # tree-sitter (8)
- # vrac (2)
- # xtdb (16)
- # yada (2)
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 foo.bar
and foo.bar-test
respectively)
Also, since both src
and test
will be on your classpath during testing, the namespaces must have different names otherwise they will conflict.
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.
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?
i have like .... :keys ("x","y") .... and I have to quote the list, as well as the empty ones.
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])
(:import
( StringReader BufferedReader ByteArrayOutputStream ByteArrayInputStream PrintWriter)
(java.util.zip GZIPOutputStream)
))
(->> (io/input-stream "")
(java.util.zip.GZIPInputStream.)
(slurp)
(str/split-lines)
count
)
sorry, just found a way that seems to work
(->> (io/input-stream "")
(java.util.zip.GZIPInputStream.)
io/reader
line-seq
count
)
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.
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 (https://github.com/borkdude/clj-kondo/issues/542#issuecomment-549054475)
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 🙂
@joel380 I'm not sure what you mean by "make the test ns match"?
or at least that there is a single resource on the classpath with a given name that when loaded will create a given 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 saw there was concept to have a file with a "master namespace"... that doesn't apply here?
use the var quote
#'my.ns/private-fn
it's ugly, but I think that's actually a good reminder that you're hitting something private in your test
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?
I usually put something like that in a (comment... )
block at the bottom so I can eval it to the repl from my editor
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
forgotten to use? or forgotten in the code?
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?
no, they are always in the comments
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 https://purelyfunctional.tv/courses/repl-driven-development-in-clojure/ 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.
Monthly/yearly subscriptions are available via this page https://purelyfunctional.tv/register/
Developing a really tight REPL-based development workflow pays off over and over, when doing Clojure.
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
example
|____.gitignore
|____.hgignore
|____CHANGELOG.md
|____deps.edn
|____doc
| |____intro.md
|____LICENSE
|____pom.xml
|____README.md
|____resources
| |____.keep
|____src
| |____joel
| | |____example.clj
|____test
| |____joel
| | |____example_test.clj
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.
@joel380 https://practicalli.github.io/clojure/testing/unit-testing/ 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?
generally, I would avoid it and spec it as a string
unless you dynamically generate the static spec (which I have seen some people do)