implemented split selector but semantics on update can be confusing (see test)
This commit is contained in:
parent
c456e72dea
commit
67ab15406e
3 changed files with 30 additions and 10 deletions
|
|
@ -107,6 +107,9 @@
|
|||
(defmacro viewfn [& args]
|
||||
`(view (fn ~@args)))
|
||||
|
||||
(defn split [& selectors]
|
||||
(->SplitPath (->> selectors (map comp-paths*) doall)))
|
||||
|
||||
(defn selected?
|
||||
"Filters the current value based on whether a selector finds anything.
|
||||
e.g. (selected? :vals ALL even?) keeps the current element only if an
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@
|
|||
|
||||
(defn- walk-until [pred on-match-fn structure]
|
||||
(if (pred structure)
|
||||
(on-match-fn structure)
|
||||
(walk/walk (partial walk-until pred on-match-fn) identity structure)
|
||||
(on-match-fn structure)
|
||||
(walk/walk (partial walk-until pred on-match-fn) identity structure)
|
||||
))
|
||||
|
||||
(defn- fn-invocation? [f]
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
(if (pred structure)
|
||||
(on-match-fn structure)
|
||||
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
||||
(if (and (fn-invocation? structure) (fn-invocation? ret))
|
||||
(if (and (fn-invocation? structure) (fn-invocation? ret))
|
||||
(with-meta ret (meta structure))
|
||||
ret
|
||||
))))
|
||||
|
|
@ -159,7 +159,7 @@
|
|||
[(conj s e) (assoc m pos i)]
|
||||
orig
|
||||
)))
|
||||
[[] {}]
|
||||
[[] {}]
|
||||
(range (count aseq))
|
||||
)))
|
||||
|
||||
|
|
@ -270,5 +270,10 @@
|
|||
(-> structure view-fn next-fn)
|
||||
))
|
||||
|
||||
|
||||
|
||||
(deftype SplitPath [selectors]
|
||||
StructureValsPath
|
||||
(select-full* [this vals structure next-fn]
|
||||
(into [] (r/mapcat #(select-full* % vals structure next-fn) selectors)))
|
||||
(update-full* [this vals structure next-fn]
|
||||
(reduce (fn [structure s] (update-full* s vals structure next-fn)) structure selectors)
|
||||
))
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
[clojure.test.check.clojure-test]
|
||||
[com.rpl specter]
|
||||
[com.rpl.specter test-helpers])
|
||||
(:require [clojure.test.check
|
||||
(:require [clojure.test.check
|
||||
[generators :as gen]
|
||||
[properties :as prop]]
|
||||
[clojure.test.check :as qc]))
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
(defspec select-all-keyword-filter
|
||||
(for-all+
|
||||
[kw gen/keyword
|
||||
v (gen/vector (max-size 5
|
||||
v (gen/vector (max-size 5
|
||||
(gen-map-with-keys gen/keyword gen/int kw)))
|
||||
pred (gen/elements [odd? even?])]
|
||||
(= (select [ALL kw pred] v)
|
||||
|
|
@ -157,7 +157,7 @@
|
|||
)))
|
||||
|
||||
(defspec replace-in-test
|
||||
(for-all+
|
||||
(for-all+
|
||||
[v (gen/vector gen/int)]
|
||||
(let [res (->> v (map (fn [v] (if (even? v) (inc v) v))))
|
||||
user-ret (->> v
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
))))
|
||||
|
||||
(defspec replace-in-custom-merge
|
||||
(for-all+
|
||||
(for-all+
|
||||
[v (gen/vector gen/int)]
|
||||
(let [res (->> v (map (fn [v] (if (even? v) (inc v) v))))
|
||||
last-even (->> v (filter even?) last)
|
||||
|
|
@ -227,3 +227,15 @@
|
|||
[:a]
|
||||
[[1 3 5] [2] [7 11 4 2] [10 1] []]
|
||||
))))
|
||||
|
||||
(deftest split-test
|
||||
(let [data {:a [1 2 3 4] :b {:c :d}}]
|
||||
(is (= (select (split [:a ALL even?] [:b :c]) data)
|
||||
[2 4 :d]))
|
||||
;;TODO: this behavior is highly confusing... any way to have split selectors go first and THEN updates applied? ... only affects updates... what if it matches both selectors?
|
||||
;; maybe shouldn't allow splitting for ALL
|
||||
(is (= (update [:a ALL (split [even? (view -)] odd?)]
|
||||
inc
|
||||
data)
|
||||
{:a [2 0 4 -2] :b {:c :d}}
|
||||
))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue