Navigation Menu

Skip to content

Commit

Permalink
Added sorted-by support for walk and tests
Browse files Browse the repository at this point in the history
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
  • Loading branch information
timothypratley authored and stuarthalloway committed Jan 5, 2011
1 parent 6ca22bc commit c567308
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
14 changes: 5 additions & 9 deletions src/clj/clojure/walk.clj
Expand Up @@ -36,25 +36,21 @@ the sorting function."}
"Traverses form, an arbitrary data structure. inner and outer are
functions. Applies inner to each element of form, building up a
data structure of the same type, then applies outer to the result.
Recognizes all Clojure data structures except sorted-map-by.
Consumes seqs as with doall."
Recognizes all Clojure data structures. Consumes seqs as with doall."

{:added "1.1"}
[inner outer form]
(cond
(list? form) (outer (apply list (map inner form)))
(instance? clojure.lang.IMapEntry form) (outer (vec (map inner form)))
(seq? form) (outer (doall (map inner form)))
(vector? form) (outer (vec (map inner form)))
(map? form) (outer (into (if (sorted? form) (sorted-map) {})
(map inner form)))
(set? form) (outer (into (if (sorted? form) (sorted-set) #{})
(map inner form)))
(coll? form) (outer (into (empty form) (map inner form)))
:else (outer form)))

(defn postwalk
"Performs a depth-first, post-order traversal of form. Calls f on
each sub-form, uses f's return value in place of the original.
Recognizes all Clojure data structures except sorted-map-by.
Consumes seqs as with doall."
Recognizes all Clojure data structures. Consumes seqs as with doall."
{:added "1.1"}
[f form]
(walk (partial postwalk f) f form))
Expand Down
1 change: 1 addition & 0 deletions test/clojure/test_clojure.clj
Expand Up @@ -67,6 +67,7 @@
:data
:reflect
:errors
:clojure-walk
])

(def test-namespaces
Expand Down
56 changes: 56 additions & 0 deletions test/clojure/test_clojure/clojure_walk.clj
@@ -0,0 +1,56 @@
(ns clojure.test-clojure.clojure-walk
(:require [clojure.walk :as w])
(:use clojure.test))

(deftest t-prewalk-replace
(is (= (w/prewalk-replace {:a :b} [:a {:a :a} (list 3 :c :a)])
[:b {:b :b} (list 3 :c :b)])))

(deftest t-postwalk-replace
(is (= (w/postwalk-replace {:a :b} [:a {:a :a} (list 3 :c :a)])
[:b {:b :b} (list 3 :c :b)])))

(deftest t-stringify-keys
(is (= (w/stringify-keys {:a 1, nil {:b 2 :c 3}, :d 4})
{"a" 1, nil {"b" 2 "c" 3}, "d" 4})))

(deftest t-prewalk-order
(is (= (let [a (atom [])]
(w/prewalk (fn [form] (swap! a conj form) form)
[1 2 {:a 3} (list 4 [5])])
@a)
[[1 2 {:a 3} (list 4 [5])]
1 2 {:a 3} [:a 3] :a 3 (list 4 [5])
4 [5] 5])))

(deftest t-postwalk-order
(is (= (let [a (atom [])]
(w/postwalk (fn [form] (swap! a conj form) form)
[1 2 {:a 3} (list 4 [5])])
@a)
[1 2
:a 3 [:a 3] {:a 3}
4 5 [5] (list 4 [5])
[1 2 {:a 3} (list 4 [5])]])))

(deftest walk
"Checks that walk returns the correct result and type of collection"
(let [colls ['(1 2 3)
[1 2 3]
#{1 2 3}
(sorted-set-by > 1 2 3)
{:a 1, :b 2, :c 3}
(sorted-map-by > 1 10, 2 20, 3 30)]]
(doseq [c colls]
(let [walked (w/walk identity identity c)]
(is (= c walked))
(is (= (type c) (type walked)))
(if (map? c)
(is (= (w/walk #(update-in % [1] inc) #(reduce + (vals %)) c)
(reduce + (map (comp inc val) c))))
(is (= (w/walk inc #(reduce + %) c)
(reduce + (map inc c)))))
(when (or (instance? clojure.lang.PersistentTreeMap c)
(instance? clojure.lang.PersistentTreeSet c))
(is (= (.comparator c) (.comparator walked))))))))

0 comments on commit c567308

Please sign in to comment.