Fork me on GitHub
#clojure-spec
<
2017-11-30
>
shaun-mahood00:11:40

I'm trying to hook a custom generator to a spec and I can't quite get it working - I suspect it's something simple that I'm missing. Details in thread.

shaun-mahood00:11:57

My custom generator is

(def gen-7-digit-plan (gen/fmap #(apply str %)
                                (gen/tuple (gen/choose 0 9)
                                           (gen/choose 0 9)
                                           (gen/choose 0 9)
                                           (gen/choose 0 9)
                                           (gen/choose 0 9)
                                           (gen/choose 0 9)
                                           (gen/choose 0 9))))

shaun-mahood00:11:24

Spec is (s/def ::plan (s/with-gen string? gen-7-digit-plan))

shaun-mahood00:11:26

Error message starts with #object[TypeError TypeError: self__.gfn.call is not a function]

shaun-mahood00:11:27

What I'm actually looking for is a 7 digit string with a range from 0000000 to 9999999 - probably there's a way better way to do this.

taylor00:11:59

(s/def ::plan (s/with-gen string? (constantly gen-7-digit-plan)))

taylor00:11:58

I know test.chuck lib has regex->string generators https://github.com/gfredericks/test.chuck#string-from-regex

shaun-mahood00:11:46

Awesome, thanks!

misha06:11:19

@shaun-mahood I might be wrong, but it seems like every gen override place in spec expects no args fn returning actual generator, hence “constantly” above.

misha07:11:19

e.g. s/exercise is one of those places

quan05:11:37

I'm trying to spec clojure.string/index-of

(defn- str-or-char? [s] (or (string? s) (char? s)))

(s/fdef clojure.string/index-of
        :args (s/alt :idx (s/cat :s string?
                                 :value str-or-char?)
                     :idx+from (s/cat :s string?
                                      :value str-or-char?
                                      :from-index int?))
        :ret (s/nilable int?))
but running into this weird exception when instrument
(stest/instrument)
(clojure.string/index-of "abc" "a" 0)
;=> CompilerException java.lang.ClassCastException: clojure.spec.test.alpha$spec_checking_fn$fn__2943 cannot be cast to clojure.lang.IFn$OOLO

quan05:11:44

not sure what's wrong here?

seancorfield06:11:37

@quan I believe that happens when you try to instrument a function that has arguments type-hinted to primitives. The IFn$OOLO type is (Object, Object, long) -> Object and is optimized for the primitive argument and that breaks spec. It's a known issue (I don't recall the JIRA issue number).

quan06:11:35

ah yes, from-index has ^long hint

shaun-mahood06:11:49

I want to use spec generators to build sample data when I'm prototyping a front end app. The generators return nil when I try to use them at runtime after requiring the file, but they work fine if I run them directly in the repl. Is there a good way to get these to work at runtime?

misha06:11:19

@shaun-mahood I might be wrong, but it seems like every gen override place in spec expects no args fn returning actual generator, hence “constantly” above.

mikeyjcat14:11:55

Hi. I’m using spec to validate data being prepared for transactions on datomic, including tempid’s. All works good. There is now a spec registered for :db/id that checks to make sure it is a instance of datomic.db.DbId. Wonderful, and I even created a custom generator. However, now when I am using spec with data read in, I have data with :db/id 123345, rather than a instance of datomic.db.DbId. This obviously fails the spec in instrumentation. It seems as though I need two versions of the spec for :db/id but this cannot be, in my understanding. Anyone tried anything similar?

eriktjacobsen21:11:42

@U1NL85J57

(s/def ::uuid (s/or :int integer? :uuid uuid? :sha256 ::sha256))

Alex Miller (Clojure team)15:11:46

your spec is not capturing all the possible forms of :db/id

tcoupland19:11:15

has anyone got a tidy way of writing core.test is checks of spec/check? I've got something that works, but it's pretty ugly!

taylor20:11:53

is it uglier than this?

(is (not (:check-failed (st/summarize-results (st/check `foo)))))

tcoupland21:11:23

Very similar tbh! Do you get good failure messages out of that?

tcoupland21:11:01

(defn check
  [sym]
  (-> sym
      (stest/check {:clojure.spec.test.alpha.check/opts {:num-tests sample-size}})
      first
      stest/abbrev-result
      :failure))

(defmacro is-check
  [sym]
  `(is (nil? (check ~sym))))

tcoupland21:11:09

that's what i'm using at the moment

tcoupland09:12:31

when i get a minute i might have a play with sumarize, might give a clearer failure message