This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-29
Channels
- # announcements (1)
- # babashka (83)
- # beginners (67)
- # chlorine-clover (22)
- # cider (11)
- # circleci (6)
- # clj-kondo (12)
- # cljs-dev (137)
- # cljsrn (15)
- # clojure (124)
- # clojure-europe (40)
- # clojure-italy (1)
- # clojure-nl (3)
- # clojure-norway (1)
- # clojure-serbia (3)
- # clojure-spec (19)
- # clojure-uk (14)
- # clojuredesign-podcast (5)
- # clojurescript (80)
- # conjure (49)
- # core-async (62)
- # cursive (18)
- # datascript (1)
- # datomic (64)
- # docker (28)
- # emacs (20)
- # figwheel-main (249)
- # fulcro (95)
- # graalvm (2)
- # jobs-discuss (11)
- # joker (2)
- # juxt (4)
- # lambdaisland (9)
- # leiningen (1)
- # meander (14)
- # mount (6)
- # off-topic (16)
- # pathom (46)
- # re-frame (35)
- # reagent (6)
- # reitit (5)
- # shadow-cljs (28)
- # spacemacs (6)
- # sql (18)
- # tools-deps (26)
- # vim (8)
- # xtdb (23)
- # yada (1)
How do You eval? I actually want the default generator because I override it, but for testing i would also like to test the generic one.
with the eval
function?
(s/gen (eval (s/form ::a)))
Hello, I want to introduce clojure spec to validate API endpoints. The parsed response naturally does not have namespaced keywords. How do I go about validating the data? Should I simply use unqualified keys? Where should I keep my spec?
I know it is a very common question of where to put spec but can't find the right answer
I answered these in #beginners - in the future, it's best to put questions in just one channel
Is it not a bad thing to use the eval function?
it's not inherently bad, it's just a tool
Clojure evals all of your expressions after all
I have a simple function and an associated fdef specification, but am not getting an error when calling the function with incorrect arguments. The function should take a map that is a ::customer
specification. Have I misunderstood something?
(defn customer-fullname
"Return customer full name from customer details"
[customer-details]
(str (::first-name customer-details)
"_"
(::last-name customer-details)))
(spec/fdef customer-fullname
:args (spec/cat :customer ::customer)
:ret string?
:fn #(= (:ret %)
(str (::first-name :args) " " (::last-name :args))))
(spec/def ::first-name string?)
(spec/def ::last-name string?)
(spec/def ::email-address
(spec/and string?
#(re-matches #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$" %)))
(spec/def ::customer
(spec/keys
:req [::first-name ::last-name ::email-address]))
I would have expected a call to the customer-fullname
to fail when the wrong kind of arguments are passed
(customer-fullname "customer")
The ::customer
spec works with spec/valid?
and spec/assert
when I use them with :pre
and :post
conditions in a function definition, but seem to be missing something when using spec/fdef
.
Ah, I have now learned about instrumenting the fdef
specifications, and now it works, well fails when I expect it too...
(spec-test/instrument `customer-fullname)
I am not clear on if it is valuable to use fdef
without instrumenting them. Some discussions suggest is it but I have not really understood why as yet. I am still not that clear on the :fn
aspect of fdef
so will be on the look out for more examples. I still have a lot to understand about spec.
you can see the specs in (doc customer-fullname)
those are the main benefits
In particular, instrumentation checks :args
passed in are correct (and ignores :ret
and :fn
). Check is generative and passes in conforming random arguments (per the :args
spec) and then checks :ret
and :fn
are satisfied.
I can see the specs in the docs, yes that is very useful (had forgotten that in my frustration to get the code to fail). Will try out spec-test/check
in the morning, sound promising. Thank you both.