Search code examples
clojureclojure.spec

Get just the test data for a spec'd function


Is there a way for me to generate just the test data for a function previously spec'd with fdef? In other words I would like to have the functionality of check but up to just generating a number of argument sets for me, not running the function and checking the outputs are correct.

Alternatively, if it's possible to lookup the argument (:args) spec of a function then this would achieve the same goal as I could then make a generator from it.


Solution

  • I think the easiest way would be to define your args spec separately so you can use it in the fspec and easily get it later for individual generation.

    (defn foo [x] (inc x))
    (s/def ::foo-args (s/cat :x number?))
    (s/fdef foo :args ::foo-args)
    (gen/sample (s/gen ::foo-args))
    => ((2.0) (-1.5) (0) (1) (1.0) (-1) (1.5) (0.5) (-5.0) (-7))
    

    If you don't have direct access to the original :args spec, here's a clunky way to recreate it from the fspec:

    (s/fdef foo :args (s/cat :x number?))
    (def foo-args-spec
      (eval (->> (s/get-spec `foo)
                 (s/form) ;; get original fspec form
                 (rest) ;; discard fspec symbol
                 (apply hash-map) ;; put fspec kwargs into map
                 (:args))))
    (gen/sample (s/gen foo-args-spec))
    => ((0.5) (-3.0) (-1.5) (2) (-1) (-5) (-1.75) (-2) (-13) (2.3828125))