Skip to content

Commit

Permalink
Merge pull request #841 from NoahTheDuke/nb/instrument-external-funct…
Browse files Browse the repository at this point in the history
…ions

Allow instrumenting external functions
  • Loading branch information
ikitommi authored Feb 21, 2023
2 parents 12513d2 + 197e7db commit 8f35221
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/malli/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2475,22 +2475,24 @@
(swap! -function-schemas* assoc-in [key ns name] (merge data {:schema (f ?schema), :ns ns, :name name}))))

#?(:clj
(defmacro => [name value]
(defmacro => [given-sym value]
(let [cljs-resolve (when (:ns &env) (ns-resolve 'cljs.analyzer.api 'resolve))
cljs-resolve-symbols (fn [env d]
(walk/postwalk (fn [x] (cond->> x (symbol? x) (or (:name (cljs-resolve env x)))))
d))
name' `'~(symbol (str name))
ns' `'~(symbol (str *ns*))
sym `'~(symbol (str *ns*) (str name))
name-str (name given-sym)
ns-str (str (or (not-empty (namespace given-sym)) *ns*))
name' `'~(symbol name-str)
ns' `'~(symbol ns-str)
sym `'~(symbol ns-str name-str)
value' (cond->> value (:ns &env) (cljs-resolve-symbols &env))]
;; in cljs we need to register the schema in clojure (the cljs compiler)
;; so it is visible in the (function-schemas :cljs) map at macroexpansion time.
(if (:ns &env)
(do
(-register-function-schema! (symbol (str *ns*)) name value' (meta name) :cljs identity)
`(do (-register-function-schema! ~ns' ~name' ~value' ~(meta name) :cljs identity) ~sym))
`(do (-register-function-schema! ~ns' ~name' ~value' ~(meta name)) ~sym)))))
(-register-function-schema! (symbol ns-str) (symbol name-str) value' (meta given-sym) :cljs identity)
`(do (-register-function-schema! ~ns' ~name' ~value' ~(meta given-sym) :cljs identity) ~sym))
`(do (-register-function-schema! ~ns' ~name' ~value' ~(meta given-sym)) ~sym)))))

(defn -instrument
"Takes an instrumentation properties map and a function and returns a wrapped function,
Expand Down
19 changes: 19 additions & 0 deletions test/malli/instrument/cljs_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,22 @@
(deftest check-test
(let [results (mi/check)]
(is (map? results))))

(deftest instrument-external-test

(testing "Without instrumentation"
(is (thrown?
js/Error
#_:clj-kondo/ignore
(select-keys {:a 1} :a))))

(testing "With instrumentation"
(m/=> clojure.core/select-keys [:=> [:cat map? sequential?] map?])
(with-out-str (mi/instrument! {:filters [(mi/-filter-ns 'clojure.core)]}))
(is (thrown-with-msg?
js/Error
#":malli.core/invalid-input"
#_:clj-kondo/ignore
(select-keys {:a 1} :a)))
(is (= {:a 1} (select-keys {:a 1} [:a])))
(with-out-str (mi/unstrument! {:filters [(mi/-filter-ns 'clojure.core)]}))))
19 changes: 19 additions & 0 deletions test/malli/instrument_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,22 @@
[:=> [:cat :int :int] :int]]
(mi/-schema #'f2)))
(is (= nil (mi/-schema #'f3))))

(deftest instrument-external-test

(testing "Without instrumentation"
(is (thrown?
java.lang.IllegalArgumentException
#_:clj-kondo/ignore
(select-keys {:a 1} :a))))

(testing "With instrumentation"
(m/=> clojure.core/select-keys [:=> [:cat map? sequential?] map?])
(with-out-str (mi/instrument! {:filters [(mi/-filter-ns 'clojure.core)]}))
(is (thrown-with-msg?
Exception
#":malli.core/invalid-input"
#_:clj-kondo/ignore
(select-keys {:a 1} :a)))
(is (= {:a 1} (select-keys {:a 1} [:a])))
(with-out-str (mi/unstrument! {:filters [(mi/-filter-ns 'clojure.core)]}))))
19 changes: 19 additions & 0 deletions test/malli/instrument_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,22 @@
(deftest ^:simple check-test
(let [results (mi/check)]
(is (map? results))))

(deftest ^:simple instrument-external-test

(testing "Without instrumentation"
(is (thrown?
js/Error
#_:clj-kondo/ignore
(select-keys {:a 1} :a))))

(testing "With instrumentation"
(m/=> cljs.core/select-keys [:=> [:cat map? sequential?] map?])
(with-out-str (mi/instrument! {:filters [(mi/-filter-ns 'cljs.core)]}))
(is (thrown-with-msg?
js/Error
#":malli.core/invalid-input"
#_:clj-kondo/ignore
(select-keys {:a 1} :a)))
(is (= {:a 1} (select-keys {:a 1} [:a])))
(with-out-str (mi/unstrument! {:filters [(mi/-filter-ns 'cljs.core)]}))))

0 comments on commit 8f35221

Please sign in to comment.