Fork me on GitHub
#clojure-spec
<
2018-09-19
>
richiardiandrea01:09:41

what is a good intermediate value for quick-check's :max-size?

richiardiandrea01:09:02

The default kind of takes forever for me for a couple of generative tests

richiardiandrea01:09:19

I am afraid 5, which is fast, is too small

taylor01:09:40

FWIW I think the default is 200

richiardiandrea01:09:18

wow, I had to reduce :max-size to 10

richiardiandrea01:09:45

don't even know what or why I am doing this frankly, any feedback is very welcome 😄

taylor01:09:42

a lot depends on what you’re generating and what you’re doing with the generated data. if it’s any thing non-trivial, it’s not unusual for generative tests to take a little while

alexmiller01:09:43

the slow part is usually generating (too large) input values

richiardiandrea01:09:16

I also added a s/coll-of :gen-max to 5

alexmiller01:09:21

the most common thing I find is large collections (default max size per coll is 20) - usually I set :gen-max 3 in all of my s/coll-of’s

alexmiller01:09:44

recursive / nested specs can also be a problem but less common than the above

richiardiandrea01:09:29

I have some kind of nasty :fn checks:

(s/fdef generate-events
  :args (s/cat :options :my-ns/options)
  :fn (s/and #(count-matches-number? (-> % :args :options :number) (:ret %))
             #(data-nil-or-object? (:ret %))
             #(event-key-matches? (-> % :args :options) (:ret %))))

taylor01:09:50

:fn can also just be a simple predicate function, not sure if that’d have much impact

taylor01:09:27

#(and (count-matches-number? (-> % :args :options :number) (:ret %))
      (data-nil-or-object? (:ret %)) ...)

richiardiandrea01:09:49

right, lemme try that

richiardiandrea01:09:27

this seems to be definitely faster!

richiardiandrea01:09:48

thanks! didn't thing about that 😄

taylor01:09:30

I imagine evaluating that s/and spec in each iteration is more expensive than a single predicate

richiardiandrea01:09:15

I was able to get up to :max-size 50 with that simple trick, I guess reporting will be different but that's ok for now

richiardiandrea01:09:10

so I think this is where it's all clogged...

richiardiandrea01:09:29

in ClojureScript too so I don't know, i might be many things

richiardiandrea01:09:36

but thanks for the answer

richiardiandrea01:09:10

if I go :max-size 20 it is taking more than I can wait for 😄 10 is good

richiardiandrea01:09:55

the trick in the tread above by @taylor makes things acceptable again:

:fn #(and (count-matches-number? (-> % :args :options :number) (:ret %))
           (data-nil-or-object? (:ret %))
           (event-key-matches? (-> % :args :options) (:ret %))))

richiardiandrea01:09:09

instead of s/and

misha05:09:46

did you try to rearrange s/and clauses?

misha05:09:38

it seems to me, at this point you could benefit from custom generator(s)

doglooksgood07:09:07

(s/valid? any? ::s/invalid) clojure.spec.alpha/invalid will always fail on spec vaild? so I can't write code like this:

(if-let [x x]
  x
  ::s/invalid)
because if-let use spec to validate the arguments.

mpenet07:09:46

you can cheat your way around this:

mpenet07:09:54

(def si :clojure.spec.alpha/invalid)
(if-let [x si]
  :foo
  :bar)

mpenet07:09:36

it works also for your example

mpenet07:09:36

(if-let [x true] si :bar)

mpenet07:09:57

but yeah that's unfortunate

mpenet07:09:37

there are a few jira issues about it already : https://dev.clojure.org/jira/browse/CLJ-1966

doglooksgood07:09:47

yeah, if this is the only problem I think it's okay

mpenet07:09:34

I only encountered this when writing custom conformers, which is something quite rare

doglooksgood07:09:38

Yes, I'm writing custom conformers...

roklenarcic21:09:54

hm I've got a head scratcher. I have two types of keys in a hashmap (keywords and strings). If key is string then spec A needs to be applied to value, if not then spec B is applied to value

roklenarcic21:09:02

what's the best way to achieve this

roklenarcic21:09:37

currently I use seq to change map to sequence of pairs

roklenarcic21:09:49

then it's trivial to spec

richiardiandrea21:09:53

@roklenarcic I do that with exclusive maps and I use s/or

richiardiandrea21:09:21

you could also use multi specs

richiardiandrea21:09:35

(if I understand the problem correctly)

alexmiller22:09:20

btw, rather than seq to pairs, you can just spec as s/every of s/tuple on the map

alexmiller22:09:00

that’s a perfectly valid way. alternately, I think given just two choices, I’d lean on s/or over s/multi-spec for this