plumatic / schema-generators

test.check generators and data completion for Schema
77 stars 8 forks source link

Pass max-tries to such-that #5

Open arichiardi opened 8 years ago

arichiardi commented 8 years ago

Very often I receive the dreaded:

expected: nil
  actual: clojure.lang.ExceptionInfo: Couldn't satisfy such-that predicate after 10 tries.
 at clojure.core$ex_info.invokeStatic (core.clj:4617)
    clojure.core$ex_info.invoke (core.clj:4617)

Especially with this schema:

(defn lt
  "Return a constrained schema that is valid iff (< (count %) size).
  The schema parameter therefore needs to be Countable."
  [schema size]
  (s/constrained schema #(< (count %) size)))

(def NonEmptyStr (s/constrained s/Str #(not (empty? (str/trim %))) "non-empty string"))

(def UserId {:email (lt NonEmptyStr 40)})

I was checking and such-that can increase the number of tries: https://clojure.github.io/test.check/clojure.test.check.generators.html#var-such-that

Maybe we can have a dynamic var to pass in there?

PS: Is the above a good way to handle that case? I am still pretty new to schema.

w01fe commented 8 years ago

The best option here (when you have a constraint that's hard to satisfy via random generation) is to pass a custom generator into the generation process for the constrained schema which always produces values that satisfy the constraints. generate takes a map of leaf generators for this purpose, you can see examples in the test. Happy to elaborate if you like.

arichiardi commented 8 years ago

Ok thanks, let me check the tests first, I am now familiar with leaf generator. I just need to know in my case which is the leaf, I guess s/constrained returns a map so I will put directly the (lt NonEmptyStr 40) as key right?

w01fe commented 8 years ago

I would recommend defing the schema you want to generate (e.g. (def UserId (lt NonEmptyStr 40))) and then using the var UserId as the key -- that way there won't be any potential issues with equality, especially if you update the schema later.