summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clj/clojure/walk.clj14
-rw-r--r--test/clojure/test_clojure.clj1
-rw-r--r--test/clojure/test_clojure/clojure_walk.clj56
3 files changed, 62 insertions, 9 deletions
diff --git a/src/clj/clojure/walk.clj b/src/clj/clojure/walk.clj
index 613a294c..10215b0f 100644
--- a/src/clj/clojure/walk.clj
+++ b/src/clj/clojure/walk.clj
@@ -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))
diff --git a/test/clojure/test_clojure.clj b/test/clojure/test_clojure.clj
index d66ecf21..97710f3a 100644
--- a/test/clojure/test_clojure.clj
+++ b/test/clojure/test_clojure.clj
@@ -67,6 +67,7 @@
:data
:reflect
:errors
+ :clojure-walk
])
(def test-namespaces
diff --git a/test/clojure/test_clojure/clojure_walk.clj b/test/clojure/test_clojure/clojure_walk.clj
new file mode 100644
index 00000000..70955222
--- /dev/null
+++ b/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))))))))
+