-
Notifications
You must be signed in to change notification settings - Fork 3
/
core.clj
64 lines (51 loc) · 1.3 KB
/
core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(ns mock-clj.core)
"""
------------------------------------
Internal functions - ignore these
"""
; Check if input is like '(var x) or #'x
(defn- var-symbol? [v]
(and
(seq? v)
(= 2 (count v))
(= (first v) 'var)))
(defn- try-strip-var [v]
(if (var-symbol? v)
(second v)
v))
(defmacro make-mock
([] `(make-mock nil))
([stub]
(let [stub-symbol-name (gensym)]
`(let [~'state (atom [])
~stub-symbol-name ~stub]
(with-meta
(fn [& ~'args]
(swap! ~'state conj ~'args)
; If stub is a function, execute it
(if (fn? ~stub-symbol-name)
(apply ~stub-symbol-name ~'args)
~stub-symbol-name))
{:args ~'state})))))
(defn- gen-redefs [[m stub & spec]]
(let [sm (try-strip-var m)]
(into
[sm `(make-mock ~stub)]
(when spec
(gen-redefs spec)))))
(defn- if-var->obj [m]
(if (var? m)
(deref m)
m))
"""
------------------------------------
APIs
"""
(defn calls [m] @(-> m if-var->obj meta :args))
(defn last-call [m] (last (calls m)))
(defn called? [m] (not-empty (calls m)))
(defn call-count [m] (-> m calls count))
(defn reset-calls! [m] (reset! (:args (meta m)) []))
(defmacro with-mock [specs & body]
`(with-redefs ~(gen-redefs specs)
(do ~@body)))