Fork me on GitHub
#clojure-spec
<
2018-06-25
>
ackerleytng12:06:54

i'm now generating all the arguments to the function as a single list

ackerleytng12:06:45

another question! is there any "state" that carries over between instances of generators?

ackerleytng12:06:46

say i define (def string-gen (gen/string))

ackerleytng12:06:35

if i use that in two different overrides, say {::foo (fn [] string-gen)} and {::bar (fn [] string-gen)}

ackerleytng13:06:06

would the two overrides generate strings independently of each other?

guy13:06:46

I think the generators have seeds? which might be different each time?

ackerleytng14:06:25

ah yes i guess so

ackerleytng14:06:56

along those lines - will a more complex generator retain any sort of state between two invocations?

favila14:06:08

a top-level generator instance and all its "sub" generator instances share a common source of randomness; it's not shared with other instances

guy14:06:33

unless you pass it a seed or something? i think

guy14:06:39

I can’t quite remember

guy14:06:43

let me google it :thumbsup:

favila14:06:57

yeah but even then you're regenerating the same randomness independently

favila14:06:00

it's not shared

guy14:06:08

yes you are correct

guy14:06:13

:thumbsup:

favila14:06:49

so if your overrides are part of a larger generator (e.g. you are generating examples for a top-level map and it has these two keys you override) then the generators share the same source of randomness

favila14:06:05

if these are independent uses of these generators, they do not share

ackerleytng14:06:05

hmm then why do the overrides have to be wrapped in a function?

ackerleytng14:06:09

it has to be {::foo/bar (fn [] (gen/return inc))} instead of just {::foo/bar (gen/return inc)} right?

ackerleytng14:06:52

does wrapping it in a function kind of force a new generator to be returned or something? to avoid state carrying over?

favila14:06:12

@ackerleytng wrapping in a function is to allow lazy invocation of the entire generator system; It's possible to use spec without a test.check dependency (e.g. in production) if you don't use any of the generation features.

ackerleytng15:06:52

ah i see, thanks!

favila14:06:44

if you didn't do this, spec would always require test.check even if you only wanted to use e.g. s/valid? s/conform s/unform etc

favila14:06:35

this is also why clojure.spec.gen.alpha exists: it wraps all the test.check functions and generators so that test.check itself is never required unless actually used

blance18:06:42

do you usually define generator together with your spec when the only use case for the generator is writing generative tests? It's nice that you can combine them with with-gen, but on the other hand I don't know if it's right to define something in src that's only needed for testing

noisesmith19:06:47

@blance consider that a generator for foo will be needed for another library that uses foo, and test files are not transitive like source files are

noisesmith19:06:20

so you end up hacking and adding the generator test files to exported classpath, or rewriting the generator

noisesmith19:06:33

of those options, a generator in the source file is the least hackish

blance19:06:29

thanks! that makes me feel better writing generator in along side with the spec itself