Fork me on GitHub
#clojure-spec
<
2018-05-29
>
callum01:05:03

I'm finding myself having to duplicate spec definitions in order to override generators and control the number of generated values. e.g.

(s/def ::name string?)
(s/def ::a (s/coll-of ::name))
(s/def ::b (s/keys :req-un [::a]))
(s/def ::c (s/keys :req-un [::a
                            ::b]))

;; only generate a single element for ::a
(gen/generate (s/gen ::c {::a #(s/gen (s/coll-of ::name :min-count 1 :max-count 1))}))

callum01:05:33

Is there a way to avoid this duplication?

bbss03:05:09

(s/def ::select
  (s/cat :plan-name #{'select}
         :thing-to-select #{"SCV" "SupplyDepot"}
         :at-least (s/cat :at-least-kw #{:at-least}
                          :at-least-number (s/int-in 1 50))
         :and-do-form (s/? (s/cat :and-do-kw #{:and-do}
                                                   :additional-do ::select))))

(gen/sample (s/gen ::select) 1)
Why does this stackoverflow? I'd expect the recursive spec to hit a "0 arity branch" of the s/? before it runs out of stack

bbss04:05:05

I notice https://clojuredocs.org/clojure.spec.alpha/*recursion-limit* doesn't mention s/? so maybe it's not intended to be used recursively.

bbss05:05:42

Ended up accepting I can't generate it, but still validate which will be enough for now.

(s/def ::select
  (s/cat :plan-name #{'select}
         :thing-to-select #{"SCV" "SupplyDepot"}
         :at-least (s/cat :at-least-kw #{:at-least}
                          :at-least-number (s/int-in 1 50))
         :and-do-form (s/with-gen (s/? (s/cat :and-do-kw #{:and-do}
                                              :additional-do (s/spec (s/and list?
                                                                            ::select))))
                        #(gen/return ()))))

bbss08:05:55

@victor.cleja you're saying a duplicate key is the issue?

bhauman18:05:06

just released a spec library