Fork me on GitHub
#clojure-spec
<
2017-02-14
>
dbushenko09:02:14

@joshjones: thanks for your answer!

kirill.salykin10:02:21

Hi guys, I am new to clojure spec, It looks like it can be used for data validation and coercion. eg checking if if username and password provided, or if phone number in correct format. But I don’t know how I can show proper error message for failed spec? I was not able to attach any meta data to specs. Any advice on this? Maybe someone got similar ideas? Thanks!

tcoupland10:02:21

@kirill.salykin try explain, explain-str or explain-data

kirill.salykin10:02:48

@tcoupland contains failed predicate, but what I want is to have a custom message in explain-data something like, (s/def ::year integer?, :message “wrong format”) I tried to attach it as meta-data - but no luck

Oliver George10:02:54

I don't think that's possible.

Oliver George10:02:31

Would a lib focused on user input validation be more appropriate?

Oliver George10:02:52

(Vs data structure validation)

kirill.salykin11:02:03

But clojure.spec looked so good to describe form objects… I guess I’ll find some validation library, thanks

Oliver George11:02:22

I agree it's great for that.

sveri11:02:57

@kirill.salykin I was at a local clojure meetup lately and @akiel presented this library: https://github.com/alexanderkiel/material-comp I totally liked the approach and think this is the direction to go. It basically normalizes a spec and returns a generic error message for it. Everything is based on explain-data.

sveri11:02:10

There is not much in it right now, but it should get you started.

akiel11:02:31

@kirill.salykin I would be happy to hear what you think about it. I’ll certainly separate the validation aspect from the material-ui lib. There are also some slides from the meetup: http://www.slideshare.net/alexanderkiel/form-validation-with-clojure-spec

witek14:02:14

What is the right way to provide a predicate which is always true? I want a spec which is a tuple of a keyword and anything. How to spec the anything?

thheller14:02:45

any? was added for this purpose

witek14:02:57

And how to spec a tuple with an optional element?

witek14:02:41

[:a] or [:b :c] should be valid. Is this possible with a simple tuple? Or do I need an or?

joshjones15:02:00

@witek one way is:

(s/def ::a-or-bc (s/or :a (s/tuple #{:a})
                       :bc (s/tuple #{:b} #{:c})))

joshjones15:02:35

depending on whether it's nested, you can also use cat instead of tuple

pesterhazy17:02:50

a wiki of "how do I spec X?" snippets would be useful

tbaldridge18:02:12

oooh...something like that talk at the last Clojure/Conj where you write example data and the computer starts generating specs until it finds one that matches all your example input?

richiardiandrea19:02:11

If I have:

(s/fdef resource->relationship
  :args (s/cat :from-fn (s/fspec :args (s/cat :resource :resource/entity)
                                 :ret qualified-keyword?))
  :ret :relationship/entity)
and my from-fn, which is :name runs fine: (:name {:name "item-definition-components", :description "The list of item definition components.", :uri "{item-definition}/components", :list-of "item-definition-component", :family-id :itemdefinitions, :id :itemdefinitions/item-definition-components}) Why is that if I instrument I get:
Call to #'rest-resources-viz.extractor/resource->relationship did not conform to spec:
                            In: [0] val: "" fails at: [:args :from-fn :ret] predicate: qualified-keyword?
                            :clojure.spec/args  (:name {:name "item-definition-components", :description "The list of item definition components.", :uri "{item-definition}/components", :list-of "item-definition-component", :family-id :itemdefinitions, :id :itemdefinitions/item-definition-components})
                            :clojure.spec/failure  :instrument

richiardiandrea19:02:10

it looks like it runs it in a different way when instrumented

richiardiandrea19:02:55

I am now doubting, is instrument good for use at the repl?

Alex Miller (Clojure team)19:02:06

instrumentation of an fdef with an fspec arg will check that arg by invoking the function you pass it with args generated from the fspec :args

Alex Miller (Clojure team)19:02:31

here it’s invoking the function you passed to resource->relationship with a generated :resource/entity and getting back empty string rather than a qualified keyword

Alex Miller (Clojure team)19:02:48

instrument is primarily designed for use at the repl (or during tests), so it should be good for that

Alex Miller (Clojure team)19:02:29

if from-fn is a keyword, then it will return a string based on the example you have above, not a keyword

Alex Miller (Clojure team)19:02:44

looks like a bug in either your code or your spec to me

richiardiandrea19:02:05

no well, I forgot to include the code of the function, but it "keywordizes" the result

richiardiandrea19:02:38

in fact, when I launch it with instrument the result is the above, but without it it runs fine, same example...of course I need a repro case 😄

richiardiandrea19:02:54

thanks for confirming though

hiredman19:02:35

well, (qualified-keyword? (keyword "")) is going to be false

hiredman19:02:08

the input you pass in doesn't matter

hiredman19:02:20

that error is from the generated data being used to test the spec

richiardiandrea19:02:40

ok so I was completely missing that point

richiardiandrea19:02:58

oh wow that explains everything

richiardiandrea19:02:41

lol thanks...weirdly enough, printlns in resource->relationship where not printing as well

hiredman19:02:37

I would have to look at the source for instrument, because if a spec for a function argument fails, it never actually runs the function

richiardiandrea19:02:57

yeah it exactly looks like it

richiardiandrea19:02:42

thanks (hired) man! You saved my chickens 😸