Fork me on GitHub

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

Alex Miller (Clojure team)03:02:03

^^ this, there's actually a bug around this iirc