Add tests for transients, fix transient navigators based on test failures
This commit is contained in:
parent
067ce9edee
commit
cb0dc261cf
3 changed files with 64 additions and 14 deletions
|
|
@ -466,6 +466,14 @@
|
|||
(defn vec-count [v]
|
||||
(count v))
|
||||
|
||||
#+clj
|
||||
(defn transient-vec-count [^clojure.lang.ITransientVector v]
|
||||
(.count v))
|
||||
|
||||
#+cljs
|
||||
(defn transient-vec-count [v]
|
||||
(count v))
|
||||
|
||||
(extend-protocol UpdateExtremes
|
||||
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
|
||||
(update-first [v afn]
|
||||
|
|
@ -505,6 +513,9 @@
|
|||
#+clj clojure.lang.IPersistentVector #+cljs cljs.core/PersistentVector
|
||||
(fast-empty? [v]
|
||||
(= 0 (vec-count v)))
|
||||
#+clj clojure.lang.ITransientVector #+cljs cljs.core/TransientVector
|
||||
(fast-empty? [v]
|
||||
(= 0 (transient-vec-count v)))
|
||||
#+clj Object #+cljs default
|
||||
(fast-empty? [s]
|
||||
(empty? s))
|
||||
|
|
@ -762,21 +773,11 @@
|
|||
(extend-protocol p/Navigator
|
||||
TransientEndNavigator
|
||||
(select* [this structure next-fn]
|
||||
[])
|
||||
(next-fn []))
|
||||
(transform* [this structure next-fn]
|
||||
(let [res (next-fn [])]
|
||||
(reduce conj! structure res))))
|
||||
|
||||
(deftype TransientLastNavigator [])
|
||||
|
||||
(extend-protocol p/Navigator
|
||||
TransientLastNavigator
|
||||
(select* [this structure next-fn]
|
||||
(next-fn (nth structure (dec (count structure)))))
|
||||
(transform* [this structure next-fn]
|
||||
(let [i (dec (count structure))]
|
||||
(assoc! structure i (next-fn (nth structure i))))))
|
||||
|
||||
#+clj
|
||||
(defn transient-all-select
|
||||
[structure next-fn]
|
||||
|
|
|
|||
|
|
@ -25,13 +25,30 @@
|
|||
"Navigates to an empty (persistent) vector at the end of a transient vector."
|
||||
(i/comp-paths* [(i/->TransientEndNavigator)]))
|
||||
|
||||
(defn- t-get-first
|
||||
[tv]
|
||||
(nth tv 0))
|
||||
|
||||
(defn- t-get-last
|
||||
[tv]
|
||||
(nth tv (dec (i/transient-vec-count tv))))
|
||||
|
||||
(defn- t-update-first
|
||||
[tv next-fn]
|
||||
(assoc! tv 0 (next-fn (nth tv 0))))
|
||||
|
||||
(defn- t-update-last
|
||||
[tv next-fn]
|
||||
(let [i (dec (i/transient-vec-count tv))]
|
||||
(assoc! tv i (next-fn (nth tv i)))))
|
||||
|
||||
(def FIRST!
|
||||
"Navigates to the first element of a transient vector."
|
||||
(keypath! 0))
|
||||
(i/->PosNavigator t-get-first t-update-first))
|
||||
|
||||
(def LAST!
|
||||
"Navigates to the last element of a transient vector."
|
||||
(i/comp-paths* [(i/->TransientLastNavigator)]))
|
||||
(i/->PosNavigator t-get-last t-update-last))
|
||||
|
||||
(defn- select-keys-from-transient-map
|
||||
"Selects keys from transient map, because built-in select-keys uses
|
||||
|
|
@ -54,7 +71,7 @@
|
|||
submap!
|
||||
[m-keys]
|
||||
(select* [this structure next-fn]
|
||||
(select-keys-from-transient-map structure m-keys))
|
||||
(next-fn (select-keys-from-transient-map structure m-keys)))
|
||||
(transform* [this structure next-fn]
|
||||
(let [selected (select-keys-from-transient-map structure m-keys)
|
||||
res (next-fn selected)]
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#+cljs [cljs.test.check.generators :as gen]
|
||||
#+cljs [cljs.test.check.properties :as prop :include-macros true]
|
||||
[com.rpl.specter :as s]
|
||||
[com.rpl.specter.transient :as t]
|
||||
[clojure.set :as set]))
|
||||
|
||||
;;TODO:
|
||||
|
|
@ -1036,3 +1037,34 @@
|
|||
(is (= 2 (key e)))
|
||||
(is (= 4 (val e)))
|
||||
))
|
||||
|
||||
(defspec transient-vector-test
|
||||
(for-all+
|
||||
[v (gen/vector (limit-size 5 gen/int))]
|
||||
(every? identity
|
||||
(for [[path transient-path f]
|
||||
[[s/FIRST t/FIRST! (fnil inc 0)] ;; fnil in case vector is empty
|
||||
[s/LAST t/LAST! (fnil inc 0)]
|
||||
[(s/keypath 0) (t/keypath! 0) (fnil inc 0)]
|
||||
[s/END t/END! #(conj % 1 2 3)]]]
|
||||
(and (= (s/transform* path f v)
|
||||
(persistent! (s/transform* transient-path f (transient v))))
|
||||
(= (s/select* path v)
|
||||
(s/select* transient-path (transient v))))))))
|
||||
|
||||
(defspec transient-map-test
|
||||
(for-all+
|
||||
[m (gen/not-empty (gen/map gen/keyword gen/int))
|
||||
new-key gen/keyword]
|
||||
(let [existing-key (first (keys m))]
|
||||
(every? identity
|
||||
(for [[path transient-path f]
|
||||
[[(s/keypath existing-key) (t/keypath! existing-key) inc]
|
||||
[(s/keypath new-key) (t/keypath! new-key) (constantly 3)]
|
||||
[(s/submap [existing-key new-key])
|
||||
(t/submap! [existing-key new-key])
|
||||
(constantly {new-key 1234})]]]
|
||||
(and (= (s/transform* path f m)
|
||||
(persistent! (s/transform* transient-path f (transient m))))
|
||||
(= (s/select* path m)
|
||||
(s/select* transient-path (transient m)))))))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue