Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add with-redefs

Remove duplication by using with-redefs in binding
  • Loading branch information...
commit ad771a67df8d69792bb81c04da3ce18fd4837f2c 1 parent 29c8597
@trptcolin trptcolin authored swannodette committed
View
39 src/clj/cljs/core.clj
@@ -862,6 +862,28 @@
calls."
`(new cljs.core/Delay (atom {:done false, :value nil}) (fn [] ~@body)))
+(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. Useful for mocking out functions during testing."
+ [bindings & body]
+ (let [names (take-nth 2 bindings)
+ vals (take-nth 2 (drop 1 bindings))
+ tempnames (map (comp gensym name) names)
+ binds (map vector names vals)
+ resets (reverse (map vector names tempnames))
+ bind-value (fn [[k v]] (list 'set! k v))]
+ `(let [~@(interleave tempnames names)]
+ (try
+ ~@(map bind-value binds)
+ ~@body
+ (finally
+ ~@(map bind-value resets))))))
+
(defmacro binding
"binding => var-symbol init-expr
@@ -871,22 +893,9 @@
are made in parallel (unlike let); all init-exprs are evaluated
before the vars are bound to their new values."
[bindings & body]
- (let [names (take-nth 2 bindings)
- vals (take-nth 2 (drop 1 bindings))
- tempnames (map (comp gensym name) names)
- binds (map vector names vals)
- resets (reverse (map vector names tempnames))]
+ (let [names (take-nth 2 bindings)]
(cljs.analyzer/confirm-bindings &env names)
- `(let [~@(interleave tempnames names)]
- (try
- ~@(map
- (fn [[k v]] (list 'set! k v))
- binds)
- ~@body
- (finally
- ~@(map
- (fn [[k v]] (list 'set! k v))
- resets))))))
+ `(with-redefs ~bindings ~@body)))
(defmacro condp
"Takes a binary predicate, an expression, and a set of clauses.
View
7 test/cljs/cljs/binding_test.cljs
@@ -4,4 +4,9 @@
(defn test-binding []
(binding [o/*foo* 2]
(assert (= o/*foo* 2)))
- (assert (= o/*foo* 1)))
+ (assert (= o/*foo* 1)))
+
+(defn test-with-redefs []
+ (with-redefs [o/bar 2]
+ (assert (= o/bar 2)))
+ (assert (= o/bar 10)))
View
4 test/cljs/cljs/binding_test_other_ns.cljs
@@ -1,3 +1,5 @@
(ns cljs.binding-test-other-ns)
-(def ^:dynamic *foo* 1)
+(def ^:dynamic *foo* 1)
+
+(def bar 10)
View
1  test/cljs/test_runner.cljs
@@ -18,6 +18,7 @@
(string-test/test-string)
(data-test/test-data)
(binding-test/test-binding)
+(binding-test/test-with-redefs)
(ns-test/test-ns)
(macro-test/test-macros)
(letfn-test/test-letfn)
Please sign in to comment.
Something went wrong with that request. Please try again.