clojure-spec

ag 2024-04-30T05:54:27.889259Z

How can I have s/with-gen for a coll of maps that ensures that :id field of maps unique within the collection? I get the first part:

(defn unique-ids? [x]
  (= (count x)
     (count (distinct (map :id x)))))
     
(s/def ::mylist
   (s/and (s/coll-of (s/keys :req-un [::id]))
     unique-ids?))
But how do I do the generator?

ag 2024-05-01T01:13:26.148419Z

Turns out my problem was not that I was getting duplicate IDs within the same collection. I needed to generate a vector of nested maps like: [{:name "foo" :items [{:id 1} {:id 2}]}] And I needed the IDs to be unique throughout the entire collection. Ended up generating a big shuffled list of random IDs. And then inside of fmap for the generator of my vector of maps, I'd iterate through the list (which is not excessively large, so parallelism concerns are unnecessary), I then can systematically replace each ID with a number from the shuffled list, ensuring uniqueness.

nikolavojicic 2024-05-02T13:16:28.098619Z

I use this for unique ints: (def gen-autoincrement (gen/fmap #(swap! % inc) (gen/return (atom 0)))

❤️ 1
lassemaatta 2024-04-30T05:58:25.735119Z

This might go into the "if it's stupid but it works .."-category, but I usually have a) a separate generator for producing a sequence of unique identifiers, b) generator for the maps and c) a final generator which utilizes both and assigns the unique id's to the maps overwriting whatever id they might have.

👍 1
💯 1
☝️ 1
2024-06-18T22:58:13.258299Z

I've used a similar pattern with (gen/return nil), but feel silly now for putting the atom outside the generator. Love the conciseness of this!