Share your thoughts in the 2021 Clojure Community Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in Spec by
Given a situation like this, exercising an fspec will fail:

(def uuid-regex #"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")

(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::id (s/and string? #(re-matches uuid-regex %)))
(s/def ::person (s/keys :req-un [::name ::age ::id]))

;; works - ::id gen override produces valid ids
(s/exercise ::person 1 {::id (fn [] (gen/fmap str (gen/uuid)))})

;; fails - ::id gen override isn't being used
  (s/fspec :args (s/cat :p ::person) :ret int?)
  {::id #(gen/fmap str (gen/uuid))})
Couldn't satisfy such-that predicate after 100 tries.

*Problem:* exercise will generate a function that validates the args and returns a gen int. When exercise then conforms that generated fspec function, it calls conform on the fspec-impl. fspec-impl conform* calls validate-function. validate-function runs quick-check on the generated function but conform* and validate-function do not have access to the generator overrides specified in exercise. This same problem also happens if you run stest/check on anything using the fspec (like an fdef with an fspec arg).

1 Answer

0 votes
Reference: (reported by alexmiller)