3

Is there a way to override generator for a core predicate function when calling clojure.spec.test.alpha/check?

It is possible to override predicate generator by path inside s/gen:

(gen/generate
 (s/gen
  (s/cat :s string?)
  {[:s] #(gen/return "xyz")}))

But that option doesn't exist for test/check:

(defn xyz [s] s)

(s/fdef xyz
  :args (s/cat :s string?)
  :ret  string?)

;; throws
(test/check
 `xyz
 {:gen {[:args :s] #(gen/return "xyz")}})

Name or symbol must be provided, but what is the name for the string? spec? I've tried using symbols, both 'string? and `string? but it didn't work either.

Overriding generator by wrapping string? with s/with-gen inside s/fdef causes generator-code to be displayed inside function's docs... that affects readability imo.

Defining new spec ::string just for this purpose doesn't feel right.

Nikola
  • 117
  • 7

1 Answers1

0
(ns so.spec
    (:require [clojure.spec.gen.alpha :as gen]
              [clojure.spec.alpha :as s]
              [clojure.spec.test.alpha :as st]))

(defn xyz [s]
    ; only to make sure it gets called
    (prn s)
    s)

(s/def ::xyz-arguments (s/cat :s string?))

(s/fdef xyz
        :args ::xyz-arguments
        :ret string?)

(st/check
    'so.spec/xyz
    {:gen {::xyz-arguments #(gen/return '("xyz"))}})
WhittlesJr
  • 122
  • 8
akond
  • 15,865
  • 4
  • 35
  • 55
  • Yes, as I noted in my question, you could also do `(s/def ::string string?)` and then use `(s/cat :s ::string)` inside `s/fdef` and `::string` when overriding... but I was hoping for a simpler solution. – Nikola Mar 31 '19 at 17:39
  • Sorry, I didn't read that last bit. My guess is no, unless there is some tricky way to create a spec with an args generator. `[:args :s]` won't work, because it must be a symbol or a keyword. – akond Apr 01 '19 at 05:57