Fork me on GitHub
#clojure-spec
<
2020-08-28
>
pip00:08:14

also is there a way to get the generators for different items in a nested map to be consistent? i.e. for instance if i had a map like:

(s/def ::begin-date inst?)
(s/def ::end-date inst?)

(s/def ::dates (s/keys :req-un [::begin-date ::end-date]))
how can i get begin-date to be less than end-date in the generated output? sorry if this is documented somewhere 🙂

pip00:08:38

^ appreciate the help in advance 🙏 😄

seancorfield00:08:11

@lpanda2014 You can wrap the s/keys part with s/and and add a predicate to check that #(some-date-lib/after? (::begin-date %) (::end-date %))

pip00:08:27

thanks! for some reason that didn’t work though 😞 had to change it to ints since i dont have a datetime library in my repl but the below code gave me a null ptr when i went to generate. is my syntax off?

(s/def ::begin-date int?)
  (s/def ::end-date int?)
  (s/def ::dates (s/and
                  (s/keys :req-un [::begin-date ::end-date])
                  #(> (::end-date %) (::begin-date %))))

(gen/generate (s/gen ::dates)) ;; broken

pip00:08:32

actually nvm figured it out - the second predicate can’t be :: 🙂 thanks for your help!

seancorfield01:08:56

https://github.com/stackoverflow/date-clj is a simple library for manipulating dates, that has before/after comparisons. We use that at work.

seancorfield00:08:00

(most of the date utility libraries have a simple function to check if one date is after another -- don't know what or if you're using)

kenny00:08:34

or built in to Date: #(.after (::end-date %) (::begin-date %))

kenny00:08:04

Needs a custom gen too. Something like (gen/fmap #(zipmap [:begin-date :end-date] (sort %)) (s/gen (s/tuple inst? inst?)))

pip00:08:52

thanks! this worked like a charm

(s/def ::dates (s/with-gen
                  (s/keys :req-un [::begin-date ::end-date])
                   #(gen/fmap (fn [d] (zipmap [:begin-date :end-date] (sort d))) (s/gen (s/tuple inst? inst?)))))

kenny00:08:27

You'll still (probably) want the predicate added with s/and

pip00:08:03

hm i couldn’t get the s/and part to work actually

kenny00:08:45

(s/and ::dates #(.after (::end-date %) (::begin-date %)))

pip00:08:59

thanks !

seancorfield01:08:04

Ah, good point. I couldn't remember whether java.util.Date had comparison built-in (and was too lazy to check the Java API docs 🙂 )