implemented split selector but semantics on update can be confusing (see test)

This commit is contained in:
Nathan Marz 2015-04-22 10:55:36 -04:00
parent c456e72dea
commit 67ab15406e
3 changed files with 30 additions and 10 deletions

View file

@ -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

View file

@ -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)
))

View file

@ -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}}
))))