I haven't touched test.check yet, si this might be completely off the mark, but based on my limited understanding, here's what I think happens.
for-all probably removes one level of nesting from your generator, which means that bindings is bound to a seq with one element, which is a map. Then, keys in the (let [ks (into #{} (keys bindings))]... Form turns its argument into a seq, which is easy as it is already one, and then tries to map the key function on the result. The key function expects a Map.Entry, but here the elements of the seq are (or actually is, as there is only one) maps, so it blows up. Easiest way to test (I'm on my phone, emse I'd have done it) this hypothesis would be to turn the into for into (into #{} (keys (first bindings))). Once confirmed, I would suggest getting ris of that extra level of nesting earlier, for example inside your ->maps fn (mapcat identity should do the trick). On Monday, 8 December 2014, cig <clifford.goldb...@gmail.com> wrote: > Hi > > I would like to test a function which recursively traverses the nodes in a > graph and collects them. For example, > > (def graph {1 [2 3 4] > 2 [5 6 7] > 6 [8 9] > 10 [11 12 13]} > > my function is given a starting point say, 1 and should then traverse each > node which is reachable and return the set. In this case the result should > be: > #{3, 4, 5, 7, 8, 9} > > note: it does not return any elements reachable by 10. > > I would like to test this using test.check, but I would like to generate > test data which will exercise the traversal of the graph. > > I found a similar thread here: > https://groups.google.com/forum/#!topic/clojure/YWeT8BFc8k4 > > But, I don't think the proposed solution would suit this use case. So, I > tried generating a graph with relations using core.logic > > (defn ->maps >> >> "take the output of run* and convert it into sequence of maps" >> [q] >> (let [r (->> q >> (partition 2) >> (map (fn [[k v]] {k (apply vector v)})) >> (apply merge))] >> r )) >> (defn gen-hierarchy >> "generate a related hierarchy" >> [size] >> (let [vars1 (->> (repeatedly 7 lvar) (into [])) >> vars2 (->> (repeatedly 7 lvar) (into [])) >> vars3 (->> (repeatedly 7 lvar) (into []))] >> (->> >> (run size [q] >> (fresh [?k1 ?k2 ?k3 ?v1 ?v2 ?v3 ?a] >> (fd/distinct vars1) >> (everyg #(fd/in % (fd/interval 1 9)) vars1) >> (fd/in ?k1 (fd/interval 1 9)) >> (rembero ?k1 vars1 ?v1) >> (membero ?k2 ?v1) >> (fd/distinct vars2) >> (everyg #(fd/in % (fd/interval 1 9)) vars2) >> (rembero ?k2 vars2 ?v2) >> (membero ?k3 ?v2) >> (fd/distinct vars3) >> (everyg #(fd/in % (fd/interval 1 9)) vars3) >> (rembero ?k3 vars3 ?v3) >> (appendo [?k1 ?v1] [?k2 ?v2] ?a) >> (appendo ?a [?k3 ?v3] q))) >> (map ->maps)))) >> >> > Hooking this into test.check. I tried the following: > > (defn gen-port-hierarchy [] >> (gen/sized (fn [size] >> (gen/fmap #(gen-hierarchy %) (gen/return size))))) >> (gen/sample (gen/not-empty (gen-port-hierarchy)) 1) > > > Which does produce more or less what I'm after: > > (({6 [2 3 4 5 7 1], 3 [6 7 1 2 4 5], 1 [3 2 4 5 6 7]}) > ({5 [1 2 3 4 6 7], 7 [5 3 4 6 1 2], 1 [7 2 3 4 5 6]})) > > However, when I try use this in a spec: > > (prop/for-all [bindings (gen/not-empty (gen-port-hierarchy))] > > (let [ ks (into #{} (keys bindings))] ...) > > > I seem to be getting back a LazySeq which then leads to a > ClassCastException: > > java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be > cast to java.util.Map$Entry > > Am I on the completely wrong path here? > Or have I incorrectly hooked this generator up with test.check? > > Any help would be very appreciated. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > <javascript:_e(%7B%7D,'cvml','clojure@googlegroups.com');> > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > <javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com > <javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');>. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.