Skip to content

Commit

Permalink
Merge pull request #45 from pitch-io/fix-mocking-again
Browse files Browse the repository at this point in the history
Correctly reset original binding values when using `setup-mocks`
  • Loading branch information
jo-sm authored Jun 19, 2023
2 parents 0de19ae + f189493 commit 95c23e0
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 17 deletions.
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

# 1.1.4

## Bugfixes

- [Fix `setup-mocks` and `with-mocks` regression when resetting to the original bindings.](https://github.com/pitch-io/cljest/pull/45)

# 1.1.3

This version and 1.1.2 have no user facing changes except that they make the `cljdoc` build work completely, as in `1.1.1` while the analysis worked, the docs didn't.
Expand Down
2 changes: 1 addition & 1 deletion cljest/build.edn
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{:lib com.pitch/cljest
:version "1.1.3"
:version "1.1.4"
:scm {:url "https://github.com/pitch-io/cljest"
:connection "scm:git:git://github.com/pitch-io/cljest.git"
:developerConnection "scm:git:[email protected]:pitch-io/cljest.git"}
Expand Down
2 changes: 1 addition & 1 deletion cljest/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 25 additions & 11 deletions cljest/src/cljest/helpers/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,32 @@
"Similar to `with-redefs` but allows arbitrarily beginning and ending when the bindings are mocked and reset by calling
`start` and `finish` respectively."
[start finish bindings & body]
(let [names (take-nth 2 bindings)
vals (take-nth 2 (drop 1 bindings))
wrapped-vals (map (fn [v] (list 'fn [] v)) vals)
orig-val-syms (for [_ names] (gensym))
temp-val-syms (for [_ names] (gensym))
binds (map vector names temp-val-syms)
redefs (reverse (map vector names orig-val-syms))
(let [original-syms (take-nth 2 bindings)
orig-vals (take-nth 2 (drop 1 bindings))

;; Wrap the values in a function so that they get recreated on each call. This
;; prevents something stateful from "keeping" its state in multiple test cases.
wrapped-orig-vals (map (fn [v] (list 'fn [] v)) orig-vals)

;; Generate new symbols for both the original values and the
;; temporary values
orig-val-syms (for [_ original-syms] (gensym))
temp-val-syms (for [_ original-syms] (gensym))

;; Create new vectors that sets the original symbols to the temporary ones
mocked-binds (map vector original-syms temp-val-syms)

;; Put the bindings back. Use the same function call method as above to mimic
;; how we handle mocks
orig-binds (reverse (map (fn [name v] [name (list 'fn [] v)]) original-syms orig-val-syms))

;; The actual `(set! sym (val))`. It calls whatever `v` it, so the values need
;; to be wrapped in a function to allow for that.
bind-value (fn [[k v]] (list 'set! k (list v)))]
`(let [~@(interleave orig-val-syms names)
~@(interleave temp-val-syms wrapped-vals)
~start #(do ~@(map bind-value binds))
~finish #(do ~@(map bind-value redefs))]
`(let [~@(interleave orig-val-syms original-syms)
~@(interleave temp-val-syms wrapped-orig-vals)
~start #(do ~@(map bind-value mocked-binds))
~finish #(do ~@(map bind-value orig-binds))]
~@body)))

(defmacro setup-mocks
Expand Down
12 changes: 11 additions & 1 deletion cljest/src/cljest/helpers/core_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
(swap! counter dec)
@counter)))

;; The presence of this function validates mocking the symbol
;; doesn't cause the function to be called. See https://github.com/pitch-io/cljest/issues/44
;; The same could be done with a primitive value that can't be `.call`-ed, but this
;; will show a nicer error.
(defn ^:private my-super-cool-fn
[]
(throw (js/Error. "This function should never be called!")))

(h/setup-mocks [something-stateful (let [counter (atom 0)]
(fn []
(swap! counter (partial + 2))
Expand All @@ -39,7 +47,9 @@
something-else-stateful (let [counter (atom 0)]
(fn []
(swap! counter #(- % 2))
@counter))])
@counter))

my-super-cool-fn (constantly nil)])

(it "works"
(is (= 2 (something-stateful)))
Expand Down
4 changes: 2 additions & 2 deletions jest-preset-cljest/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion jest-preset-cljest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jest-preset-cljest",
"version": "1.1.3",
"version": "1.1.4",
"description": "A preset for Jest to allow compiling ClojureScript tests",
"main": "jest-preset.js",
"scripts": {},
Expand Down

0 comments on commit 95c23e0

Please sign in to comment.