Skip to content
Snippets Groups Projects
Unverified Commit 2a260cc9 authored by Chris Truter's avatar Chris Truter Committed by GitHub
Browse files

Demonstrate nesting dynamic redefines (#43496)

parent f61a0657
Branches
Tags
No related merge requests found
......@@ -318,7 +318,11 @@
with-test-drivers]
[schema-migrations-test.impl
with-temp-empty-app-db])
with-temp-empty-app-db]
[tu.dr
dynamic-value
with-dynamic-redefs])
;; Rename this instead of using `import-vars` to make it clear that it's related to `=?`
(p/import-fn hawk.approx/malli malli=?)
......@@ -327,11 +331,3 @@
(alter-meta! #'with-temp update :doc str "\n\n Note: by default, this will execute its body inside a transaction, making
it thread safe. If it is wrapped in a call to [[metabase.test/test-helpers-set-global-values!]], it will affect the
global state of the application database.")
;; Cursive does not understand p/import-macro, so we just proxy this manually
(defmacro with-dynamic-redefs
"A thread-safe version of with-redefs. It only support functions, and adds a fair amount of overhead.
It works by replacing each original definition with a proxy the first time it is redefined.
This proxy uses a dynamic mapping to check whether the function is currently redefined."
[bindings & body]
`(tu.dr/with-dynamic-redefs ~bindings ~@body))
......@@ -8,8 +8,8 @@
"A thread-local mapping from vars to their most recently bound definition."
{})
(defn- get-local-definition
"Get the version of this function that is in scope. It is the unpatched version if there is no override."
(defn dynamic-value
"Get the value of this var that is in scope. It is the unpatched version if there is no override."
[a-var]
(get *local-redefs* a-var
(get (meta a-var) ::original)))
......@@ -18,7 +18,7 @@
"Build a proxy function to intercept the given var. The proxy checks the current scope for what to call."
[a-var]
(fn [& args]
(let [current-f (get-local-definition a-var)]
(let [current-f (dynamic-value a-var)]
(apply current-f args))))
(defn patch-vars!
......
......@@ -102,3 +102,19 @@
(take-latch)
(testing "The original definition survives"
(is (= "original" (clump "orig" "inal")))))))
(defn mock-me-inner []
:mock/original)
(defn mock-me-outer []
(mock-me-inner))
(deftest with-dynamic-redefs-nested-binding-test
(defn z []
(mt/with-dynamic-redefs [mock-me-outer
(let [orig (mt/dynamic-value mock-me-outer)]
(fn []
(mt/with-dynamic-redefs [mock-me-inner (constantly :mock/redefined)]
(orig))))]
(mock-me-outer)))
(is (= :mock/redefined (z))))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment