Clojure doesn't have ''
or strings right? Including some JSON fragments in a unit test and there is a lot of escaping like \"
Oops .. single quoted strings DO exist!
Glad that I am in #beginners š
no, they don't
Oh is that just a repl thing?
single quoted forms exist (just single quote at the beginning) - that means to read, but not evaluate
'(1 2 3)
means read that as a list but don't evaluate (by invoking the 1 as a function)
strings in Clojure are always double quotes
yeah ok so i evaluated 'hello' - that was confusing š
yeah that will give you the symbol hello'
need a brighter emacs theme at night š
I use Doom Solarized Light theme for Emacs, find it great for night and day, you can see it in action in my live broadcasts https://practicalli.github.io/
Is there a code (test) coverage story for Clojure?
@st3fan cloverage (although I've never used it in a decade of production Clojure work so I can't speak to how good it is or how easy it is to use).
Seems well-maintained https://github.com/cloverage/cloverage
@st3fan I just recently added code coverage reporting to https://github.com/lread/rewrite-cljc-playground. I used the kaocha plugin for cloverage and send results to http://codecov.io.
That looks great on codecov. Sorry if this is a dumb question but what is the cljc
extension?
@st3fan .cljc
means that it works in both Clojure and ClojureScript.
.cljs
is pure ClojureScript, .clj
is pure Clojure.
:thumbsup:
It was introduced in Clojure 1.7. Here's the section of the change log that talks about it: https://github.com/clojure/clojure/blob/master/changes.md#22-reader-conditionals
Thanks I'll take a peek. Is it not a Clojure thing to do code coverage? Like it is with Java/Kotlin?
My first reaction to that is "what makes you think java or kotlin are all doing code coverage?"
@iulian.birlica Your latest code is good. I plugged it in and got...
Would you be willing to share how you run the code, or a small project that does just this? I trimmed down a project to only render this component, and it still runs fine all except for actually rendering this component.
So the issue is somewhere else
Well, we do for our projects š
I know it is debatable
Whoohoo - all the ring middleware for my github webhook handler is now 100% unit tested
</hack night>
Hmm lein test
only runs one file from my project's test/
directory ... that is odd .. does not simply test $PROJECT_ROOT/test/**/_test.clj
?
Ok that is for tomorrow to find out
Looks like I copy/pasted some namespaces incorrectly š
What do people use to juggle environments like test, dev, production? Iāve looked at environ
but it doesnāt seem to handle lein uberjar build well when it comes to processing environment vars. Should I be putting my config in .edn files and load them in main or something? Seems to work for non-uberjar scenario with environ
, would be nice to have something consistent across the build scenarios.
Iāve used aero
with some success in the past. Have a look at profiles in aero for config across environments. https://github.com/juxt/aero#profile
Yes, I use aero too (with juxt clip)
Using profiles you can externalise things, also you can
include other configurations, so for example, I have this
BTW Iāve never had problems with environ
and lein uberjar
;;
;; Configuration
;;
{:secrets {:kafka #include "/var/run/secrets/kafka-config.edn"
:txi-higgins #include "/var/run/secrets/txi-higgins-config.edn"}
:runtime-config #include "/config/txi-higgins-runtime-config.edn"
the kafka-config.edn
and the txi-higgins-runtime-config.edn
are dynamically mounted as docker volumes in each environment, so naturally they contain different values depending upon the enviornment.
of course, you could use any other mechanism for pulling in your environment specific config.
.
Okay, thanks guys š @agile_geek my issue may very well be user error on my part. What I was trying to do was use something like (`environ/env :database-url)` which worked well for dev and text but didnāt work when I did lein uberjar
The environ github page says at the bottom āImportantĀ -- environ will not pick up configuration settings from theĀ `project.clj`Ā when called from a compiled uberjar. So for any compiled code you produce withĀ `lein uberjar`, you will want to set your configuration values via shell environment and/or system properties.ā
So it may be that for my use case, a separate config .edn could be better.
Eh, some other way to set context other than project.clj/profiles.clj, rather.
environ
reads system properties but uses the defaults in the lein profile if theyāre not present. But as @weavejester points out uberjar is compiling your code so it no longer has any access to the config in project.clj it canāt read defaults as theyāre not there at runtime
So environ
works as designed and you could set system properties for the values required in your runtime environment
e.g. export database-url=the/db/url
If you want defaults for these values you need to put them in a resources file that will be packaged as part of the uberjar or is on the file system at runtime
Typically this is an edn file
This is what aero
is designed for.
Typically the :env
settings in the profile.clj are just convenience default values for system properties that are expected to be set in the runtime environment e.g. using export
. Any config that has defaults that either donāt vary from env to env OR you would prefer to default in your code and not set explicitly using export
you would store in a .edn
file and aero
is useful for reading these files.
@agile_geek yes, I have no doubt environ
works as intended. Iām not idiomatic enough with Clojure yet to understand what the ābestā way forward could be. Iāll take a look at aero
for sure, thanks :)
Is there a standard function that will apply a function to each adjacent pair of elements in a sequence?
e.g. if I have:
(def xs '(a b c d e))
and I apply this function to it then I want the result to be ( (f a b) (f b c) (f c d) (f d e) )
I know I can do map f xs (rest xs)
but Iām lazy and Iām hoping thereās a pre-existing function so I donāt have to implement it again.
You can use partition with a step of 1 but I don't think that's better than what you have...
(map #(apply f %) (partition 2 1 xs))
I have a map where the keys are unqualified keywords, and I want to add the same namespace qualification to each key. Is there something a bit more elegant than
(into {} (map (fn [[k v]] [(keyword "my-ns" (name k)) v]) {:hello 1 :world 2}))
?
there is something a bit more elegant, but itās a separate dependency, so there is some complexity introduced
itās introductory post describes exactly your use-case: http://nathanmarz.com/blog/clojures-missing-piece.html
I would use something similar to your code just because itās simpler, even though somewhat clunky. Maybe the transducer version (e.g. (into {} (map ...) {...})
)
How about reduce-kv
?
(reduce-kv (fn [a k v]
(assoc a (keyword "my-ns" (name k)) v))
{}
{:hello 1
:world 2})
=> #:my-ns{:hello 1, :world 2}
Thanks both!
Cool thanks. I wasnāt quite aware that you could do that with partition and I like the way it looks.
Can this be written more idiomatic.
(true? (some my-pred-func my-coll))
Im creating a function that searches a collection of maps for a value and should return true/false if the value is found.that's fine. probably more common to see the use of the boolean
function
ok
ah, let me say that's probably often not fine to use true?
sorry
most of the time you wouldn't even wrap it, since if / when etc. already treat values the same way boolean would
and some
returns the first logical true value which is not restricted to just true
.
ahh, ok
In a test is it possible to mock functions?
as an example, i want to test something that a few levels down calls (api/make-rest-call ...)
and replace that with a function that simply records the invocation somewhere so that I can verify that the function I am testing eventually results in that API request.
In this specific case I could also re-bind (?) the API endpoint to a local server, but I still have the same question about replacing/mocking functions for the sake of testing.
Yep, just with-redefs
the fn you want to track
If your code is separated into components, you can use https://github.com/bguthrie/shrubbery for more "traditional" mocking
also note that with-redefs is not thread safe - using it in threaded code can cause the original function definition to be lost
ohh. i knew it was (edit: NOT) thread safe but i always assumed it was you might accidentally fire missels not lose the key lol
yeah, the specific issue is that if two threads a/b call with redefs, you can have the following: 1. a replaces f with g 2. b replaces g with h 3. a replaces h with f 4. b replaces f with g
now f is gone, and g has replaced it outside with-redefs
also, as a smaller but still significant concern, b uses the original f for some span of time, where the caller intended to be using h
(which I think counts as the "fire-the-missiles" case @dpsutton was concerned with)
ok with multiple redefs i see. there's no way to know who has the "original"
right - and this only comes up if the calls overlap in two or more threads
old blog about with-redefs https://www.cognitect.com/blog/2016/9/15/works-on-my-machine-understanding-var-bindings-and-roots
if you want more gory details
I wonder then, would you be better of to redef the var as dynamic, and then kickoff your threads each one with their own binding?
@didibus that would avoid the issue, yes
I don't think I'd ever accept a PR using with-redefs other than a single threaded test, and even then I'd encourage an alternative