fixed inline precompilation of inline sets in paths, fix bug leading to wrong params order during inline precompilation, change select/transform operations to be macros and move code around accordingly, rename previous versions of select/transform functions with * added

This commit is contained in:
Nathan Marz 2016-05-22 08:57:53 -04:00
parent cdcdbbbaa4
commit fcb5e013d4
5 changed files with 243 additions and 202 deletions

View file

@ -33,45 +33,33 @@
(def ^{:doc "Version of select that takes in a path pre-compiled with comp-paths"} (def ^{:doc "Version of select that takes in a path pre-compiled with comp-paths"}
compiled-select i/compiled-select*) compiled-select i/compiled-select*)
(defn select (defn select*
"Navigates to and returns a sequence of all the elements specified by the path." "Navigates to and returns a sequence of all the elements specified by the path."
[path structure] [path structure]
(compiled-select (i/comp-paths* path) (compiled-select (i/comp-paths* path)
structure)) structure))
(defn compiled-select-one (def ^{:doc "Version of select-one that takes in a path pre-compiled with comp-paths"}
"Version of select-one that takes in a path pre-compiled with comp-paths" compiled-select-one i/compiled-select-one*)
[path structure]
(let [res (compiled-select path structure)]
(when (> (count res) 1)
(i/throw-illegal "More than one element found for params: " path structure))
(first res)
))
(defn select-one (defn select-one*
"Like select, but returns either one element or nil. Throws exception if multiple elements found" "Like select, but returns either one element or nil. Throws exception if multiple elements found"
[path structure] [path structure]
(compiled-select-one (i/comp-paths* path) structure)) (compiled-select-one (i/comp-paths* path) structure))
(defn compiled-select-one! (def ^{:doc "Version of select-one! that takes in a path pre-compiled with comp-paths"}
"Version of select-one! that takes in a path pre-compiled with comp-paths" compiled-select-one! i/compiled-select-one!*)
[path structure]
(let [res (compiled-select path structure)]
(when (not= 1 (count res)) (i/throw-illegal "Expected exactly one element for params: " path structure))
(first res)
))
(defn select-one! (defn select-one!*
"Returns exactly one element, throws exception if zero or multiple elements found" "Returns exactly one element, throws exception if zero or multiple elements found"
[path structure] [path structure]
(compiled-select-one! (i/comp-paths* path) structure)) (compiled-select-one! (i/comp-paths* path) structure))
(defn compiled-select-first (def ^{:doc "Version of select-first that takes in a path pre-compiled with comp-paths"}
"Version of select-first that takes in a path pre-compiled with comp-paths" compiled-select-first i/compiled-select-first*)
[path structure]
(first (compiled-select path structure)))
(defn select-first
(defn select-first*
"Returns first element found. Not any more efficient than select, just a convenience" "Returns first element found. Not any more efficient than select, just a convenience"
[path structure] [path structure]
(compiled-select-first (i/comp-paths* path) structure)) (compiled-select-first (i/comp-paths* path) structure))
@ -82,42 +70,24 @@
(def ^{:doc "Version of transform that takes in a path pre-compiled with comp-paths"} (def ^{:doc "Version of transform that takes in a path pre-compiled with comp-paths"}
compiled-transform i/compiled-transform*) compiled-transform i/compiled-transform*)
(defn transform (defn transform*
"Navigates to each value specified by the path and replaces it by the result of running "Navigates to each value specified by the path and replaces it by the result of running
the transform-fn on it" the transform-fn on it"
[path transform-fn structure] [path transform-fn structure]
(compiled-transform (i/comp-paths* path) transform-fn structure)) (compiled-transform (i/comp-paths* path) transform-fn structure))
(defn compiled-setval (def ^{:doc "Version of setval that takes in a path precompiled with comp-paths"}
"Version of setval that takes in a path pre-compiled with comp-paths" compiled-setval i/compiled-setval*)
[path val structure]
(compiled-transform path (fn [_] val) structure))
(defn setval (defn setval*
"Navigates to each value specified by the path and replaces it by val" "Navigates to each value specified by the path and replaces it by val"
[path val structure] [path val structure]
(compiled-setval (i/comp-paths* path) val structure)) (compiled-setval (i/comp-paths* path) val structure))
(defn compiled-replace-in (def ^{:doc "Version of replace-in that takes in a path precompiled with comp-paths"}
"Version of replace-in that takes in a path pre-compiled with comp-paths" compiled-replace-in i/compiled-replace-in*)
[path transform-fn structure & {:keys [merge-fn] :or {merge-fn concat}}]
(let [state (i/mutable-cell nil)]
[(compiled-transform path
(fn [& args]
(let [res (apply transform-fn args)]
(if res
(let [[ret user-ret] res]
(->> user-ret
(merge-fn (i/get-cell state))
(i/set-cell! state))
ret)
(last args)
)))
structure)
(i/get-cell state)]
))
(defn replace-in (defn replace-in*
"Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret]. "Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
The transform-fn in this case is expected to return [ret user-ret]. ret is The transform-fn in this case is expected to return [ret user-ret]. ret is
what's used to transform the data structure, while user-ret will be added to the user-ret sequence what's used to transform the data structure, while user-ret will be added to the user-ret sequence

View file

@ -753,7 +753,7 @@
;; - could extend this to see if it contains nested function calls which ;; - could extend this to see if it contains nested function calls which
;; are only on constants ;; are only on constants
(do (do
(swap! params-atom concat ps) (swap! params-atom #(vec (concat % ps)))
vv vv
) )
@ -776,9 +776,16 @@
)) ))
:else :else
(if (valid-navigator? p) (cond (set? p)
p (do (swap! params-atom conj p)
(magic-fail! "Constant " p " is not a valid navigator")) pred*)
(keyword? p)
p
:else
(magic-fail! "Code " p " is not a valid navigator or can't be factored")
)
))) )))
(defn magic-precompilation [prepared-path used-locals] (defn magic-precompilation [prepared-path used-locals]
@ -813,6 +820,43 @@
)) ))
(defn compiled-select-one* [path structure]
(let [res (compiled-select* path structure)]
(when (> (count res) 1)
(throw-illegal "More than one element found for params: " path structure))
(first res)
))
(defn compiled-select-one!* [path structure]
(let [res (compiled-select* path structure)]
(when (not= 1 (count res)) (throw-illegal "Expected exactly one element for params: " path structure))
(first res)
))
(defn compiled-select-first* [path structure]
(first (compiled-select* path structure)))
(defn compiled-setval* [path val structure]
(compiled-transform* path (fn [_] val) structure))
(defn compiled-replace-in*
[path transform-fn structure & {:keys [merge-fn] :or {merge-fn concat}}]
(let [state (mutable-cell nil)]
[(compiled-transform* path
(fn [& args]
(let [res (apply transform-fn args)]
(if res
(let [[ret user-ret] res]
(->> user-ret
(merge-fn (get-cell state))
(set-cell! state))
ret)
(last args)
)))
structure)
(get-cell state)]
))
#+clj #+clj
(defn extend-protocolpath* [protpath protpath-prot extensions] (defn extend-protocolpath* [protpath protpath-prot extensions]
(let [extensions (partition 2 extensions) (let [extensions (partition 2 extensions)

View file

@ -341,11 +341,11 @@
) )
:else :else
path `(quote ~path)
)) ))
;; still possible to mess this up with alter-var-root ;; still possible to mess this up with alter-var-root
(defmacro ic! [& path] ; "inline cache" (defmacro path [& path] ; "inline cache"
(let [local-syms (-> &env keys set) (let [local-syms (-> &env keys set)
used-locals (vec (i/walk-select local-syms vector path)) used-locals (vec (i/walk-select local-syms vector path))
prepared-path (ic-prepare-path local-syms (walk/macroexpand-all (vec path))) prepared-path (ic-prepare-path local-syms (walk/macroexpand-all (vec path)))
@ -383,3 +383,26 @@
(i/comp-paths* ~(vec path)) (i/comp-paths* ~(vec path))
)) ))
)) ))
(defmacro select [apath structure]
`(i/compiled-select* (path ~apath) ~structure))
(defmacro select-one! [apath structure]
`(i/compiled-select-one!* (path ~apath) ~structure))
(defmacro select-one [apath structure]
`(i/compiled-select-one* (path ~apath) ~structure))
(defmacro select-first [apath structure]
`(i/compiled-select-first* (path ~apath) ~structure))
(defmacro transform [apath transform-fn structure]
`(i/compiled-transform* (path ~apath) ~transform-fn ~structure))
(defmacro setval [apath aval structure]
`(i/compiled-setval* (path ~apath) ~aval ~structure))
(defmacro replace-in
[apath transform-fn structure & args]
`(i/compiled-replace-in* (path ~apath) ~transform-fn ~structure ~@args))

View file

@ -5,14 +5,16 @@
[com.rpl.specter.cljs-test-helpers :refer [for-all+]] [com.rpl.specter.cljs-test-helpers :refer [for-all+]]
[com.rpl.specter.macros [com.rpl.specter.macros
:refer [paramsfn defprotocolpath defnav extend-protocolpath :refer [paramsfn defprotocolpath defnav extend-protocolpath
nav declarepath providepath]]) nav declarepath providepath select select-one select-one!
select-first transform setval replace-in]])
(:use (:use
#+clj [clojure.test :only [deftest is]] #+clj [clojure.test :only [deftest is]]
#+clj [clojure.test.check.clojure-test :only [defspec]] #+clj [clojure.test.check.clojure-test :only [defspec]]
#+clj [com.rpl.specter.test-helpers :only [for-all+]] #+clj [com.rpl.specter.test-helpers :only [for-all+]]
#+clj [com.rpl.specter.macros #+clj [com.rpl.specter.macros
:only [paramsfn defprotocolpath defnav extend-protocolpath :only [paramsfn defprotocolpath defnav extend-protocolpath
nav declarepath providepath]] nav declarepath providepath select select-one select-one!
select-first transform setval replace-in]]
) )
@ -46,7 +48,7 @@
v (gen/vector (limit-size 5 v (gen/vector (limit-size 5
(gen-map-with-keys gen/keyword gen/int kw))) (gen-map-with-keys gen/keyword gen/int kw)))
pred (gen/elements [odd? even?])] pred (gen/elements [odd? even?])]
(= (s/select [s/ALL kw pred] v) (= (select [s/ALL kw pred] v)
(->> v (map kw) (filter pred)) (->> v (map kw) (filter pred))
))) )))
@ -55,45 +57,45 @@
[v (gen/vector gen/int) [v (gen/vector gen/int)
pred (gen/elements [odd? even?]) pred (gen/elements [odd? even?])
pos (gen/elements [[s/FIRST first] [s/LAST last]])] pos (gen/elements [[s/FIRST first] [s/LAST last]])]
(= (s/select-one [(s/filterer pred) (first pos)] v) (= (select-one [(s/filterer pred) (first pos)] v)
(->> v (filter pred) ((last pos))) (->> v (filter pred) ((last pos)))
))) )))
(defspec select-all-on-map (defspec select-all-on-map
(for-all+ (for-all+
[m (limit-size 5 (gen/map gen/keyword gen/int))] [m (limit-size 5 (gen/map gen/keyword gen/int))]
(= (s/select [s/ALL s/LAST] m) (= (select [s/ALL s/LAST] m)
(for [[k v] m] v)) (for [[k v] m] v))
)) ))
(deftest select-one-test (deftest select-one-test
(is (thrown? #+clj Exception #+cljs js/Error (s/select-one [s/ALL even?] [1 2 3 4]))) (is (thrown? #+clj Exception #+cljs js/Error (select-one [s/ALL even?] [1 2 3 4])))
(is (= 1 (s/select-one [s/ALL odd?] [2 4 1 6]))) (is (= 1 (select-one [s/ALL odd?] [2 4 1 6])))
) )
(deftest select-first-test (deftest select-first-test
(is (= 7 (s/select-first [(s/filterer odd?) s/ALL #(> % 4)] [3 4 2 3 7 5 9 8]))) (is (= 7 (select-first [(s/filterer odd?) s/ALL #(> % 4)] [3 4 2 3 7 5 9 8])))
(is (nil? (s/select-first [s/ALL even?] [1 3 5 9]))) (is (nil? (select-first [s/ALL even?] [1 3 5 9])))
) )
(defspec transform-all-on-map (defspec transform-all-on-map
(for-all+ (for-all+
[m (limit-size 5 (gen/map gen/keyword gen/int))] [m (limit-size 5 (gen/map gen/keyword gen/int))]
(= (s/transform [s/ALL s/LAST] inc m) (= (transform [s/ALL s/LAST] inc m)
(into {} (for [[k v] m] [k (inc v)])) (into {} (for [[k v] m] [k (inc v)]))
))) )))
(defspec transform-all (defspec transform-all
(for-all+ (for-all+
[v (gen/vector gen/int)] [v (gen/vector gen/int)]
(let [v2 (s/transform [s/ALL] inc v)] (let [v2 (transform [s/ALL] inc v)]
(and (vector? v2) (= v2 (map inc v))) (and (vector? v2) (= v2 (map inc v)))
))) )))
(defspec transform-all-list (defspec transform-all-list
(for-all+ (for-all+
[v (gen/list gen/int)] [v (gen/list gen/int)]
(let [v2 (s/transform [s/ALL] inc v)] (let [v2 (transform [s/ALL] inc v)]
(and (seq? v2) (= v2 (map inc v))) (and (seq? v2) (= v2 (map inc v)))
))) )))
@ -102,7 +104,7 @@
[v (gen/vector gen/int) [v (gen/vector gen/int)
pred (gen/elements [odd? even?]) pred (gen/elements [odd? even?])
action (gen/elements [inc dec])] action (gen/elements [inc dec])]
(let [v2 (s/transform [s/ALL pred] action v)] (let [v2 (transform [s/ALL pred] action v)]
(= v2 (map (fn [v] (if (pred v) (action v) v)) v)) (= v2 (map (fn [v] (if (pred v) (action v) v)) v))
))) )))
@ -110,7 +112,7 @@
(for-all+ (for-all+
[v (gen/not-empty (gen/vector gen/int)) [v (gen/not-empty (gen/vector gen/int))
pred (gen/elements [inc dec])] pred (gen/elements [inc dec])]
(let [v2 (s/transform [s/LAST] pred v)] (let [v2 (transform [s/LAST] pred v)]
(= v2 (concat (butlast v) [(pred (last v))])) (= v2 (concat (butlast v) [(pred (last v))]))
))) )))
@ -118,7 +120,7 @@
(for-all+ (for-all+
[v (gen/not-empty (gen/vector gen/int)) [v (gen/not-empty (gen/vector gen/int))
pred (gen/elements [inc dec])] pred (gen/elements [inc dec])]
(let [v2 (s/transform [s/FIRST] pred v)] (let [v2 (transform [s/FIRST] pred v)]
(= v2 (concat [(pred (first v))] (rest v) )) (= v2 (concat [(pred (first v))] (rest v) ))
))) )))
@ -129,8 +131,8 @@
pred (gen/elements [even? odd?]) pred (gen/elements [even? odd?])
updater (gen/elements [inc dec])] updater (gen/elements [inc dec])]
(let [v (into target-type s) (let [v (into target-type s)
v2 (s/transform [(s/filterer pred) s/ALL] updater v) v2 (transform [(s/filterer pred) s/ALL] updater v)
v3 (s/transform [s/ALL pred] updater v)] v3 (transform [s/ALL pred] updater v)]
(and (= v2 v3) (= (type v2) (type v3))) (and (= v2 v3) (= (type v2) (type v3)))
))) )))
@ -140,7 +142,7 @@
kw2 gen/keyword kw2 gen/keyword
m (limit-size 10 (gen-map-with-keys gen/keyword gen/int kw1 kw2)) m (limit-size 10 (gen-map-with-keys gen/keyword gen/int kw1 kw2))
pred (gen/elements [odd? even?])] pred (gen/elements [odd? even?])]
(= (s/transform [(s/collect-one kw2) kw1 pred] + m) (= (transform [(s/collect-one kw2) kw1 pred] + m)
(if (pred (kw1 m)) (if (pred (kw1 m))
(assoc m kw1 (+ (kw1 m) (kw2 m))) (assoc m kw1 (+ (kw1 m) (kw2 m)))
m m
@ -157,7 +159,7 @@
(for-all+ (for-all+
[pred (gen/elements [odd? even?]) [pred (gen/elements [odd? even?])
v (gen/such-that #(some pred %) (gen/vector gen/int))] v (gen/such-that #(some pred %) (gen/vector gen/int))]
(let [v2 (s/transform [(s/filterer pred) s/LAST] inc v) (let [v2 (transform [(s/filterer pred) s/LAST] inc v)
differing-elems (differing-elements v v2)] differing-elems (differing-elements v v2)]
(and (= (count v2) (count v)) (and (= (count v2) (count v))
(= (count differing-elems) 1) (= (count differing-elems) 1)
@ -175,7 +177,7 @@
(gen-map-with-keys gen/keyword gen/int k2) (gen-map-with-keys gen/keyword gen/int k2)
k1)) k1))
pred (gen/elements [inc dec])] pred (gen/elements [inc dec])]
(let [m2 (s/transform [k1 k2] pred m1)] (let [m2 (transform [k1 k2] pred m1)]
(and (= (assoc-in m1 [k1 k2] nil) (assoc-in m2 [k1 k2] nil)) (and (= (assoc-in m1 [k1 k2] nil) (assoc-in m2 [k1 k2] nil))
(= (pred (get-in m1 [k1 k2])) (get-in m2 [k1 k2]))) (= (pred (get-in m1 [k1 k2])) (get-in m2 [k1 k2])))
))) )))
@ -189,7 +191,7 @@
(map (fn [v] [v v])) (map (fn [v] [v v]))
(apply concat)) (apply concat))
user-ret (if (empty? user-ret) nil user-ret)] user-ret (if (empty? user-ret) nil user-ret)]
(= (s/replace-in [s/ALL even?] (fn [v] [(inc v) [v v]]) v) (= (replace-in [s/ALL even?] (fn [v] [(inc v) [v v]]) v)
[res user-ret] [res user-ret]
)))) ))))
@ -199,7 +201,7 @@
(let [res (->> v (map (fn [v] (if (even? v) (inc v) v)))) (let [res (->> v (map (fn [v] (if (even? v) (inc v) v))))
last-even (->> v (filter even?) last) last-even (->> v (filter even?) last)
user-ret (if last-even {:a last-even})] user-ret (if last-even {:a last-even})]
(= (s/replace-in [s/ALL even?] (fn [v] [(inc v) v]) v :merge-fn (fn [curr new] (= (replace-in [s/ALL even?] (fn [v] [(inc v) v]) v :merge-fn (fn [curr new]
(assoc curr :a new))) (assoc curr :a new)))
[res user-ret] [res user-ret]
)))) ))))
@ -208,8 +210,8 @@
(for-all+ (for-all+
[v (gen/vector gen/int) [v (gen/vector gen/int)
v2 (gen/vector gen/int)] v2 (gen/vector gen/int)]
(let [b (s/setval s/BEGINNING v2 v) (let [b (setval s/BEGINNING v2 v)
e (s/setval s/END v2 v)] e (setval s/END v2 v)]
(and (= b (concat v2 v)) (and (= b (concat v2 v))
(= e (concat v v2))) (= e (concat v v2)))
))) )))
@ -224,29 +226,29 @@
predcount (fn [pred v] (->> v (filter pred) count)) predcount (fn [pred v] (->> v (filter pred) count))
even-count (partial predcount even?) even-count (partial predcount even?)
odd-count (partial predcount odd?) odd-count (partial predcount odd?)
b (s/transform (s/srange b e) (fn [r] (filter odd? r)) v)] b (transform (s/srange b e) (fn [r] (filter odd? r)) v)]
(and (= (odd-count v) (odd-count b)) (and (= (odd-count v) (odd-count b))
(= (+ (even-count b) (even-count sv)) (= (+ (even-count b) (even-count sv))
(even-count v))) (even-count v)))
))) )))
(deftest structure-path-directly-test (deftest structure-path-directly-test
(is (= 3 (s/select-one :b {:a 1 :b 3}))) (is (= 3 (select-one :b {:a 1 :b 3})))
(is (= 5 (s/select-one (s/comp-paths :a :b) {:a {:b 5}}))) (is (= 5 (select-one (s/comp-paths :a :b) {:a {:b 5}})))
) )
(deftest atom-test (deftest atom-test
(let [v (s/transform s/ATOM inc (atom 1))] (let [v (transform s/ATOM inc (atom 1))]
(is (instance? clojure.lang.Atom v)) (is (instance? clojure.lang.Atom v))
(is (= 2 (s/select-one s/ATOM v) @v)))) (is (= 2 (select-one s/ATOM v) @v))))
(defspec view-test (defspec view-test
(for-all+ (for-all+
[i gen/int [i gen/int
afn (gen/elements [inc dec])] afn (gen/elements [inc dec])]
(= (first (s/select (s/view afn) i)) (= (first (select (s/view afn) i))
(afn i) (afn i)
(s/transform (s/view afn) identity i) (transform (s/view afn) identity i)
))) )))
(defspec must-test (defspec must-test
@ -257,11 +259,11 @@
op (gen/elements [inc dec]) op (gen/elements [inc dec])
] ]
(let [m (dissoc m k2)] (let [m (dissoc m k2)]
(and (= (s/transform (s/must k1) op m) (and (= (transform (s/must k1) op m)
(s/transform (s/keypath k1) op m)) (transform (s/keypath k1) op m))
(= (s/transform (s/must k2) op m) m) (= (transform (s/must k2) op m) m)
(= (s/select (s/must k1) m) (s/select (s/keypath k1) m)) (= (select (s/must k1) m) (select (s/keypath k1) m))
(empty? (s/select (s/must k2) m)) (empty? (select (s/must k2) m))
)))) ))))
(defspec parser-test (defspec parser-test
@ -270,15 +272,15 @@
afn (gen/elements [inc dec #(* % 2)]) afn (gen/elements [inc dec #(* % 2)])
bfn (gen/elements [inc dec #(* % 2)]) bfn (gen/elements [inc dec #(* % 2)])
cfn (gen/elements [inc dec #(* % 2)])] cfn (gen/elements [inc dec #(* % 2)])]
(and (= (s/select-one! (s/parser afn bfn) i) (and (= (select-one! (s/parser afn bfn) i)
(afn i)) (afn i))
(= (s/transform (s/parser afn bfn) cfn i) (= (transform (s/parser afn bfn) cfn i)
(-> i afn cfn bfn)) (-> i afn cfn bfn))
))) )))
(deftest selected?-test (deftest selected?-test
(is (= [[1 3 5] [2 :a] [7 11 4 2 :a] [10 1 :a] []] (is (= [[1 3 5] [2 :a] [7 11 4 2 :a] [10 1 :a] []]
(s/setval [s/ALL (s/selected? s/ALL even?) s/END] (setval [s/ALL (s/selected? s/ALL even?) s/END]
[:a] [:a]
[[1 3 5] [2] [7 11 4 2] [10 1] []] [[1 3 5] [2] [7 11 4 2] [10 1] []]
)))) ))))
@ -287,19 +289,19 @@
(for-all+ (for-all+
[i gen/int [i gen/int
afn (gen/elements [inc dec])] afn (gen/elements [inc dec])]
(and (= [i] (s/select nil i)) (and (= [i] (select nil i))
(= (afn i) (s/transform nil afn i))))) (= (afn i) (transform nil afn i)))))
(deftest nil-comp-test (deftest nil-comp-test
(is (= [5] (s/select (com.rpl.specter.impl/comp-paths* nil) 5)))) (is (= [5] (select (com.rpl.specter.impl/comp-paths* nil) 5))))
(defspec putval-test (defspec putval-test
(for-all+ (for-all+
[kw gen/keyword [kw gen/keyword
m (limit-size 10 (gen-map-with-keys gen/keyword gen/int kw)) m (limit-size 10 (gen-map-with-keys gen/keyword gen/int kw))
c gen/int] c gen/int]
(= (s/transform [(s/putval c) kw] + m) (= (transform [(s/putval c) kw] + m)
(s/transform [kw (s/putval c)] + m) (transform [kw (s/putval c)] + m)
(assoc m kw (+ c (get m kw))) (assoc m kw (+ c (get m kw)))
))) )))
@ -307,11 +309,11 @@
(for-all+ (for-all+
[v (gen/vector gen/int)] [v (gen/vector gen/int)]
(= [v] (= [v]
(s/select [] v) (select [] v)
(s/select nil v) (select nil v)
(s/select (s/comp-paths) v) (select (s/comp-paths) v)
(s/select (s/comp-paths nil) v) (select (s/comp-paths nil) v)
(s/select [nil nil nil] v) (select [nil nil nil] v)
))) )))
(defspec empty-selector-transform-test (defspec empty-selector-transform-test
@ -319,22 +321,22 @@
[kw gen/keyword [kw gen/keyword
m (limit-size 10 (gen-map-with-keys gen/keyword gen/int kw))] m (limit-size 10 (gen-map-with-keys gen/keyword gen/int kw))]
(and (= m (and (= m
(s/transform nil identity m) (transform nil identity m)
(s/transform [] identity m) (transform [] identity m)
(s/transform (s/comp-paths []) identity m) (transform (s/comp-paths []) identity m)
(s/transform (s/comp-paths nil nil) identity m) (transform (s/comp-paths nil nil) identity m)
) )
(= (s/transform kw inc m) (= (transform kw inc m)
(s/transform [nil kw] inc m) (transform [nil kw] inc m)
(s/transform (s/comp-paths kw nil) inc m) (transform (s/comp-paths kw nil) inc m)
(s/transform (s/comp-paths nil kw nil) inc m) (transform (s/comp-paths nil kw nil) inc m)
)))) ))))
(deftest compose-empty-comp-path-test (deftest compose-empty-comp-path-test
(let [m {:a 1}] (let [m {:a 1}]
(is (= [1] (is (= [1]
(s/select [:a (s/comp-paths)] m) (select [:a (s/comp-paths)] m)
(s/select [(s/comp-paths) :a] m) (select [(s/comp-paths) :a] m)
)))) ))))
(defspec mixed-selector-test (defspec mixed-selector-test
@ -347,28 +349,28 @@
(gen-map-with-keys gen/keyword gen/int k2) (gen-map-with-keys gen/keyword gen/int k2)
k1))] k1))]
(= [(-> m k1 k2)] (= [(-> m k1 k2)]
(s/select [k1 (s/comp-paths k2)] m) (select [k1 (s/comp-paths k2)] m)
(s/select [(s/comp-paths k1) k2] m) (select [(s/comp-paths k1) k2] m)
(s/select [(s/comp-paths k1 k2) nil] m) (select [(s/comp-paths k1 k2) nil] m)
(s/select [(s/comp-paths) k1 k2] m) (select [(s/comp-paths) k1 k2] m)
(s/select [k1 (s/comp-paths) k2] m) (select [k1 (s/comp-paths) k2] m)
))) )))
(deftest cond-path-test (deftest cond-path-test
(is (= [4 2 6 8 10] (is (= [4 2 6 8 10]
(s/select [s/ALL (s/cond-path even? [(s/view inc) (s/view inc)] (select [s/ALL (s/cond-path even? [(s/view inc) (s/view inc)]
#(= 3 %) (s/view dec))] #(= 3 %) (s/view dec))]
[1 2 3 4 5 6 7 8]))) [1 2 3 4 5 6 7 8])))
(is (empty? (s/select (s/if-path odd? (s/view inc)) 2))) (is (empty? (select (s/if-path odd? (s/view inc)) 2)))
(is (= [6 2 10 6 14] (is (= [6 2 10 6 14]
(s/transform [(s/putval 2) (transform [(s/putval 2)
s/ALL s/ALL
(s/if-path odd? [(s/view inc) (s/view inc)] (s/view dec))] (s/if-path odd? [(s/view inc) (s/view inc)] (s/view dec))]
* *
[1 2 3 4 5] [1 2 3 4 5]
))) )))
(is (= 2 (is (= 2
(s/transform [(s/putval 2) (transform [(s/putval 2)
(s/if-path odd? (s/view inc))] (s/if-path odd? (s/view inc))]
* *
2))) 2)))
@ -391,10 +393,10 @@
(let [v1 (get m k1) (let [v1 (get m k1)
k (if (pred v1) k2 k3)] k (if (pred v1) k2 k3)]
(and (and
(= (s/transform (s/if-path [k1 pred] k2 k3) inc m) (= (transform (s/if-path [k1 pred] k2 k3) inc m)
(s/transform k inc m)) (transform k inc m))
(= (s/select (s/if-path [k1 pred] k2 k3) m) (= (select (s/if-path [k1 pred] k2 k3) m)
(s/select k m)) (select k m))
)))) ))))
(defspec multi-path-test (defspec multi-path-test
@ -408,17 +410,17 @@
k1 k1
k2)) k2))
] ]
(= (s/transform (s/multi-path k1 k2) inc m) (= (transform (s/multi-path k1 k2) inc m)
(->> m (->> m
(s/transform k1 inc) (transform k1 inc)
(s/transform k2 inc))) (transform k2 inc)))
)) ))
(deftest empty-pos-transform (deftest empty-pos-transform
(is (empty? (s/select s/FIRST []))) (is (empty? (select s/FIRST [])))
(is (empty? (s/select s/LAST []))) (is (empty? (select s/LAST [])))
(is (= [] (s/transform s/FIRST inc []))) (is (= [] (transform s/FIRST inc [])))
(is (= [] (s/transform s/LAST inc []))) (is (= [] (transform s/LAST inc [])))
) )
(defspec set-filter-test (defspec set-filter-test
@ -427,12 +429,12 @@
k2 (gen/such-that #(not= k1 %) gen/keyword) k2 (gen/such-that #(not= k1 %) gen/keyword)
k3 (gen/such-that (complement #{k1 k2}) gen/keyword) k3 (gen/such-that (complement #{k1 k2}) gen/keyword)
v (gen/vector (gen/elements [k1 k2 k3]))] v (gen/vector (gen/elements [k1 k2 k3]))]
(= (filter #{k1 k2} v) (s/select [s/ALL #{k1 k2}] v)) (= (filter #{k1 k2} v) (select [s/ALL #{k1 k2}] v))
)) ))
(deftest nil-select-one-test (deftest nil-select-one-test
(is (= nil (s/select-one! s/ALL [nil]))) (is (= nil (select-one! s/ALL [nil])))
(is (thrown? #+clj Exception #+cljs js/Error (s/select-one! s/ALL []))) (is (thrown? #+clj Exception #+cljs js/Error (select-one! s/ALL [])))
) )
@ -441,8 +443,8 @@
[v (gen/vector gen/int) [v (gen/vector gen/int)
pred (gen/elements [even? odd?]) pred (gen/elements [even? odd?])
op (gen/elements [inc dec])] op (gen/elements [inc dec])]
(= (s/select-one (s/transformed [s/ALL pred] op) v) (= (select-one (s/transformed [s/ALL pred] op) v)
(s/transform [s/ALL pred] op v)) (transform [s/ALL pred] op v))
)) ))
(defspec basic-parameterized-composition-test (defspec basic-parameterized-composition-test
@ -457,8 +459,8 @@
pred (gen/elements [inc dec])] pred (gen/elements [inc dec])]
(let [p (s/comp-paths s/keypath s/keypath)] (let [p (s/comp-paths s/keypath s/keypath)]
(and (and
(= (s/compiled-select (p k1 k2) m1) (s/select [k1 k2] m1)) (= (s/compiled-select (p k1 k2) m1) (select [k1 k2] m1))
(= (s/compiled-transform (p k1 k2) pred m1) (s/transform [k1 k2] pred m1)) (= (s/compiled-transform (p k1 k2) pred m1) (transform [k1 k2] pred m1))
)))) ))))
(defspec various-orders-comp-test (defspec various-orders-comp-test
@ -526,8 +528,8 @@
{:a [{:c 3}]} {:a [{:c 3}]}
{:a [{:b [{:c 7}] :e [1]}]}] {:a [{:b [{:c 7}] :e [1]}]}]
] ]
(is (= (s/select p2 data) (is (= (select p2 data)
(s/select p3 data) (select p3 data)
[[{:a [{:b [{:c 4 :d 5}]}]}]] [[{:a [{:b [{:c 4 :d 5}]}]}]]
)) ))
)) ))
@ -589,11 +591,11 @@
(and (and
(apply = (apply =
(for [p paths] (for [p paths]
(s/select p m) (select p m)
)) ))
(apply = (apply =
(for [p paths] (for [p paths]
(s/transform p updater m) (transform p updater m)
)) ))
)))) ))))
@ -604,8 +606,8 @@
op (gen/elements [inc dec]) op (gen/elements [inc dec])
comparator (gen/elements [= > <])] comparator (gen/elements [= > <])]
(let [cpath (s/comp-paths s/ALL (paramsfn [p] [v] (comparator v p)))] (let [cpath (s/comp-paths s/ALL (paramsfn [p] [v] (comparator v p)))]
(= (s/transform (cpath val) op v) (= (transform (cpath val) op v)
(s/transform [s/ALL #(comparator % val)] op v))) (transform [s/ALL #(comparator % val)] op v)))
)) ))
(defspec subset-test (defspec subset-test
@ -621,53 +623,53 @@
combined (set/union s1 s2) combined (set/union s1 s2)
ss (set/union s2 s3)] ss (set/union s2 s3)]
(and (and
(= (s/transform (s/subset s3) identity combined) combined) (= (transform (s/subset s3) identity combined) combined)
(= (s/setval (s/subset s3) #{} combined) (set/difference combined s2)) (= (setval (s/subset s3) #{} combined) (set/difference combined s2))
(= (s/setval (s/subset s3) s4 combined) (-> combined (set/difference s2) (set/union s4))) (= (setval (s/subset s3) s4 combined) (-> combined (set/difference s2) (set/union s4)))
)))) ))))
(deftest submap-test (deftest submap-test
(is (= [{:foo 1}] (is (= [{:foo 1}]
(s/select [(s/submap [:foo :baz])] {:foo 1 :bar 2}))) (select [(s/submap [:foo :baz])] {:foo 1 :bar 2})))
(is (= {:foo 1, :barry 1} (is (= {:foo 1, :barry 1}
(s/setval [(s/submap [:bar])] {:barry 1} {:foo 1 :bar 2}))) (setval [(s/submap [:bar])] {:barry 1} {:foo 1 :bar 2})))
(is (= {:bar 1, :foo 2} (is (= {:bar 1, :foo 2}
(s/transform [(s/submap [:foo :baz]) s/ALL s/LAST] inc {:foo 1 :bar 1}))) (transform [(s/submap [:foo :baz]) s/ALL s/LAST] inc {:foo 1 :bar 1})))
(is (= {:a {:new 1} (is (= {:a {:new 1}
:c {:new 1 :c {:new 1
:old 1}} :old 1}}
(s/setval [s/ALL s/LAST (s/submap [])] {:new 1} {:a nil, :c {:old 1}})))) (setval [s/ALL s/LAST (s/submap [])] {:new 1} {:a nil, :c {:old 1}}))))
(deftest nil->val-test (deftest nil->val-test
(is (= {:a #{:b}} (is (= {:a #{:b}}
(s/setval [:a s/NIL->SET (s/subset #{})] #{:b} nil))) (setval [:a s/NIL->SET (s/subset #{})] #{:b} nil)))
(is (= {:a #{:b :c :d}} (is (= {:a #{:b :c :d}}
(s/setval [:a s/NIL->SET (s/subset #{})] #{:b} {:a #{:c :d}}))) (setval [:a s/NIL->SET (s/subset #{})] #{:b} {:a #{:c :d}})))
(is (= {:a [:b]} (is (= {:a [:b]}
(s/setval [:a s/NIL->VECTOR s/END] [:b] nil))) (setval [:a s/NIL->VECTOR s/END] [:b] nil)))
) )
(defspec void-test (defspec void-test
(for-all+ (for-all+
[s1 (gen/vector (limit-size 5 gen/int))] [s1 (gen/vector (limit-size 5 gen/int))]
(and (and
(empty? (s/select s/STOP s1)) (empty? (select s/STOP s1))
(empty? (s/select [s/STOP s/ALL s/ALL s/ALL s/ALL] s1)) (empty? (select [s/STOP s/ALL s/ALL s/ALL s/ALL] s1))
(= s1 (s/transform s/STOP inc s1)) (= s1 (transform s/STOP inc s1))
(= s1 (s/transform [s/ALL s/STOP s/ALL] inc s1)) (= s1 (transform [s/ALL s/STOP s/ALL] inc s1))
(= (s/transform [s/ALL (s/cond-path even? nil odd? s/STOP)] inc s1) (= (transform [s/ALL (s/cond-path even? nil odd? s/STOP)] inc s1)
(s/transform [s/ALL even?] inc s1)) (transform [s/ALL even?] inc s1))
))) )))
(deftest stay-continue-tests (deftest stay-continue-tests
(is (= [[1 2 [:a :b]] [3 [:a :b]] [:a :b [:a :b]]] (is (= [[1 2 [:a :b]] [3 [:a :b]] [:a :b [:a :b]]]
(s/setval [(s/stay-then-continue s/ALL) s/END] [[:a :b]] [[1 2] [3]]))) (setval [(s/stay-then-continue s/ALL) s/END] [[:a :b]] [[1 2] [3]])))
(is (= [[1 2 [:a :b]] [3 [:a :b]] [:a :b]] (is (= [[1 2 [:a :b]] [3 [:a :b]] [:a :b]]
(s/setval [(s/continue-then-stay s/ALL) s/END] [[:a :b]] [[1 2] [3]]))) (setval [(s/continue-then-stay s/ALL) s/END] [[:a :b]] [[1 2] [3]])))
(is (= [[1 2 3] 1 3] (is (= [[1 2 3] 1 3]
(s/select (s/stay-then-continue s/ALL odd?) [1 2 3]))) (select (s/stay-then-continue s/ALL odd?) [1 2 3])))
(is (= [1 3 [1 2 3]] (is (= [1 3 [1 2 3]]
(s/select (s/continue-then-stay s/ALL odd?) [1 2 3]))) (select (s/continue-then-stay s/ALL odd?) [1 2 3])))
) )
@ -682,11 +684,11 @@
(deftest recursive-path-test (deftest recursive-path-test
(is (= [9 1 10 3 1] (is (= [9 1 10 3 1]
(s/select [MyWalker s/ALL number?] (select [MyWalker s/ALL number?]
[:bb [:aa 34 [:abc 10 [:ccc 9 8 [:abc 9 1]]]] [:abc 1 [:abc 3]]]) [:bb [:aa 34 [:abc 10 [:ccc 9 8 [:abc 9 1]]]] [:abc 1 [:abc 3]]])
)) ))
(is (= [:bb [:aa 34 [:abc 11 [:ccc 9 8 [:abc 10 2]]]] [:abc 2 [:abc 4]]] (is (= [:bb [:aa 34 [:abc 11 [:ccc 9 8 [:abc 10 2]]]] [:abc 2 [:abc 4]]]
(s/transform [MyWalker s/ALL number?] inc (transform [MyWalker s/ALL number?] inc
[:bb [:aa 34 [:abc 10 [:ccc 9 8 [:abc 9 1]]]] [:abc 1 [:abc 3]]]) [:bb [:aa 34 [:abc 10 [:ccc 9 8 [:abc 9 1]]]] [:abc 1 [:abc 3]]])
)) ))
) )
@ -700,23 +702,23 @@
[s/LAST (s/params-reset map-key-walker)])]) [s/LAST (s/params-reset map-key-walker)])])
(deftest recursive-params-path-test (deftest recursive-params-path-test
(is (= #{1 2 3} (set (s/select (map-key-walker :aaa) (is (= #{1 2 3} (set (select (map-key-walker :aaa)
{:a {:aaa 3 :b {:c {:aaa 2} :aaa 1}}})))) {:a {:aaa 3 :b {:c {:aaa 2} :aaa 1}}}))))
(is (= {:a {:aaa 4 :b {:c {:aaa 3} :aaa 2}}} (is (= {:a {:aaa 4 :b {:c {:aaa 3} :aaa 2}}}
(s/transform (map-key-walker :aaa) inc (transform (map-key-walker :aaa) inc
{:a {:aaa 3 :b {:c {:aaa 2} :aaa 1}}}))) {:a {:aaa 3 :b {:c {:aaa 2} :aaa 1}}})))
(is (= {:a {:c {:b "X"}}} (is (= {:a {:c {:b "X"}}}
(s/setval (map-key-walker :b) "X" {:a {:c {:b {:d 1}}}}))) (setval (map-key-walker :b) "X" {:a {:c {:b {:d 1}}}})))
) )
(deftest recursive-params-composable-path-test (deftest recursive-params-composable-path-test
(let [p (s/comp-paths s/keypath map-key-walker)] (let [p (s/comp-paths s/keypath map-key-walker)]
(is (= [1] (s/select (p 1 :a) [{:a 3} {:a 1} {:a 2}]))) (is (= [1] (select (p 1 :a) [{:a 3} {:a 1} {:a 2}])))
)) ))
(deftest all-map-test (deftest all-map-test
(is (= {3 3} (s/transform [s/ALL s/FIRST] inc {2 3}))) (is (= {3 3} (transform [s/ALL s/FIRST] inc {2 3})))
(is (= {3 21 4 31} (s/transform [s/ALL s/ALL] inc {2 20 3 30}))) (is (= {3 21 4 31} (transform [s/ALL s/ALL] inc {2 20 3 30})))
) )
(declarepath NestedHigherOrderWalker [k]) (declarepath NestedHigherOrderWalker [k])
@ -730,7 +732,7 @@
(deftest nested-higher-order-walker-test (deftest nested-higher-order-walker-test
(is (= [:q [:abc :I 3] [:ccc [:abc :I] [:abc :I "a" [:abc :I [:abc :I [:d]]]]]] (is (= [:q [:abc :I 3] [:ccc [:abc :I] [:abc :I "a" [:abc :I [:abc :I [:d]]]]]]
(s/setval [(NestedHigherOrderWalker :abc) (s/srange 1 1)] (setval [(NestedHigherOrderWalker :abc) (s/srange 1 1)]
[:I] [:I]
[:q [:abc 3] [:ccc [:abc] [:abc "a" [:abc [:abc [:d]]]]]] [:q [:abc 3] [:ccc [:abc] [:abc "a" [:abc [:abc [:d]]]]]]
)))) ))))
@ -743,7 +745,7 @@
{k m}) {k m})
:a :a
(reverse (range 25)))] (reverse (range 25)))]
(is (= :a (s/select-one (apply path (range 25)) m))) (is (= :a (select-one (apply path (range 25)) m)))
)) ))
;;TODO: there's a bug in clojurescript that won't allow ;;TODO: there's a bug in clojurescript that won't allow
;; non function implementations of IFn to have more than 20 arguments ;; non function implementations of IFn to have more than 20 arguments
@ -763,11 +765,11 @@
(->User (->Account 50)) (->User (->Account 50))
(->Family [(->Account 51) (->Account 52)])]] (->Family [(->Account 51) (->Account 52)])]]
(is (= [30 50 51 52] (is (= [30 50 51 52]
(s/select [s/ALL AccountPath :funds] data))) (select [s/ALL AccountPath :funds] data)))
(is (= [(->User (->Account 31)) (is (= [(->User (->Account 31))
(->User (->Account 51)) (->User (->Account 51))
(->Family [(->Account 52) (->Account 53)])] (->Family [(->Account 52) (->Account 53)])]
(s/transform [s/ALL AccountPath :funds] (transform [s/ALL AccountPath :funds]
inc inc
data))) data)))
)) ))
@ -788,11 +790,11 @@
(->LabeledUser {:a (->Account 50)}) (->LabeledUser {:a (->Account 50)})
(->LabeledFamily {:a [(->Account 51) (->Account 52)]})]] (->LabeledFamily {:a [(->Account 51) (->Account 52)]})]]
(is (= [30 50 51 52] (is (= [30 50 51 52]
(s/select [s/ALL (LabeledAccountPath :a) :funds] data))) (select [s/ALL (LabeledAccountPath :a) :funds] data)))
(is (= [(->LabeledUser {:a (->Account 31)}) (is (= [(->LabeledUser {:a (->Account 31)})
(->LabeledUser {:a (->Account 51)}) (->LabeledUser {:a (->Account 51)})
(->LabeledFamily {:a [(->Account 52) (->Account 53)]})] (->LabeledFamily {:a [(->Account 52) (->Account 53)]})]
(s/transform [s/ALL (LabeledAccountPath :a) :funds] (transform [s/ALL (LabeledAccountPath :a) :funds]
inc inc
data))) data)))
)) ))
@ -813,9 +815,9 @@
#+clj #+clj
(deftest mixed-rich-regular-protocolpath (deftest mixed-rich-regular-protocolpath
(is (= [1 2 3 11 21 22 25] (is (= [1 2 3 11 21 22 25]
(s/select [CustomWalker number?] [{:a [1 2 :c [3]]} [[[[[[11]]] 21 [22 :c 25]]]]]))) (select [CustomWalker number?] [{:a [1 2 :c [3]]} [[[[[[11]]] 21 [22 :c 25]]]]])))
(is (= [2 3 [[[4]] :b 0] {:a 4 :b 10}] (is (= [2 3 [[[4]] :b 0] {:a 4 :b 10}]
(s/transform [CustomWalker number?] inc [1 2 [[[3]] :b -1] {:a 3 :b 10}]))) (transform [CustomWalker number?] inc [1 2 [[[3]] :b -1] {:a 3 :b 10}])))
) )
#+cljs #+cljs
@ -839,11 +841,11 @@
m1 (gen/map gen/keyword gen/int)] m1 (gen/map gen/keyword gen/int)]
(let [s1 (set v1) (let [s1 (set v1)
q1 (make-queue v1) q1 (make-queue v1)
v2 (s/transform s/ALL identity v1) v2 (transform s/ALL identity v1)
m2 (s/transform s/ALL identity m1) m2 (transform s/ALL identity m1)
s2 (s/transform s/ALL identity s1) s2 (transform s/ALL identity s1)
l2 (s/transform s/ALL identity l1) l2 (transform s/ALL identity l1)
q2 (s/transform s/ALL identity q1)] q2 (transform s/ALL identity q1)]
(and (and
(= v1 v2) (= v1 v2)
(= (type v1) (type v2)) (= (type v1) (type v2))

View file

@ -4,14 +4,16 @@
[cljs.test.check.cljs-test :refer [defspec]] [cljs.test.check.cljs-test :refer [defspec]]
[com.rpl.specter.cljs-test-helpers :refer [for-all+]] [com.rpl.specter.cljs-test-helpers :refer [for-all+]]
[com.rpl.specter.macros [com.rpl.specter.macros
:refer [declarepath providepath]] :refer [declarepath providepath select select-one select-one!
select-first transform setval replace-in]]
) )
(:use (:use
#+clj [clojure.test :only [deftest is]] #+clj [clojure.test :only [deftest is]]
#+clj [clojure.test.check.clojure-test :only [defspec]] #+clj [clojure.test.check.clojure-test :only [defspec]]
#+clj [com.rpl.specter.test-helpers :only [for-all+]] #+clj [com.rpl.specter.test-helpers :only [for-all+]]
#+clj [com.rpl.specter.macros #+clj [com.rpl.specter.macros
:only [declarepath providepath]] :only [declarepath providepath select select-one select-one!
select-first transform setval replace-in]]
) )
(:require #+clj [clojure.test.check.generators :as gen] (:require #+clj [clojure.test.check.generators :as gen]
#+clj [clojure.test.check.properties :as prop] #+clj [clojure.test.check.properties :as prop]
@ -25,13 +27,13 @@
(for-all+ (for-all+
[v (gen/not-empty (gen/vector gen/int)) [v (gen/not-empty (gen/vector gen/int))
i (gen/vector gen/int)] i (gen/vector gen/int)]
(= (s/setval s/END i v) (= (setval s/END i v)
(s/setval [z/VECTOR-ZIP z/DOWN z/RIGHTMOST z/INNER-RIGHT] i v)) (setval [z/VECTOR-ZIP z/DOWN z/RIGHTMOST z/INNER-RIGHT] i v))
)) ))
(deftest zipper-multi-insert-test (deftest zipper-multi-insert-test
(is (= [1 2 :a :b 3 :a :b 4] (is (= [1 2 :a :b 3 :a :b 4]
(s/setval [z/VECTOR-ZIP (setval [z/VECTOR-ZIP
z/DOWN z/DOWN
z/RIGHT z/RIGHT
z/RIGHT z/RIGHT
@ -40,7 +42,7 @@
[:a :b] [:a :b]
[1 2 3 4] [1 2 3 4]
) )
(s/setval [z/VECTOR-ZIP (setval [z/VECTOR-ZIP
z/DOWN z/DOWN
z/RIGHT z/RIGHT
z/RIGHT z/RIGHT
@ -54,7 +56,7 @@
(deftest zipper-down-up-test (deftest zipper-down-up-test
(is (= [1 [2 3 5] 6] (is (= [1 [2 3 5] 6]
(s/transform [z/VECTOR-ZIP (transform [z/VECTOR-ZIP
z/DOWN z/DOWN
z/RIGHT z/RIGHT
z/DOWN z/DOWN
@ -72,11 +74,11 @@
(deftest next-terminate-test (deftest next-terminate-test
(is (= [2 [3 4 [5]] 6] (is (= [2 [3 4 [5]] 6]
(s/transform [z/VECTOR-ZIP z/NEXT-WALK z/NODE number?] (transform [z/VECTOR-ZIP z/NEXT-WALK z/NODE number?]
inc inc
[1 [2 3 [4]] 5]))) [1 [2 3 [4]] 5])))
(is (= [1 [3 [[]] 5]] (is (= [1 [3 [[]] 5]]
(s/setval [z/VECTOR-ZIP (setval [z/VECTOR-ZIP
z/NEXT-WALK z/NEXT-WALK
(s/selected? z/NODE number? even?) (s/selected? z/NODE number? even?)
z/NODE-SEQ] z/NODE-SEQ]
@ -88,18 +90,18 @@
(deftest zipper-nav-stop-test (deftest zipper-nav-stop-test
(is (= [1] (is (= [1]
(s/transform [z/VECTOR-ZIP z/UP z/NODE] inc [1]))) (transform [z/VECTOR-ZIP z/UP z/NODE] inc [1])))
(is (= [1] (is (= [1]
(s/transform [z/VECTOR-ZIP z/DOWN z/LEFT z/NODE] inc [1]))) (transform [z/VECTOR-ZIP z/DOWN z/LEFT z/NODE] inc [1])))
(is (= [1] (is (= [1]
(s/transform [z/VECTOR-ZIP z/DOWN z/RIGHT z/NODE] inc [1]))) (transform [z/VECTOR-ZIP z/DOWN z/RIGHT z/NODE] inc [1])))
(is (= [] (is (= []
(s/transform [z/VECTOR-ZIP z/DOWN z/NODE] inc []))) (transform [z/VECTOR-ZIP z/DOWN z/NODE] inc [])))
) )
(deftest find-first-test (deftest find-first-test
(is (= [1 [3 [[4]] 5] 6] (is (= [1 [3 [[4]] 5] 6]
(s/setval [z/VECTOR-ZIP (setval [z/VECTOR-ZIP
(z/find-first #(and (number? %) (even? %))) (z/find-first #(and (number? %) (even? %)))
z/NODE-SEQ z/NODE-SEQ
] ]
@ -110,7 +112,7 @@
(deftest nodeseq-expand-test (deftest nodeseq-expand-test
(is (= [2 [2] [[4 4 4]] 4 4 4 6] (is (= [2 [2] [[4 4 4]] 4 4 4 6]
(s/transform [z/VECTOR-ZIP (transform [z/VECTOR-ZIP
z/NEXT-WALK z/NEXT-WALK
(s/selected? z/NODE number? odd?) (s/selected? z/NODE number? odd?)
(s/collect-one z/NODE) (s/collect-one z/NODE)