Fork me on GitHub
#clojure-spec
<
2016-10-14
>
Alex Miller (Clojure team)01:10:24

I don't know - try it? You can specify a generator too

danielcompton02:10:17

yep, generating works fine with :kind sequential?

roberto15:10:39

fyi, snippets slow down slack a lot. Maybe we should default to creating posts instead of snippets.

samedhi15:10:03

I keep having to with-gen or overspecify my generator in clojurescript as generation just takes too long and eventually times out.

samedhi15:10:35

Specifically coll? as a :args always causes me to eventually time out

samedhi15:10:41

Anything clever to fix this?

samedhi15:10:52

Oh, I mean when using clojure.spec.test/check.

samedhi15:10:49

> (defn fx [coll] coll)
> (s/fdef fx :args (s/cat :coll coll?))
> (stest/summarize-results (stest/check `fx))

samedhi15:10:54

As an example of timing out in cljs.

Alex Miller (Clojure team)15:10:07

Have you tried using the :gen-max option?

Alex Miller (Clojure team)15:10:27

For spec'ing collections that is

samedhi15:10:01

yeah, I saw one example of that in the spec getting started guide, forgot about it.

Alex Miller (Clojure team)15:10:02

You could use (s/coll-of any? :gen-max 3)

spieden17:10:29

i’m looking at doing form validation using spec. any thoughts on mapping from an explain to a slightly more human readable messages to put under fields? can’t find anything to put metadata on

spieden17:10:38

maybe just a map from spec keys to messages would do

spieden17:10:37

hmm, looks like i’d need to key off the pred symbol actually

user=> (s/explain-data (s/keys :req [::foo]) {::foo ""})
#:clojure.spec{:problems ({:path [:user/foo], :pred not-empty, :val "", :via [:user/foo], :in [:user/foo]})}

samedhi17:10:57

@alexmiller Thank you for your help. I played around with it since then. Actually, the real issue was that I was including a spec in the :ret part of my s/fdef. This causes the value in :ret in the :fn part of the same s/fdef to be the spec-conformed-return version of the :ret, not the function-value-return version of the return. Kept causing failures that I just couldn’t understand. 🙂

samedhi17:10:44

tldr; If your spec does not conform to the identity of the value passed to it, you should think about what you are doing when using it in s/fdef’s :ret

spieden17:10:49

hrm, wrapping it in s/and allows you to retrieve the “ground” spec:

cljs.user=> (cljs.spec/explain-data (cljs.spec/keys :req [::foo]) {::foo ""})
{:cljs.spec/problems {[:cljs.user/foo] {:pred not-empty?, :val "", :via [:cljs.user/foo], :in [:cljs.user/foo]}}}
cljs.user=> (cljs.spec/def ::foo (cljs.spec/and ::not-empty))
:cljs.user/foo
cljs.user=> (cljs.spec/explain-data (cljs.spec/keys :req [::foo]) {::foo ""})
{:cljs.spec/problems {[:cljs.user/foo] {:pred not-empty?, :val "", :via [:cljs.user/foo :cljs.user/not-empty], :in [:cljs.user/foo]}}}

spieden17:10:45

(difference is in :via values)

samedhi19:10:43

@spieden Thanks you for letting me know, I did reach that solution as well. It all makes pretty good sense, it just caught me by surprise that :ret also effected the :ret in :fn.