summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2010-10-29 11:26:46 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-11-05 08:41:43 -0700
commit178d8c42609d899208e745b76b89297c4287c078 (patch)
tree8b0383e11dd5a28fc0838f83efccf35d7c21cb56 /src
parente354b01133e7cff8dc0d0eb9e90cde894c12e127 (diff)
Add with-redefs macro and with-redefs-fn, CLJ-665
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 42ca9449..4cdf794d 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -6193,3 +6193,38 @@
[fdecl]
(if-let [bad-args (seq (remove #(vector? %) (map first fdecl)))]
(throw (IllegalArgumentException. (str "Parameter declaration " (first bad-args) " should be a vector")))))
+
+(defn with-redefs-fn
+ "Temporarily redefines Vars during a call to func. Each val of
+ binding-map will replace the root value of its key which must be
+ a Var. After func is called with no args, the root values of all
+ the Vars will be set back to their old values. These temporary
+ changes will be visible in all threads. Useful for mocking out
+ functions during testing."
+ {:added "1.3"}
+ [binding-map func]
+ (let [root-bind (fn [m]
+ (doseq [[a-var a-val] m]
+ (.bindRoot ^clojure.lang.Var a-var a-val)))
+ old-vals (zipmap (keys binding-map)
+ (map deref (keys binding-map)))]
+ (try
+ (root-bind binding-map)
+ (func)
+ (finally
+ (root-bind old-vals)))))
+
+(defmacro with-redefs
+ "binding => var-symbol temp-value-expr
+
+ Temporarily redefines Vars while executing the body. The
+ temp-value-exprs will be evaluated and each resulting value will
+ replace in parallel the root value of its Var. After the body is
+ executed, the root values of all the Vars will be set back to their
+ old values. These temporary changes will be visible in all threads.
+ Useful for mocking out functions during testing."
+ {:added "1.3"}
+ [bindings & body]
+ `(with-redefs-fn ~(zipmap (map #(list `var %) (take-nth 2 bindings))
+ (take-nth 2 (next bindings)))
+ (fn [] ~@body)))