added tests and cljs-specific fixes
This commit is contained in:
parent
218cbcb933
commit
4f3990c239
4 changed files with 97 additions and 8 deletions
|
|
@ -681,8 +681,7 @@
|
|||
#+cljs
|
||||
(defn handle-params [precompiled params-maker possible-params]
|
||||
(let [params (fast-object-array (count params-maker))]
|
||||
;;TODO: is there a faster way to do this in cljs?
|
||||
(doseq [i (range (count params-maker))]
|
||||
(dotimes [i (count params-maker)]
|
||||
(aset params i ((get possible-params (get params-maker i)))))
|
||||
(bind-params* precompiled params 0)
|
||||
))
|
||||
|
|
@ -729,7 +728,7 @@
|
|||
))
|
||||
|
||||
(instance? SpecialFormUse p)
|
||||
(if (-> p :code first (= 'fn*))
|
||||
(if (->> p :code first (contains? #{'fn* 'fn}))
|
||||
(do
|
||||
(swap! params-atom conj (:code p))
|
||||
pred*
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@
|
|||
|
||||
(i/fn-invocation? path)
|
||||
(let [[op & params] path]
|
||||
(if (special-symbol? op)
|
||||
;; need special case for 'fn since macroexpand does NOT
|
||||
;; expand fn when run on cljs code, but it's also not considered a special symbol
|
||||
(if (or (= 'fn op) (special-symbol? op))
|
||||
`(com.rpl.specter.impl/->SpecialFormUse ~path (quote ~path))
|
||||
`(com.rpl.specter.impl/->FnInvocation
|
||||
~(ic-prepare-path locals-set op)
|
||||
|
|
@ -351,7 +353,7 @@
|
|||
(fn [e]
|
||||
(cond (or (set? e)
|
||||
(map? e) ; in case inline maps are ever extended
|
||||
(and (i/fn-invocation? e) (= 'fn* (first e))))
|
||||
(and (i/fn-invocation? e) (contains? #{'fn* 'fn} (first e))))
|
||||
[e]
|
||||
|
||||
(i/fn-invocation? e)
|
||||
|
|
@ -399,7 +401,6 @@
|
|||
~(mapv (fn [p] `(fn [] ~p)) possible-params)
|
||||
))
|
||||
]
|
||||
;; in order to pass the used locals to the clj handle-params macro
|
||||
`(let [info# (i/get-path-cache ~cache-id)
|
||||
|
||||
^com.rpl.specter.impl.CachedPathInfo info#
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
[cljs.test :refer [is deftest]]
|
||||
[cljs.test.check.cljs-test :refer [defspec]]
|
||||
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
|
||||
[com.rpl.specter.test-helpers :refer [ic-test]]
|
||||
[com.rpl.specter.macros
|
||||
:refer [paramsfn defprotocolpath defnav extend-protocolpath
|
||||
nav declarepath providepath select select-one select-one!
|
||||
|
|
@ -10,7 +11,7 @@
|
|||
(: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.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!
|
||||
|
|
@ -858,3 +859,67 @@
|
|||
(= q1 q2)
|
||||
(= (type q1) (type q2))))))
|
||||
|
||||
(def ^:dynamic *APATH* s/keypath)
|
||||
|
||||
(deftest inline-caching-test
|
||||
(ic-test
|
||||
true
|
||||
[k]
|
||||
[s/ALL (s/must k)]
|
||||
inc
|
||||
[{:a 1} {:b 2 :c 3} {:a 7 :d -1}]
|
||||
[[:a] [:b] [:c] [:d] [:e]])
|
||||
(ic-test
|
||||
true
|
||||
[]
|
||||
[s/ALL #{4 5 11} #(> % 2) (fn [e] (< e 7))]
|
||||
inc
|
||||
(range 20)
|
||||
[])
|
||||
(ic-test
|
||||
false
|
||||
[v]
|
||||
(if v :a :b)
|
||||
inc
|
||||
{:a 1 :b 2}
|
||||
[[true] [false]])
|
||||
(ic-test
|
||||
false
|
||||
[k]
|
||||
(*APATH* k)
|
||||
str
|
||||
{:a 1 :b 2}
|
||||
[[:a] [:b] [:c]]
|
||||
)
|
||||
(binding [*APATH* s/must]
|
||||
(ic-test
|
||||
false
|
||||
[k]
|
||||
(*APATH* k)
|
||||
inc
|
||||
{:a 1 :b 2}
|
||||
[[:a] [:b] [:c]]
|
||||
))
|
||||
(ic-test
|
||||
true
|
||||
[k k2]
|
||||
[s/ALL (s/selected? (s/must k) #(> % 2)) (s/must k2)]
|
||||
dec
|
||||
[{:a 1 :b 2} {:a 10 :b 6} {:c 7 :b 8} {:c 1 :d 9} {:c 3 :d -1}]
|
||||
[[:a :b] [:b :a] [:c :d] [:b :c]]
|
||||
)
|
||||
;; TODO: test exception thrown when can't cache and must-cache-paths!
|
||||
)
|
||||
|
||||
;;TODO:
|
||||
;; make a macro to help with testing inline caching
|
||||
;; - put into test-helpers
|
||||
;; - do must-cache-paths!
|
||||
;; - take in params vec, path expression, data, transform fn, and sequence of param vecs
|
||||
;; - verify that functional version gets same result as inline
|
||||
;; caching version run on the data multiple times (make sure same callsite)
|
||||
;; - have another test that turns must-cache-paths on and verifies certain paths
|
||||
;; don't cache (but still run with must-cache-paths off)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
(ns com.rpl.specter.test-helpers
|
||||
(:require [clojure.test.check
|
||||
[generators :as gen]
|
||||
[properties :as prop]]))
|
||||
[properties :as prop]]
|
||||
[clojure.test]
|
||||
[cljs.test])
|
||||
(:use [com.rpl.specter.macros :only [select transform]]
|
||||
[com.rpl.specter :only [select* transform* must-cache-paths!]]))
|
||||
|
||||
|
||||
;; it seems like gen/bind and gen/return are a monad (hence the names)
|
||||
;; this is only for clj (cljs version in different file)
|
||||
(defmacro for-all+ [bindings & body]
|
||||
(let [parts (partition 2 bindings)
|
||||
vars (vec (map first parts))
|
||||
|
|
@ -15,3 +20,22 @@
|
|||
(reverse parts))]
|
||||
`(prop/for-all [~vars ~genned]
|
||||
~@body )))
|
||||
|
||||
|
||||
(defmacro ic-test [must-cache? params-decl apath transform-fn data params]
|
||||
(let [platform (if (contains? &env :locals) :cljs :clj)
|
||||
is-sym (if (= platform :clj) 'clojure.test/is 'cljs.test/is)]
|
||||
`(let [icfnsel# (fn [~@params-decl] (select ~apath ~data))
|
||||
icfntran# (fn [~@params-decl] (transform ~apath ~transform-fn ~data))
|
||||
regfnsel# (fn [~@params-decl] (select* ~apath ~data))
|
||||
regfntran# (fn [~@params-decl] (transform* ~apath ~transform-fn ~data))
|
||||
params# (if (empty? ~params) [[]] ~params)
|
||||
]
|
||||
(must-cache-paths! ~must-cache?)
|
||||
(dotimes [_# 3]
|
||||
(doseq [ps# params#]
|
||||
(~is-sym (= (apply icfnsel# ps#) (apply regfnsel# ps#)))
|
||||
(~is-sym (= (apply icfntran# ps#) (apply regfntran# ps#)))
|
||||
))
|
||||
(must-cache-paths! false)
|
||||
)))
|
||||
|
|
|
|||
Loading…
Reference in a new issue