Skip to content

Instantly share code, notes, and snippets.

@bhb
Created August 23, 2018 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhb/b4ca38670c9c20f3d2ed8623aca5ec11 to your computer and use it in GitHub Desktop.
Save bhb/b4ca38670c9c20f3d2ed8623aca5ec11 to your computer and use it in GitHub Desktop.
Quick hacky idea for generating maps with refs (still has bugs)
(require '[clojure.test.check.generators :as gen2])
(require '[clojure.spec.alpha :as s])
(s/def :aero/path (s/coll-of simple-keyword? :kind vector? :min-count 1 :max-count 3))
(defn aero-map [paths vals-or-refs backups]
(->> (map vector paths vals-or-refs backups)
(reduce
(fn [m [p [t v] [_ backup-v]]]
(case t
:aero/scalar
(assoc-in m p v)
:aero/ref
;; refs should not refer to themselves
(if (= p v)
(assoc-in m p backup-v)
(assoc-in m p [t v]))))
{})))
(gen/sample (gen2/let [paths (s/gen (s/coll-of :aero/path :min-count 1))
;; "scalars" is only strings right now,
;; but of course could be expanded to other scalar types
scalars (s/gen (s/coll-of
(s/tuple
#{:aero/scalar}
string?)
:count (count paths)))
refs (gen/vector (gen/elements
(map (fn [r] [:aero/ref r]) paths))
(count paths))
vals-or-refs (gen/vector (gen/elements
(concat
scalars
refs))
(count paths))]
(aero-map paths vals-or-refs scalars)
) 3)
@bhb
Copy link
Author

bhb commented Aug 23, 2018

There is a bug where assoc-in isn't always safe, depending on the old state of map. What we need is a "safe" version of assoc-in that only inserts the value if there is a valid path so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment