I'm trying to figure out how the overrides map for (s/gen)
works, namely for overriding a generator that's down the tree a bit. That is, I have a top level spec ::data
which has a key ::things
which is a collection of ::thing
, which has a key ::properties
. I'm generating the top level - ::data
- and wanting to override both ::things
so I get only 1 thing, and ::properties
so I get an empty list. using (s/gen ::data {::things #(s/gen (s/coll-of ::thing :min-count 1 :max-count 1))})
, I'm able to force ::things
to only have 1 ::thing
, but I haven't figured out the incantation needed to have ::properties
be empty.
The docstring talks about providing a vector of keyword paths, but I haven't been able to find any more detail on what those paths should look like. I've been trying various combinations
I suspect the issue is in using (s/coll-of)
- for now I'm using an spec.gen/fmap
call to remove any extra data I don't want, but would prefer to be able to just generate only the data needed
Your s/gen
override for ::things
could have a third argument which is the override for ::properties
A bit like this
(s/exercise ::things 10 {::things #(s/gen (s/coll-of ::thing :min-count 1 :max-count 1) {::properties (fn [] (s/gen (s/coll-of string? :min-count 0 :max-count 0)))})})
gotcha. that makes sense
I would have expected to be able to use [::properties]
as a key in the top-level overrides but that doesn't seem to work.
I can't figure it out from the code 😕
Yeah I spent some time walking through some spec guts but couldn't unravel it
s/keys
and several others build a vector of keys to index into the overrides
but I got lost trying to trace through multiple layers
I think it's because the nested s/gen
creates a different context that doesn't know about the overrides in the top level s/exercise
^^ this, there's actually a bug around this iirc