switch from cljx to cljc

This commit is contained in:
Nathan Marz 2016-08-06 10:40:45 -04:00
parent fb6cd38b1d
commit 74f38d93a9
11 changed files with 269 additions and 267 deletions

View file

@ -7,7 +7,6 @@
:source-paths ["src/clj"]
:java-source-paths ["src/java"]
:test-paths ["test", "target/test-classes"]
:jar-exclusions [#"\.cljx"]
:auto-clean false
:dependencies [[riddley "0.1.12"]]
:plugins [[lein-codox "0.9.5"]]
@ -26,25 +25,8 @@
[[org.clojure/test.check "0.7.0"]
[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "1.7.10"]]
:plugins
[[com.keminglabs/cljx "0.6.0"]]
:cljx {:builds [{:source-paths ["src/clj"]
:output-path "target/classes"
:rules :clj}
{:source-paths ["src/clj"]
:output-path "target/classes"
:rules :cljs}
{:source-paths ["test"]
:output-path "target/test-classes"
:rules :clj}
{:source-paths ["test"]
:output-path "target/test-classes"
:rules :cljs}]}
}
:test {:dependencies [[org.clojure/clojure "1.7.0"]]}
}
:aliases {"cleantest" ["do" "clean,"
"cljx" "once,"
"test"]
"deploy" ["do" "clean," "cljx" "once," "deploy" "clojars"]}
:aliases {"deploy" ["do" "clean," "deploy" "clojars"]}
)

View file

@ -1,5 +1,5 @@
(ns com.rpl.specter
#+cljs (:require-macros
#?(:cljs (:require-macros
[com.rpl.specter.macros
:refer
[fixed-pathed-collector
@ -12,17 +12,17 @@
]]
[com.rpl.specter.util-macros :refer
[doseqres]]
)
))
(:use [com.rpl.specter.protocols :only [ImplicitNav]]
#+clj [com.rpl.specter.macros :only
[fixed-pathed-collector
fixed-pathed-nav
defcollector
defnav
defpathedfn
richnav
defnavconstructor]]
#+clj [com.rpl.specter.util-macros :only [doseqres]]
#?(:clj [com.rpl.specter.macros :only
[fixed-pathed-collector
fixed-pathed-nav
defcollector
defnav
defpathedfn
richnav
defnavconstructor]])
#?(:clj [com.rpl.specter.util-macros :only [doseqres]])
)
(:require [com.rpl.specter.impl :as i]
[com.rpl.specter.navs :as n]
@ -525,16 +525,16 @@
ImplicitNav
(implicit-nav [this] STAY))
(extend-type #+clj clojure.lang.Keyword #+cljs cljs.core/Keyword
(extend-type #?(:clj clojure.lang.Keyword :cljs cljs.core/Keyword)
ImplicitNav
(implicit-nav [this] (keypath this))
)
(extend-type #+clj clojure.lang.AFn #+cljs function
(extend-type #?(:clj clojure.lang.AFn :cljs function)
ImplicitNav
(implicit-nav [this] (pred this)))
(extend-type #+clj clojure.lang.PersistentHashSet #+cljs cljs.core/PersistentHashSet
(extend-type #?(:clj clojure.lang.PersistentHashSet :cljs cljs.core/PersistentHashSet)
ImplicitNav
(implicit-nav [this] (pred this)))

View file

@ -1,21 +1,18 @@
(ns com.rpl.specter.impl
#+cljs (:require-macros
[com.rpl.specter.prot-opt-invoke
:refer [mk-optimized-invocation]]
#?(:cljs (:require-macros
[com.rpl.specter.defhelpers :refer [define-ParamsNeededPath]]
[com.rpl.specter.util-macros :refer [doseqres]]
)
))
(:use [com.rpl.specter.protocols :only
[select* transform* collect-val Navigator]]
#+clj [com.rpl.specter.util-macros :only [doseqres]]
#?(:clj [com.rpl.specter.util-macros :only [doseqres]])
)
(:require [com.rpl.specter.protocols :as p]
[clojure.string :as s]
#+clj [com.rpl.specter.defhelpers :as dh]
#+clj [riddley.walk :as riddley]
#?(:clj [com.rpl.specter.defhelpers :as dh])
#?(:clj [riddley.walk :as riddley])
)
#+clj
(:import [com.rpl.specter Util MutableCell])
#?(:clj (:import [com.rpl.specter Util MutableCell]))
)
(def NONE ::NONE)
@ -51,45 +48,53 @@
([a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 & r] v)
))
#+clj
#?(:clj
(defmacro throw* [etype & args]
`(throw (new ~etype (smart-str ~@args))))
`(throw (new ~etype (smart-str ~@args)))))
#+clj
#?(
:clj
(defmacro throw-illegal [& args]
`(throw* IllegalArgumentException ~@args))
#+cljs
:cljs
(defn throw-illegal [& args]
(throw (js/Error. (apply str args))))
)
;; need to get the expansion function like this so that
;; this code compiles in a clojure environment where cljs.analyzer
;; namespace does not exist
#+clj
#?(
:clj
(defn cljs-analyzer-macroexpand-1 []
(eval 'cljs.analyzer/macroexpand-1))
;; this version is for bootstrap cljs
#+cljs
:cljs
(defn cljs-analyzer-macroexpand-1 []
^:cljs.analyzer/no-resolve cljs.analyzer/macroexpand-1)
)
#+clj
#?(
:clj
(defn clj-macroexpand-all [form]
(riddley/macroexpand-all form))
#+cljs
:cljs
(defn clj-macroexpand-all [form]
(throw-illegal "not implemented"))
)
#+clj
#?(
:clj
(defn intern* [ns name val] (intern ns name val))
#+cljs
:cljs
(defn intern* [ns name val]
(throw-illegal "intern not supported in ClojureScript"))
)
(defn benchmark [iters afn]
(time
@ -105,45 +110,53 @@
(rich-transform* [this params params-idx vals structure next-fn])
)
#+clj
#?(
:clj
(defmacro exec-rich-select* [this & args]
(let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})]
`(.rich-select* ~hinted ~@args)
))
#+cljs
:cljs
(defn exec-rich-select* [this params params-idx vals structure next-fn]
(rich-select* ^not-native this params params-idx vals structure next-fn))
)
#+clj
#?(
:clj
(defmacro exec-rich-transform* [this & args]
(let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})]
`(.rich-transform* ~hinted ~@args)
))
#+cljs
:cljs
(defn exec-rich-transform* [this params params-idx vals structure next-fn]
(rich-transform* ^not-native this params params-idx vals structure next-fn))
)
#+clj
#?(
:clj
(defmacro exec-select* [this & args]
(let [hinted (with-meta this {:tag 'com.rpl.specter.protocols.Navigator})]
`(.select* ~hinted ~@args)
))
#+cljs
:cljs
(defn exec-select* [this structure next-fn]
(p/select* ^not-native this structure next-fn))
)
#+clj
#?(
:clj
(defmacro exec-transform* [this & args]
(let [hinted (with-meta this {:tag 'com.rpl.specter.protocols.Navigator})]
`(.transform* ~hinted ~@args)
))
#+cljs
:cljs
(defn exec-transform* [this structure next-fn]
(p/transform* ^not-native this structure next-fn))
)
(def RichPathExecutor
(->ExecutorFunctions
@ -194,16 +207,18 @@
(declare bind-params*)
#+clj
#?(
:clj
(defmacro fast-object-array [i]
`(com.rpl.specter.Util/makeObjectArray ~i))
#+cljs
:cljs
(defn fast-object-array [i]
(object-array i))
)
#+clj
#?(
:clj
(dh/define-ParamsNeededPath
true
clojure.lang.IFn
@ -212,7 +227,7 @@
(let [a (object-array args)]
(com.rpl.specter.impl/bind-params* this a 0))))
#+cljs
:cljs
(define-ParamsNeededPath
false
cljs.core/IFn
@ -227,6 +242,7 @@
rest))]
(com.rpl.specter.impl/bind-params* this a 0))
))
)
(defn params-needed-path? [o]
(instance? ParamsNeededPath o))
@ -288,24 +304,24 @@
(coerce-path [this]
this)
#+clj java.util.List #+cljs cljs.core/PersistentVector
#?(:clj java.util.List :cljs cljs.core/PersistentVector)
(coerce-path [this]
(do-comp-paths this))
#+cljs cljs.core/IndexedSeq
#+cljs (coerce-path [this]
(coerce-path (vec this)))
#+cljs cljs.core/EmptyList
#+cljs (coerce-path [this]
(coerce-path (vec this)))
#+cljs cljs.core/List
#+cljs (coerce-path [this]
(coerce-path (vec this)))
#+cljs cljs.core/LazySeq
#+cljs (coerce-path [this]
(coerce-path (vec this)))
#?(:cljs cljs.core/IndexedSeq)
#?(:cljs (coerce-path [this]
(coerce-path (vec this))))
#?(:cljs cljs.core/EmptyList)
#?(:cljs (coerce-path [this]
(coerce-path (vec this))))
#?(:cljs cljs.core/List)
#?(:cljs (coerce-path [this]
(coerce-path (vec this))))
#?(:cljs cljs.core/LazySeq)
#?(:cljs (coerce-path [this]
(coerce-path (vec this))))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(coerce-path [this]
(coerce-object this)))
@ -388,10 +404,10 @@
nil
(do-comp-paths [o]
(coerce-path o))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(do-comp-paths [o]
(coerce-path o))
#+clj java.util.List #+cljs cljs.core/PersistentVector
#?(:clj java.util.List :cljs cljs.core/PersistentVector)
(do-comp-paths [navigators]
(if (empty? navigators)
(coerce-path nil)
@ -430,42 +446,50 @@
;; cell implementation idea taken from prismatic schema library
#+cljs
#?(:cljs
(defprotocol PMutableCell
(set_cell [cell x]))
)
#+cljs
#?(:cljs
(deftype MutableCell [^:volatile-mutable q]
PMutableCell
(set_cell [this x] (set! q x)))
)
#+cljs
(defn mutable-cell
([] (mutable-cell nil))
([init] (MutableCell. init)))
#+cljs
(defn set-cell! [cell val]
(set_cell cell val))
#+cljs
(defn get-cell [cell]
#+clj (get_cell cell) #+cljs (.-q cell)
)
#+clj
#?(
:clj
(defn mutable-cell
([] (mutable-cell nil))
([v] (MutableCell. v)))
#+clj
:cljs
(defn mutable-cell
([] (mutable-cell nil))
([init] (MutableCell. init)))
)
#?(
:clj
(defn set-cell! [^MutableCell c v]
(.set c v))
:cljs
(defn set-cell! [cell val]
(set_cell cell val))
)
#?(
:clj
(defn get-cell [^MutableCell c]
(.get c))
#+clj
(defn set-cell! [^MutableCell c v]
(.set c v))
:cljs
(defn get-cell [cell]
(.-q cell))
)
(defn update-cell! [cell afn]
@ -488,7 +512,8 @@
;; amazingly doing this as a macro shows a big effect in the
;; benchmark for getting a value out of a nested map
#+clj
#?(
:clj
(defmacro compiled-traverse* [path result-fn structure]
`(let [nav# (compiled-nav-field ~path)
ex# (compiled-executors-field ~path)]
@ -498,7 +523,7 @@
~structure)
))
#+cljs
:cljs
(defn compiled-traverse* [path result-fn structure]
(let [nav (compiled-nav-field path)
ex (compiled-executors-field path)]
@ -507,13 +532,14 @@
result-fn
structure)
))
)
(defn do-compiled-traverse [apath structure]
(reify #+clj clojure.lang.IReduce #+cljs cljs.core/IReduce
(#+clj reduce #+cljs -reduce
(reify #?(:clj clojure.lang.IReduce :cljs cljs.core/IReduce)
(#?(:clj reduce :cljs -reduce)
[this afn]
(#+clj .reduce #+cljs -reduce this afn (afn)))
(#+clj reduce #+cljs -reduce
(#?(:clj .reduce :cljs -reduce) this afn (afn)))
(#?(:clj reduce :cljs -reduce)
[this afn start]
(let [cell (mutable-cell start)]
(compiled-traverse*
@ -616,9 +642,9 @@
))))
(defn fn-invocation? [f]
(or #+clj (instance? clojure.lang.Cons f)
#+clj (instance? clojure.lang.LazySeq f)
#+cljs (instance? cljs.core.LazySeq f)
(or #?(:clj (instance? clojure.lang.Cons f))
#?(:clj (instance? clojure.lang.LazySeq f))
#?(:cljs (instance? cljs.core.LazySeq f))
(list? f)))
(defrecord LayeredNav [underlying])
@ -702,13 +728,13 @@
(or (satisfies? p/ImplicitNav v)
(instance? CompiledPath v)))
#+cljs
#?(:cljs
(defn handle-params [precompiled params-maker possible-params]
(let [params (fast-object-array (count params-maker))]
(dotimes [i (count params-maker)]
(aset params i ((get possible-params (get params-maker i)))))
(bind-params* precompiled params 0)
))
)))
(defn filter-select [afn structure next-fn]
(if (afn structure)
@ -980,11 +1006,12 @@
;; This is needed when aset is used on primitive values in mk-params-maker
;; to avoid reflection
#+clj
#?(:clj
(defn aset-object [^objects a i ^Object v]
(aset a i v))
(aset a i v)))
#+clj
#?(
:clj
(defn mk-params-maker [ns-str params-code possible-params-code used-locals]
(let [ns (find-ns (symbol ns-str))
array-sym (gensym "array")]
@ -1000,13 +1027,14 @@
~array-sym
))))))
#+cljs
:cljs
(defn mk-params-maker [ns-str params-code possible-params-code used-locals]
(let [indexed (->> possible-params-code
(map-indexed (comp vec reverse vector))
(into {}))]
;;TODO: may be more efficient as an array
(mapv (fn [c] (get indexed c)) params-code)))
)
;; possible-params-code is for cljs impl that can't use eval
(defn magic-precompilation [prepared-path ns-str used-locals possible-params-code]
@ -1060,7 +1088,7 @@
(defn compiled-multi-transform* [path structure]
(compiled-transform* path multi-transform-error-fn structure))
#+clj
#?(:clj
(defn extend-protocolpath* [protpath protpath-prot extensions]
(let [extensions (partition 2 extensions)
m (-> protpath-prot :sigs keys first)
@ -1074,7 +1102,7 @@
(throw-illegal "Invalid number of params in extended protocol path, expected "
expected-params " but got " needed-params))
(extend atype protpath-prot {m (fn [_] rich-nav)})
))))
)))))
(defn parameterize-path [apath params params-idx]
(if (instance? CompiledPath apath)

View file

@ -1,5 +1,5 @@
(ns com.rpl.specter.navs
#+cljs (:require-macros
#?(:cljs (:require-macros
[com.rpl.specter.macros
:refer
[fixed-pathed-collector
@ -12,12 +12,12 @@
]]
[com.rpl.specter.util-macros :refer
[doseqres]]
)
(:use #+clj [com.rpl.specter macros]
#+clj [com.rpl.specter.util-macros :only [doseqres]])
))
(:use #?(:clj [com.rpl.specter macros])
#?(:clj [com.rpl.specter.util-macros :only [doseqres]]))
(:require [com.rpl.specter.impl :as i]
[clojure.walk :as walk]
#+clj [clojure.core.reducers :as r]
#?(:clj [clojure.core.reducers :as r])
[com.rpl.specter.defnavhelpers] ; so that for cljs it's loaded as macros expand to this
)
)
@ -61,14 +61,16 @@
(doseqres i/NONE [e structure]
(next-fn e)))
#+cljs
(defn queue? [coll]
(= (type coll) (type #queue [])))
#+clj
#?(
:clj
(defn queue? [coll]
(instance? clojure.lang.PersistentQueue coll))
:cljs
(defn queue? [coll]
(= (type coll) (type #queue [])))
)
(defprotocol AllTransformProtocol
(all-transform [structure next-fn]))
@ -89,21 +91,20 @@
)
;; in cljs they're PersistentVector so don't need a special case
#+clj clojure.lang.MapEntry
#+clj
#?(:clj clojure.lang.MapEntry)
#?(:clj
(all-transform [structure next-fn]
(let [newk (next-fn (key structure))
newv (next-fn (val structure))]
(clojure.lang.MapEntry. newk newv)
))
)))
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
#?(:clj clojure.lang.PersistentVector :cljs cljs.core/PersistentVector)
(all-transform [structure next-fn]
(mapv next-fn structure))
#+clj
clojure.lang.PersistentArrayMap
#+clj
#?(:clj clojure.lang.PersistentArrayMap)
#?(:clj
(all-transform [structure next-fn]
(let [k-it (.keyIterator structure)
v-it (.valIterator structure)]
@ -114,21 +115,20 @@
[newk newv] (next-fn [k v])]
(recur (assoc ret newk newv)))
ret
))))
)))))
#+cljs
cljs.core/PersistentArrayMap
#+cljs
#?(:cljs cljs.core/PersistentArrayMap)
#?(:cljs
(all-transform [structure next-fn]
(non-transient-map-all-transform structure next-fn {})
)
))
#+clj clojure.lang.PersistentTreeMap #+cljs cljs.core/PersistentTreeMap
#?(:clj clojure.lang.PersistentTreeMap :cljs cljs.core/PersistentTreeMap)
(all-transform [structure next-fn]
(non-transient-map-all-transform structure next-fn (empty structure))
)
#+clj clojure.lang.PersistentHashMap #+cljs cljs.core/PersistentHashMap
#?(:clj clojure.lang.PersistentHashMap :cljs cljs.core/PersistentHashMap)
(all-transform [structure next-fn]
(persistent!
(reduce-kv
@ -137,15 +137,14 @@
(assoc! m newk newv)
))
(transient
#+clj clojure.lang.PersistentHashMap/EMPTY #+cljs cljs.core.PersistentHashMap.EMPTY
#?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY)
)
structure
)))
#+clj
Object
#+clj
#?(:clj Object)
#?(:clj
(all-transform [structure next-fn]
(let [empty-structure (empty structure)]
(cond (and (list? empty-structure) (not (queue? empty-structure)))
@ -165,18 +164,17 @@
:else
(->> structure (r/map next-fn) (into empty-structure))
)))
))))
#+cljs
default
#+cljs
#?(:cljs default)
#?(:cljs
(all-transform [structure next-fn]
(let [empty-structure (empty structure)]
(if (and (list? empty-structure) (not (queue? empty-structure)))
;; this is done to maintain order, otherwise lists get reversed
(doall (map next-fn structure))
(into empty-structure (map #(next-fn %)) structure)
)))
))))
)
(defprotocol MapValsTransformProtocol
@ -195,9 +193,8 @@
nil
)
#+clj
clojure.lang.PersistentArrayMap
#+clj
#?(:clj clojure.lang.PersistentArrayMap)
#?(:clj
(map-vals-transform [structure next-fn]
(let [k-it (.keyIterator structure)
v-it (.valIterator structure)]
@ -207,33 +204,32 @@
v (.next v-it)]
(recur (assoc ret k (next-fn v))))
ret
))))
)))))
#+cljs
cljs.core/PersistentArrayMap
#+cljs
#?(:cljs cljs.core/PersistentArrayMap)
#?(:cljs
(map-vals-transform [structure next-fn]
(map-vals-non-transient-transform structure {} next-fn)
)
))
#+clj clojure.lang.PersistentTreeMap #+cljs cljs.core/PersistentTreeMap
#?(:clj clojure.lang.PersistentTreeMap :cljs cljs.core/PersistentTreeMap)
(map-vals-transform [structure next-fn]
(map-vals-non-transient-transform structure (empty structure) next-fn)
)
#+clj clojure.lang.PersistentHashMap #+cljs cljs.core/PersistentHashMap
#?(:clj clojure.lang.PersistentHashMap :cljs cljs.core/PersistentHashMap)
(map-vals-transform [structure next-fn]
(persistent!
(reduce-kv
(fn [m k v]
(assoc! m k (next-fn v)))
(transient
#+clj clojure.lang.PersistentHashMap/EMPTY #+cljs cljs.core.PersistentHashMap.EMPTY
#?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY)
)
structure
)))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(map-vals-transform [structure next-fn]
(reduce-kv
(fn [m k v]
@ -334,7 +330,7 @@
(prepend-all [_ elements]
elements)
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
#?(:clj clojure.lang.PersistentVector :cljs cljs.core/PersistentVector)
(append-all [structure elements]
(reduce conj structure elements))
(prepend-all [structure elements]
@ -345,7 +341,7 @@
(persistent! <>)
)))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(append-all [structure elements]
(concat structure elements))
(prepend-all [structure elements]
@ -380,24 +376,28 @@
(defn- update-last-list [l afn]
(append (butlast l) (afn (last l))))
#+clj
#?(
:clj
(defn vec-count [^clojure.lang.IPersistentVector v]
(.length v))
#+cljs
:cljs
(defn vec-count [v]
(count v))
)
#+clj
#?(
:clj
(defn transient-vec-count [^clojure.lang.ITransientVector v]
(.count v))
#+cljs
:cljs
(defn transient-vec-count [v]
(count v))
)
(extend-protocol UpdateExtremes
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
#?(:clj clojure.lang.PersistentVector :cljs cljs.core/PersistentVector)
(update-first [v afn]
(let [val (nth v 0)]
(assoc v 0 (afn val))
@ -411,7 +411,7 @@
(let [i (dec c)]
(assoc v i (afn (nth v i)))
))))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(update-first [l val]
(update-first-list l val))
(update-last [l val]
@ -419,12 +419,12 @@
))
(extend-protocol GetExtremes
#+clj clojure.lang.IPersistentVector #+cljs cljs.core/PersistentVector
#?(:clj clojure.lang.IPersistentVector :cljs cljs.core/PersistentVector)
(get-first [v]
(nth v 0))
(get-last [v]
(peek v))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(get-first [s]
(first s))
(get-last [s]
@ -436,13 +436,13 @@
nil
(fast-empty? [_] true)
#+clj clojure.lang.IPersistentVector #+cljs cljs.core/PersistentVector
#?(:clj clojure.lang.IPersistentVector :cljs cljs.core/PersistentVector)
(fast-empty? [v]
(= 0 (vec-count v)))
#+clj clojure.lang.ITransientVector #+cljs cljs.core/TransientVector
#?(:clj clojure.lang.ITransientVector :cljs cljs.core/TransientVector)
(fast-empty? [v]
(= 0 (transient-vec-count v)))
#+clj Object #+cljs default
#?(:clj Object :cljs default)
(fast-empty? [s]
(empty? s))
)

View file

@ -1,11 +0,0 @@
(ns com.rpl.specter.prot-opt-invoke)
(defmacro mk-optimized-invocation [protocol obj method num-args]
(let [args (take num-args (repeatedly gensym))
o (-> (gensym) (with-meta {:tag 'not-native}))]
`(if (~'implements? ~protocol ~obj)
(fn [~o ~@args]
(~method ~o ~@args)
)
~method
)))

View file

@ -1,13 +1,13 @@
(ns com.rpl.specter.transients
#+cljs
#?(:cljs
(:require-macros [com.rpl.specter.macros
:refer
[defnav
defpathedfn]])
(:use #+clj
defpathedfn]]))
(:use #?(:clj
[com.rpl.specter.macros :only
[defnav
defpathedfn]])
defpathedfn]]))
(:require [com.rpl.specter.navs :as n]
[com.rpl.specter :refer [subselect selected?]]))
@ -59,7 +59,8 @@
"Navigates to the last element of a transient vector."
(n/PosNavigator t-get-last t-update-last))
#+clj
#?(
:clj
(defn- select-keys-from-transient-map
"Selects keys from transient map, because built-in select-keys uses
`find` which is unsupported."
@ -76,11 +77,12 @@
result)
(rest m-keys))))))
#+cljs
:cljs
(defn- select-keys-from-transient-map
"Uses select-keys on a transient map."
[m m-keys]
(select-keys m m-keys))
)
(defnav
^{:doc "Navigates to the specified persistent submap of a transient map."}

View file

@ -1,10 +1,10 @@
(ns com.rpl.specter.zipper
#+cljs (:require-macros
#?(:cljs (:require-macros
[com.rpl.specter.macros
:refer [defnav nav declarepath providepath]])
#+clj
:refer [defnav nav declarepath providepath]]))
#?(:clj
(:use
[com.rpl.specter.macros :only [defnav nav declarepath providepath]])
[com.rpl.specter.macros :only [defnav nav declarepath providepath]]))
(:require [com.rpl.specter :as s]
[clojure.zip :as zip]))

View file

@ -1,5 +1,5 @@
(ns com.rpl.specter.core-test
#+cljs (:require-macros
#?(:cljs (:require-macros
[cljs.test :refer [is deftest]]
[cljs.test.check.cljs-test :refer [defspec]]
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
@ -9,25 +9,25 @@
nav declarepath providepath select select-one select-one!
select-first transform setval replace-in defnavconstructor
select-any selected-any? collected? traverse
multi-transform]])
multi-transform]]))
(:use
#+clj [clojure.test :only [deftest is]]
#+clj [clojure.test.check.clojure-test :only [defspec]]
#+clj [com.rpl.specter.test-helpers :only [for-all+ ic-test]]
#+clj [com.rpl.specter.macros
:only [paramsfn defprotocolpath defnav extend-protocolpath
nav declarepath providepath select select-one select-one!
select-first transform setval replace-in defnavconstructor
select-any selected-any? collected? traverse
multi-transform]]
#?(:clj [clojure.test :only [deftest is]])
#?(:clj [clojure.test.check.clojure-test :only [defspec]])
#?(:clj [com.rpl.specter.test-helpers :only [for-all+ ic-test]])
#?(:clj [com.rpl.specter.macros
:only [paramsfn defprotocolpath defnav extend-protocolpath
nav declarepath providepath select select-one select-one!
select-first transform setval replace-in defnavconstructor
select-any selected-any? collected? traverse
multi-transform]])
)
(:require #+clj [clojure.test.check.generators :as gen]
#+clj [clojure.test.check.properties :as prop]
#+cljs [cljs.test.check :as tc]
#+cljs [cljs.test.check.generators :as gen]
#+cljs [cljs.test.check.properties :as prop :include-macros true]
(:require #?(:clj [clojure.test.check.generators :as gen])
#?(:clj [clojure.test.check.properties :as prop])
#?(:cljs [cljs.test.check :as tc])
#?(: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.transients :as t]
[clojure.set :as set]))
@ -76,7 +76,7 @@
))
(deftest select-one-test
(is (thrown? #+clj Exception #+cljs js/Error (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 (select-one [s/ALL odd?] [2 4 1 6])))
)
@ -247,7 +247,7 @@
(deftest atom-test
(let [v (transform s/ATOM inc (atom 1))]
(is (instance? #+clj clojure.lang.Atom #+cljs cljs.core/Atom v))
(is (instance? #?(:clj clojure.lang.Atom :cljs cljs.core/Atom) v))
(is (= 2 (select-one s/ATOM v) @v))))
(defspec view-test
@ -453,7 +453,7 @@
(deftest nil-select-one-test
(is (= nil (select-one! s/ALL [nil])))
(is (thrown? #+clj Exception #+cljs js/Error (select-one! s/ALL [])))
(is (thrown? #?(:clj Exception :cljs js/Error) (select-one! s/ALL [])))
)
@ -756,7 +756,7 @@
[:q [:abc 3] [:ccc [:abc] [:abc "a" [:abc [:abc [:d]]]]]]
))))
#+clj
#?(:clj
(deftest large-params-test
(let [path (apply s/comp-paths (repeat 25 s/keypath))
m (reduce
@ -765,20 +765,20 @@
:a
(reverse (range 25)))]
(is (= :a (select-one (apply path (range 25)) m)))
))
)))
;;TODO: there's a bug in clojurescript that won't allow
;; non function implementations of IFn to have more than 20 arguments
#+clj
#?(:clj
(do
(defprotocolpath AccountPath [])
(defrecord Account [funds])
(defrecord User [account])
(defrecord Family [accounts])
(extend-protocolpath AccountPath User :account Family [:accounts s/ALL])
)
))
#+clj
#?(:clj
(deftest protocolpath-basic-test
(let [data [(->User (->Account 30))
(->User (->Account 50))
@ -791,9 +791,9 @@
(transform [s/ALL AccountPath :funds]
inc
data)))
))
)))
#+clj
#?(:clj
(do
(defprotocolpath LabeledAccountPath [label])
(defrecord LabeledUser [account])
@ -801,9 +801,9 @@
(extend-protocolpath LabeledAccountPath
LabeledUser [:account s/keypath]
LabeledFamily [:accounts s/keypath s/ALL])
)
))
#+clj
#?(:clj
(deftest protocolpath-params-test
(let [data [(->LabeledUser {:a (->Account 30)})
(->LabeledUser {:a (->Account 50)})
@ -816,10 +816,10 @@
(transform [s/ALL (LabeledAccountPath :a) :funds]
inc
data)))
))
)))
#+clj
#?(:clj
(do
(defprotocolpath CustomWalker [])
(extend-protocolpath CustomWalker
@ -827,32 +827,33 @@
clojure.lang.PersistentHashMap [(s/keypath :a) CustomWalker]
clojure.lang.PersistentArrayMap [(s/keypath :a) CustomWalker]
clojure.lang.PersistentVector [s/ALL CustomWalker]
)
)))
)
#+clj
#?(:clj
(deftest mixed-rich-regular-protocolpath
(is (= [1 2 3 11 21 22 25]
(select [CustomWalker number?] [{:a [1 2 :c [3]]} [[[[[[11]]] 21 [22 :c 25]]]]])))
(is (= [2 3 [[[4]] :b 0] {:a 4 :b 10}]
(transform [CustomWalker number?] inc [1 2 [[[3]] :b -1] {:a 3 :b 10}])))
)
))
#+cljs
(defn make-queue [coll]
(reduce
#(conj %1 %2)
#queue []
coll))
#+clj
#?(
:clj
(defn make-queue [coll]
(reduce
#(conj %1 %2)
clojure.lang.PersistentQueue/EMPTY
coll))
:cljs
(defn make-queue [coll]
(reduce
#(conj %1 %2)
#queue []
coll))
)
(defspec transform-idempotency 50
(for-all+
[v1 (gen/vector gen/int)
@ -964,26 +965,26 @@
)
(s/must-cache-paths!)
(is (thrown? #+clj Exception #+cljs js/Error
(is (thrown? #?(:clj Exception :cljs js/Error)
(select (if true :a :b) nil)
))
(is (thrown? #+clj Exception #+cljs js/Error
(is (thrown? #?(:clj Exception :cljs js/Error)
(select (*APATH* :a) nil)
))
(is (thrown? #+clj Exception #+cljs js/Error
(is (thrown? #?(:clj Exception :cljs js/Error)
(select [:a (identity even?)] {:a 2})
))
;; this tests a bug that existed before ^:staticparam annotation
;; for pathedfns
(is (thrown? #+clj Exception #+cljs js/Error
(is (thrown? #?(:clj Exception :cljs js/Error)
(select [(s/putval 10) (s/transformed s/STAY #(inc %))] 10)
))
(let [p :a]
(is (thrown? #+clj Exception #+cljs js/Error
(is (thrown? #?(:clj Exception :cljs js/Error)
(select [p even?] {:a 2})
)))
(let [p :a]
(is (thrown? #+clj Exception #+cljs js/Error
(is (thrown? #?(:clj Exception :cljs js/Error)
(select [s/ALL (s/selected? p even?)] [{:a 2}])
)))
(s/must-cache-paths! false)
@ -1036,13 +1037,13 @@
(is (= false (select-one! (s/nil->val true) false)))
)
#+clj
#?(:clj
(deftest all-map-entry
(let [e (transform s/ALL inc (first {1 3}))]
(is (instance? clojure.lang.MapEntry e))
(is (= 2 (key e)))
(is (= 4 (val e)))
))
)))
(deftest select-on-empty-vector
(is (= s/NONE (select-any s/ALL [])))
@ -1320,7 +1321,7 @@
))))
(deftest multi-transform-overrun-error
(is (thrown? #+clj Exception #+cljs js/Error (multi-transform s/STAY 3)))
(is (thrown? #?(:clj Exception :cljs js/Error) (multi-transform s/STAY 3)))
)
(deftest terminal-val-test

View file

@ -1,25 +1,25 @@
(ns com.rpl.specter.zipper-test
#+cljs (:require-macros
#?(:cljs (:require-macros
[cljs.test :refer [is deftest]]
[cljs.test.check.cljs-test :refer [defspec]]
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
[com.rpl.specter.macros
:refer [declarepath providepath select select-one select-one!
select-first transform setval replace-in]]
)
))
(:use
#+clj [clojure.test :only [deftest is]]
#+clj [clojure.test.check.clojure-test :only [defspec]]
#+clj [com.rpl.specter.test-helpers :only [for-all+]]
#+clj [com.rpl.specter.macros
:only [declarepath providepath select select-one select-one!
select-first transform setval replace-in]]
#?(:clj [clojure.test :only [deftest is]])
#?(:clj [clojure.test.check.clojure-test :only [defspec]])
#?(:clj [com.rpl.specter.test-helpers :only [for-all+]])
#?(:clj [com.rpl.specter.macros
:only [declarepath providepath select select-one select-one!
select-first transform setval replace-in]])
)
(:require #+clj [clojure.test.check.generators :as gen]
#+clj [clojure.test.check.properties :as prop]
#+cljs [cljs.test.check :as tc]
#+cljs [cljs.test.check.generators :as gen]
#+cljs [cljs.test.check.properties :as prop :include-macros true]
(:require #?(:clj [clojure.test.check.generators :as gen])
#?(:clj [clojure.test.check.properties :as prop])
#?(:cljs [cljs.test.check :as tc])
#?(: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.zipper :as z]))