Fork me on GitHub
#clojure-spec
<
2018-12-02
>
fossifoo06:12:52

nice talk/announcement. really looking forward to it, especially the "Better programmatic manipulation of specs" part 🙂

djtango20:12:31

Does anyone know why this is crazy slow / never terminates?

(require '[clojure.spec.alpha :as s])
(require '[clojure.spec.test.alpha :as stest])
(defn my-reverse [c]
  (reverse c))
(s/def ::reverse-args (s/cat :c (s/coll-of any?)))
(s/def ::reverse-ret (s/coll-of any?))
(s/exercise ::reverse-args)
(s/exercise ::reverse-ret)
(s/def ::reverse-fn
  (fn [{:keys [args ret]}]
    (let [input-c (:c args)]
      (= input-c
         (my-reverse ret)))))
(s/fdef my-reverse
        :args ::reverse-args
        :ret ::reverse-ret
        :fn ::reverse-fn)
(stest/check `my-reverse)

djtango20:12:42

^ (you should be able to copy paste that straight into your REPL)

djtango20:12:36

oddly - if I swap out (s/coll-of any?) for coll? I see the same behaviour but if I use (s/coll-of integer?) it terminates nearly instantly (and successfully)

lilactown20:12:01

it looks like there are many cases to generate 🙂

djtango20:12:17

did it work for you?

jaihindhreddy20:12:51

any? generates pretty hairy stuff

lilactown20:12:58

I didn’t try it, but I can tell that generating cases for (s/coll-of any?) is going to cause test.check to really go crazy

jaihindhreddy21:12:05

And is generally not a good fit for generative testing

lilactown21:12:28

you can specify an upper limit to generation

djtango21:12:28

have I unwittingly stumbled onto a bad example of how to use spec / gen testing?

jaihindhreddy21:12:10

You might wanna customize the generator so the tests will be quick without changing the semantics of validation that your spec gives

djtango21:12:12

reverse felt like a nice simple function for illustrating fn specs

jaihindhreddy21:12:12

It is, and I think you wanna keep any? in your spec but customize the generator to improve the testing

lilactown21:12:35

clojure.spec/coll-of takes a :gen-max argument

lilactown21:12:00

you could limit it to like 5 or 100 or something that at least finishes 😛

jaihindhreddy21:12:05

That is an option too.

jaihindhreddy21:12:04

This is what I was talking about: (s/def ::reverse-ret (s/with-gen (s/coll-of any?) #(s/gen (s/coll-of int?))))